Skip to content

Commit

Permalink
Fix dependencies and dependents to use output file when using json fo…
Browse files Browse the repository at this point in the history
…rmatting (Cherry-pick of #20843) (#20877)

Fix dependencies and dependents goals to use the provided output file
when formatting with json. See
#20842 for more details.

Co-authored-by: yjabri <yjabri@gmail.com>
  • Loading branch information
WorkerPants and yjabri authored May 7, 2024
1 parent 312cb2b commit f2dec19
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 11 deletions.
4 changes: 3 additions & 1 deletion src/python/pants/backend/project_info/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ async def list_dependencies_as_json(
# for them, the lists of dependencies are returned in the very same order.
mapping = dict(zip([str(tgt.address) for tgt in target_roots], iterated_targets))
output = json.dumps(mapping, indent=4)
console.print_stdout(output)

with dependencies_subsystem.line_oriented(console) as print_stdout:
print_stdout(output)


async def list_dependencies_as_plain_text(
Expand Down
37 changes: 33 additions & 4 deletions src/python/pants/backend/project_info/dependencies_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,35 @@ def assert_dependencies(
specs: List[str],
expected: List[str],
transitive: bool = False,
output_file: Optional[str] = None,
closed: bool = False,
output_format: DependenciesOutputFormat = DependenciesOutputFormat.text,
) -> None:
args = []
if transitive:
args.append("--transitive")
if output_file:
args.extend([f"--output-file={output_file}"])
if closed:
args.append("--closed")
args.append(f"--format={output_format.value}")

result = rule_runner.run_goal_rule(
Dependencies, args=[*args, *specs], env_inherit={"PATH", "PYENV_ROOT", "HOME"}
)
if output_format == DependenciesOutputFormat.text:
assert result.stdout.splitlines() == expected
elif output_format == DependenciesOutputFormat.json:
assert json.loads(result.stdout) == expected

if output_file is None:
if output_format == DependenciesOutputFormat.text:
assert result.stdout.splitlines() == expected
elif output_format == DependenciesOutputFormat.json:
assert json.loads(result.stdout) == expected
else:
assert not result.stdout
with open(output_file) as f:
if output_format == DependenciesOutputFormat.text:
assert f.read().splitlines() == expected
elif output_format == DependenciesOutputFormat.json:
assert json.load(f) == expected


def test_no_target(rule_runner: PythonRuleRunner) -> None:
Expand Down Expand Up @@ -223,6 +235,12 @@ def test_python_dependencies(rule_runner: PythonRuleRunner) -> None:
],
closed=True,
)
assert_deps(
specs=["some/other/target:target"],
transitive=False,
output_file="dependencies.txt",
expected=["some/other/target/a.py"],
)


def test_python_dependencies_output_format_json_direct_deps(rule_runner: PythonRuleRunner) -> None:
Expand Down Expand Up @@ -336,6 +354,17 @@ def test_python_dependencies_output_format_json_direct_deps(rule_runner: PythonR
]
},
)
assert_deps(
specs=["some/target/a.py"],
transitive=False,
output_file="dependencies.json",
expected={
"some/target/a.py": [
"3rdparty/python:req1",
"dep/target/a.py",
]
},
)


def test_python_dependencies_output_format_json_transitive_deps(
Expand Down
3 changes: 2 additions & 1 deletion src/python/pants/backend/project_info/dependents.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ async def list_dependents_as_json(
iterated_addresses.append(sorted([str(address) for address in dependents]))
mapping = dict(zip([str(address) for address in addresses], iterated_addresses))
output = json.dumps(mapping, indent=4)
console.print_stdout(output)
with dependents_subsystem.line_oriented(console) as print_stdout:
print_stdout(output)


@goal_rule
Expand Down
32 changes: 27 additions & 5 deletions src/python/pants/backend/project_info/dependents_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Licensed under the Apache License, Version 2.0 (see LICENSE).
import json
from functools import partial
from typing import Dict, List, Union
from typing import Dict, List, Optional, Union

import pytest

Expand Down Expand Up @@ -44,20 +44,32 @@ def assert_dependents(
targets: List[str],
expected: Union[List[str], Dict[str, List[str]]],
transitive: bool = False,
output_file: Optional[str] = None,
closed: bool = False,
output_format: DependentsOutputFormat = DependentsOutputFormat.text,
) -> None:
args = []
if transitive:
args.append("--transitive")
if output_file:
args.extend([f"--output-file={output_file}"])
if closed:
args.append("--closed")
args.append(f"--format={output_format.value}")
result = rule_runner.run_goal_rule(DependentsGoal, args=[*args, *targets])
if output_format == DependentsOutputFormat.text:
assert result.stdout.splitlines() == expected
elif output_format == DependentsOutputFormat.json:
assert json.loads(result.stdout) == expected

if output_file is None:
if output_format == DependentsOutputFormat.text:
assert result.stdout.splitlines() == expected
elif output_format == DependentsOutputFormat.json:
assert json.loads(result.stdout) == expected
else:
assert not result.stdout
with open(output_file) as f:
if output_format == DependentsOutputFormat.text:
assert f.read().splitlines() == expected
elif output_format == DependentsOutputFormat.json:
assert json.load(f) == expected


def test_no_targets(rule_runner: RuleRunner) -> None:
Expand Down Expand Up @@ -165,6 +177,16 @@ def test_dependents_as_json_direct_deps(rule_runner: RuleRunner) -> None:
},
)

# input: single target with output file
assert_deps(
targets=["base"],
transitive=False,
output_file="output.json",
expected={
"base:base": ["intermediate:intermediate"],
},
)


def test_dependents_as_json_transitive_deps(rule_runner: RuleRunner) -> None:
rule_runner.write_files({"special/BUILD": "tgt(special_deps=['intermediate'])"})
Expand Down

0 comments on commit f2dec19

Please sign in to comment.