mirror of
https://github.com/mesonbuild/meson.git
synced 2026-06-24 08:48:03 +00:00
mformat: Make --recursive recurse subprojects with --subprojects flag
Currently, `meson format --recursive` only recurse meson.build files that are reachable via a `subdir` function. Add `--subprojects` flag to also recurse subprojects.
This commit is contained in:
committed by
Paolo Bonzini
parent
97d7e6091b
commit
31a1a87bd8
4
docs/markdown/snippets/mformat-recursive-subprojects.md
Normal file
4
docs/markdown/snippets/mformat-recursive-subprojects.md
Normal file
@@ -0,0 +1,4 @@
|
||||
## New option `--subprojects` for `meson format`
|
||||
|
||||
A new option `--subprojects`, to be specified together with `--recursive`,
|
||||
tells `meson format` to also recurse into subprojects.
|
||||
@@ -874,11 +874,16 @@ class ComputeLineLengths(FullAstVisitor):
|
||||
|
||||
class SubdirFetcher(FullAstVisitor):
|
||||
|
||||
def __init__(self, current_dir: Path):
|
||||
def __init__(self, current_dir: Path, fetch_subprojects: bool):
|
||||
self.current_dir = current_dir
|
||||
self.fetch_subprojects = fetch_subprojects
|
||||
self.subdirs: T.List[Path] = []
|
||||
|
||||
def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
|
||||
if self.fetch_subprojects and node.func_name.value == 'subproject':
|
||||
if node.args.arguments and isinstance(node.args.arguments[0], mparser.StringNode):
|
||||
subdir = node.args.arguments[0].value
|
||||
self.subdirs.append(self.current_dir / 'subprojects' / subdir)
|
||||
if node.func_name.value == 'subdir':
|
||||
if node.args.arguments and isinstance(node.args.arguments[0], mparser.StringNode):
|
||||
subdir = node.args.arguments[0].value
|
||||
@@ -888,8 +893,9 @@ class SubdirFetcher(FullAstVisitor):
|
||||
|
||||
class Formatter:
|
||||
|
||||
def __init__(self, configuration_file: T.Optional[Path], use_editor_config: bool, fetch_subdirs: bool):
|
||||
def __init__(self, configuration_file: T.Optional[Path], use_editor_config: bool, fetch_subdirs: bool, fetch_subprojects: bool = False):
|
||||
self.fetch_subdirs = fetch_subdirs
|
||||
self.fetch_subprojects = fetch_subprojects
|
||||
self.use_editor_config = use_editor_config
|
||||
self.config = self.load_configuration(configuration_file)
|
||||
self.current_config = self.config
|
||||
@@ -974,7 +980,7 @@ class Formatter:
|
||||
|
||||
ast = mparser.Parser(code, source_file.as_posix()).parse()
|
||||
if self.fetch_subdirs:
|
||||
subdir_fetcher = SubdirFetcher(self.current_dir)
|
||||
subdir_fetcher = SubdirFetcher(self.current_dir, self.fetch_subprojects)
|
||||
ast.accept(subdir_fetcher)
|
||||
self.subdirs = subdir_fetcher.subdirs
|
||||
|
||||
@@ -1016,6 +1022,11 @@ def add_arguments(parser: argparse.ArgumentParser) -> None:
|
||||
action='store_true',
|
||||
help='recurse subdirs (requires --check-only, --check-diff or --inplace option)',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-s', '--subprojects',
|
||||
action='store_true',
|
||||
help='recurse subprojects (requires --recursive)',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-c', '--configuration',
|
||||
metavar='meson.format',
|
||||
@@ -1058,6 +1069,8 @@ def run(options: argparse.Namespace) -> int:
|
||||
raise MesonException('--output argument implies having exactly one source file')
|
||||
if options.recursive and not (options.inplace or options.check_only or options.check_diff):
|
||||
raise MesonException('--recursive argument requires one of --inplace, --check-diff or --check-only')
|
||||
if options.subprojects and not options.recursive:
|
||||
raise MesonException('--subprojects argument requires --recursive option')
|
||||
|
||||
from_stdin = len(options.sources) == 1 and options.sources[0].name == '-' and options.sources[0].parent == Path()
|
||||
if options.recursive and from_stdin:
|
||||
@@ -1074,7 +1087,7 @@ def run(options: argparse.Namespace) -> int:
|
||||
if not options.configuration:
|
||||
options.configuration = get_meson_format(sources)
|
||||
|
||||
formatter = Formatter(options.configuration, options.editor_config, options.recursive)
|
||||
formatter = Formatter(options.configuration, options.editor_config, options.recursive, options.subprojects)
|
||||
err = 0
|
||||
|
||||
while sources:
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright © 2026 Arthur Grillo
|
||||
|
||||
import argparse
|
||||
import subprocess
|
||||
import sys
|
||||
import difflib
|
||||
|
||||
|
||||
def compare(actual: str, expected: str) -> int:
|
||||
if actual == expected:
|
||||
return 0
|
||||
|
||||
diff = difflib.ndiff(expected, actual)
|
||||
for line in diff:
|
||||
print(line, file=sys.stderr, end='')
|
||||
return 1
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('meson_cmd_path', nargs='+')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
result = subprocess.run([
|
||||
*args.meson_cmd_path,
|
||||
'format',
|
||||
'--recursive',
|
||||
'--subprojects',
|
||||
'--check-diff',
|
||||
], capture_output=True, text=True)
|
||||
|
||||
with open('subprojects/find-me/expected.diff', 'r', encoding='utf-8') as f:
|
||||
actual = result.stdout.replace('\\', '/')
|
||||
expected = f.read()
|
||||
|
||||
return compare(
|
||||
actual,
|
||||
expected,
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
14
test cases/format/7 recurse subprojects/meson.build
Normal file
14
test cases/format/7 recurse subprojects/meson.build
Normal file
@@ -0,0 +1,14 @@
|
||||
project('format')
|
||||
|
||||
python = import('python')
|
||||
meson_cmd = [python.find_installation(), find_program('meson').full_path()]
|
||||
file_compare = find_program(files('compare_format_diff.py'))
|
||||
|
||||
test(
|
||||
'recurse subprojects',
|
||||
file_compare,
|
||||
args: meson_cmd,
|
||||
workdir: meson.project_source_root(),
|
||||
)
|
||||
|
||||
subproject('find-me')
|
||||
@@ -0,0 +1,7 @@
|
||||
--- subprojects/find-me/meson.build (original)
|
||||
+++ subprojects/find-me/meson.build (reformatted)
|
||||
@@ -1,3 +1 @@
|
||||
-project(
|
||||
- 'a'
|
||||
-) # should be on one line
|
||||
+project('a') # should be on one line
|
||||
@@ -0,0 +1,3 @@
|
||||
project(
|
||||
'a'
|
||||
) # should be on one line
|
||||
Reference in New Issue
Block a user