Exemplo n.º 1
0
def test_process_non_registry_dependency_invalid_location():
    dep_identifier = "file:rxjs-6.5.5.tar.gz"
    dep_name = "rxjs"
    dep_info = {
        "version": dep_identifier,
        "requires": {
            "tslib": "^1.9.0"
        },
    }
    dep = general_js.JSDependency(dep_name, source=dep_info["version"])

    expected = f"The dependency {dep_name}@{dep_identifier} is hosted in an unsupported location"
    with pytest.raises(CachitoError, match=expected):
        general_js.process_non_registry_dependency(dep)
Exemplo n.º 2
0
def test_process_non_registry_dependency_http_integrity_missing():
    dep_identifier = "https://github.com/ReactiveX/rxjs/archive/6.5.5.tar.gz"
    dep_name = "rxjs"
    dep_info = {
        "version": dep_identifier,
        "requires": {
            "tslib": "^1.9.0"
        },
    }
    dep = general_js.JSDependency(dep_name, source=dep_info["version"])

    expected = (
        f"The dependency {dep_name}@{dep_identifier} is missing the integrity value. "
        'Is the "integrity" key missing in your lockfile?')
    with pytest.raises(CachitoError, match=expected):
        general_js.process_non_registry_dependency(dep)
Exemplo n.º 3
0
def convert_to_nexus_hosted(dep_name, dep_info):
    """
    Convert the input dependency not from the NPM registry to a Nexus hosted dependency.

    :param str dep_name: the name of the dependency
    :param dict dep_info: the dependency info from the npm lock file (e.g. package-lock.json)
    :return: the dependency information of the Nexus hosted version to use in the npm lock file
        instead of the original
    :raise CachitoError: if the dependency is from an unsupported location or has an unexpected
        format in the lock file
    """
    # The version value for a dependency outside of the npm registry is the identifier to use for
    # commands such as `npm pack` or `npm install`
    # Examples of version values:
    #   git+https://github.com/ReactiveX/rxjs.git#dfa239d41b97504312fa95e13f4d593d95b49c4b
    #   github:ReactiveX/rxjs#78032157f5c1655436829017bbda787565b48c30
    #   https://github.com/jsplumb/jsplumb/archive/2.10.2.tar.gz
    dep_identifier = dep_info["version"]

    dep = JSDependency(name=dep_name, source=dep_identifier, integrity=dep_info.get("integrity"))
    dep_in_nexus = process_non_registry_dependency(dep)

    converted_dep_info = copy.deepcopy(dep_info)
    # The "from" value is the original value from package.json for some locations
    converted_dep_info.pop("from", None)
    converted_dep_info.update(
        {
            "integrity": dep_in_nexus.integrity,
            "resolved": dep_in_nexus.source,
            "version": dep_in_nexus.version,
        }
    )
    return converted_dep_info
Exemplo n.º 4
0
def _convert_to_nexus_hosted(dep_name, dep_source, dep_info):
    """
    Convert the input dependency not from the NPM registry to a Nexus hosted dependency.

    :param str dep_name: the name of the dependency
    :param str dep_source: the source (url or relative path) of the dependency
    :param dict dep_info: the dependency info from the yarn lock file
    :return: a dict with the "version" and "integrity" keys to replace in the lock file
    :raise CachitoError: if the dependency is from an unsupported location or has an unexpected
        format in the lock file
    """
    integrity = dep_info.get("integrity")
    if integrity:
        integrity = _pick_strongest_crypto_hash(integrity)
    else:
        # For http(s) non-registry dependencies, yarn does not seem to include the "integrity" key
        # by default. It does, however, include a sha1 hash in the resolved url fragment.
        url = urlparse(dep_source)
        if url.fragment and url.scheme in ("http", "https"):
            integrity = convert_hex_sha_to_npm(url.fragment, "sha1")

    dep = JSDependency(name=dep_name, source=dep_source, integrity=integrity)
    dep_in_nexus = process_non_registry_dependency(dep)

    return {
        "integrity": dep_in_nexus.integrity,
        # "resolved": this value must be filled in later, after Cachito downloads the dependencies
        "version": dep_in_nexus.version,
    }
