Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ambiguation for some packages and additional licenses #9

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

pkgname=vrms-arch-git
_pkgname=vrms-arch
pkgver=2.0.r0.g86a3195
pkgver=2.0.1.r3.g79316e8
pkgrel=1
pkgdesc="Virtual Richard M. Stallman for Arch Linux (gardenapple's fork)"
arch=('any')
Expand Down
11 changes: 11 additions & 0 deletions src/vrms_arch/disambiguation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
'adobe-source-serif-pro-fonts': ['OFL'],
'amd-ucode': ['custom:non-free'],
'aom': ['BSD', 'custom:free'],
'apptainer': ['BSD-3-Clause-LBNL'],
'blas': ['custom:BSD-like'],
'boost': ['Boost'],
'boost-libs': ['Boost'],
Expand All @@ -17,6 +18,7 @@
'cups-filters': ['GPL', 'GPL2', 'GPL3-only', 'GPL3'],
'db': ['custom:Sleepycat'],
'discord': ['custom:non-free'],
'endless-sky': ['custom:GPL-2.0-or-later', 'custom:GPL-3.0-or-later', 'custom:public-domain', 'custom:CC0', 'custom:CC-BY-2.0', 'custom:CC-BY-3.0', 'custom:CC-BY-4.0', 'custom:CC-BY-SA-3.0', 'custom:CC-BY-SA-4.0'],
'expat': ['MIT'],
'file': ['BSD'],
'flashplugin': ['custom:non-free'],
Expand Down Expand Up @@ -131,6 +133,7 @@
'spirv-tools': ['Apache'],
'steam': ['custom:non-free'],
'sudo': ['ISC', 'BSD3', 'BSD2', 'ZLIB'],
'svt-av1': ['BSD-3-Clause'], # additionally 'Alliance for Open Media Patent License 1.0'
'tcl': ['custom:BSD-like'],
'tk': ['custom:BSD-like'],
'ttf-bitstream-vera': ['custom:bitstream-vera'],
Expand All @@ -157,6 +160,7 @@
'xfce4-wavelan-plugin': ['BSD2'],
'xfce4-xkb-plugin': ['BSD2'],
'xkeyboard-config': ['MIT', 'custom:HPND', 'custom:X11', 'custom:MIT-style'],
'xcalib': ['GPL-2.0'], # additionally with optional postcardware
'xorg-bdftopcf': ['custom:X11'],
'xorg-fonts-encodings': ['custom:Public Domain'],
'xorg-font-util': ['custom:UCD', 'MIT', 'BSD2'],
Expand Down Expand Up @@ -197,6 +201,8 @@
'zoom': ['custom:non-free'], # AUR
'zsh-abbr': ['custom:CC-BY-NC-SA-4.0', 'custom:Hippocratic'], # AUR
'zsh': ['custom:MIT-style', 'GPL'],
'zeroc-ice': ['GPL-2.0-only'], # alternatively non-free commercial license
'zeroc-ice-java': ['GPL-2.0-only'], # alternatively non-free commerical license
}

class Package(object):
Expand All @@ -213,5 +219,10 @@ def __init__(self, db):
self.packages.append(Package(pkg.name, AMBIGUOUS_PACKAGES[pkg.name]))
elif pkg.name.startswith("lib32") and pkg.name[6:] in AMBIGUOUS_PACKAGES:
self.packages.append(Package(pkg.name, AMBIGUOUS_PACKAGES[pkg.name[6:]]))
elif any([' OR ' in l for l in pkg.licenses]):
licenses = []
for l in pkg.licenses:
licenses.extend(l.split(' OR '))
self.packages.append(Package(pkg.name, licenses))
Copy link
Owner

@gardenappl gardenappl Oct 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think OR should be a special case, we should check if at least one of the OR terms is free, and if so, discard the commercial alternatives. At least that's how I'd interpret that legally, I am not a lawyer though.

Funny enough, earlier I was thinking of some over-engineered solution of creating some parser for AND and OR alternative licenses, and resolving them to see if the product can be used with a free license. But honestly just splitting the string on OR probably works just as well, no need for a parser.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought, doesn't this conflict with things like GPL2-or-later?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought, doesn't this conflict with things like GPL2-or-later?

Could indeed be if someone declared it as e.g. custom:GPL2 OR later, because it is before the cleaning. I agree it’s not the cleanest hack, but for the given packages (five in Manjaro) it works.

