mirror of
https://github.com/f-droid/fdroidserver.git
synced 2025-09-13 22:42:29 +03:00
Merge branch 'lint-config.yml' into 'master'
Lint config.yml See merge request fdroid/fdroidserver!1606
This commit is contained in:
commit
0f5a1a0bfb
4 changed files with 175 additions and 6 deletions
|
@ -675,8 +675,6 @@ def checkupdates_app(app: metadata.App, auto: bool, commit: bool = False) -> Non
|
||||||
if commit:
|
if commit:
|
||||||
logging.info("Commiting update for " + app.metadatapath)
|
logging.info("Commiting update for " + app.metadatapath)
|
||||||
gitcmd = ["git", "commit", "-m", commitmsg]
|
gitcmd = ["git", "commit", "-m", commitmsg]
|
||||||
if 'auto_author' in config:
|
|
||||||
gitcmd.extend(['--author', config['auto_author']])
|
|
||||||
gitcmd.extend(["--", app.metadatapath])
|
gitcmd.extend(["--", app.metadatapath])
|
||||||
if subprocess.call(gitcmd) != 0:
|
if subprocess.call(gitcmd) != 0:
|
||||||
raise FDroidException("Git commit failed")
|
raise FDroidException("Git commit failed")
|
||||||
|
|
|
@ -361,7 +361,7 @@ def fill_config_defaults(thisconfig):
|
||||||
|
|
||||||
# Expand paths (~users and $vars)
|
# Expand paths (~users and $vars)
|
||||||
def expand_path(path):
|
def expand_path(path):
|
||||||
if path is None:
|
if not path or not isinstance(path, str):
|
||||||
return None
|
return None
|
||||||
orig = path
|
orig = path
|
||||||
path = os.path.expanduser(path)
|
path = os.path.expanduser(path)
|
||||||
|
|
|
@ -213,6 +213,83 @@ regex_checks = {
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# config keys that are currently ignored by lint, but could be supported.
|
||||||
|
ignore_config_keys = (
|
||||||
|
'github_releases',
|
||||||
|
'java_paths',
|
||||||
|
)
|
||||||
|
|
||||||
|
bool_keys = (
|
||||||
|
'allow_disabled_algorithms',
|
||||||
|
'androidobservatory',
|
||||||
|
'build_server_always',
|
||||||
|
'deploy_process_logs',
|
||||||
|
'keep_when_not_allowed',
|
||||||
|
'make_current_version_link',
|
||||||
|
'nonstandardwebroot',
|
||||||
|
'per_app_repos',
|
||||||
|
'rclone',
|
||||||
|
'refresh_scanner',
|
||||||
|
's3cmd',
|
||||||
|
'scan_binary',
|
||||||
|
'sync_from_local_copy_dir',
|
||||||
|
)
|
||||||
|
|
||||||
|
check_config_keys = (
|
||||||
|
'ant',
|
||||||
|
'archive',
|
||||||
|
'archive_description',
|
||||||
|
'archive_icon',
|
||||||
|
'archive_name',
|
||||||
|
'archive_older',
|
||||||
|
'archive_url',
|
||||||
|
'archive_web_base_url',
|
||||||
|
'awsaccesskeyid',
|
||||||
|
'awsbucket',
|
||||||
|
'awssecretkey',
|
||||||
|
'binary_transparency_remote',
|
||||||
|
'cachedir',
|
||||||
|
'char_limits',
|
||||||
|
'current_version_name_source',
|
||||||
|
'git_mirror_size_limit',
|
||||||
|
'github_token',
|
||||||
|
'gpghome',
|
||||||
|
'gpgkey',
|
||||||
|
'gradle',
|
||||||
|
'identity_file',
|
||||||
|
'install_list',
|
||||||
|
'java_paths',
|
||||||
|
'keyaliases',
|
||||||
|
'keydname',
|
||||||
|
'keypass',
|
||||||
|
'keystore',
|
||||||
|
'keystorepass',
|
||||||
|
'lint_licenses',
|
||||||
|
'local_copy_dir',
|
||||||
|
'mirrors',
|
||||||
|
'mvn3',
|
||||||
|
'ndk_paths',
|
||||||
|
'path_to_custom_rclone_config',
|
||||||
|
'rclone_config',
|
||||||
|
'repo',
|
||||||
|
'repo_description',
|
||||||
|
'repo_icon',
|
||||||
|
'repo_keyalias',
|
||||||
|
'repo_maxage',
|
||||||
|
'repo_name',
|
||||||
|
'repo_pubkey',
|
||||||
|
'repo_url',
|
||||||
|
'repo_web_base_url',
|
||||||
|
'scanner_signature_sources',
|
||||||
|
'sdk_path',
|
||||||
|
'servergitmirrors',
|
||||||
|
'serverwebroot',
|
||||||
|
'smartcardoptions',
|
||||||
|
'sync_from_local_copy_dir',
|
||||||
|
'uninstall_list',
|
||||||
|
'virustotal_apikey',
|
||||||
|
)
|
||||||
|
|
||||||
locale_pattern = re.compile(r"[a-z]{2,3}(-([A-Z][a-zA-Z]+|\d+|[a-z]+))*")
|
locale_pattern = re.compile(r"[a-z]{2,3}(-([A-Z][a-zA-Z]+|\d+|[a-z]+))*")
|
||||||
|
|
||||||
versioncode_check_pattern = re.compile(r"(\\d|\[(0-9|\\d)_?(a-fA-F)?])[+]")
|
versioncode_check_pattern = re.compile(r"(\\d|\[(0-9|\\d)_?(a-fA-F)?])[+]")
|
||||||
|
@ -791,6 +868,41 @@ def lint_config(arg):
|
||||||
msg += ' '
|
msg += ' '
|
||||||
msg += _('Did you mean {code}?').format(code=', '.join(sorted(m)))
|
msg += _('Did you mean {code}?').format(code=', '.join(sorted(m)))
|
||||||
print(msg)
|
print(msg)
|
||||||
|
elif path.name == config_name and path.parent.name != 'config':
|
||||||
|
valid_keys = set(tuple(common.default_config) + bool_keys + check_config_keys)
|
||||||
|
for key in ignore_config_keys:
|
||||||
|
if key in valid_keys:
|
||||||
|
valid_keys.remove(key)
|
||||||
|
for key in data:
|
||||||
|
if key not in valid_keys:
|
||||||
|
passed = False
|
||||||
|
msg = _("ERROR: {key} not a valid key!").format(key=key)
|
||||||
|
m = difflib.get_close_matches(key.lower(), valid_keys, 2, 0.5)
|
||||||
|
if m:
|
||||||
|
msg += ' '
|
||||||
|
msg += _('Did you mean {code}?').format(code=', '.join(sorted(m)))
|
||||||
|
print(msg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if key in bool_keys:
|
||||||
|
t = bool
|
||||||
|
else:
|
||||||
|
t = type(common.default_config.get(key, ""))
|
||||||
|
|
||||||
|
show_error = False
|
||||||
|
if t is str:
|
||||||
|
if type(data[key]) not in (str, dict):
|
||||||
|
passed = False
|
||||||
|
show_error = True
|
||||||
|
elif type(data[key]) != t:
|
||||||
|
passed = False
|
||||||
|
show_error = True
|
||||||
|
if show_error:
|
||||||
|
print(
|
||||||
|
_("ERROR: {key}'s value should be of type {t}!").format(
|
||||||
|
key=key, t=t.__name__
|
||||||
|
)
|
||||||
|
)
|
||||||
elif path.name in (config_name, categories_name, antifeatures_name):
|
elif path.name in (config_name, categories_name, antifeatures_name):
|
||||||
for key in data:
|
for key in data:
|
||||||
if path.name == config_name and key not in ('archive', 'repo'):
|
if path.name == config_name and key not in ('archive', 'repo'):
|
||||||
|
|
|
@ -345,7 +345,7 @@ class LintTest(unittest.TestCase):
|
||||||
def test_check_categories_from_config_yml(self):
|
def test_check_categories_from_config_yml(self):
|
||||||
"""In config.yml, categories is a list."""
|
"""In config.yml, categories is a list."""
|
||||||
os.chdir(self.testdir)
|
os.chdir(self.testdir)
|
||||||
Path('config.yml').write_text('categories: [foo, bar]')
|
Path('config.yml').write_text('categories: [foo, bar]\n')
|
||||||
fdroidserver.lint.config = fdroidserver.common.read_config()
|
fdroidserver.lint.config = fdroidserver.common.read_config()
|
||||||
fdroidserver.lint.load_categories_config()
|
fdroidserver.lint.load_categories_config()
|
||||||
self.assertEqual(fdroidserver.lint.CATEGORIES_KEYS, ['foo', 'bar'])
|
self.assertEqual(fdroidserver.lint.CATEGORIES_KEYS, ['foo', 'bar'])
|
||||||
|
@ -435,13 +435,13 @@ class LintTest(unittest.TestCase):
|
||||||
def test_lint_invalid_config_keys(self):
|
def test_lint_invalid_config_keys(self):
|
||||||
os.chdir(self.testdir)
|
os.chdir(self.testdir)
|
||||||
Path('config').mkdir()
|
Path('config').mkdir()
|
||||||
Path('config/config.yml').write_text('repo:\n invalid_key: test')
|
Path('config/config.yml').write_text('repo:\n invalid_key: test\n')
|
||||||
self.assertFalse(fdroidserver.lint.lint_config('config/config.yml'))
|
self.assertFalse(fdroidserver.lint.lint_config('config/config.yml'))
|
||||||
|
|
||||||
def test_lint_invalid_localized_config_keys(self):
|
def test_lint_invalid_localized_config_keys(self):
|
||||||
os.chdir(self.testdir)
|
os.chdir(self.testdir)
|
||||||
Path('config/en').mkdir(parents=True)
|
Path('config/en').mkdir(parents=True)
|
||||||
Path('config/en/antiFeatures.yml').write_text('NonFreeNet:\n icon: test.png')
|
Path('config/en/antiFeatures.yml').write_text('NonFreeNet:\n icon: test.png\n')
|
||||||
self.assertFalse(fdroidserver.lint.lint_config('config/en/antiFeatures.yml'))
|
self.assertFalse(fdroidserver.lint.lint_config('config/en/antiFeatures.yml'))
|
||||||
|
|
||||||
def test_check_certificate_pinned_binaries_empty(self):
|
def test_check_certificate_pinned_binaries_empty(self):
|
||||||
|
@ -529,3 +529,62 @@ class LintAntiFeaturesTest(unittest.TestCase):
|
||||||
app = fdroidserver.metadata.App()
|
app = fdroidserver.metadata.App()
|
||||||
app['Builds'] = [{'antifeatures': ['Ads', 'Tracker']}]
|
app['Builds'] = [{'antifeatures': ['Ads', 'Tracker']}]
|
||||||
self.assertEqual(1, len(list(fdroidserver.lint.check_antiFeatures(app))))
|
self.assertEqual(1, len(list(fdroidserver.lint.check_antiFeatures(app))))
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigYmlTest(LintTest):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.config_yml = Path(self.testdir) / 'config.yml'
|
||||||
|
|
||||||
|
def test_config_yml_int(self):
|
||||||
|
self.config_yml.write_text('repo_maxage: 1\n')
|
||||||
|
self.assertTrue(fdroidserver.lint.lint_config(self.config_yml))
|
||||||
|
|
||||||
|
def test_config_yml_int_bad(self):
|
||||||
|
self.config_yml.write_text('repo_maxage: "1"\n')
|
||||||
|
self.assertFalse(fdroidserver.lint.lint_config(self.config_yml))
|
||||||
|
|
||||||
|
def test_config_yml_str(self):
|
||||||
|
self.config_yml.write_text('sdk_path: /opt/android-sdk\n')
|
||||||
|
self.assertTrue(fdroidserver.lint.lint_config(self.config_yml))
|
||||||
|
|
||||||
|
def test_config_yml_str_dict(self):
|
||||||
|
self.config_yml.write_text('sdk_path: {env: ANDROID_HOME}\n')
|
||||||
|
self.assertTrue(fdroidserver.lint.lint_config(self.config_yml))
|
||||||
|
|
||||||
|
def test_config_yml_str_bad(self):
|
||||||
|
self.config_yml.write_text('sdk_path: 1.0\n')
|
||||||
|
self.assertFalse(fdroidserver.lint.lint_config(self.config_yml))
|
||||||
|
|
||||||
|
def test_config_yml_bool(self):
|
||||||
|
self.config_yml.write_text("deploy_process_logs: true\n")
|
||||||
|
self.assertTrue(fdroidserver.lint.lint_config(self.config_yml))
|
||||||
|
|
||||||
|
def test_config_yml_bool_bad(self):
|
||||||
|
self.config_yml.write_text('deploy_process_logs: 2342fe23\n')
|
||||||
|
self.assertFalse(fdroidserver.lint.lint_config(self.config_yml))
|
||||||
|
|
||||||
|
def test_config_yml_dict(self):
|
||||||
|
self.config_yml.write_text("keyaliases: {com.example: '@com.foo'}\n")
|
||||||
|
self.assertTrue(fdroidserver.lint.lint_config(self.config_yml))
|
||||||
|
|
||||||
|
def test_config_yml_dict_bad(self):
|
||||||
|
self.config_yml.write_text('keyaliases: 2342fe23\n')
|
||||||
|
self.assertFalse(fdroidserver.lint.lint_config(self.config_yml))
|
||||||
|
|
||||||
|
def test_config_yml_bad_key_name(self):
|
||||||
|
self.config_yml.write_text('keyalias: 2342fe23\n')
|
||||||
|
self.assertFalse(fdroidserver.lint.lint_config(self.config_yml))
|
||||||
|
|
||||||
|
def test_config_yml_bad_value_for_all_keys(self):
|
||||||
|
"""Check all config keys with a bad value."""
|
||||||
|
for key in fdroidserver.lint.check_config_keys:
|
||||||
|
if key in fdroidserver.lint.bool_keys:
|
||||||
|
value = 'foobar'
|
||||||
|
else:
|
||||||
|
value = 'false'
|
||||||
|
self.config_yml.write_text(f'{key}: {value}\n')
|
||||||
|
self.assertFalse(
|
||||||
|
fdroidserver.lint.lint_config(self.config_yml),
|
||||||
|
f'{key} should fail on value of "{value}"',
|
||||||
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue