Switch from `cargo_metadata`+`petgraph` to `guppy`

finchie
Apr 18, 2024, 6:20 AM
ZPFD3275NTWST7F5YCWYOOUS3QB5HE23LUOZXZIND4HBFSX62NCQC

Dependencies

  • [2] O7TNUABZ Migrate `CrateMetadata::graph_data()` from `HashMap` to `petgraph` representation
  • [3] JVYWRCPT Add basic chart visualisation
  • [4] Q3Z6XMP5 Migrate dependency tree to `petgraph::Graph`
  • [5] 7CVIL7UJ Create simple metadata parser
  • [6] B2L26LOA Store index of dependency nodes

Change contents

  • edit in src/main.rs at line 1
    [3.49][3.0:32](),[3.32][3.0:48]()
    use std::collections::HashMap;
    use cargo_metadata::{Node, Package, PackageId};
  • replacement in src/main.rs at line 2
    [3.85][3.85:136](),[3.136][2.0:70](),[2.70][3.136:147](),[3.136][3.136:147]()
    use petgraph::{
    data::{Element, FromElements},
    visit::{EdgeRef, IntoEdgeReferences, IntoEdgesDirected, NodeRef},
    Graph,
    [3.85]
    [3.123]
    use guppy::{
    graph::{DependencyDirection, PackageGraph},
    MetadataCommand,
  • edit in src/main.rs at line 6
    [3.126][3.89:263](),[3.89][3.89:263](),[3.263][3.148:205](),[3.97][3.263:265](),[3.205][3.263:265](),[3.263][3.263:265]()
    #[derive(Clone, Debug)]
    struct CrateMetadata<'metadata> {
    data: &'metadata cargo_metadata::Metadata,
    packages: &'metadata Vec<Node>,
    root: &'metadata PackageId,
    dependency_tree: Graph<&'metadata PackageId, usize>,
    }
  • replacement in src/main.rs at line 7
    [3.266][3.266:588](),[3.588][3.206:429]()
    impl<'metadata> CrateMetadata<'metadata> {
    fn new(metadata: &'metadata cargo_metadata::Metadata) -> Self {
    let resolve = metadata
    .resolve
    .as_ref()
    .expect("Cargo did not resolve dependencies");
    let root = resolve.root.as_ref().expect("Must select a root crate");
    let edge_count = resolve.nodes.iter().map(|node| node.deps.len()).count();
    let mut dependency_tree = Graph::with_capacity(metadata.packages.len(), edge_count);
    let mut node_indexes = HashMap::new();
    [3.266]
    [3.429]
    fn graph_data(graph: &PackageGraph) -> charming::series::GraphData {
    let categories = vec![charming::series::GraphCategory {
    name: String::from("default"),
    }];
  • replacement in src/main.rs at line 12
    [3.430][3.430:601](),[3.601][3.601:602](),[3.602][3.602:737](),[3.737][3.737:738](),[3.738][3.738:952](),[3.952][3.394:405](),[3.394][3.394:405](),[3.405][3.588:687](),[3.588][3.588:687](),[3.687][3.953:982](),[3.982][3.127:144](),[3.430][3.127:144](),[3.144][3.983:1105](),[3.1105][3.225:306](),[3.225][3.225:306](),[3.306][2.71:302](),[2.302][3.530:761](),[3.530][3.530:761]()
    for node in &metadata.packages {
    let node_index = dependency_tree.add_node(&node.id);
    node_indexes.insert(&node.id, node_index);
    }
    for resolved_dependency in &resolve.nodes {
    let parent_index = node_indexes.get(&resolved_dependency.id).unwrap();
    for child in &resolved_dependency.deps {
    let child_index = node_indexes.get(&child.pkg).unwrap();
    dependency_tree.add_edge(*parent_index, *child_index, 1);
    }
    }
    Self {
    data: metadata,
    packages: &resolve.nodes,
    root,
    dependency_tree,
    }
    }
    fn graph_data(&self) -> charming::series::GraphData {
    let categories = vec![charming::series::GraphCategory {
    name: String::from("default"),
    }];
    let nodes = self
    .dependency_tree
    .node_weights()
    .enumerate()
    .map(|(coords, id)| charming::series::GraphNode {
    id: id.to_string(),
    name: self.data[*id].name.clone(),
    x: coords as f64,
    y: coords as f64,
    value: 1_f64,
    category: 0,
    symbol_size: 1_f64,
    label: None,
    })
    .collect();
    [3.430]
    [3.761]
    let nodes = graph
    .packages()
    .enumerate()
    .map(|(coords, package)| charming::series::GraphNode {
    id: package.id().repr().to_string(),
    name: package.name().to_string(),
    x: coords as f64,
    y: coords as f64,
    value: 1_f64,
    category: 0,
    symbol_size: 1_f64,
    label: None,
    })
    .collect();
  • replacement in src/main.rs at line 27
    [3.762][3.762:787](),[3.787][2.303:692](),[2.692][3.983:998](),[3.983][3.983:998](),[3.998][2.693:849](),[2.849][3.1147:1215](),[3.1147][3.1147:1215]()
    let links = self
    .dependency_tree
    .edge_indices()
    .map(|edge_idx| self.dependency_tree.edge_endpoints(edge_idx))
    .filter_map(|optional_endpoints| optional_endpoints)
    .map(|(source_idx, target_idx)| {
    (
    &self.dependency_tree[source_idx],
    &self.dependency_tree[target_idx],
    )
    })
    .map(|(source, target)| charming::series::GraphLink {
    source: source.repr.clone(),
    target: target.repr.clone(),
    value: None,
    })
    .collect();
    [3.762]
    [3.1215]
    let links = graph
    .query_forward(graph.package_ids())
    .unwrap()
    .resolve()
    .links(DependencyDirection::Forward)
    .map(|link| link.endpoints())
    .map(|(source, target)| charming::series::GraphLink {
    source: source.id().repr().to_string(),
    target: target.id().repr().to_string(),
    value: None,
    })
    .collect();
  • replacement in src/main.rs at line 40
    [3.1216][3.1236:1274](),[3.1274][3.1236:1298](),[3.1236][3.1236:1298](),[3.430][3.687:697](),[3.1298][3.687:697](),[3.687][3.687:697]()
    charming::series::GraphData {
    nodes,
    links,
    categories,
    }
    [3.1216]
    [3.697]
    charming::series::GraphData {
    nodes,
    links,
    categories,
  • replacement in src/main.rs at line 48
    [3.718][3.718:896]()
    let cmd = cargo_metadata::MetadataCommand::new();
    let metadata = cmd.exec().expect("Cargo did not resolve metadata");
    let root_crate = CrateMetadata::new(&metadata);
    [3.718]
    [3.896]
    let mut cmd = MetadataCommand::new();
    let package_graph = PackageGraph::from_command(&mut cmd).unwrap();
  • replacement in src/main.rs at line 56
    [3.1460][3.1373:1417]()
    .data(root_crate.graph_data()),
    [3.1460]
    [3.1499]
    .data(graph_data(&package_graph)),
  • edit in Cargo.toml at line 7
    [3.1040][3.1040:1066]()
    cargo_metadata = "0.18.1"
  • replacement in Cargo.toml at line 8
    [3.1656][3.1418:1437]()
    petgraph = "0.6.4"
    [3.1656]
    guppy = "0.17.5"
  • edit in Cargo.lock at line 6
    [3.1670]
    [3.1670]
    name = "ahash"
    version = "0.8.11"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
    dependencies = [
    "cfg-if",
    "getrandom",
    "once_cell",
    "version_check",
    "zerocopy",
    ]
    [[package]]
  • edit in Cargo.lock at line 60
    [3.1963]
    [3.1892]
    name = "cfg-expr"
    version = "0.15.8"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
    dependencies = [
    "smallvec",
    "target-lexicon",
    ]
    [[package]]
  • edit in Cargo.lock at line 104
    [3.2790]
    [3.2790]
    [[package]]
    name = "debug-ignore"
    version = "1.0.5"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "ffe7ed1d93f4553003e20b629abe9085e1e81b1429520f897f8f8860bc6dfc21"
  • edit in Cargo.lock at line 115
    [3.2014][3.2014:2033]()
    "cargo_metadata",
  • replacement in Cargo.lock at line 116
    [3.2817][3.1438:1451]()
    "petgraph",
    [3.2817]
    [3.2817]
    "guppy",
  • edit in Cargo.lock at line 128
    [3.3064]
    [3.1452]
    [[package]]
    name = "either"
    version = "1.11.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
  • edit in Cargo.lock at line 156
    [3.3311]
    [3.3311]
    [[package]]
    name = "getrandom"
    version = "0.2.14"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
    dependencies = [
    "cfg-if",
    "libc",
    "wasi",
    ]
    [[package]]
    name = "guppy"
    version = "0.17.5"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "34e99a7734579b834a076ef11789783c153c6eb5fb3520ed15bc41f483f0f317"
    dependencies = [
    "ahash",
    "camino",
    "cargo_metadata",
    "cfg-if",
    "debug-ignore",
    "fixedbitset",
    "guppy-workspace-hack",
    "indexmap",
    "itertools",
    "nested",
    "once_cell",
    "pathdiff",
    "petgraph",
    "semver",
    "serde",
    "serde_json",
    "smallvec",
    "static_assertions",
    "target-spec",
    ]
    [[package]]
    name = "guppy-workspace-hack"
    version = "0.1.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "92620684d99f750bae383ecb3be3748142d6095760afd5cbcf2261e9a279d780"
  • edit in Cargo.lock at line 232
    [3.2277]
    [3.2048]
    name = "itertools"
    version = "0.12.1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
    dependencies = [
    "either",
    ]
    [[package]]
  • edit in Cargo.lock at line 265
    [3.2237]
    [3.4164]
    name = "nested"
    version = "0.1.1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "ca2b420f638f07fe83056b55ea190bb815f609ec5a35e7017884a10f78839c9e"
    [[package]]
  • edit in Cargo.lock at line 277
    [3.4358]
    [3.4358]
    name = "pathdiff"
    version = "0.2.1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
    dependencies = [
    "camino",
    ]
    [[package]]
  • edit in Cargo.lock at line 414
    [3.3810]
    [3.3810]
    [[package]]
    name = "smallvec"
    version = "1.13.2"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
    [[package]]
    name = "static_assertions"
    version = "1.1.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
  • edit in Cargo.lock at line 439
    [3.4074]
    [3.4074]
    name = "target-lexicon"
    version = "0.12.14"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
    [[package]]
    name = "target-spec"
    version = "3.1.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "36a8e795b1824524d13cdf04f73cf8b4f244ce86c96b4d2a83a6ca1a753d2752"
    dependencies = [
    "cfg-expr",
    "guppy-workspace-hack",
    "target-lexicon",
    "unicode-ident",
    ]
    [[package]]
  • edit in Cargo.lock at line 499
    [3.6193]
    [[package]]
    name = "wasi"
    version = "0.11.0+wasi-snapshot-preview1"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
    [[package]]
    name = "zerocopy"
    version = "0.7.32"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
    dependencies = [
    "zerocopy-derive",
    ]
    [[package]]
    name = "zerocopy-derive"
    version = "0.7.32"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
    dependencies = [
    "proc-macro2",
    "quote",
    "syn",
    ]