cloud-init: ['GPL-3.0-only OR Apache-2.0']
maturin: ['Apache-2.0 OR MIT']
openpgp-card-tools: ['Apache-2.0 OR MIT']
python-maturin: ['Apache-2.0 OR MIT']
snd: ['BSD-2-Clause', 'GPL-2.0-or-later OR GL2PS', 'LLGPL', 'TCL']

But I agree that proper treatment would be of course better. This would also include the proper treatment of exceptions and their splitting word WITH.

If you prefer I can also remove this addition for now. And in future we can think about how to implement this properly. Let me know!

else:
self.packages.append(Package(pkg.name, pkg.licenses))
108 changes: 82 additions & 26 deletions src/vrms_arch/license_finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,65 @@

def clean_license_name(license):
license = license.lower()
license = re.sub('(?:^custom:|[,\s_"-])', '', license)
license = re.sub('(?:^custom:|[,\s_"/\(\)\:-])', '', license)
license = re.sub('licence', 'license', license)
return license

AMBIGUOUS_LICENSES = [clean_license_name(license) for license in [
"custom",
"other",
"unknown",
# CCPL (Creative Commons) should be specified with one of the
# sublicenses (one of /usr/share/licenses/common/CCPL/*) , some of
# sublicenses (one of /usr/share/licenses/common/CCPL/*), some of
# which are non-free
"CC",
"CCPL",
"Creative Commons",
"CCPL", # ['claws-mail-themes', '0ad', '0ad-data', 'archlinux-lxdm-theme', 'mari0', 'performous-freesongs']
"Creative Commons"
]]

