Skip to content

Commit

Permalink
javascript: Assign a default name to root nodejs resolves (#19047)
Browse files Browse the repository at this point in the history
Also validate the resolve names, ensuring they are 1:1 with project
roots.

Fixes #18924

---------

Co-authored-by: Stu Hood <[email protected]>
  • Loading branch information
tobni and stuhood authored Jun 3, 2023
1 parent 86ad0ef commit 0aedb6b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 7 deletions.
54 changes: 47 additions & 7 deletions src/python/pants/backend/javascript/nodejs_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
PnpmWorkspaces,
)
from pants.backend.javascript.subsystems import nodejs
from pants.backend.javascript.subsystems.nodejs import NodeJS
from pants.backend.javascript.subsystems.nodejs import NodeJS, UserChosenNodeJSResolveAliases
from pants.core.util_rules import stripped_source_files
from pants.core.util_rules.stripped_source_files import StrippedFileName, StrippedFileNameRequest
from pants.engine.collection import Collection
Expand All @@ -25,7 +25,7 @@
from pants.engine.rules import Rule, collect_rules, rule
from pants.engine.unions import UnionRule
from pants.util.ordered_set import FrozenOrderedSet
from pants.util.strutil import softwrap
from pants.util.strutil import bullet_list, softwrap


@dataclass(frozen=True)
Expand Down Expand Up @@ -123,7 +123,11 @@ def single_workspace(self) -> bool:

@classmethod
def from_tentative(
cls, project: _TentativeProject, nodejs: NodeJS, pnpm_workspaces: PnpmWorkspaces
cls,
project: _TentativeProject,
nodejs: NodeJS,
pnpm_workspaces: PnpmWorkspaces,
resolve_names: UserChosenNodeJSResolveAliases,
) -> NodeJSProject:
root_ws = project.root_workspace()
package_manager: str | None = None
Expand Down Expand Up @@ -163,7 +167,7 @@ def from_tentative(
return NodeJSProject(
root_dir=project.root_dir,
workspaces=project.workspaces,
default_resolve_name=project.default_resolve_name,
default_resolve_name=project.default_resolve_name or "nodejs-default",
package_manager=package_manager_command,
package_manager_version=package_manager_version,
pnpm_workspace=pnpm_workspaces.for_root(project.root_dir),
Expand Down Expand Up @@ -206,7 +210,10 @@ async def _get_default_resolve_name(path: str) -> str:

@rule
async def find_node_js_projects(
package_workspaces: AllPackageJson, pnpm_workspaces: PnpmWorkspaces, nodejs: NodeJS
package_workspaces: AllPackageJson,
pnpm_workspaces: PnpmWorkspaces,
nodejs: NodeJS,
resolve_names: UserChosenNodeJSResolveAliases,
) -> AllNodeJSProjects:
project_paths = (
ProjectPaths(pkg.root_dir, ["", *pkg.workspaces])
Expand All @@ -224,9 +231,42 @@ async def find_node_js_projects(
for paths in project_paths
}
merged_projects = _merge_workspaces(node_js_projects)
return AllNodeJSProjects(
NodeJSProject.from_tentative(p, nodejs, pnpm_workspaces) for p in merged_projects
all_projects = AllNodeJSProjects(
NodeJSProject.from_tentative(p, nodejs, pnpm_workspaces, resolve_names)
for p in merged_projects
)
_ensure_resolve_names_are_unique(all_projects, resolve_names)

return all_projects


_AMBIGUOUS_RESOLVE_SOLUTIONS = [
f"Configure [{NodeJS.options_scope}].resolves to grant the package.json directories different names.",
"Make one package a workspace of the other.",
"Re-configure your source root(s).",
]


def _ensure_resolve_names_are_unique(
all_projects: AllNodeJSProjects, resolve_names: UserChosenNodeJSResolveAliases
) -> None:
seen: dict[str, NodeJSProject] = {}
for project in all_projects:
resolve_name = resolve_names.get(project.root_dir, project.default_resolve_name)
seen_project = seen.get(resolve_name)
if seen_project:
raise ValueError(
softwrap(
f"""
Projects with root directories '{project.root_dir}' and '{seen_project.root_dir}'
have the same resolve name {resolve_name}. This will cause ambiguities.
To disambiguate, either:\n\n
{bullet_list(_AMBIGUOUS_RESOLVE_SOLUTIONS)}
"""
)
)
seen[resolve_name] = project


def _project_to_parents(
Expand Down
1 change: 1 addition & 0 deletions src/python/pants/backend/javascript/nodejs_project_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def test_root_package_json_is_supported(rule_runner: RuleRunner) -> None:
)
projects = rule_runner.request(AllNodeJSProjects, [])
assert {project.root_dir for project in projects} == {"", "src/js/bar"}
assert {project.default_resolve_name for project in projects} == {"nodejs-default", "js.bar"}


def test_parses_project_with_workspaces(rule_runner: RuleRunner) -> None:
Expand Down

0 comments on commit 0aedb6b

Please sign in to comment.