Exemplo n.º 5
0
def _convert_to_nexus_hosted(dep_name, dep_source, dep_info):
    """
    Convert the input dependency not from the NPM registry to a Nexus hosted dependency.

    :param str dep_name: the name of the dependency
    :param str dep_source: the source (url or relative path) of the dependency
    :param dict dep_info: the dependency info from the yarn lock file
    :return: the dependency information of the Nexus hosted version to use in the yarn lock file
        instead of the original
    :raise CachitoError: if the dependency is from an unsupported location or has an unexpected
        format in the lock file
    """
    integrity = dep_info.get("integrity")
    if integrity:
        integrity = _pick_strongest_crypto_hash(integrity)
    else:
        # For http(s) non-registry dependencies, yarn does not seem to include the "integrity" key
        # by default. It does, however, include a sha1 hash in the resolved url fragment.
        url = urlparse(dep_source)
        if url.fragment and url.scheme in ("http", "https"):
            integrity = convert_hex_sha_to_npm(url.fragment, "sha1")

    dep = JSDependency(name=dep_name, source=dep_source, integrity=integrity)
    dep_in_nexus = process_non_registry_dependency(dep)

    converted_dep_info = copy.deepcopy(dep_info)
    converted_dep_info.update({
        "integrity": dep_in_nexus.integrity,
        "resolved": dep_in_nexus.source,
        "version": dep_in_nexus.version,
    })
    return converted_dep_info
Exemplo n.º 6
0
def test_process_non_registry_dependency_github_not_in_nexus(
        mock_unrd, mock_gncifn):
    mock_gncifn.return_value = None

    dep_identifier = "github:ReactiveX/rxjs#8cc6491771fcbf44984a419b7f26ff442a5d58f5"
    dep_name = "rxjs"
    dep_info = {
        "version": dep_identifier,
        "from":
        "github:ReactiveX/rxjs#8cc6491771fcbf44984a419b7f26ff442a5d58f5",
        "requires": {
            "tslib": "^1.9.0"
        },
    }
    dep = general_js.JSDependency(dep_name, source=dep_info["version"])

    expected = (
        f"The dependency {dep_name}@{dep_identifier} was uploaded to Nexus but is not accessible"
    )
    with pytest.raises(CachitoError, match=expected):
        general_js.process_non_registry_dependency(dep)
Exemplo n.º 7
0
def test_process_non_registry_dependency_http(mock_unrd, mock_gncifn, exists):
    checksum = (
        "325f07861e0ab888d90606b1074fde956fd3954dcc4c6e418dbff9d8aa8342b5507481408832bfaac8e48f344"
        "dc650c8df0f8182c0271ed9fa233aa32c329839")
    nexus_component_info = {
        "assets": [{
            "checksum": {
                "sha512": checksum
            },
            "downloadUrl":
            ("https://nexus.domain.local/repository/cachito-js-hosted/rxjs/-/"
             "rxjs-6.5.5-external-sha512-325f07861e0ab888d90606b1074fde956fd3954dcc4c6e418d"
             "bff9d8aa8342b5507481408832bfaac8e48f344.tgz"),
        }],
        "version":
        ("6.5.5-external-sha512-325f07861e0ab888d90606b1074fde956fd3954dcc4c6e418dbff9d8aa8342"
         "b5507481408832bfaac8e48f344"),
    }
    if exists:
        mock_gncifn.return_value = nexus_component_info
    else:
        mock_gncifn.side_effect = [None, nexus_component_info]

    dep_name = "rxjs"
    dep_info = {
        "version":
        "https://github.com/ReactiveX/rxjs/archive/6.5.5.tar.gz",
        "requires": {
            "tslib": "^1.9.0"
        },
        "integrity":
        ("sha512-Ml8Hhh4KuIjZBgaxB0/elW/TlU3MTG5Bjb/52KqDQrVQdIFAiDK/qsjkjzRNxlDI3w+BgsAnHtn6I"
         "zqjLDKYOQ=="),
    }

    dep = general_js.JSDependency(name=dep_name,
                                  source=dep_info["version"],
                                  integrity=dep_info["integrity"])
    new_dep = general_js.process_non_registry_dependency(dep)

    assert new_dep == general_js.JSDependency(
        name=dep.name,
        source=
        ("https://nexus.domain.local/repository/cachito-js-hosted/rxjs/-/rxjs-6.5.5-"
         "external-sha512-325f07861e0ab888d90606b1074fde956fd3954dcc4c6e418dbff9d8aa8342b55074"
         "81408832bfaac8e48f344.tgz"),
        version=
        ("6.5.5-external-sha512-325f07861e0ab888d90606b1074fde956fd3954dcc4c6e418dbff9d8"
         "aa8342b5507481408832bfaac8e48f344"),
        integrity=
        ("sha512-Ml8Hhh4KuIjZBgaxB0/elW/TlU3MTG5Bjb/52KqDQrVQdIFAiDK/qsjkjzRNxlDI3w+BgsAnHtn6I"
         "zqjLDKYOQ=="),
    )

    suffix = (
        "-external-sha512-325f07861e0ab888d90606b1074fde956fd3954dcc4c6e418dbff9d8aa8342b5"
        "507481408832bfaac8e48f344dc650c8df0f8182c0271ed9fa233aa32c329839")

    suffix_search = f"*{suffix}"
    if exists:
        mock_gncifn.assert_called_once_with("rxjs", suffix_search)
        # Verify no upload occurs when the component already exists in Nexus
        mock_unrd.assert_not_called()
    else:
        assert mock_gncifn.call_count == 2
        mock_gncifn.assert_has_calls([
            mock.call("rxjs", suffix_search),
            mock.call("rxjs", suffix_search, max_attempts=5)
        ])
        mock_unrd.assert_called_once_with(
            "https://github.com/ReactiveX/rxjs/archive/6.5.5.tar.gz",
            suffix,
            False,
            general.ChecksumInfo(
                "sha512",
                "325f07861e0ab888d90606b1074fde956fd3954dcc4c6e418dbff9d8aa8342b5507481408832bf"
                "aac8e48f344dc650c8df0f8182c0271ed9fa233aa32c329839",
            ),
        )
