-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ensure packageManager is correctly set for yarn
STONEBLD-1776 Since we will rely on corepack to download and configure the correct version of yarn for a request, ensure that packageManager is defined in package.json. Use either yarnPath from .yarnrc, packageManager, or a combination of the two to set the correct yarn version. Raise exceptions for the following cases: - packageManager is already set, but we can't parse it - neither yarnPath or packageManager is set (or parseable) - the versions specified by yarnPath and packageManager are different Signed-off-by: Taylor Madore <[email protected]>
- Loading branch information
1 parent
c53b7b2
commit b74ff6c
Showing
4 changed files
with
342 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import re | ||
from typing import Optional, Union | ||
from unittest import mock | ||
|
||
import pytest | ||
import semver | ||
|
||
from cachi2.core.errors import PackageRejected, UnexpectedFormat | ||
from cachi2.core.package_managers.yarn.main import _configure_yarn_version | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"yarn_path_version, package_manager_version", | ||
[ | ||
pytest.param(semver.VersionInfo(1, 0, 0), None, id="valid-yarnpath-no-packagemanager"), | ||
pytest.param(None, semver.VersionInfo(1, 0, 0), id="no-yarnpath-valid-packagemanager"), | ||
pytest.param( | ||
semver.VersionInfo(1, 0, 0), | ||
semver.VersionInfo(1, 0, 0), | ||
id="matching-yarnpath-and-packagemanager", | ||
), | ||
pytest.param( | ||
semver.VersionInfo(1, 0, 0), | ||
semver.VersionInfo( | ||
1, 0, 0, build="sha224.953c8233f7a92884eee2de69a1b92d1f2ec1655e66d08071ba9a02fa" | ||
), | ||
id="matching-yarnpath-and-packagemanager-with-build", | ||
), | ||
], | ||
) | ||
@mock.patch("cachi2.core.package_managers.yarn.main.get_semver_from_package_manager") | ||
@mock.patch("cachi2.core.package_managers.yarn.main.get_semver_from_yarn_path") | ||
def test_configure_yarn_version( | ||
mock_yarn_path_semver: mock.Mock, | ||
mock_package_manager_semver: mock.Mock, | ||
yarn_path_version: Optional[semver.version.Version], | ||
package_manager_version: Optional[semver.version.Version], | ||
) -> None: | ||
mock_project = mock.Mock() | ||
mock_yarn_path_semver.return_value = yarn_path_version | ||
mock_package_manager_semver.return_value = package_manager_version | ||
|
||
_configure_yarn_version(mock_project) | ||
|
||
if package_manager_version is None: | ||
assert mock_project.package_json.package_manager == f"yarn@{yarn_path_version}" | ||
mock_project.package_json.write_to_file.assert_called_once() | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"yarn_path_version, package_manager_version, expected_error", | ||
[ | ||
pytest.param( | ||
None, | ||
None, | ||
PackageRejected( | ||
"Unable to determine the yarn version to use to process the request", | ||
solution="Ensure that either yarnPath is defined in .yarnrc or that packageManager is defined in package.json", | ||
), | ||
id="no-yarnpath-no-packagemanager", | ||
), | ||
pytest.param( | ||
None, | ||
UnexpectedFormat("some error about packageManager formatting"), | ||
UnexpectedFormat("some error about packageManager formatting"), | ||
id="exception-parsing-packagemanager", | ||
), | ||
pytest.param( | ||
semver.VersionInfo(1, 0, 1), | ||
semver.VersionInfo(1, 0, 0), | ||
PackageRejected( | ||
"Mismatch between the yarn versions specified by yarnPath ([email protected]) and packageManager ([email protected])", | ||
solution="Ensure that the yarnPath version in .yarnrc and the packageManager version in package.json agree", | ||
), | ||
id="yarnpath-packagemanager-mismatch", | ||
), | ||
], | ||
) | ||
@mock.patch("cachi2.core.package_managers.yarn.main.get_semver_from_package_manager") | ||
@mock.patch("cachi2.core.package_managers.yarn.main.get_semver_from_yarn_path") | ||
def test_configure_yarn_version_fail( | ||
mock_yarn_path_semver: mock.Mock, | ||
mock_package_manager_semver: mock.Mock, | ||
yarn_path_version: Optional[semver.version.Version], | ||
package_manager_version: Union[semver.version.Version, None, Exception], | ||
expected_error: Exception, | ||
) -> None: | ||
mock_project = mock.Mock() | ||
mock_yarn_path_semver.return_value = yarn_path_version | ||
mock_package_manager_semver.side_effect = [package_manager_version] | ||
|
||
with pytest.raises(type(expected_error), match=re.escape(str(expected_error))): | ||
_configure_yarn_version(mock_project) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import re | ||
from typing import Optional | ||
|
||
import pytest | ||
import semver | ||
|
||
from cachi2.core.errors import UnexpectedFormat | ||
from cachi2.core.package_managers.yarn.project import ( | ||
get_semver_from_package_manager, | ||
get_semver_from_yarn_path, | ||
) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"yarn_path, expected_result", | ||
[ | ||
( | ||
None, | ||
None, | ||
), | ||
( | ||
"", | ||
None, | ||
), | ||
( | ||
"/some/path/yarn-1.0.cjs", | ||
None, | ||
), | ||
( | ||
"/some/path/yarn-1.0.0.cjs", | ||
semver.VersionInfo(1, 0, 0), | ||
), | ||
( | ||
"/some/path/yarn-1.0.0-rc.cjs", | ||
semver.VersionInfo(1, 0, 0, prerelease="rc"), | ||
), | ||
( | ||
"/some/path/yarn.cjs", | ||
None, | ||
), | ||
], | ||
) | ||
def test_get_semver_from_yarn_path( | ||
yarn_path: str, expected_result: Optional[semver.version.Version] | ||
) -> None: | ||
yarn_semver = get_semver_from_yarn_path(yarn_path) | ||
|
||
if yarn_semver is None: | ||
assert expected_result is None | ||
else: | ||
assert expected_result is not None | ||
assert yarn_semver == expected_result | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"package_manager, expected_result", | ||
[ | ||
( | ||
None, | ||
None, | ||
), | ||
( | ||
"", | ||
None, | ||
), | ||
( | ||
"[email protected]", | ||
semver.VersionInfo(1, 0, 0), | ||
), | ||
( | ||
"[email protected]", | ||
semver.VersionInfo(1, 0, 0, prerelease="rc"), | ||
), | ||
( | ||
"[email protected]+sha224.953c8233f7a92884eee2de69a1b92d1f2ec1655e66d08071ba9a02fa", | ||
semver.VersionInfo( | ||
1, 0, 0, build="sha224.953c8233f7a92884eee2de69a1b92d1f2ec1655e66d08071ba9a02fa" | ||
), | ||
), | ||
( | ||
"[email protected]+sha224.953c8233f7a92884eee2de69a1b92d1f2ec1655e66d08071ba9a02fa", | ||
semver.VersionInfo( | ||
1, | ||
0, | ||
0, | ||
prerelease="rc", | ||
build="sha224.953c8233f7a92884eee2de69a1b92d1f2ec1655e66d08071ba9a02fa", | ||
), | ||
), | ||
], | ||
) | ||
def test_get_semver_from_package_manager( | ||
package_manager: str, expected_result: Optional[semver.version.Version] | ||
) -> None: | ||
yarn_semver = get_semver_from_package_manager(package_manager) | ||
|
||
if yarn_semver is None: | ||
assert expected_result is None | ||
else: | ||
assert expected_result is not None | ||
assert yarn_semver == expected_result | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"package_manager, expected_error", | ||
[ | ||
( | ||
"no-one-expected-it", | ||
"could not parse packageManager spec in package.json (expected name@semver)", | ||
), | ||
( | ||
"[email protected]", | ||
"1.0 is not a valid semver for packageManager in package.json", | ||
), | ||
( | ||
"[email protected]", | ||
"packageManager in package.json must be yarn", | ||
), | ||
], | ||
) | ||
def test_get_semver_from_package_manager_fail(package_manager: str, expected_error: str) -> None: | ||
with pytest.raises(UnexpectedFormat, match=re.escape(expected_error)): | ||
get_semver_from_package_manager(package_manager) |