From 301e08f504bc955fec347bd0bc5e66f821cfbd93 Mon Sep 17 00:00:00 2001 From: Tobias Nilsson Date: Wed, 24 May 2023 20:22:24 +0200 Subject: [PATCH] javascript: Allow nodejs-backed tools to point to a resolve and/or package manager (#19040) Features: - Enable the use of nodejs resolves(~=lockfiles) for the prettier, spectral and pyright subsystems/tools. This is sort of equivalent to the "user lockfiles for tools" in python - Enable users to use a different package manager to execute the tool. Mostly useful to utilize pnpm CAS. Breaking plugin change that might be worth mentioning: - Rename `NpxToolBase` to `NodeJSToolBase` - Removed `NodeToolProcess.npx`. - I think the package manager agnostic execute interface is better to use. Fixes https://github.com/pantsbuild/pants/issues/17615 Preparatory for a typescript backend, to implement a check goal using the user resolve `tsc` (compiler) version. --- .../pants/backend/javascript/goals/BUILD | 2 +- .../backend/javascript/goals/lockfile.py | 17 +- .../backend/javascript/goals/lockfile_test.py | 2 +- .../backend/javascript/lint/prettier/rules.py | 15 +- .../javascript/lint/prettier/subsystem.py | 4 +- .../pants/backend/javascript/resolve.py | 43 + .../pants/backend/javascript/subsystems/BUILD | 3 + .../backend/javascript/subsystems/nodejs.py | 29 - .../javascript/subsystems/nodejs_test.py | 32 - .../javascript/subsystems/nodejs_tool.py | 187 +++++ .../javascript/subsystems/nodejs_tool_test.py | 97 +++ .../backend/javascript/subsystems/npx_tool.py | 20 - .../javascript/subsystems/npx_tool_test.py | 36 - .../javascript/subsystems/package-lock.json | 794 ++++++++++++++++++ .../javascript/subsystems/pnpm-lock.yaml | 220 +++++ .../backend/javascript/subsystems/yarn.lock | 220 +++++ .../backend/openapi/lint/spectral/rules.py | 13 +- .../openapi/lint/spectral/subsystem.py | 4 +- .../backend/python/typecheck/pyright/rules.py | 12 +- .../pyright/rules_integration_test.py | 173 +++- .../python/typecheck/pyright/subsystem.py | 4 +- 21 files changed, 1740 insertions(+), 187 deletions(-) create mode 100644 src/python/pants/backend/javascript/subsystems/nodejs_tool.py create mode 100644 src/python/pants/backend/javascript/subsystems/nodejs_tool_test.py delete mode 100644 src/python/pants/backend/javascript/subsystems/npx_tool.py delete mode 100644 src/python/pants/backend/javascript/subsystems/npx_tool_test.py create mode 100644 src/python/pants/backend/javascript/subsystems/package-lock.json create mode 100644 src/python/pants/backend/javascript/subsystems/pnpm-lock.yaml create mode 100644 src/python/pants/backend/javascript/subsystems/yarn.lock diff --git a/src/python/pants/backend/javascript/goals/BUILD b/src/python/pants/backend/javascript/goals/BUILD index d1f9a719994..45af37dba16 100644 --- a/src/python/pants/backend/javascript/goals/BUILD +++ b/src/python/pants/backend/javascript/goals/BUILD @@ -8,7 +8,7 @@ python_tests( # The package.json files are inlined in ./test_integration_tests.py overrides={ "test_integration_test.py": dict( - dependencies=["./jest_resources", "./mocha_resources"], timeout=120 + dependencies=["./jest_resources", "./mocha_resources"], timeout=240 ), }, ) diff --git a/src/python/pants/backend/javascript/goals/lockfile.py b/src/python/pants/backend/javascript/goals/lockfile.py index 6d32c1374b7..5070805da90 100644 --- a/src/python/pants/backend/javascript/goals/lockfile.py +++ b/src/python/pants/backend/javascript/goals/lockfile.py @@ -13,7 +13,7 @@ NodeJsProjectEnvironmentProcess, ) from pants.backend.javascript.package_json import PackageJsonTarget -from pants.backend.javascript.subsystems.nodejs import UserChosenNodeJSResolveAliases +from pants.backend.javascript.resolve import NodeJSProjectResolves, UserChosenNodeJSResolveAliases from pants.core.goals.generate_lockfiles import ( GenerateLockfile, GenerateLockfileResult, @@ -92,24 +92,15 @@ async def determine_package_json_user_resolves( @rule async def setup_user_lockfile_requests( + resolves: NodeJSProjectResolves, requested: RequestedPackageJsonUserResolveNames, - all_projects: AllNodeJSProjects, - user_chosen_resolves: UserChosenNodeJSResolveAliases, ) -> UserGenerateLockfiles: - def get_name(project: NodeJSProject) -> str: - return user_chosen_resolves.get( - os.path.join(project.root_dir, project.lockfile_name), project.default_resolve_name - ) - - projects_by_name = {get_name(project): project for project in all_projects} return UserGenerateLockfiles( GeneratePackageLockJsonFile( resolve_name=name, - lockfile_dest=os.path.join( - projects_by_name[name].root_dir, projects_by_name[name].lockfile_name - ), + lockfile_dest=os.path.join(resolves[name].root_dir, resolves[name].lockfile_name), diff=False, - project=projects_by_name[name], + project=resolves[name], ) for name in requested ) diff --git a/src/python/pants/backend/javascript/goals/lockfile_test.py b/src/python/pants/backend/javascript/goals/lockfile_test.py index b73971a6236..285b814361d 100644 --- a/src/python/pants/backend/javascript/goals/lockfile_test.py +++ b/src/python/pants/backend/javascript/goals/lockfile_test.py @@ -20,7 +20,7 @@ PackageJsonForGlobs, PackageJsonTarget, ) -from pants.backend.javascript.subsystems.nodejs import UserChosenNodeJSResolveAliases +from pants.backend.javascript.resolve import UserChosenNodeJSResolveAliases from pants.core.goals.generate_lockfiles import ( GenerateLockfileResult, KnownUserResolveNames, diff --git a/src/python/pants/backend/javascript/lint/prettier/rules.py b/src/python/pants/backend/javascript/lint/prettier/rules.py index 688b100b387..4f97a535961 100644 --- a/src/python/pants/backend/javascript/lint/prettier/rules.py +++ b/src/python/pants/backend/javascript/lint/prettier/rules.py @@ -4,11 +4,13 @@ from __future__ import annotations import logging +import os from dataclasses import dataclass from typing import Iterable from pants.backend.javascript.lint.prettier.subsystem import Prettier -from pants.backend.javascript.subsystems.nodejs import NodeJSToolProcess +from pants.backend.javascript.subsystems import nodejs_tool +from pants.backend.javascript.subsystems.nodejs_tool import NodeJSToolRequest from pants.backend.javascript.target_types import JSSourceField from pants.core.goals.fmt import FmtResult, FmtTargetsRequest from pants.core.util_rules.config_files import ConfigFiles, ConfigFilesRequest @@ -59,13 +61,9 @@ async def prettier_fmt(request: PrettierFmtRequest.Batch, prettier: Prettier) -> result = await Get( ProcessResult, - NodeJSToolProcess, - NodeJSToolProcess.npx( - npm_package=prettier.version, - args=( - "--write", - *request.files, - ), + NodeJSToolRequest, + prettier.request( + args=("--write", *(os.path.join("{chroot}", file) for file in request.files)), input_digest=input_digest, output_files=request.files, description=f"Run Prettier on {pluralize(len(request.files), 'file')}.", @@ -78,5 +76,6 @@ async def prettier_fmt(request: PrettierFmtRequest.Batch, prettier: Prettier) -> def rules() -> Iterable[Rule | UnionRule]: return ( *collect_rules(), + *nodejs_tool.rules(), *PrettierFmtRequest.rules(), ) diff --git a/src/python/pants/backend/javascript/lint/prettier/subsystem.py b/src/python/pants/backend/javascript/lint/prettier/subsystem.py index f8e1279028b..3fa4c6d10db 100644 --- a/src/python/pants/backend/javascript/lint/prettier/subsystem.py +++ b/src/python/pants/backend/javascript/lint/prettier/subsystem.py @@ -6,13 +6,13 @@ import os from typing import Iterable -from pants.backend.javascript.subsystems.npx_tool import NpxToolBase +from pants.backend.javascript.subsystems.nodejs_tool import NodeJSToolBase from pants.core.util_rules.config_files import ConfigFilesRequest from pants.option.option_types import ArgsListOption, SkipOption from pants.util.strutil import help_text -class Prettier(NpxToolBase): +class Prettier(NodeJSToolBase): options_scope = "prettier" name = "Prettier" help = help_text( diff --git a/src/python/pants/backend/javascript/resolve.py b/src/python/pants/backend/javascript/resolve.py index 451d5c26488..8980fcf01f8 100644 --- a/src/python/pants/backend/javascript/resolve.py +++ b/src/python/pants/backend/javascript/resolve.py @@ -9,17 +9,21 @@ from pants.backend.javascript import nodejs_project from pants.backend.javascript.nodejs_project import AllNodeJSProjects, NodeJSProject from pants.backend.javascript.package_json import ( + FirstPartyNodePackageTargets, NodePackageNameField, OwningNodePackage, OwningNodePackageRequest, PackageJsonSourceField, ) +from pants.backend.javascript.subsystems.nodejs import NodeJS from pants.build_graph.address import Address from pants.engine.fs import PathGlobs from pants.engine.internals.selectors import Get from pants.engine.rules import Rule, collect_rules, rule from pants.engine.target import Target, WrappedTarget, WrappedTargetRequest from pants.engine.unions import UnionRule +from pants.util.frozendict import FrozenDict +from pants.util.logging import LogLevel @dataclass(frozen=True) @@ -68,5 +72,44 @@ async def resolve_for_package( return ChosenNodeResolve(project) +class NodeJSProjectResolves(FrozenDict[str, NodeJSProject]): + pass + + +class UserChosenNodeJSResolveAliases(FrozenDict[str, str]): + pass + + +@rule +async def resolve_to_projects( + all_projects: AllNodeJSProjects, user_chosen_resolves: UserChosenNodeJSResolveAliases +) -> NodeJSProjectResolves: + def get_name(project: NodeJSProject) -> str: + return user_chosen_resolves.get( + os.path.join(project.root_dir, project.lockfile_name), project.default_resolve_name + ) + + return NodeJSProjectResolves((get_name(project), project) for project in all_projects) + + +class FirstPartyNodePackageResolves(FrozenDict[str, Target]): + pass + + +@rule +async def resolve_to_first_party_node_package( + resolves: NodeJSProjectResolves, all_first_party: FirstPartyNodePackageTargets +) -> FirstPartyNodePackageResolves: + by_dir = {first_party.residence_dir: first_party for first_party in all_first_party} + return FirstPartyNodePackageResolves( + (resolve, by_dir[project.root_dir]) for resolve, project in resolves.items() + ) + + +@rule(level=LogLevel.DEBUG) +async def user_chosen_resolve_aliases(nodejs: NodeJS) -> UserChosenNodeJSResolveAliases: + return UserChosenNodeJSResolveAliases((value, key) for key, value in nodejs.resolves.items()) + + def rules() -> Iterable[Rule | UnionRule]: return [*collect_rules(), *nodejs_project.rules()] diff --git a/src/python/pants/backend/javascript/subsystems/BUILD b/src/python/pants/backend/javascript/subsystems/BUILD index 49b1a2f4e86..8df0fe35c35 100644 --- a/src/python/pants/backend/javascript/subsystems/BUILD +++ b/src/python/pants/backend/javascript/subsystems/BUILD @@ -7,5 +7,8 @@ python_tests( name="tests", overrides={ "nodejs_test.py": {"timeout": 240}, + "nodejs_tool_test.py": {"timeout": 120, "dependencies": [":cowsay_lockfiles"]}, }, ) + +resources(name="cowsay_lockfiles", sources=["package-lock.json", "pnpm-lock.yaml", "yarn.lock"]) diff --git a/src/python/pants/backend/javascript/subsystems/nodejs.py b/src/python/pants/backend/javascript/subsystems/nodejs.py index 3fda6be7eaa..55b3030a022 100644 --- a/src/python/pants/backend/javascript/subsystems/nodejs.py +++ b/src/python/pants/backend/javascript/subsystems/nodejs.py @@ -219,15 +219,6 @@ def corepack_env_vars(self) -> tuple[str, ...]: return tuple(sorted(set(self._corepack_env_vars))) -class UserChosenNodeJSResolveAliases(FrozenDict[str, str]): - pass - - -@rule(level=LogLevel.DEBUG) -async def user_chosen_resolve_aliases(nodejs: NodeJS) -> UserChosenNodeJSResolveAliases: - return UserChosenNodeJSResolveAliases((value, key) for key, value in nodejs.resolves.items()) - - @dataclass(frozen=True) class NodeJSToolProcess: """A request for a tool installed with NodeJS.""" @@ -278,26 +269,6 @@ def npm( project_digest=project_digest, ) - @classmethod - def npx( - cls, - args: Iterable[str], - npm_package: str, - description: str, - level: LogLevel = LogLevel.INFO, - input_digest: Digest = EMPTY_DIGEST, - output_files: tuple[str, ...] = (), - ) -> NodeJSToolProcess: - return cls( - tool="npx", - tool_version=None, - args=("--yes", npm_package, *args), - description=description, - level=level, - input_digest=input_digest, - output_files=output_files, - ) - @dataclass(frozen=True) class NodeJSBinaries: diff --git a/src/python/pants/backend/javascript/subsystems/nodejs_test.py b/src/python/pants/backend/javascript/subsystems/nodejs_test.py index 06af6880453..91d256a30ff 100644 --- a/src/python/pants/backend/javascript/subsystems/nodejs_test.py +++ b/src/python/pants/backend/javascript/subsystems/nodejs_test.py @@ -59,38 +59,6 @@ def rule_runner() -> RuleRunner: return rule_runner -def test_npx_process(rule_runner: RuleRunner): - rule_runner.set_options(["--nodejs-package-managers={'npm': '8.5.5'}"], env_inherit={"PATH"}) - result = rule_runner.request( - ProcessResult, - [ - nodejs.NodeJSToolProcess.npx( - npm_package="", - args=("--version",), - description="Testing NpxProcess", - ) - ], - ) - - assert result.stdout.strip() == b"8.5.5" - - -def test_npx_process_with_different_version(rule_runner: RuleRunner): - rule_runner.set_options(["--nodejs-package-managers={'npm': '7.20.0'}"], env_inherit={"PATH"}) - result = rule_runner.request( - ProcessResult, - [ - nodejs.NodeJSToolProcess.npx( - npm_package="", - args=("--version",), - description="Testing NpxProcess", - ) - ], - ) - - assert result.stdout.strip() == b"7.20.0" - - def test_npm_process(rule_runner: RuleRunner): rule_runner.set_options(["--nodejs-package-managers={'npm': '8.5.5'}"], env_inherit={"PATH"}) result = rule_runner.request( diff --git a/src/python/pants/backend/javascript/subsystems/nodejs_tool.py b/src/python/pants/backend/javascript/subsystems/nodejs_tool.py new file mode 100644 index 00000000000..8a6e0110dd4 --- /dev/null +++ b/src/python/pants/backend/javascript/subsystems/nodejs_tool.py @@ -0,0 +1,187 @@ +# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md). +# Licensed under the Apache License, Version 2.0 (see LICENSE). + +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import ClassVar, Iterable, Mapping + +from pants.backend.javascript import install_node_package, nodejs_project_environment +from pants.backend.javascript.install_node_package import ( + InstalledNodePackage, + InstalledNodePackageRequest, +) +from pants.backend.javascript.nodejs_project_environment import NodeJsProjectEnvironmentProcess +from pants.backend.javascript.resolve import FirstPartyNodePackageResolves, NodeJSProjectResolves +from pants.backend.javascript.subsystems.nodejs import NodeJS, NodeJSToolProcess +from pants.engine.internals.native_engine import Digest, MergeDigests +from pants.engine.internals.selectors import Get +from pants.engine.process import Process +from pants.engine.rules import Rule, collect_rules, rule +from pants.engine.unions import UnionRule +from pants.option.option_types import StrOption +from pants.option.subsystem import Subsystem +from pants.util.frozendict import FrozenDict +from pants.util.logging import LogLevel +from pants.util.strutil import softwrap + + +class NodeJSToolBase(Subsystem): + # Subclasses must set. + default_version: ClassVar[str] + + version = StrOption( + advanced=True, + default=lambda cls: cls.default_version, + help="Version string for the tool in the form package@version (e.g. prettier@2.6.2)", + ) + + install_from_resolve = StrOption( + advanced=True, + default=None, + help=lambda cls: softwrap( + f"""\ + If specified, install the tool using the lockfile for this named resolve, + instead of the version configured in this subsystem. + + If unspecified, the tool will use the default configured package manager + [{NodeJS.options_scope}].package_manager`, and install the tool without a + lockfile. + """ + ), + ) + + def request( + self, + args: tuple[str, ...], + input_digest: Digest, + description: str, + level: LogLevel, + output_files: tuple[str, ...] = (), + output_directories: tuple[str, ...] = (), + append_only_caches: FrozenDict[str, str] | None = None, + timeout_seconds: int | None = None, + extra_env: Mapping[str, str] | None = None, + ) -> NodeJSToolRequest: + return NodeJSToolRequest( + tool=self.version, + resolve=self.install_from_resolve, + args=args, + input_digest=input_digest, + description=description, + level=level, + output_files=output_files, + output_directories=output_directories, + append_only_caches=append_only_caches or FrozenDict(), + timeout_seconds=timeout_seconds, + extra_env=extra_env or FrozenDict(), + options_scope=self.options_scope, + ) + + +@dataclass(frozen=True) +class NodeJSToolRequest: + tool: str + resolve: str | None + args: tuple[str, ...] + input_digest: Digest + description: str + level: LogLevel + options_scope: str + output_files: tuple[str, ...] = () + output_directories: tuple[str, ...] = () + append_only_caches: FrozenDict[str, str] = field(default_factory=FrozenDict) + timeout_seconds: int | None = None + extra_env: Mapping[str, str] = field(default_factory=FrozenDict) + + +async def _run_tool_without_resolve(request: NodeJSToolRequest) -> Process: + nodejs = await Get(NodeJS) + dl_and_execute_args = { + "npm": ("exec", "--yes", "--"), + "pnpm": ("dlx",), + "yarn": ("dlx", "--quiet"), + } + + pkg_manager_version = nodejs.package_managers.get(nodejs.package_manager) + if pkg_manager_version is None: + # Occurs when a user configures a custom package manager but without a resolve. + # Corepack requires a package.json to make a decision on a "good known release". + raise ValueError( + softwrap( + f""" + Version for {nodejs.package_manager} has to be configured + in [{nodejs.options_scope}].package_managers when running + the tool '{request.tool}' without setting [{request.options_scope}].install_from_resolve. + """ + ) + ) + return await Get( + Process, + NodeJSToolProcess( + nodejs.package_manager, + pkg_manager_version, + args=(*dl_and_execute_args[nodejs.package_manager], request.tool, *request.args), + description=request.description, + input_digest=request.input_digest, + output_files=request.output_files, + output_directories=request.output_directories, + append_only_caches=request.append_only_caches, + timeout_seconds=request.timeout_seconds, + extra_env=FrozenDict({"PNPM_HOME": "{chroot}/._pnpm_home", **request.extra_env}), + ), + ) + + +async def _run_tool_with_resolve(request: NodeJSToolRequest, resolve: str) -> Process: + resolves = await Get(NodeJSProjectResolves) + + if request.resolve not in resolves: + reason = ( + f"Available resolves are {', '.join(resolves.keys())}." + if resolves + else "This project contains no resolves." + ) + raise ValueError(f"{resolve} is not a named NodeJS resolve. {reason}") + + all_first_party = await Get(FirstPartyNodePackageResolves) + package_for_resolve = all_first_party[resolve] + project = resolves[resolve] + installed = await Get( + InstalledNodePackage, InstalledNodePackageRequest(package_for_resolve.address) + ) + execute_args = { + "npm": ("exec", "--no", "--"), + "pnpm": ("exec",), + "yarn": ("--silent", "exec", "--"), + } + request_tool_without_version = request.tool.partition("@")[0] + return await Get( + Process, + NodeJsProjectEnvironmentProcess( + env=installed.project_env, + args=( + *execute_args[project.package_manager], + request_tool_without_version, + *request.args, + ), + description=request.description, + input_digest=await Get(Digest, MergeDigests([request.input_digest, installed.digest])), + output_files=request.output_files, + output_directories=request.output_directories, + per_package_caches=request.append_only_caches, + timeout_seconds=request.timeout_seconds, + extra_env=FrozenDict(request.extra_env), + ), + ) + + +@rule +async def prepare_tool_process(request: NodeJSToolRequest) -> Process: + if request.resolve is None: + return await _run_tool_without_resolve(request) + return await _run_tool_with_resolve(request, request.resolve) + + +def rules() -> Iterable[Rule | UnionRule]: + return [*collect_rules(), *nodejs_project_environment.rules(), *install_node_package.rules()] diff --git a/src/python/pants/backend/javascript/subsystems/nodejs_tool_test.py b/src/python/pants/backend/javascript/subsystems/nodejs_tool_test.py new file mode 100644 index 00000000000..13af786a8ed --- /dev/null +++ b/src/python/pants/backend/javascript/subsystems/nodejs_tool_test.py @@ -0,0 +1,97 @@ +# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md). +# Licensed under the Apache License, Version 2.0 (see LICENSE). + +from __future__ import annotations + +import json +from pathlib import Path + +import pytest + +from pants.backend.javascript.package_json import PackageJsonTarget +from pants.backend.javascript.subsystems import nodejs_tool +from pants.backend.javascript.subsystems.nodejs_tool import NodeJSToolBase, NodeJSToolRequest +from pants.engine.internals.native_engine import EMPTY_DIGEST +from pants.engine.process import ProcessResult +from pants.testutil.rule_runner import QueryRule, RuleRunner +from pants.util.logging import LogLevel + + +class CowsayTool(NodeJSToolBase): + options_scope = "cowsay" + name = "Cowsay" + # Intentionally older version. + default_version = "cowsay@1.4.0" + help = "The Cowsay utility for printing cowsay messages" + + +@pytest.fixture +def rule_runner() -> RuleRunner: + return RuleRunner( + rules=[ + *nodejs_tool.rules(), + *CowsayTool.rules(), + QueryRule(CowsayTool, []), + QueryRule(ProcessResult, [NodeJSToolRequest]), + ], + target_types=[PackageJsonTarget], + ) + + +def test_version_option_overrides_default(rule_runner: RuleRunner): + rule_runner.set_options(["--cowsay-version=cowsay@1.5.0"], env_inherit={"PATH"}) + tool = rule_runner.request(CowsayTool, []) + assert tool.default_version == "cowsay@1.4.0" + assert tool.version == "cowsay@1.5.0" + + +@pytest.mark.parametrize("package_manager", ["yarn", "npm", "pnpm"]) +def test_execute_process_with_package_manager(rule_runner: RuleRunner, package_manager: str): + rule_runner.set_options( + [ + "--cowsay-version=cowsay@1.5.0", + f"--nodejs-package-manager={package_manager}", + "--nodejs-package-managers={'npm': '7.20.1', 'yarn': '1.22.15', 'pnpm': '6.32.12'}", + ], + env_inherit={"PATH"}, + ) + tool = rule_runner.request(CowsayTool, []) + result = rule_runner.request( + ProcessResult, + [tool.request(("--version",), EMPTY_DIGEST, "Cowsay version", LogLevel.DEBUG)], + ) + + assert result.stdout == b"1.5.0\n" + + +@pytest.mark.parametrize( + "lockfile_path, package_manager", + [ + pytest.param(Path(__file__).parent / "yarn.lock", "yarn", id="yarn_resolve"), + pytest.param(Path(__file__).parent / "pnpm-lock.yaml", "pnpm", id="pnpm_resolve"), + pytest.param(Path(__file__).parent / "package-lock.json", "npm", id="npm_resolve"), + ], +) +def test_resolve_dictates_version( + rule_runner: RuleRunner, lockfile_path: Path, package_manager: str +): + rule_runner.write_files( + { + "BUILD": "package_json(name='root_pkg')", + "package.json": json.dumps( + {"name": "@the-company/project", "devDependencies": {"cowsay": "1.5.0"}} + ), + lockfile_path.name: lockfile_path.read_text(), + } + ) + rule_runner.set_options( + ["--cowsay-install-from-resolve=", f"--nodejs-package-manager={package_manager}"], + env_inherit={"PATH"}, + ) + tool = rule_runner.request(CowsayTool, []) + result = rule_runner.request( + ProcessResult, + [tool.request(("--version",), EMPTY_DIGEST, "Cowsay version", LogLevel.DEBUG)], + ) + + assert result.stdout == b"1.5.0\n" diff --git a/src/python/pants/backend/javascript/subsystems/npx_tool.py b/src/python/pants/backend/javascript/subsystems/npx_tool.py deleted file mode 100644 index a24ba5b1600..00000000000 --- a/src/python/pants/backend/javascript/subsystems/npx_tool.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md). -# Licensed under the Apache License, Version 2.0 (see LICENSE). - -from __future__ import annotations - -from typing import ClassVar - -from pants.option.option_types import StrOption -from pants.option.subsystem import Subsystem - - -class NpxToolBase(Subsystem): - # Subclasses must set. - default_version: ClassVar[str] - - version = StrOption( - advanced=True, - default=lambda cls: cls.default_version, - help="Version string for the tool in the form package@version (e.g. prettier@2.6.2)", - ) diff --git a/src/python/pants/backend/javascript/subsystems/npx_tool_test.py b/src/python/pants/backend/javascript/subsystems/npx_tool_test.py deleted file mode 100644 index d6b15bba36c..00000000000 --- a/src/python/pants/backend/javascript/subsystems/npx_tool_test.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md). -# Licensed under the Apache License, Version 2.0 (see LICENSE). - -from __future__ import annotations - -import pytest - -from pants.backend.javascript.subsystems import nodejs -from pants.backend.javascript.subsystems.npx_tool import NpxToolBase -from pants.testutil.rule_runner import QueryRule, RuleRunner - - -class CowsayTool(NpxToolBase): - options_scope = "cowsay" - name = "Cowsay" - # Intentionally older version. - default_version = "cowsay@1.4.0" - help = "The Cowsay utility for printing cowsay messages" - - -@pytest.fixture -def rule_runner() -> RuleRunner: - return RuleRunner( - rules=[ - *nodejs.rules(), - *CowsayTool.rules(), - QueryRule(CowsayTool, []), - ], - ) - - -def test_version_option_overrides_default(rule_runner: RuleRunner): - rule_runner.set_options(["--cowsay-version=cowsay@1.5.0"], env_inherit={"PATH"}) - tool = rule_runner.request(CowsayTool, []) - assert tool.default_version == "cowsay@1.4.0" - assert tool.version == "cowsay@1.5.0" diff --git a/src/python/pants/backend/javascript/subsystems/package-lock.json b/src/python/pants/backend/javascript/subsystems/package-lock.json new file mode 100644 index 00000000000..5531b4ade6d --- /dev/null +++ b/src/python/pants/backend/javascript/subsystems/package-lock.json @@ -0,0 +1,794 @@ +{ + "name": "@the-company/project", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@the-company/project", + "devDependencies": { + "cowsay": "1.5.0" + } + }, + "node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/cowsay": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.5.0.tgz", + "integrity": "sha512-8Ipzr54Z8zROr/62C8f0PdhQcDusS05gKTS87xxdji8VbWefWly0k8BwGK7+VqamOrkv3eGsCkPtvlHzrhWsCA==", + "dev": true, + "dependencies": { + "get-stdin": "8.0.0", + "string-width": "~2.1.1", + "strip-final-newline": "2.0.0", + "yargs": "15.4.1" + }, + "bin": { + "cowsay": "cli.js", + "cowthink": "cli.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + } + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "cowsay": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.5.0.tgz", + "integrity": "sha512-8Ipzr54Z8zROr/62C8f0PdhQcDusS05gKTS87xxdji8VbWefWly0k8BwGK7+VqamOrkv3eGsCkPtvlHzrhWsCA==", + "dev": true, + "requires": { + "get-stdin": "8.0.0", + "string-width": "~2.1.1", + "strip-final-newline": "2.0.0", + "yargs": "15.4.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/src/python/pants/backend/javascript/subsystems/pnpm-lock.yaml b/src/python/pants/backend/javascript/subsystems/pnpm-lock.yaml new file mode 100644 index 00000000000..f94f426204e --- /dev/null +++ b/src/python/pants/backend/javascript/subsystems/pnpm-lock.yaml @@ -0,0 +1,220 @@ +lockfileVersion: 5.3 + +specifiers: + cowsay: 1.5.0 + +devDependencies: + cowsay: 1.5.0 + +packages: + + /ansi-regex/3.0.1: + resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} + engines: {node: '>=4'} + dev: true + + /ansi-regex/5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles/4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /camelcase/5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /cliui/6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + + /color-convert/2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name/1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /cowsay/1.5.0: + resolution: {integrity: sha512-8Ipzr54Z8zROr/62C8f0PdhQcDusS05gKTS87xxdji8VbWefWly0k8BwGK7+VqamOrkv3eGsCkPtvlHzrhWsCA==} + engines: {node: '>= 4'} + hasBin: true + dependencies: + get-stdin: 8.0.0 + string-width: 2.1.1 + strip-final-newline: 2.0.0 + yargs: 15.4.1 + dev: true + + /decamelize/1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /find-up/4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /get-caller-file/2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-stdin/8.0.0: + resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} + engines: {node: '>=10'} + dev: true + + /is-fullwidth-code-point/2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + dev: true + + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /locate-path/5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /p-limit/2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-locate/4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-try/2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /path-exists/4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /require-directory/2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /require-main-filename/2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: true + + /set-blocking/2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + + /string-width/2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + dev: true + + /string-width/4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /strip-ansi/4.0.0: + resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} + engines: {node: '>=4'} + dependencies: + ansi-regex: 3.0.1 + dev: true + + /strip-ansi/6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-final-newline/2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /which-module/2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: true + + /wrap-ansi/6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /y18n/4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: true + + /yargs-parser/18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: true + + /yargs/15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: true diff --git a/src/python/pants/backend/javascript/subsystems/yarn.lock b/src/python/pants/backend/javascript/subsystems/yarn.lock new file mode 100644 index 00000000000..225f08bcb6e --- /dev/null +++ b/src/python/pants/backend/javascript/subsystems/yarn.lock @@ -0,0 +1,220 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +ansi-regex@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" + integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +cowsay@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/cowsay/-/cowsay-1.5.0.tgz#4a2a453b8b59383c7d7a50e44d765c5de0bf615f" + integrity sha512-8Ipzr54Z8zROr/62C8f0PdhQcDusS05gKTS87xxdji8VbWefWly0k8BwGK7+VqamOrkv3eGsCkPtvlHzrhWsCA== + dependencies: + get-stdin "8.0.0" + string-width "~2.1.1" + strip-final-newline "2.0.0" + yargs "15.4.1" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stdin@8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" + integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@~2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-final-newline@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +which-module@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" + integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@15.4.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" diff --git a/src/python/pants/backend/openapi/lint/spectral/rules.py b/src/python/pants/backend/openapi/lint/spectral/rules.py index 34d16dbfb14..280ed4734c0 100644 --- a/src/python/pants/backend/openapi/lint/spectral/rules.py +++ b/src/python/pants/backend/openapi/lint/spectral/rules.py @@ -1,10 +1,11 @@ # Copyright 2022 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). - +import os from dataclasses import dataclass from typing import Any -from pants.backend.javascript.subsystems.nodejs import NodeJSToolProcess +from pants.backend.javascript.subsystems import nodejs_tool +from pants.backend.javascript.subsystems.nodejs_tool import NodeJSToolRequest from pants.backend.openapi.lint.spectral.skip_field import SkipSpectralField from pants.backend.openapi.lint.spectral.subsystem import SpectralSubsystem from pants.backend.openapi.target_types import ( @@ -89,16 +90,15 @@ async def run_spectral( process_result = await Get( FallibleProcessResult, - NodeJSToolProcess, - NodeJSToolProcess.npx( - npm_package=spectral.version, + NodeJSToolRequest, + spectral.request( args=( "lint", "--display-only-failures", "--ruleset", ".spectral.yaml", *spectral.args, - *target_sources.snapshot.files, + *(os.path.join("{chroot}", file) for file in target_sources.snapshot.files), ), input_digest=input_digest, description=f"Run Spectral on {pluralize(len(request.elements), 'file')}.", @@ -112,5 +112,6 @@ async def run_spectral( def rules(): return [ *collect_rules(), + *nodejs_tool.rules(), *SpectralRequest.rules(), ] diff --git a/src/python/pants/backend/openapi/lint/spectral/subsystem.py b/src/python/pants/backend/openapi/lint/spectral/subsystem.py index 2d655fe5491..4e09c4cc6bc 100644 --- a/src/python/pants/backend/openapi/lint/spectral/subsystem.py +++ b/src/python/pants/backend/openapi/lint/spectral/subsystem.py @@ -3,11 +3,11 @@ from __future__ import annotations -from pants.backend.javascript.subsystems.npx_tool import NpxToolBase +from pants.backend.javascript.subsystems.nodejs_tool import NodeJSToolBase from pants.option.option_types import ArgsListOption, SkipOption -class SpectralSubsystem(NpxToolBase): +class SpectralSubsystem(NodeJSToolBase): options_scope = "spectral" name = "Spectral" help = "A flexible JSON/YAML linter for creating automated style guides (https://github.com/stoplightio/spectral)." diff --git a/src/python/pants/backend/python/typecheck/pyright/rules.py b/src/python/pants/backend/python/typecheck/pyright/rules.py index 4662d87e734..58b1fbd7c97 100644 --- a/src/python/pants/backend/python/typecheck/pyright/rules.py +++ b/src/python/pants/backend/python/typecheck/pyright/rules.py @@ -5,12 +5,14 @@ import json import logging +import os from dataclasses import dataclass, replace from typing import Iterable import toml -from pants.backend.javascript.subsystems.nodejs import NodeJSToolProcess +from pants.backend.javascript.subsystems import nodejs_tool +from pants.backend.javascript.subsystems.nodejs_tool import NodeJSToolRequest from pants.backend.python.subsystems.setup import PythonSetup from pants.backend.python.target_types import ( InterpreterConstraintsField, @@ -212,13 +214,12 @@ async def pyright_typecheck_partition( complete_pex_env = pex_environment.in_workspace() process = await Get( Process, - NodeJSToolProcess, - NodeJSToolProcess.npx( - npm_package=pyright.version, + NodeJSToolRequest, + pyright.request( args=( f"--venv-path={complete_pex_env.pex_root}", # Used with `venv` in config *pyright.args, # User-added arguments - *root_sources.snapshot.files, + *(os.path.join("{chroot}", file) for file in root_sources.snapshot.files), ), input_digest=input_digest, description=f"Run Pyright on {pluralize(len(root_sources.snapshot.files), 'file')}.", @@ -291,5 +292,6 @@ def rules() -> Iterable[Rule | UnionRule]: *collect_rules(), *config_files.rules(), *pex_from_targets.rules(), + *nodejs_tool.rules(), UnionRule(CheckRequest, PyrightRequest), ) diff --git a/src/python/pants/backend/python/typecheck/pyright/rules_integration_test.py b/src/python/pants/backend/python/typecheck/pyright/rules_integration_test.py index 33fbd6bae03..a27a98d443b 100644 --- a/src/python/pants/backend/python/typecheck/pyright/rules_integration_test.py +++ b/src/python/pants/backend/python/typecheck/pyright/rules_integration_test.py @@ -3,11 +3,13 @@ from __future__ import annotations +import json from textwrap import dedent +from typing import Iterable import pytest -from pants.backend.javascript.subsystems.nodejs import rules as nodejs_rules +from pants.backend.javascript.package_json import PackageJsonTarget from pants.backend.python import target_types_rules from pants.backend.python.target_types import ( PythonRequirementTarget, @@ -35,13 +37,17 @@ def rule_runner() -> PythonRuleRunner: return PythonRuleRunner( rules=[ - *nodejs_rules(), *pyright_rules(), *target_types_rules.rules(), QueryRule(CheckResults, (PyrightRequest,)), QueryRule(PyrightPartitions, (PyrightRequest,)), ], - target_types=[PythonRequirementTarget, PythonSourcesGeneratorTarget, PythonSourceTarget], + target_types=[ + PythonRequirementTarget, + PythonSourcesGeneratorTarget, + PythonSourceTarget, + PackageJsonTarget, + ], ) @@ -84,9 +90,36 @@ def add(x: int, y: int) -> int: """ ) +PYRIGHT_LOCKFILE = json.dumps( + { + "name": "@the-company/project", + "lockfileVersion": 2, + "requires": True, + "packages": { + "": {"name": "@the-company/project", "devDependencies": {"pyright": "1.1.274"}}, + "node_modules/pyright": { + "version": "1.1.274", + "resolved": "https://registry.npmjs.org/pyright/-/pyright-1.1.274.tgz", + "integrity": "sha512-+MEiHktoAxlehWbBAF2vwJkJxV5tObbLK6vnc7u+iDBH06vuHqTqY33AV+YGNwfDEU35chw5zu7H3EpGROXsGQ==", + "dev": True, + "bin": {"pyright": "index.js", "pyright-langserver": "langserver.index.js"}, + "engines": {"node": ">=12.0.0"}, + }, + }, + "dependencies": { + "pyright": { + "version": "1.1.274", + "resolved": "https://registry.npmjs.org/pyright/-/pyright-1.1.274.tgz", + "integrity": "sha512-+MEiHktoAxlehWbBAF2vwJkJxV5tObbLK6vnc7u+iDBH06vuHqTqY33AV+YGNwfDEU35chw5zu7H3EpGROXsGQ==", + "dev": True, + } + }, + } +) + def run_pyright( - rule_runner: PythonRuleRunner, targets: list[Target], *, extra_args: list[str] | None = None + rule_runner: PythonRuleRunner, targets: list[Target], *, extra_args: Iterable[str] | None = None ) -> tuple[CheckResult, ...]: rule_runner.set_options(extra_args or (), env_inherit={"PATH", "PYENV_ROOT", "HOME"}) result = rule_runner.request( @@ -161,17 +194,65 @@ def test_config_file( assert result[0].exit_code == exit_code -def test_additional_source_roots(rule_runner: PythonRuleRunner) -> None: - LIB_1_PACKAGE = f"{PACKAGE}/lib1" - LIB_2_PACKAGE = f"{PACKAGE}/lib2" - rule_runner.write_files( - { - f"{LIB_1_PACKAGE}/core/a.py": GOOD_FILE, - f"{LIB_1_PACKAGE}/core/BUILD": "python_sources()", - f"{LIB_2_PACKAGE}/core/b.py": "from core.a import add", - f"{LIB_2_PACKAGE}/core/BUILD": "python_sources()", - } - ) +LIB_1_PACKAGE = f"{PACKAGE}/lib1" +LIB_2_PACKAGE = f"{PACKAGE}/lib2" + + +@pytest.mark.parametrize( + "files, extra_args", + [ + pytest.param( + { + f"{LIB_1_PACKAGE}/core/a.py": GOOD_FILE, + f"{LIB_1_PACKAGE}/core/BUILD": "python_sources()", + f"{LIB_2_PACKAGE}/core/b.py": "from core.a import add", + f"{LIB_2_PACKAGE}/core/BUILD": "python_sources()", + }, + (f"--source-root-patterns=['{LIB_1_PACKAGE}', '{LIB_2_PACKAGE}']",), + id="from_version", + ), + pytest.param( + { + f"{LIB_1_PACKAGE}/core/a.py": GOOD_FILE, + f"{LIB_1_PACKAGE}/core/BUILD": "python_sources()", + f"{LIB_2_PACKAGE}/core/b.py": "from core.a import add", + f"{LIB_2_PACKAGE}/core/BUILD": "python_sources()", + "src/js/lib3/BUILD": "package_json()", + "src/js/lib3/package.json": json.dumps( + {"name": "@the-company/project", "dependencies": {"pyright": "1.1.274"}} + ), + "src/js/lib3/package-lock.json": PYRIGHT_LOCKFILE, + }, + ( + f"--source-root-patterns=['{LIB_1_PACKAGE}', '{LIB_2_PACKAGE}', 'src/js']", + "--pyright-install-from-resolve=lib3", + ), + id="from_resolve", + ), + pytest.param( + { + f"{LIB_1_PACKAGE}/core/a.py": GOOD_FILE, + f"{LIB_1_PACKAGE}/core/BUILD": "python_sources()", + f"{LIB_2_PACKAGE}/core/b.py": "from core.a import add", + f"{LIB_2_PACKAGE}/core/BUILD": "python_sources()", + "BUILD": "package_json(name='root_package')", + "package.json": json.dumps( + {"name": "@the-company/project", "dependencies": {"pyright": "1.1.274"}} + ), + "package-lock.json": PYRIGHT_LOCKFILE, + }, + ( + f"--source-root-patterns=['{LIB_1_PACKAGE}', '{LIB_2_PACKAGE}', '/']", + "--pyright-install-from-resolve=", # See: https://github.com/pantsbuild/pants/issues/18924 + ), + id="from_resolve_at_root", + ), + ], +) +def test_additional_source_roots( + files: dict[str, str], extra_args: tuple[str, ...], rule_runner: PythonRuleRunner +) -> None: + rule_runner.write_files(files) tgts = [ rule_runner.get_target(Address(f"{LIB_1_PACKAGE}/core", relative_file_path="a.py")), rule_runner.get_target(Address(f"{LIB_2_PACKAGE}/core", relative_file_path="b.py")), @@ -184,7 +265,7 @@ def test_additional_source_roots(rule_runner: PythonRuleRunner) -> None: result = run_pyright( rule_runner, tgts, - extra_args=[f"--source-root-patterns=['{LIB_1_PACKAGE}', '{LIB_2_PACKAGE}']"], + extra_args=extra_args, ) assert len(result) == 1 assert result[0].exit_code == 0 @@ -193,7 +274,7 @@ def test_additional_source_roots(rule_runner: PythonRuleRunner) -> None: result = run_pyright( rule_runner, tgts[1:], - extra_args=[f"--source-root-patterns=['{LIB_1_PACKAGE}', '{LIB_2_PACKAGE}']"], + extra_args=extra_args, ) assert len(result) == 1 assert result[0].exit_code == 0 @@ -206,24 +287,56 @@ def test_skip(rule_runner: PythonRuleRunner) -> None: assert not result -def test_thirdparty_dependency(rule_runner: PythonRuleRunner) -> None: - rule_runner.write_files( - { - "BUILD": ( - "python_requirement(name='more-itertools', requirements=['more-itertools==8.4.0'])" - ), - f"{PACKAGE}/f.py": dedent( - """\ +@pytest.mark.parametrize( + "files, extra_args", + [ + pytest.param( + { + "BUILD": ( + "python_requirement(name='more-itertools', requirements=['more-itertools==8.4.0'])" + ), + f"{PACKAGE}/f.py": dedent( + """\ + from more_itertools import flatten + + assert flatten(42) == [4, 2] + """ + ), + f"{PACKAGE}/BUILD": "python_sources()", + }, + (), + id="from_version", + ), + pytest.param( + { + "BUILD": ( + "python_requirement(name='more-itertools', requirements=['more-itertools==8.4.0'])" + ), + f"{PACKAGE}/f.py": dedent( + """\ from more_itertools import flatten assert flatten(42) == [4, 2] """ - ), - f"{PACKAGE}/BUILD": "python_sources()", - } - ) + ), + f"{PACKAGE}/BUILD": "python_sources()", + "src/js/BUILD": "package_json()", + "src/js/package.json": json.dumps( + {"name": "@the-company/project", "dependencies": {"pyright": "1.1.274"}} + ), + "src/js/package-lock.json": PYRIGHT_LOCKFILE, + }, + ("--pyright-install-from-resolve=js",), + id="from_resolve", + ), + ], +) +def test_thirdparty_dependency( + rule_runner: PythonRuleRunner, files: dict[str, str], extra_args: tuple[str, ...] +) -> None: + rule_runner.write_files(files) tgt = rule_runner.get_target(Address(PACKAGE, relative_file_path="f.py")) - result = run_pyright(rule_runner, [tgt]) + result = run_pyright(rule_runner, [tgt], extra_args=extra_args) assert len(result) == 1 assert result[0].exit_code == 1 assert f"{PACKAGE}/f.py:3" in result[0].stdout diff --git a/src/python/pants/backend/python/typecheck/pyright/subsystem.py b/src/python/pants/backend/python/typecheck/pyright/subsystem.py index c3937f032f4..29f6d84e527 100644 --- a/src/python/pants/backend/python/typecheck/pyright/subsystem.py +++ b/src/python/pants/backend/python/typecheck/pyright/subsystem.py @@ -3,14 +3,14 @@ from __future__ import annotations -from pants.backend.javascript.subsystems.npx_tool import NpxToolBase +from pants.backend.javascript.subsystems.nodejs_tool import NodeJSToolBase from pants.backend.python.util_rules.interpreter_constraints import InterpreterConstraints from pants.core.util_rules.config_files import ConfigFilesRequest from pants.option.option_types import ArgsListOption, SkipOption, StrListOption from pants.util.strutil import help_text -class Pyright(NpxToolBase): +class Pyright(NodeJSToolBase): options_scope = "pyright" name = "Pyright" help = help_text(