mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-10-02 09:10:11 +02:00
lint: license override config option + require FSF/OSI approved licenses by default
This commit is contained in:
parent
3c9535d64b
commit
d5ab303d83
@ -330,3 +330,20 @@ The repository of older versions of applications from the main demo repository.
|
||||
# 'com.facebook.orca',
|
||||
# 'com.android.vending',
|
||||
# )
|
||||
|
||||
# `fdroid lint` checks licenses in metadata against a built white list. By
|
||||
# default we will require license metadata to be present and only allow
|
||||
# licenses approved either by FSF or OSI. We're using the standardized SPDX
|
||||
# license IDs. (https://spdx.org/licenses/)
|
||||
#
|
||||
# We use `python3 -m spdx-license-list print --filter-fsf-or-osi` for
|
||||
# generating our default list. (https://pypi.org/project/spdx-license-list)
|
||||
#
|
||||
# You can override our default list of allowed licenes by setting this option.
|
||||
# Just supply a custom list of licene names you would like to allow. Setting
|
||||
# this to `None` disables this lint check.
|
||||
#
|
||||
# lint_licenses = (
|
||||
# 'Custom-License-A',
|
||||
# 'Another-License',
|
||||
# )
|
||||
|
@ -57,6 +57,7 @@ from pyasn1_modules import rfc2315
|
||||
from pyasn1.error import PyAsn1Error
|
||||
|
||||
import fdroidserver.metadata
|
||||
import fdroidserver.lint
|
||||
from fdroidserver import _
|
||||
from fdroidserver.exception import FDroidException, VCSException, NoSubmodulesException,\
|
||||
BuildException, VerificationException
|
||||
@ -145,6 +146,7 @@ default_config = {
|
||||
using the tools on https://gitlab.com/u/fdroid.
|
||||
''',
|
||||
'archive_older': 0,
|
||||
'lint_licenses': fdroidserver.lint.APPROVED_LICENSES,
|
||||
}
|
||||
|
||||
|
||||
|
@ -440,10 +440,17 @@ def check_format(app):
|
||||
|
||||
|
||||
def check_license_tag(app):
|
||||
'''Ensure all license tags are in https://spdx.org/license-list'''
|
||||
if app.License.rstrip('+') not in FSF_APPROVED_SPDX:
|
||||
yield _('Unexpected license tag "{}"! Use only FSF approved tags '
|
||||
'from https://spdx.org/license-list').format(app.License)
|
||||
'''Ensure all license tags contain only valid/approved values'''
|
||||
if config['lint_licenses'] is None:
|
||||
return
|
||||
if app.License not in config['lint_licenses']:
|
||||
if config['lint_licenses'] == APPROVED_LICENSES:
|
||||
yield _('Unexpected license tag "{}"! Only use FSF or OSI '
|
||||
'approved tags from https://spdx.org/license-list') \
|
||||
.format(app.License)
|
||||
else:
|
||||
yield _('Unexpected license tag "{}"! Only use license tags '
|
||||
'configured in your config file').format(app.License)
|
||||
|
||||
|
||||
def check_extlib_dir(apps):
|
||||
@ -622,38 +629,175 @@ def main():
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# A compiled, public domain list of official SPDX license tags.
|
||||
# generated using: `python3 -m spdx_license_list print --filter-fsf`
|
||||
# Only contains licenes approved by FSF to be libre/free software
|
||||
FSF_APPROVED_SPDX = ['AFL-1.1', 'AFL-1.2', 'AFL-2.0', 'AFL-2.1', 'AFL-3.0',
|
||||
'AGPL-3.0-only', 'AGPL-3.0-or-later', 'APSL-2.0',
|
||||
'Apache-1.0', 'Apache-1.1', 'Apache-2.0', 'Artistic-2.0',
|
||||
'BSD-2-Clause-FreeBSD', 'BSD-3-Clause',
|
||||
'BSD-3-Clause-Clear', 'BSD-4-Clause', 'BSL-1.0',
|
||||
'BitTorrent-1.1', 'CC-BY-4.0', 'CC-BY-SA-4.0', 'CC0-1.0',
|
||||
'CDDL-1.0', 'CECILL-2.0', 'CECILL-B', 'CECILL-C',
|
||||
'CPAL-1.0', 'CPL-1.0', 'ClArtistic', 'Condor-1.1',
|
||||
'ECL-2.0', 'EFL-2.0', 'EPL-1.0', 'EPL-2.0', 'EUDatagrid',
|
||||
'EUPL-1.1', 'EUPL-1.2', 'FSFAP', 'FTL', 'GFDL-1.1-only',
|
||||
'GFDL-1.1-or-later', 'GFDL-1.2-only', 'GFDL-1.2-or-later',
|
||||
'GFDL-1.3-only', 'GFDL-1.3-or-later', 'GPL-2.0-only',
|
||||
'GPL-2.0-or-later', 'GPL-3.0-only', 'GPL-3.0-or-later',
|
||||
'HPND', 'IJG', 'IPA', 'IPL-1.0', 'ISC', 'Imlib2', 'Intel',
|
||||
'LGPL-2.1-only', 'LGPL-2.1-or-later', 'LGPL-3.0-only',
|
||||
'LGPL-3.0-or-later', 'LPL-1.02', 'LPPL-1.2', 'LPPL-1.3a',
|
||||
'MIT', 'MPL-1.1', 'MPL-2.0', 'MS-PL', 'MS-RL', 'NCSA',
|
||||
'NOSL', 'NPL-1.0', 'NPL-1.1', 'Nokia', 'ODbL-1.0',
|
||||
'OFL-1.0', 'OFL-1.1', 'OLDAP-2.3', 'OLDAP-2.7', 'OSL-1.0',
|
||||
'OSL-1.1', 'OSL-2.0', 'OSL-2.1', 'OSL-3.0', 'OpenSSL',
|
||||
'PHP-3.01', 'Python-2.0', 'QPL-1.0', 'RPSL-1.0', 'Ruby',
|
||||
'SGI-B-2.0', 'SISSL', 'SMLNJ', 'SPL-1.0', 'Sleepycat',
|
||||
'UPL-1.0', 'Unlicense', 'Vim', 'W3C', 'WTFPL', 'X11',
|
||||
'XFree86-1.1', 'YPL-1.1', 'ZPL-2.0', 'ZPL-2.1',
|
||||
'Zend-2.0', 'Zimbra-1.3', 'Zlib', 'gnuplot', 'iMatix',
|
||||
'xinetd']
|
||||
# A compiled, public domain list of official SPDX license tags. generated
|
||||
# using: `python3 -m spdx_license_list print --filter-fsf-or-osi` Only contains
|
||||
# licenes approved by either FSF to be free/libre software or OSI to be open
|
||||
# source
|
||||
APPROVED_LICENSES = [
|
||||
'0BSD',
|
||||
'AAL',
|
||||
'AFL-1.1',
|
||||
'AFL-1.2',
|
||||
'AFL-2.0',
|
||||
'AFL-2.1',
|
||||
'AFL-3.0',
|
||||
'AGPL-3.0-only',
|
||||
'AGPL-3.0-or-later',
|
||||
'APL-1.0',
|
||||
'APSL-1.0',
|
||||
'APSL-1.1',
|
||||
'APSL-1.2',
|
||||
'APSL-2.0',
|
||||
'Apache-1.0',
|
||||
'Apache-1.1',
|
||||
'Apache-2.0',
|
||||
'Artistic-1.0',
|
||||
'Artistic-1.0-Perl',
|
||||
'Artistic-1.0-cl8',
|
||||
'Artistic-2.0',
|
||||
'BSD-2-Clause',
|
||||
'BSD-2-Clause-FreeBSD',
|
||||
'BSD-2-Clause-Patent',
|
||||
'BSD-3-Clause',
|
||||
'BSD-3-Clause-Clear',
|
||||
'BSD-3-Clause-LBNL',
|
||||
'BSD-4-Clause',
|
||||
'BSL-1.0',
|
||||
'BitTorrent-1.1',
|
||||
'CATOSL-1.1',
|
||||
'CC-BY-4.0',
|
||||
'CC-BY-SA-4.0',
|
||||
'CC0-1.0',
|
||||
'CDDL-1.0',
|
||||
'CECILL-2.0',
|
||||
'CECILL-2.1',
|
||||
'CECILL-B',
|
||||
'CECILL-C',
|
||||
'CNRI-Python',
|
||||
'CPAL-1.0',
|
||||
'CPL-1.0',
|
||||
'CUA-OPL-1.0',
|
||||
'ClArtistic',
|
||||
'Condor-1.1',
|
||||
'ECL-1.0',
|
||||
'ECL-2.0',
|
||||
'EFL-1.0',
|
||||
'EFL-2.0',
|
||||
'EPL-1.0',
|
||||
'EPL-2.0',
|
||||
'EUDatagrid',
|
||||
'EUPL-1.1',
|
||||
'EUPL-1.2',
|
||||
'Entessa',
|
||||
'FSFAP',
|
||||
'FTL',
|
||||
'Fair',
|
||||
'Frameworx-1.0',
|
||||
'GFDL-1.1-only',
|
||||
'GFDL-1.1-or-later',
|
||||
'GFDL-1.2-only',
|
||||
'GFDL-1.2-or-later',
|
||||
'GFDL-1.3-only',
|
||||
'GFDL-1.3-or-later',
|
||||
'GPL-2.0-only',
|
||||
'GPL-2.0-or-later',
|
||||
'GPL-3.0-only',
|
||||
'GPL-3.0-or-later',
|
||||
'HPND',
|
||||
'IJG',
|
||||
'IPA',
|
||||
'IPL-1.0',
|
||||
'ISC',
|
||||
'Imlib2',
|
||||
'Intel',
|
||||
'LGPL-2.0-only',
|
||||
'LGPL-2.0-or-later',
|
||||
'LGPL-2.1-only',
|
||||
'LGPL-2.1-or-later',
|
||||
'LGPL-3.0-only',
|
||||
'LGPL-3.0-or-later',
|
||||
'LPL-1.0',
|
||||
'LPL-1.02',
|
||||
'LPPL-1.2',
|
||||
'LPPL-1.3a',
|
||||
'LPPL-1.3c',
|
||||
'LiLiQ-P-1.1',
|
||||
'LiLiQ-R-1.1',
|
||||
'LiLiQ-Rplus-1.1',
|
||||
'MIT',
|
||||
'MIT-0',
|
||||
'MPL-1.0',
|
||||
'MPL-1.1',
|
||||
'MPL-2.0',
|
||||
'MPL-2.0-no-copyleft-exception',
|
||||
'MS-PL',
|
||||
'MS-RL',
|
||||
'MirOS',
|
||||
'Motosoto',
|
||||
'Multics',
|
||||
'NASA-1.3',
|
||||
'NCSA',
|
||||
'NGPL',
|
||||
'NOSL',
|
||||
'NPL-1.0',
|
||||
'NPL-1.1',
|
||||
'NPOSL-3.0',
|
||||
'NTP',
|
||||
'Naumen',
|
||||
'Nokia',
|
||||
'OCLC-2.0',
|
||||
'ODbL-1.0',
|
||||
'OFL-1.0',
|
||||
'OFL-1.1',
|
||||
'OGTSL',
|
||||
'OLDAP-2.3',
|
||||
'OLDAP-2.7',
|
||||
'OSET-PL-2.1',
|
||||
'OSL-1.0',
|
||||
'OSL-1.1',
|
||||
'OSL-2.0',
|
||||
'OSL-2.1',
|
||||
'OSL-3.0',
|
||||
'OpenSSL',
|
||||
'PHP-3.0',
|
||||
'PHP-3.01',
|
||||
'PostgreSQL',
|
||||
'Python-2.0',
|
||||
'QPL-1.0',
|
||||
'RPL-1.1',
|
||||
'RPL-1.5',
|
||||
'RPSL-1.0',
|
||||
'RSCPL',
|
||||
'Ruby',
|
||||
'SGI-B-2.0',
|
||||
'SISSL',
|
||||
'SMLNJ',
|
||||
'SPL-1.0',
|
||||
'SimPL-2.0',
|
||||
'Sleepycat',
|
||||
'UPL-1.0',
|
||||
'Unlicense',
|
||||
'VSL-1.0',
|
||||
'Vim',
|
||||
'W3C',
|
||||
'WTFPL',
|
||||
'Watcom-1.0',
|
||||
'X11',
|
||||
'XFree86-1.1',
|
||||
'Xnet',
|
||||
'YPL-1.1',
|
||||
'ZPL-2.0',
|
||||
'ZPL-2.1',
|
||||
'Zend-2.0',
|
||||
'Zimbra-1.3',
|
||||
'Zlib',
|
||||
'gnuplot',
|
||||
'iMatix',
|
||||
'xinetd',
|
||||
]
|
||||
|
||||
# an F-Droid addition, until we can enforce a better option
|
||||
FSF_APPROVED_SPDX.append("PublicDomain")
|
||||
APPROVED_LICENSES.append("PublicDomain")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -179,6 +179,100 @@ class LintTest(unittest.TestCase):
|
||||
logging.debug(warn)
|
||||
self.assertTrue(anywarns)
|
||||
|
||||
def test_check_license_tag_no_custom_pass(self):
|
||||
config = dict()
|
||||
fdroidserver.common.fill_config_defaults(config)
|
||||
fdroidserver.common.config = config
|
||||
fdroidserver.lint.config = config
|
||||
|
||||
app = fdroidserver.metadata.App()
|
||||
app.License = "GPL-3.0-or-later"
|
||||
|
||||
anywarns = False
|
||||
for warn in fdroidserver.lint.check_license_tag(app):
|
||||
anywarns = True
|
||||
logging.debug(warn)
|
||||
self.assertFalse(anywarns)
|
||||
|
||||
def test_check_license_tag_no_custom_fail(self):
|
||||
config = dict()
|
||||
fdroidserver.common.fill_config_defaults(config)
|
||||
fdroidserver.common.config = config
|
||||
fdroidserver.lint.config = config
|
||||
|
||||
app = fdroidserver.metadata.App()
|
||||
app.License = "Adobe-2006"
|
||||
|
||||
anywarns = False
|
||||
for warn in fdroidserver.lint.check_license_tag(app):
|
||||
anywarns = True
|
||||
logging.debug(warn)
|
||||
self.assertTrue(anywarns)
|
||||
|
||||
def test_check_license_tag_with_custom_pass(self):
|
||||
config = dict()
|
||||
fdroidserver.common.fill_config_defaults(config)
|
||||
fdroidserver.common.config = config
|
||||
fdroidserver.lint.config = config
|
||||
config['lint_licenses'] = ['fancy-license', 'GPL-3.0-or-later']
|
||||
|
||||
app = fdroidserver.metadata.App()
|
||||
app.License = "fancy-license"
|
||||
|
||||
anywarns = False
|
||||
for warn in fdroidserver.lint.check_license_tag(app):
|
||||
anywarns = True
|
||||
logging.debug(warn)
|
||||
self.assertFalse(anywarns)
|
||||
|
||||
def test_check_license_tag_with_custom_fail(self):
|
||||
config = dict()
|
||||
fdroidserver.common.fill_config_defaults(config)
|
||||
fdroidserver.common.config = config
|
||||
fdroidserver.lint.config = config
|
||||
config['lint_licenses'] = ['fancy-license', 'GPL-3.0-or-later']
|
||||
|
||||
app = fdroidserver.metadata.App()
|
||||
app.License = "Apache-2.0"
|
||||
|
||||
anywarns = False
|
||||
for warn in fdroidserver.lint.check_license_tag(app):
|
||||
anywarns = True
|
||||
logging.debug(warn)
|
||||
self.assertTrue(anywarns)
|
||||
|
||||
def test_check_license_tag_with_custom_empty(self):
|
||||
config = dict()
|
||||
fdroidserver.common.fill_config_defaults(config)
|
||||
fdroidserver.common.config = config
|
||||
fdroidserver.lint.config = config
|
||||
config['lint_licenses'] = []
|
||||
|
||||
app = fdroidserver.metadata.App()
|
||||
app.License = "Apache-2.0"
|
||||
|
||||
anywarns = False
|
||||
for warn in fdroidserver.lint.check_license_tag(app):
|
||||
anywarns = True
|
||||
logging.debug(warn)
|
||||
self.assertTrue(anywarns)
|
||||
|
||||
def test_check_license_tag_disabled(self):
|
||||
config = dict()
|
||||
fdroidserver.common.fill_config_defaults(config)
|
||||
fdroidserver.common.config = config
|
||||
fdroidserver.lint.config = config
|
||||
config['lint_licenses'] = None
|
||||
|
||||
app = fdroidserver.metadata.App()
|
||||
app.License = "Apache-2.0"
|
||||
|
||||
anywarns = False
|
||||
for warn in fdroidserver.lint.check_license_tag(app):
|
||||
anywarns = True
|
||||
logging.debug(warn)
|
||||
self.assertFalse(anywarns)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
|
Loading…
Reference in New Issue
Block a user