From ce64fc24e5c0cc68598ddb17941db9cc73b2302c Mon Sep 17 00:00:00 2001 From: James Powis Date: Wed, 17 Jan 2024 14:55:37 -0700 Subject: [PATCH] handle symlinks in a semi dry manner --- tests/common.py | 10 +++++++++- tests/test_cli.py | 16 ++++++++++------ yamllint/cli.py | 17 +++++++++++++---- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/tests/common.py b/tests/common.py index 1aef9e62..df235693 100644 --- a/tests/common.py +++ b/tests/common.py @@ -58,11 +58,19 @@ def build_temp_workspace(files): tempdir = tempfile.mkdtemp(prefix='yamllint-tests-') for path, content in files.items(): + is_symlink = False + if path.startswith("symlink:"): + is_symlink = True + path = path.replace("symlink:", "") + path = os.path.join(tempdir, path).encode('utf-8') if not os.path.exists(os.path.dirname(path)): os.makedirs(os.path.dirname(path)) + if is_symlink: + target = os.path.join(os.path.dirname(path), content.encode('utf-8')) + os.symlink(target, path) - if isinstance(content, list): + elif isinstance(content, list): os.mkdir(path) else: mode = 'wb' if isinstance(content, bytes) else 'w' diff --git a/tests/test_cli.py b/tests/test_cli.py index bcdd000b..7dd6c015 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -86,6 +86,8 @@ def setUpModule(): class CommandLineTestCase(unittest.TestCase): + maxDiff = None + @classmethod def setUpClass(cls): super().setUpClass() @@ -130,7 +132,9 @@ def setUpClass(cls): 'a: true', 'en.yaml': '---\n' 'a: true\n' - 'A: true' + 'A: true', + 'symlink:some/other/directory/en.yaml': '../../../en.yaml', + 'symlink:abslink.yml': '/tmp/non-exist.yml', }) @classmethod @@ -142,7 +146,7 @@ def tearDownClass(cls): def test_find_files_recursively(self): conf = config.YamlLintConfig('extends: default') self.assertEqual( - sorted(cli.find_files_recursively([self.wd], conf)), + sorted(set(cli.find_files_recursively([self.wd], conf))), [os.path.join(self.wd, 'a.yaml'), os.path.join(self.wd, 'c.yaml'), os.path.join(self.wd, 'dos.yml'), @@ -151,7 +155,7 @@ def test_find_files_recursively(self): os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), os.path.join(self.wd, 'sub/directory.yaml/empty.yml'), os.path.join(self.wd, 'sub/ok.yaml'), - os.path.join(self.wd, 'warn.yaml')], + os.path.join(self.wd, 'warn.yaml')] ) items = [os.path.join(self.wd, 'sub/ok.yaml'), @@ -182,7 +186,7 @@ def test_find_files_recursively(self): 'yaml-files:\n' ' - \'*.yaml\' \n') self.assertEqual( - sorted(cli.find_files_recursively([self.wd], conf)), + sorted(set(cli.find_files_recursively([self.wd], conf))), [os.path.join(self.wd, 'a.yaml'), os.path.join(self.wd, 'c.yaml'), os.path.join(self.wd, 'en.yaml'), @@ -213,7 +217,7 @@ def test_find_files_recursively(self): 'yaml-files:\n' ' - \'*\'\n') self.assertEqual( - sorted(cli.find_files_recursively([self.wd], conf)), + sorted(set(cli.find_files_recursively([self.wd], conf))), [os.path.join(self.wd, 'a.yaml'), os.path.join(self.wd, 'c.yaml'), os.path.join(self.wd, 'dos.yml'), @@ -234,7 +238,7 @@ def test_find_files_recursively(self): ' - \'*\'\n' ' - \'**\'\n') self.assertEqual( - sorted(cli.find_files_recursively([self.wd], conf)), + sorted(set(cli.find_files_recursively([self.wd], conf))), [os.path.join(self.wd, 'a.yaml'), os.path.join(self.wd, 'c.yaml'), os.path.join(self.wd, 'dos.yml'), diff --git a/yamllint/cli.py b/yamllint/cli.py index 8d13000a..16e28fdf 100644 --- a/yamllint/cli.py +++ b/yamllint/cli.py @@ -30,8 +30,17 @@ def find_files_recursively(items, conf): for root, _dirnames, filenames in os.walk(item): for f in filenames: filepath = os.path.join(root, f) - if conf.is_yaml_file(filepath): - yield filepath + if conf.is_yaml_file(filepath) and not conf.is_file_ignored(filepath): + if os.path.islink(filepath): + target_path = os.readlink(filepath) + relative_path = os.path.join(filepath, target_path) + if os.path.exists(relative_path): + norm_path = os.path.normpath(relative_path) + if conf.is_yaml_file(norm_path) and not conf.is_file_ignored(norm_path): + yield norm_path + + elif conf.is_yaml_file(filepath): + yield filepath else: yield item @@ -208,14 +217,14 @@ def run(argv=None): locale.setlocale(locale.LC_ALL, conf.locale) if args.list_files: - for file in find_files_recursively(args.files, conf): + for file in set(find_files_recursively(args.files, conf)): if not conf.is_file_ignored(file): print(file) sys.exit(0) max_level = 0 - for file in find_files_recursively(args.files, conf): + for file in set(find_files_recursively(args.files, conf)): filepath = file[2:] if file.startswith('./') else file try: with open(file, newline='') as f: