mirror of
				https://github.com/f-droid/fdroidserver.git
				synced 2025-11-04 06:30:27 +03:00 
			
		
		
		
	lint: support linting config files
This commit is contained in:
		
							parent
							
								
									3f35b0b361
								
							
						
					
					
						commit
						4511da68b9
					
				
					 3 changed files with 95 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -361,6 +361,26 @@ def regsub_file(pattern, repl, path):
 | 
			
		|||
        f.write(text)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def config_type_check(path, data):
 | 
			
		||||
    if Path(path).name == 'mirrors.yml':
 | 
			
		||||
        expected_type = list
 | 
			
		||||
    else:
 | 
			
		||||
        expected_type = dict
 | 
			
		||||
    if expected_type == dict:
 | 
			
		||||
        if not isinstance(data, dict):
 | 
			
		||||
            msg = _('{path} is not "key: value" dict, but a {datatype}!')
 | 
			
		||||
            raise TypeError(msg.format(path=path, datatype=type(data).__name__))
 | 
			
		||||
    elif not isinstance(data, expected_type):
 | 
			
		||||
        msg = _('{path} is not {expected_type}, but a {datatype}!')
 | 
			
		||||
        raise TypeError(
 | 
			
		||||
            msg.format(
 | 
			
		||||
                path=path,
 | 
			
		||||
                expected_type=expected_type.__name__,
 | 
			
		||||
                datatype=type(data).__name__,
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def read_config(opts=None):
 | 
			
		||||
    """Read the repository config.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -401,11 +421,7 @@ def read_config(opts=None):
 | 
			
		|||
            config = yaml.safe_load(fp)
 | 
			
		||||
        if not config:
 | 
			
		||||
            config = {}
 | 
			
		||||
        if not isinstance(config, dict):
 | 
			
		||||
            msg = _('{path} is not "key: value" dict, but a {datatype}!')
 | 
			
		||||
            raise TypeError(
 | 
			
		||||
                msg.format(path=config_file, datatype=type(config).__name__)
 | 
			
		||||
            )
 | 
			
		||||
        config_type_check(config_file, config)
 | 
			
		||||
    elif os.path.exists(old_config_file):
 | 
			
		||||
        logging.warning(_("""{oldfile} is deprecated, use {newfile}""")
 | 
			
		||||
                        .format(oldfile=old_config_file, newfile=config_file))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,7 @@ from argparse import ArgumentParser
 | 
			
		|||
import re
 | 
			
		||||
import sys
 | 
			
		||||
import platform
 | 
			
		||||
import ruamel.yaml
 | 
			
		||||
import urllib.parse
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -739,6 +740,21 @@ def check_certificate_pinned_binaries(app):
 | 
			
		|||
            return
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def lint_config(arg):
 | 
			
		||||
    path = Path(arg)
 | 
			
		||||
    passed = True
 | 
			
		||||
    yamllintresult = common.run_yamllint(path)
 | 
			
		||||
    if yamllintresult:
 | 
			
		||||
        print(yamllintresult)
 | 
			
		||||
        passed = False
 | 
			
		||||
 | 
			
		||||
    with path.open() as fp:
 | 
			
		||||
        data = ruamel.yaml.YAML(typ='safe').load(fp)
 | 
			
		||||
    common.config_type_check(arg, data)
 | 
			
		||||
 | 
			
		||||
    return passed
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    global config, options
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -777,6 +793,33 @@ def main():
 | 
			
		|||
 | 
			
		||||
        yamllint  # make pyflakes ignore this
 | 
			
		||||
 | 
			
		||||
    paths = list()
 | 
			
		||||
    for arg in options.appid:
 | 
			
		||||
        if (
 | 
			
		||||
            arg == 'config.yml'
 | 
			
		||||
            or Path(arg).parent.name == 'config'
 | 
			
		||||
            or Path(arg).parent.parent.name == 'config'  # localized
 | 
			
		||||
        ):
 | 
			
		||||
            paths.append(arg)
 | 
			
		||||
 | 
			
		||||
    failed = 0
 | 
			
		||||
    if paths:
 | 
			
		||||
        for path in paths:
 | 
			
		||||
            options.appid.remove(path)
 | 
			
		||||
            if not lint_config(path):
 | 
			
		||||
                failed += 1
 | 
			
		||||
        # an empty list of appids means check all apps, avoid that if files were given
 | 
			
		||||
        if not options.appid:
 | 
			
		||||
            sys.exit(failed)
 | 
			
		||||
 | 
			
		||||
    if not lint_metadata(options):
 | 
			
		||||
        failed += 1
 | 
			
		||||
 | 
			
		||||
    if failed:
 | 
			
		||||
        sys.exit(failed)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def lint_metadata(options):
 | 
			
		||||
    # Get all apps...
 | 
			
		||||
    allapps = metadata.read_metadata(options.appid)
 | 
			
		||||
    apps = common.read_app_args(options.appid, allapps, False)
 | 
			
		||||
| 
						 | 
				
			
			@ -856,8 +899,7 @@ def main():
 | 
			
		|||
                anywarns = True
 | 
			
		||||
                print("%s: %s" % (appid, warn))
 | 
			
		||||
 | 
			
		||||
    if anywarns:
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
    return not anywarns
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# A compiled, public domain list of official SPDX license tags.  generated
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2838,6 +2838,36 @@ class CommonTest(unittest.TestCase):
 | 
			
		|||
        with self.assertRaises(TypeError):
 | 
			
		||||
            fdroidserver.common.load_localized_config(CATEGORIES_CONFIG_NAME, 'repo')
 | 
			
		||||
 | 
			
		||||
    def test_config_type_check_config_yml_dict(self):
 | 
			
		||||
        fdroidserver.common.config_type_check('config.yml', dict())
 | 
			
		||||
 | 
			
		||||
    def test_config_type_check_config_yml_list(self):
 | 
			
		||||
        with self.assertRaises(TypeError):
 | 
			
		||||
            fdroidserver.common.config_type_check('config.yml', list())
 | 
			
		||||
 | 
			
		||||
    def test_config_type_check_config_yml_set(self):
 | 
			
		||||
        with self.assertRaises(TypeError):
 | 
			
		||||
            fdroidserver.common.config_type_check('config.yml', set())
 | 
			
		||||
 | 
			
		||||
    def test_config_type_check_config_yml_str(self):
 | 
			
		||||
        with self.assertRaises(TypeError):
 | 
			
		||||
            fdroidserver.common.config_type_check('config.yml', str())
 | 
			
		||||
 | 
			
		||||
    def test_config_type_check_mirrors_list(self):
 | 
			
		||||
        fdroidserver.common.config_type_check('config/mirrors.yml', list())
 | 
			
		||||
 | 
			
		||||
    def test_config_type_check_mirrors_dict(self):
 | 
			
		||||
        with self.assertRaises(TypeError):
 | 
			
		||||
            fdroidserver.common.config_type_check('config/mirrors.yml', dict())
 | 
			
		||||
 | 
			
		||||
    def test_config_type_check_mirrors_set(self):
 | 
			
		||||
        with self.assertRaises(TypeError):
 | 
			
		||||
            fdroidserver.common.config_type_check('config/mirrors.yml', set())
 | 
			
		||||
 | 
			
		||||
    def test_config_type_check_mirrors_str(self):
 | 
			
		||||
        with self.assertRaises(TypeError):
 | 
			
		||||
            fdroidserver.common.config_type_check('config/mirrors.yml', str())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    os.chdir(os.path.dirname(__file__))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue