diff --git a/lockfile/src/parsers/pypi.rs b/lockfile/src/parsers/pypi.rs index 9fb2593fa..8eb996a05 100644 --- a/lockfile/src/parsers/pypi.rs +++ b/lockfile/src/parsers/pypi.rs @@ -11,14 +11,15 @@ use nom::Err as NomErr; use phylum_types::types::package::PackageType; use crate::parsers::{self, IResult}; -use crate::{Package, PackageVersion}; +use crate::{Package, PackageVersion, ThirdPartyVersion}; pub fn parse(mut input: &str) -> IResult<&str, Vec> { let mut pkgs = Vec::new(); + let mut registry = None; while !input.is_empty() { // Get the next line. - let (new_input, line) = line(input)?; + let (new_input, line) = line(input, &mut registry)?; input = new_input; // Ignore empty lines. @@ -30,7 +31,7 @@ pub fn parse(mut input: &str) -> IResult<&str, Vec> { let (_, line) = alt((take_until(" #"), rest))(line)?; // Parse dependency. - let (_, pkg) = package(line)?; + let (_, pkg) = package(line, registry)?; pkgs.push(pkg); } @@ -38,7 +39,7 @@ pub fn parse(mut input: &str) -> IResult<&str, Vec> { } /// Parse one line in the lockfile. -fn line(input: &str) -> IResult<&str, &str> { +fn line<'a>(input: &'a str, registry: &mut Option<&'a str>) -> IResult<&'a str, &'a str> { // Take everything until the next newline. // // This takes line continuation characters into account. @@ -53,14 +54,21 @@ fn line(input: &str) -> IResult<&str, &str> { } // Ignore index config options. - if line.starts_with("--index-url") || line.starts_with("--extra-index-url") { + // + // Since `ThirdPartyVersion` only allows a single registry, we only record the + // primary one. + if let Some(index_url) = line.strip_prefix("--index-url") { + *registry = Some(index_url.trim()); + line = ""; + } + if line.starts_with("--extra-index-url") { line = ""; } Ok((input, line)) } -fn package(input: &str) -> IResult<&str, Package> { +fn package<'a>(input: &'a str, registry: Option<&str>) -> IResult<&'a str, Package> { // Ignore everything after `;`. let (_, input) = alt((take_until(";"), rest))(input)?; @@ -90,7 +98,13 @@ fn package(input: &str) -> IResult<&str, Package> { // Parse first-party dependencies. let (input, version) = package_version(input)?; - let version = PackageVersion::FirstParty(version.trim().into()); + let version = match registry { + Some(registry) => PackageVersion::ThirdParty(ThirdPartyVersion { + version: version.trim().into(), + registry: registry.into(), + }), + None => PackageVersion::FirstParty(version.trim().into()), + }; // Ensure line is empty after the dependency. line_done(input)?; diff --git a/lockfile/src/python.rs b/lockfile/src/python.rs index 7cee3eda4..f383c3b87 100644 --- a/lockfile/src/python.rs +++ b/lockfile/src/python.rs @@ -238,7 +238,7 @@ mod tests { let pkgs = PyRequirements .parse(include_str!("../../tests/fixtures/requirements-locked.txt")) .unwrap(); - assert_eq!(pkgs.len(), 12); + assert_eq!(pkgs.len(), 13); let expected_pkgs = [ Package { @@ -301,6 +301,14 @@ mod tests { version: PackageVersion::Path(Some("/tmp/editable".into())), package_type: PackageType::PyPi, }, + Package { + name: "other-registry".into(), + version: PackageVersion::ThirdParty(ThirdPartyVersion { + registry: "https://mirror1.phylum.io/simple/".into(), + version: "1.2.3".into(), + }), + package_type: PackageType::PyPi, + }, ]; for expected_pkg in expected_pkgs { diff --git a/tests/fixtures/requirements-locked.txt b/tests/fixtures/requirements-locked.txt index d6c2e94e9..c59235206 100644 --- a/tests/fixtures/requirements-locked.txt +++ b/tests/fixtures/requirements-locked.txt @@ -18,9 +18,6 @@ attrs==20.2.0 # This is an inline comment requests[security,tests]==2.28.1 ---index-url https://mirror1.phylum.io/simple/ ---extra-index-url https://mirror2.phylum.io/simple/ - werkzeug==2.9.2 ; python_version >= "3.7" and python_version < "3.12" attr @ file:///tmp/attr @@ -35,3 +32,7 @@ tomli @ https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a25 -e git+ssh://git@github.com/phylum-dev/phylum-ci.git@7d6d859ad368d1ab0a933f24679e3d3c08a40eac#egg=phylum -e /tmp/editable ; python_version >= "3.7" and python_version < "3.12" + +--index-url https://mirror1.phylum.io/simple/ +--extra-index-url https://mirror2.phylum.io/simple/ +other-registry==1.2.3