Skip to content
Open
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
39 changes: 23 additions & 16 deletions crate_universe/src/cli/splice.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! The cli entrypoint for the `splice` subcommand

use std::fs::File;
use std::path::PathBuf;
use std::process::Stdio;

use anyhow::Context;
use camino::Utf8PathBuf;
Expand All @@ -9,9 +11,7 @@ use itertools::Itertools;

use crate::cli::Result;
use crate::config::Config;
use crate::metadata::{
write_metadata, Cargo, CargoUpdateRequest, Generator, MetadataGenerator, TreeResolver,
};
use crate::metadata::{Cargo, CargoUpdateRequest, TreeResolver};
use crate::splicing::{
generate_lockfile, Splicer, SplicerKind, SplicingManifest, WorkspaceMetadata,
};
Expand Down Expand Up @@ -111,6 +111,7 @@ pub fn splice(opt: SpliceOptions) -> Result<()> {
&config.supported_platform_triples,
)
.context("Failed to generate features")?;

// Write the registry url info to the manifest now that a lockfile has been generated
WorkspaceMetadata::write_registry_urls_and_feature_map(
&cargo,
Expand All @@ -121,13 +122,26 @@ pub fn splice(opt: SpliceOptions) -> Result<()> {
)
.context("Failed to write registry URLs and feature map")?;

let output_dir = opt.output_dir.clone();
// Generate the consumable outputs of the splicing process
std::fs::create_dir_all(&opt.output_dir).with_context(|| {
format!(
"Failed to create directories for {}",
opt.output_dir.display()
)
})?;

let metadata_json = File::create(opt.output_dir.join("metadata.json"))?;

// Write metadata to the workspace for future reuse
let (cargo_metadata, _) = Generator::new()
.with_cargo(cargo.clone())
.with_rustc(opt.rustc.clone())
.generate(manifest_path.as_path_buf())
cargo
.metadata_command_with_options(
manifest_path.as_path_buf().as_ref(),
vec!["--locked".to_owned()],
)?
.cargo_command()
.stdout(Stdio::from(metadata_json))
.stderr(Stdio::null())
.status()
.context("Failed to generate cargo metadata")?;

let cargo_lockfile_path = manifest_path
Expand All @@ -141,14 +155,7 @@ pub fn splice(opt: SpliceOptions) -> Result<()> {
})?
.join("Cargo.lock");

// Generate the consumable outputs of the splicing process
std::fs::create_dir_all(&output_dir)
.with_context(|| format!("Failed to create directories for {}", &output_dir.display()))?;

write_metadata(&opt.output_dir.join("metadata.json"), &cargo_metadata)
.context("Failed to write metadata")?;

std::fs::copy(cargo_lockfile_path, output_dir.join("Cargo.lock"))
std::fs::copy(cargo_lockfile_path, opt.output_dir.join("Cargo.lock"))
.context("Failed to copy lockfile")?;

if let SplicerKind::Workspace { path, .. } = prepared_splicer {
Expand Down
12 changes: 7 additions & 5 deletions crate_universe/src/cli/vendor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::context::Context;
use crate::lockfile::{lock_context, write_lockfile};
use crate::metadata::CargoUpdateRequest;
use crate::metadata::TreeResolver;
use crate::metadata::{Annotations, Cargo, Generator, MetadataGenerator, VendorGenerator};
use crate::metadata::{Annotations, Cargo, VendorGenerator};
use crate::rendering::{render_module_label, write_outputs, Renderer};
use crate::splicing::{generate_lockfile, Splicer, SplicingManifest, WorkspaceMetadata};
use crate::utils::normalize_cargo_file_paths;
Expand Down Expand Up @@ -246,10 +246,12 @@ pub fn vendor(opt: VendorOptions) -> anyhow::Result<()> {
)?;

// Write metadata to the workspace for future reuse
let (cargo_metadata, cargo_lockfile) = Generator::new()
.with_cargo(cargo.clone())
.with_rustc(opt.rustc.clone())
.generate(manifest_path.as_path_buf())?;
let cargo_metadata = cargo
.metadata_command_with_options(
manifest_path.as_path_buf().as_ref(),
vec!["--locked".to_owned()],
)?
.exec()?;

// Annotate metadata
let annotations = Annotations::new(
Expand Down
72 changes: 0 additions & 72 deletions crate_universe/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,83 +5,19 @@ mod cargo_tree_resolver;
mod dependency;
mod metadata_annotation;

use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::str::FromStr;

use anyhow::{bail, Context, Result};
use camino::Utf8Path;
use cargo_lock::Lockfile as CargoLockfile;
use cargo_metadata::Metadata as CargoMetadata;
use tracing::debug;

pub(crate) use self::cargo_bin::*;
pub(crate) use self::cargo_tree_resolver::*;
pub(crate) use self::dependency::*;
pub(crate) use self::metadata_annotation::*;

// TODO: This should also return a set of [crate-index::IndexConfig]s for packages in metadata.packages
/// A Trait for generating metadata (`cargo metadata` output and a lock file) from a Cargo manifest.
pub(crate) trait MetadataGenerator {
fn generate<T: AsRef<Path>>(&self, manifest_path: T) -> Result<(CargoMetadata, CargoLockfile)>;
}

/// Generates Cargo metadata and a lockfile from a provided manifest.
pub(crate) struct Generator {
/// The path to a `cargo` binary
cargo_bin: Cargo,

/// The path to a `rustc` binary
rustc_bin: PathBuf,
}

impl Generator {
pub(crate) fn new() -> Self {
let rustc_bin = PathBuf::from(env::var("RUSTC").unwrap_or_else(|_| "rustc".to_string()));
Generator {
cargo_bin: Cargo::new(
PathBuf::from(env::var("CARGO").unwrap_or_else(|_| "cargo".to_string())),
rustc_bin.clone(),
),
rustc_bin,
}
}

pub(crate) fn with_cargo(mut self, cargo_bin: Cargo) -> Self {
self.cargo_bin = cargo_bin;
self
}

pub(crate) fn with_rustc(mut self, rustc_bin: PathBuf) -> Self {
self.rustc_bin = rustc_bin;
self
}
}

impl MetadataGenerator for Generator {
fn generate<T: AsRef<Path>>(&self, manifest_path: T) -> Result<(CargoMetadata, CargoLockfile)> {
let manifest_dir = manifest_path
.as_ref()
.parent()
.expect("The manifest should have a parent directory");
let lockfile = {
let lock_path = manifest_dir.join("Cargo.lock");
if !lock_path.exists() {
bail!("No `Cargo.lock` file was found with the given manifest")
}
cargo_lock::Lockfile::load(lock_path)?
};

let metadata = self
.cargo_bin
.metadata_command_with_options(manifest_path.as_ref(), vec!["--locked".to_owned()])?
.exec()?;

Ok((metadata, lockfile))
}
}

/// A configuration describing how to invoke [cargo update](https://doc.rust-lang.org/cargo/commands/cargo-update.html).
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CargoUpdateRequest {
Expand Down Expand Up @@ -340,14 +276,6 @@ impl VendorGenerator {
}
}

/// A helper function for writing Cargo metadata to a file.
pub(crate) fn write_metadata(path: &Path, metadata: &cargo_metadata::Metadata) -> Result<()> {
let content =
serde_json::to_string_pretty(metadata).context("Failed to serialize Cargo Metadata")?;

fs::write(path, content).context("Failed to write metadata to disk")
}

/// A helper function for deserializing Cargo metadata and lockfiles
pub(crate) fn load_metadata(
metadata_path: &Path,
Expand Down