FREE_LICENSES = [clean_license_name(license) for license in [
'AFL-3.0',
'AGPL',
'AGPL3',
'AGPL-3.0-only',
'AGPL-3.0-or-later',
'Apache',
'Apache2',
'Apache 2.0',
'Apache 2.0 with LLVM Exception',
'Apache 2.0 with LLVM Execption',
'Apache License (2.0)',
'Arphic Public License',
'Artistic',
'Artistic 2.0',
'Beerware',
'bitstream-vera',
'Boost',
'0BSD',
'BSD',
'BSD2',
'BSD-2-clause',
'BSD-2-Clause',
'BSD-2-Clause-Patent',
'BSD3',
'BSD-3-clause',
'BSD-3-Clause',
'BSD-3-Clause-LBNL',
'BSD License',
'BSD-like',
'BSDL',
'BSD-style',
'BSL',
'bzip2',
'CC0',
'CC0 1.0',
'CC0-1.0',
'CC-BY',
'CC-BY-2.5',
'CC-BY-3.0',
'CC-BY-4.0',
'CC-BY-SA',
'CC-BY-SA-2.5',
'CC-BY-SA-3.0',
'CC BY-SA-4.0',
'CC-BY-SA-4.0',
'CCPL:by',
'CCPL:by-4.0'
'CCPL:by-sa',
'CCPL:cc-by',
'CCPL:cc-by-sa',
Expand All @@ -62,29 +73,50 @@ def clean_license_name(license):
'custom:free',
'dumb',
'EDL',
'EDL-1.0',
'EPL',
'EPL/1.1',
'EPL-1.1',
'EPL-2.0',
'etpan',
'EUPL-1.1',
'EUPL-1.2',
'ex',
'Expat',
'FDL',
'FDL1.2',
'FDL1.3',
'FFSL',
'FIPL',
'font embedding exception',
'Free Public License 1.0.0',
'FSFAP',
'GD',
'GFDL',
'GFDL-1.1-no-invariants-or-later',
'GFDL-1.2-only',
'GFDL-1.2-no-invariants-only',
'GFDL-1.3-or-later',
'GFL',
'GPL',
'GPL-1.0-or-later',
'GPL2+',
'GPL2',
'GPL-2.0+',
'GPL-2.0',
'GPL-2.0-only',
'GPL-2.0-or-later',
'GPL-2.0-or-later with GCC-exception-2.0 exception',
'GPL2-only',
'GPL2-or-later',
'GPL2 or any later version',
'GPL2 with OpenSSL exception',
'GPL3',
'GPL-3.0',
'GPL-3.0-only',
'GPL-3.0-or-later',
'GPL3+GPLv2',
'GPL3-only',
'GPL3-or-later',
'GPL3 or any later version',
'GPL/BSD',
'GPL+FE',
Expand All @@ -103,13 +135,25 @@ def clean_license_name(license):
'Khronos',
'LGPL',
'LGPL2',
'LGPL-2.0-only',
'LGPL-2.0-or-later',
'LGPL2.1+',
'LGPL2.1',
'LGPL2_1',
'LGPL-2.1-only',
'LGPL-2.1-or-later',
'LGPL2.1 with linking exception',
'LGPL3',
'LGPLv3+',
'LGPL-3.0',
'LGPL-3.0-only',
'LGPL-3.0-or-later',
'LGPL-3.0+ with WxWindows-exception-3.1',
'LGPL-exception',
'libpng',
'libtiff',
'libxcomposite',
'LLGPL',
'LPPL',
'lsof',
'MirOS',
Expand All @@ -122,24 +166,29 @@ def clean_license_name(license):
'MPL2',
'MPLv2',
'NCSA',
'NCSAOSL',
'neovim',
'nfsidmap',
'NoCopyright',
'NYSL',
'OASIS',
'OFL',
'OFL-1.1',
'OPEN DATA LICENSE',
'OpenLDAP',
'OpenMPI',
'OpenSSL Linking Exception',
'OSGPL',
'perl',
'PerlArtistic',
'PerlArtistic2',
'PHP',
'PHP-3.01',
'pil',
'PostgreSQL',
'PSF',
'Public Domain',
'Public',
'public-domain',
'Python',
'Qhull',
'QPL',
Expand All @@ -148,6 +197,7 @@ def clean_license_name(license):
'Ruby',
'scite',
'scowl',
'sdbus-c++ LGPL Exception 1.0',
'Sendmail',
'Sendmail open source license',
'SGI',
Expand All @@ -161,9 +211,13 @@ def clean_license_name(license):
'tcl',
'TekHVC',
'TRADEMARKS',
'Ubuntu Font Licence 1.0',
'Tumbolia',
'UBDL',
'Ubuntu Font License 1.0',
'UCD',
'UFL-1.0',
'Unicode-DFS',
'University of California and Stanford University License',
'University of Illinois/NCSA Open Source License',
'Unlicense',
'usermin',
Expand All @@ -179,6 +233,7 @@ def clean_license_name(license):
'X11-DEC',
'XFREE86',
'Xiph',
'Zero-Clause BSD',
'zlib',
'zlib/libpng',
'ZPL',
Expand All @@ -188,23 +243,23 @@ def clean_license_name(license):
# technically not open source but deserve mention
# see https://ethicalsource.dev/
ETHICAL_LICENSES = [clean_license_name(license) for license in [
'custom:JSON', # "shall be used for Good, not Evil"
'custom:ACSL',
'custom:Anti-966',
'custom:Atmosphere',
'custom:CNPL',
'custom:Hippocratic',
'custom:Hippocratic 2.1',
'custom:NoHarm',
'custom:NoHarm-draft',
'custom:NPL',
'custom:PPL',
'JSON', # "shall be used for Good, not Evil"
'ACSL',
'Anti-966',
'Atmosphere',
'CNPL',
'Hippocratic',
'Hippocratic 2.1',
'NoHarm',
'NoHarm-draft',
'NPL',
'PPL',
]]

class LicenseFinder(object):
def __init__(self):
# number of packages
self.num_pkgs = set()
self.num_pkgs = 0

# all of the seen (clean) license names with counts
self.by_license = {}
Expand All @@ -223,7 +278,7 @@ def __init__(self):

def visit_db(self, db):
pkgs = db.packages
self.num_pkgs = len(db.packages)
self.num_pkgs += len(db.packages)

free_pkgs = []

Expand Down Expand Up @@ -295,7 +350,8 @@ def list_all_nonfree_packages(self):
self.list_all_ethical_packages(sys.stderr)

print("\nThere are %d ambiguously licensed packages that vrms cannot certify." % len(self.unknown_packages), file=sys.stderr)
print("Use --list-unknowns to list them (or --help for more info)")
print("Use --list-unknowns to list them (or --help for more info)",
file=sys.stderr)

def list_all_ethical_packages(self, file=sys.stdout):
for epackage in sorted(self.ethical_packages, key=lambda pkg: pkg.name):
Expand Down