Skip to content

Commit

Permalink
Yarn Berry: make _configure_yarn_version return a semver.Version
Browse files Browse the repository at this point in the history
This makes it possible to avoid parsing the version from package.json
a second time when setting the .yarnrc.yaml configuration (there's a
configuration key that is dependent on the Yarn version).

Signed-off-by: Bruno Pimentel <bpimente@redhat.com>
  • Loading branch information
brunoapimentel committed Jan 3, 2025
1 parent dcd2a13 commit 5ef2ee1
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 43 deletions.
16 changes: 8 additions & 8 deletions cachi2/core/package_managers/yarn/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,17 @@ def _resolve_yarn_project(project: Project, output_dir: RootedPath) -> list[Comp
"""
log.info(f"Fetching the yarn dependencies at the subpath {project.source_dir}")

_configure_yarn_version(project)
version = _configure_yarn_version(project)
_verify_repository(project)

_set_yarnrc_configuration(project, output_dir)
_set_yarnrc_configuration(project, output_dir, version)
packages = resolve_packages(project.source_dir)
_fetch_dependencies(project.source_dir)

return create_components(packages, project, output_dir)


def _configure_yarn_version(project: Project) -> None:
def _configure_yarn_version(project: Project) -> semver.Version:
"""Resolve the yarn version and set it in the package.json file if needed.
:raises PackageRejected:
Expand Down Expand Up @@ -166,6 +166,8 @@ def _configure_yarn_version(project: Project) -> None:

_verify_corepack_yarn_version(version, project.source_dir)

return version


def _get_plugin_allowlist(yarn_rc: YarnRc) -> list[Plugin]:
"""Return a list of plugins that can be kept in .yarnrc.yml.
Expand All @@ -191,7 +193,9 @@ def _get_plugin_allowlist(yarn_rc: YarnRc) -> list[Plugin]:
return [plugin for plugin in default_plugins if plugin in yarn_rc["plugins"]]


def _set_yarnrc_configuration(project: Project, output_dir: RootedPath) -> None:
def _set_yarnrc_configuration(
project: Project, output_dir: RootedPath, version: semver.Version
) -> None:
"""Set all the necessary configuration in yarnrc for the project processing.
:param project: a Project instance
Expand All @@ -213,10 +217,6 @@ def _set_yarnrc_configuration(project: Project, output_dir: RootedPath) -> None:
yarn_rc["enableGlobalCache"] = True
yarn_rc["globalFolder"] = str(output_dir.join_within_root("deps", "yarn"))

# version can be read from `package.json` since we have already executed
# `_configure_yarn_version` at this point
version = get_semver_from_package_manager(project.package_json["packageManager"])

# In Yarn v4, constraints can be automatically executed as part of `yarn install`, so they
# need to be explicitly disabled
if version in VersionsRange("4.0.0-rc1", "5.0.0"): # type: ignore
Expand Down
47 changes: 12 additions & 35 deletions tests/unit/package_managers/yarn/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
fetch_yarn_source,
)
from cachi2.core.package_managers.yarn.project import PackageJson, Plugin, YarnRc
from cachi2.core.package_managers.yarn.utils import VersionsRange
from cachi2.core.rooted_path import RootedPath


Expand Down Expand Up @@ -271,9 +272,9 @@ def test_resolve_zero_installs_fail() -> None:


@pytest.mark.parametrize(
"yarn_rc_content, expected_plugins",
"yarn_rc_content, expected_plugins, yarn_version",
[
pytest.param("", [], id="empty_yarn_rc"),
pytest.param("", [], "3.0.0", id="empty_yarn_rc"),
pytest.param(
SAMPLE_PLUGINS,
[
Expand All @@ -282,17 +283,19 @@ def test_resolve_zero_installs_fail() -> None:
"spec": "@yarnpkg/plugin-exec",
},
],
"3.0.0",
id="yarn_rc_with_default_plugins",
),
pytest.param("", [], "4.0.0", id="yarn_v4"),
pytest.param("", [], "4.0.0-rc1", id="yarn_v4_rc1"),
],
)
@mock.patch("cachi2.core.package_managers.yarn.project.YarnRc.write")
@mock.patch("cachi2.core.package_managers.yarn.main.get_semver_from_package_manager")
def test_set_yarnrc_configuration(
mock_get_semver: mock.Mock,
mock_write: mock.Mock,
yarn_rc_content: str,
expected_plugins: list[Plugin],
yarn_version: semver.Version,
rooted_tmp_path: RootedPath,
) -> None:
yarn_rc_path = rooted_tmp_path.join_within_root(".yarnrc.yml")
Expand All @@ -305,7 +308,7 @@ def test_set_yarnrc_configuration(
project.package_json = mock.MagicMock()
output_dir = RootedPath("/tmp/output")

_set_yarnrc_configuration(project, output_dir)
_set_yarnrc_configuration(project, output_dir, yarn_version)

expected_data = {
"checksumBehavior": "throw",
Expand All @@ -322,39 +325,13 @@ def test_set_yarnrc_configuration(
"plugins": expected_plugins,
}

if yarn_version in VersionsRange("4.0.0-rc1", "5.0.0"):
expected_data["enableConstraintsChecks"] = False

assert yarn_rc.data == expected_data
mock_write.assert_called_once()


@pytest.mark.parametrize(
"yarn_version, enable_constraints_checks",
[
pytest.param("yarn@4.0.0", False, id="yarn-v4"),
pytest.param("yarn@4.0.0-rc1", False, id="yarn-v4-rc1"),
pytest.param("yarn@3.5.0", True, id="yarn-v3"),
],
)
@mock.patch("cachi2.core.package_managers.yarn.project.YarnRc.write")
def test_enable_constraints_checks_in_yarn_v4(
mock_write: mock.Mock,
rooted_tmp_path: RootedPath,
yarn_version: str,
enable_constraints_checks: bool,
) -> None:
yarn_rc = YarnRc(mock.Mock(), {})
package_json = PackageJson(mock.Mock(), {})
package_json["packageManager"] = yarn_version

project = mock.Mock()
project.yarn_rc = yarn_rc
project.package_json = package_json

_set_yarnrc_configuration(project, rooted_tmp_path)

# for versions <4, enableConstraintsChecks should not be set
assert yarn_rc.data.get("enableConstraintsChecks", True) is enable_constraints_checks


@mock.patch("cachi2.core.package_managers.yarn.main.get_semver_from_package_manager")
def test_verify_yarnrc_paths(mock_get_semver: mock.Mock) -> None:
output_dir = RootedPath("/tmp/output")
Expand All @@ -363,7 +340,7 @@ def test_verify_yarnrc_paths(mock_get_semver: mock.Mock) -> None:
project.yarn_rc = yarn_rc
project.package_json = mock.MagicMock()

_set_yarnrc_configuration(project, output_dir)
_set_yarnrc_configuration(project, output_dir, semver.Version.parse("3.0.0"))
_verify_yarnrc_paths(project)


Expand Down

0 comments on commit 5ef2ee1

Please sign in to comment.