Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ISSUE-16 - Construct cargo_geiger PackageId from a cargo_metadata #146

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cargo-geiger-serde/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ name = "cargo-geiger-serde"
version = "0.1.0"

[dependencies]
semver = "0.10.0"
semver = "0.11.0"
serde = { version = "1.0.116", features = ["derive"] }
url = { version = "2.1.1", features = ["serde"] }
2 changes: 1 addition & 1 deletion cargo-geiger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ insta = "0.16.1"
rand = "0.7.3"
regex = "1.3.9"
rstest = "0.6.4"
semver = "0.10.0"
semver = "0.11.0"
tempfile = "3.1.0"
28 changes: 9 additions & 19 deletions cargo-geiger/src/mapping.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
mod core;
mod geiger;
mod krates;
mod metadata;

use ::krates::Krates;
use cargo::core::dependency::DepKind;
use cargo::core::{Package, PackageId, PackageSet};
use cargo_metadata::{DependencyKind, Metadata};
use std::collections::HashSet;
use std::path::PathBuf;
Expand Down Expand Up @@ -75,11 +75,17 @@ pub trait ToCargoCoreDepKind {
pub trait ToCargoGeigerPackageId {
fn to_cargo_geiger_package_id(
&self,
krates: &Krates,
package_set: &PackageSet,
metadata: &Metadata,
) -> cargo_geiger_serde::PackageId;
}

pub trait ToCargoGeigerSource {
fn to_cargo_geiger_source(
&self,
metadata: &Metadata,
) -> cargo_geiger_serde::Source;
}

pub trait ToCargoMetadataDependencyKind {
fn to_cargo_metadata_dependency_kind(&self) -> DependencyKind;
}
Expand All @@ -97,19 +103,3 @@ pub trait ToCargoMetadataPackageId {
metadata: &Metadata,
) -> Option<cargo_metadata::PackageId>;
}

pub trait ToPackage {
fn to_package(
&self,
krates: &Krates,
package_set: &PackageSet,
) -> Option<Package>;
}

pub trait ToPackageId {
fn to_package_id(
&self,
krates: &Krates,
package_set: &PackageSet,
) -> Option<PackageId>;
}
133 changes: 133 additions & 0 deletions cargo-geiger/src/mapping/geiger.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use super::ToCargoGeigerSource;

use crate::mapping::ToCargoMetadataPackage;

use cargo_metadata::Metadata;
use url::Url;

impl ToCargoGeigerSource for cargo_metadata::PackageId {
fn to_cargo_geiger_source(
&self,
metadata: &Metadata,
) -> cargo_geiger_serde::Source {
let package = self.to_cargo_metadata_package(metadata).unwrap();

match package.source {
Some(source) => handle_source_repr(&source.repr),
None => handle_path_source(self),
}
}
}

fn handle_source_repr(source_repr: &str) -> cargo_geiger_serde::Source {
let mut source_repr_vec = source_repr.split('+').collect::<Vec<&str>>();

let source_type = source_repr_vec[0];

match source_type {
"registry" => {
cargo_geiger_serde::Source::Registry {
// It looks like cargo metadata drops this information
name: String::from("crates.io"),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure on this, it looks like it gets dropped by cargo_metadata, I'm not sure if we want to parse this from somewhere else (or even where we would parse it from)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the comment is good enough for now.

url: Url::parse(source_repr_vec.pop().unwrap()).unwrap(),
}
}
"git" => {
let raw_git_representation = source_repr_vec.pop().unwrap();
let raw_git_url = Url::parse(raw_git_representation).unwrap();
let git_url_without_query = format!(
"{}://{}{}",
raw_git_url.scheme(),
raw_git_url.host_str().unwrap(),
raw_git_url.path()
);
let revision = raw_git_url
.query_pairs()
.find(|(query_key, _)| query_key == "rev")
.unwrap()
.1;

cargo_geiger_serde::Source::Git {
url: Url::parse(&git_url_without_query).unwrap(),
rev: String::from(revision),
}
}
_ => {
panic!("Unrecognised source type: {}", source_type)
}
}
}

fn handle_path_source(
package_id: &cargo_metadata::PackageId,
) -> cargo_geiger_serde::Source {
let raw_repr = package_id.repr.clone();
let raw_path_repr = raw_repr[1..raw_repr.len() - 1]
.split("+file://")
.skip(1)
.collect::<Vec<&str>>()
.pop()
.unwrap();

let source_url: Url;
if cfg!(windows) {
source_url = Url::from_file_path(&raw_path_repr[1..]).unwrap();
} else {
source_url = Url::from_file_path(raw_path_repr).unwrap();
}

cargo_geiger_serde::Source::Path(source_url)
}

#[cfg(test)]
mod geiger_tests {
use super::*;

use rstest::*;
use url::Url;

#[rstest(
input_source_repr,
expected_source,
case(
"registry+https://github.com/rust-lang/crates.io-index",
cargo_geiger_serde::Source::Registry {
name: String::from("crates.io"),
url: Url::parse("https://github.com/rust-lang/crates.io-index").unwrap()
}
),
case(
"git+https://github.com/rust-itertools/itertools.git?rev=8761fbefb3b209",
cargo_geiger_serde::Source::Git {
url: Url::parse("https://github.com/rust-itertools/itertools.git").unwrap(),
rev: String::from("8761fbefb3b209")
}
)
)]
fn handle_source_repr_test(
input_source_repr: &str,
expected_source: cargo_geiger_serde::Source,
) {
let source = handle_source_repr(input_source_repr);
assert_eq!(source, expected_source);
}

#[rstest]
fn handle_path_source_test() {
if !cfg!(windows) {
let package_id = cargo_metadata::PackageId {
repr: String::from("(path+file:///cargo_geiger/test_crates/test1_package_with_no_deps)"),
};

let expected_source = cargo_geiger_serde::Source::Path(
Url::from_file_path(
"/cargo_geiger/test_crates/test1_package_with_no_deps",
)
.unwrap(),
);

let source = handle_path_source(&package_id);
assert_eq!(source, expected_source);
}
}
}
Loading