Exemplo n.º 8
0
def test_process_non_registry_dependency_github(mock_unrd, mock_gncifn,
                                                exists):
    checksum = (
        "325f07861e0ab888d90606b1074fde956fd3954dcc4c6e418dbff9d8aa8342b5507481408832bfaac8e48f344"
        "dc650c8df0f8182c0271ed9fa233aa32c329839")
    # The information returned from Nexus of the uploaded component
    nexus_component_info = {
        "assets": [{
            "checksum": {
                "sha512": checksum
            },
            "downloadUrl":
            ("https://nexus.domain.local/repository/cachito-js-hosted/rxjs/-/"
             "rxjs-6.5.5-external-gitcommit-dfa239d41b97504312fa95e13f4d593d95b49c4b.tgz"
             ),
        }],
        "version":
        "6.5.5-external-gitcommit-8cc6491771fcbf44984a419b7f26ff442a5d58f5",
    }
    if exists:
        mock_gncifn.return_value = nexus_component_info
    else:
        mock_gncifn.side_effect = [None, nexus_component_info]

    dep_name = "rxjs"
    # The information from the lock file
    dep_info = {
        "version":
        "github:ReactiveX/rxjs#8cc6491771fcbf44984a419b7f26ff442a5d58f5",
        "from":
        "github:ReactiveX/rxjs#8cc6491771fcbf44984a419b7f26ff442a5d58f5",
        "requires": {
            "tslib": "^1.9.0"
        },
    }

    dep = general_js.JSDependency(name=dep_name, source=dep_info["version"])
    new_dep = general_js.process_non_registry_dependency(dep)

    # Verify the information to update the lock file with is correct
    assert new_dep == general_js.JSDependency(
        name=dep.name,
        source=
        ("https://nexus.domain.local/repository/cachito-js-hosted/rxjs/-/rxjs-6.5.5-"
         "external-gitcommit-dfa239d41b97504312fa95e13f4d593d95b49c4b.tgz"),
        version=
        "6.5.5-external-gitcommit-8cc6491771fcbf44984a419b7f26ff442a5d58f5",
        integrity=
        ("sha512-Ml8Hhh4KuIjZBgaxB0/elW/TlU3MTG5Bjb/52KqDQrVQdIFAiDK/qsjkjzRNxlDI3w+BgsAnHtn6I"
         "zqjLDKYOQ=="),
    )
    if exists:
        mock_gncifn.assert_called_once_with(
            "rxjs",
            "*-external-gitcommit-8cc6491771fcbf44984a419b7f26ff442a5d58f5")
        # Verify no upload occurs when the component already exists in Nexus
        mock_unrd.assert_not_called()
    else:
        assert mock_gncifn.call_count == 2
        mock_gncifn.assert_has_calls([
            mock.call(
                "rxjs",
                "*-external-gitcommit-8cc6491771fcbf44984a419b7f26ff442a5d58f5"
            ),
            mock.call(
                "rxjs",
                "*-external-gitcommit-8cc6491771fcbf44984a419b7f26ff442a5d58f5",
                max_attempts=5,
            ),
        ])
        mock_unrd.assert_called_once_with(
            "github:ReactiveX/rxjs#8cc6491771fcbf44984a419b7f26ff442a5d58f5",
            "-external-gitcommit-8cc6491771fcbf44984a419b7f26ff442a5d58f5",
            True,
            None,
        )