From 6e3711c5561318d3222b850610b1c852a992ef13 Mon Sep 17 00:00:00 2001 From: Taylor Madore Date: Tue, 14 Nov 2023 14:52:44 -0500 Subject: [PATCH] configure yarn request output env variables Several yarn settings must be supplied by the cachi2 request output in order for the user to make use of the prefetched dependencies. These will be supplied by way of environment variables, which when sourced, will override any preexisting user configuration in .yarnrc.yml These yarn settings are all related to the process of installing cachi2-fetched dependencies from the globalFolder. Cachi2 must populate globalFolder for the build rather than cacheFolder because when mounting globalFolder, the `yarn install` step in the Containerfile will copy everything from the global cache to the project-local cache. That means the project-local cache stays populated after the build. When mounting cacheFolder, `yarn install` doesn't do anything (the cache is already populated). But when the build ends, podman unmounts the folder and the cache disappears. When you try to run the app: Error: Required package missing from disk. If you keep your packages inside your repository then restarting the Node process may be enough. Otherwise, try to run an install first. YARN_GLOBAL_FOLDER must be configured to the deps/yarn subdirectory of the cachi2 request output directory. This is the path that cachi2 will populate with the prefetched dependencies. YARN_ENABLE_MIRROR must be set to true, otherwise the user build will not make use of the global cache located at the globalFolder path that cachi2 prepopulates. YARN_ENABLE_GLOBAL_CACHE must be set to false, otherwise the user build will exclusively rely on the cachi2 populated globalFolder cache rather than copying the dependencies to cacheFolder. If the volume containing globalFolder is only mounted at build-time and the dependencies are not copied to cacheFolder, the dependencies will be missing at run-time. YARN_ENABLE_IMMUTABLE_CACHE must be set to false, otherwise the `yarn install` will fail to populate cacheFolder from the cachi2-supplied globalFolder cache. Signed-off-by: Taylor Madore --- cachi2/core/package_managers/yarn/main.py | 9 ++++++++- tests/unit/package_managers/yarn/test_main.py | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/cachi2/core/package_managers/yarn/main.py b/cachi2/core/package_managers/yarn/main.py index 14f928086..87f06e1ea 100644 --- a/cachi2/core/package_managers/yarn/main.py +++ b/cachi2/core/package_managers/yarn/main.py @@ -160,4 +160,11 @@ def _undo_changes(project: Project) -> None: def _generate_environment_variables() -> list[EnvironmentVariable]: """Generate environment variables that will be used for building the project.""" - return [] + env_vars = { + "YARN_ENABLE_GLOBAL_CACHE": {"value": "false", "kind": "literal"}, + "YARN_ENABLE_IMMUTABLE_CACHE": {"value": "false", "kind": "literal"}, + "YARN_ENABLE_MIRROR": {"value": "true", "kind": "literal"}, + "YARN_GLOBAL_FOLDER": {"value": "deps/yarn", "kind": "path"}, + } + + return [EnvironmentVariable(name=name, **obj) for name, obj in env_vars.items()] diff --git a/tests/unit/package_managers/yarn/test_main.py b/tests/unit/package_managers/yarn/test_main.py index 8efc02a4b..6e1cbbd30 100644 --- a/tests/unit/package_managers/yarn/test_main.py +++ b/tests/unit/package_managers/yarn/test_main.py @@ -8,9 +8,11 @@ import semver from cachi2.core.errors import PackageRejected, UnexpectedFormat, YarnCommandError +from cachi2.core.models.output import EnvironmentVariable from cachi2.core.package_managers.yarn.main import ( _configure_yarn_version, _fetch_dependencies, + _generate_environment_variables, _resolve_yarn_project, _set_yarnrc_configuration, ) @@ -18,6 +20,16 @@ from cachi2.core.rooted_path import RootedPath +@pytest.fixture() +def yarn_env_variables() -> list[EnvironmentVariable]: + return [ + EnvironmentVariable(name="YARN_ENABLE_GLOBAL_CACHE", value="false", kind="literal"), + EnvironmentVariable(name="YARN_ENABLE_IMMUTABLE_CACHE", value="false", kind="literal"), + EnvironmentVariable(name="YARN_ENABLE_MIRROR", value="true", kind="literal"), + EnvironmentVariable(name="YARN_GLOBAL_FOLDER", value="deps/yarn", kind="path"), + ] + + class YarnVersions(Enum): YARN_V1 = semver.VersionInfo(1, 0, 0) YARN_V2 = semver.VersionInfo(2, 0, 0) @@ -212,3 +224,8 @@ def test_set_yarnrc_configuration(mock_write: mock.Mock) -> None: assert yarn_rc._data == expected_data assert mock_write.called_once() + + +def test_generate_environment_variables(yarn_env_variables: list[EnvironmentVariable]) -> None: + result = _generate_environment_variables() + assert result == yarn_env_variables