Skip to content

Commit

Permalink
Add workspace publishing
Browse files Browse the repository at this point in the history
Co-authored-by: Tor Hovland <55164+torhovland@users.noreply.github.com>
  • Loading branch information
jneem and torhovland committed Aug 30, 2024
1 parent 1f4e6be commit 28420d8
Show file tree
Hide file tree
Showing 6 changed files with 524 additions and 179 deletions.
69 changes: 34 additions & 35 deletions src/cargo/ops/cargo_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,30 +93,6 @@ struct GitVcsInfo {
dirty: bool,
}

/// Packages a single package in a workspace, returning the resulting tar file.
///
/// # Panics
/// Panics if `opts.list` is true. In that case you probably don't want to
/// actually build the package tarball; you should just make and print the list
/// of files. (We don't currently provide a public API for that, but see how
/// [`package`] does it.)
pub fn package_one(
ws: &Workspace<'_>,
pkg: &Package,
opts: &PackageOpts<'_>,
) -> CargoResult<FileLock> {
assert!(!opts.list);

let ar_files = prepare_archive(ws, pkg, opts)?;
let tarball = create_package(ws, pkg, ar_files, None)?;

if opts.verify {
run_verify(ws, pkg, &tarball, None, opts)?;
}

Ok(tarball)
}

// Builds a tarball and places it in the output directory.
fn create_package(
ws: &Workspace<'_>,
Expand Down Expand Up @@ -179,6 +155,29 @@ fn create_package(
/// Returns the generated package files. If `opts.list` is true, skips
/// generating package files and returns an empty list.
pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Vec<FileLock>> {
Ok(do_package(ws, opts)?.into_iter().map(|x| x.2).collect())
}

/// Packages an entire workspace.
///
/// Returns the generated package files and the dependencies between them. If
/// `opts.list` is true, skips generating package files and returns an empty
/// list.
pub(crate) fn package_with_dep_graph(
ws: &Workspace<'_>,
opts: &PackageOpts<'_>,
) -> CargoResult<LocalDependencies<(CliFeatures, FileLock)>> {
let output = do_package(ws, opts)?;

Ok(local_deps(output.into_iter().map(
|(pkg, opts, tarball)| (pkg, (opts.cli_features, tarball)),
)))
}

fn do_package<'a>(
ws: &Workspace<'_>,
opts: &PackageOpts<'a>,
) -> CargoResult<Vec<(Package, PackageOpts<'a>, FileLock)>> {
let specs = &opts.to_package.to_package_id_specs(ws)?;
// If -p is used, we should check spec is matched with the members (See #13719)
if let ops::Packages::Packages(_) = opts.to_package {
Expand Down Expand Up @@ -264,7 +263,7 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Vec<Fi
}
}

Ok(outputs.into_iter().map(|x| x.2).collect())
Ok(outputs)
}

/// Determine which registry the packages are for.
Expand Down Expand Up @@ -308,15 +307,14 @@ fn get_registry(
}

/// Just the part of the dependency graph that's between the packages we're packaging.
/// (Is the package name a good key? Does it uniquely identify packages?)
#[derive(Clone, Debug, Default)]
struct LocalDependencies {
packages: HashMap<PackageId, (Package, CliFeatures)>,
graph: Graph<PackageId, ()>,
pub(crate) struct LocalDependencies<T> {
pub packages: HashMap<PackageId, (Package, T)>,
pub graph: Graph<PackageId, ()>,
}

impl LocalDependencies {
fn sort(&self) -> Vec<(Package, CliFeatures)> {
impl<T: Clone> LocalDependencies<T> {
pub fn sort(&self) -> Vec<(Package, T)> {
self.graph
.sort()
.into_iter()
Expand All @@ -335,9 +333,10 @@ impl LocalDependencies {
/// ignoring dev dependencies.
///
/// We assume that the packages all belong to this workspace.
fn local_deps(packages: impl Iterator<Item = (Package, CliFeatures)>) -> LocalDependencies {
let packages: HashMap<PackageId, (Package, CliFeatures)> =
packages.map(|pkg| (pkg.0.package_id(), pkg)).collect();
fn local_deps<T>(packages: impl Iterator<Item = (Package, T)>) -> LocalDependencies<T> {
let packages: HashMap<PackageId, (Package, T)> = packages
.map(|(pkg, payload)| (pkg.package_id(), (pkg, payload)))
.collect();

// Dependencies have source ids but not package ids. We draw an edge
// whenever a dependency's source id matches one of our packages. This is
Expand All @@ -349,7 +348,7 @@ fn local_deps(packages: impl Iterator<Item = (Package, CliFeatures)>) -> LocalDe
.collect();

let mut graph = Graph::new();
for (pkg, _features) in packages.values() {
for (pkg, _payload) in packages.values() {
graph.add(pkg.package_id());
for dep in pkg.dependencies() {
// Ignore local dev-dependencies because they aren't needed for intra-workspace
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub use self::cargo_fetch::{fetch, FetchOptions};
pub use self::cargo_install::{install, install_list};
pub use self::cargo_new::{init, new, NewOptions, NewProjectKind, VersionControl};
pub use self::cargo_output_metadata::{output_metadata, ExportInfo, OutputMetadataOptions};
pub use self::cargo_package::{check_yanked, package, package_one, PackageOpts};
pub use self::cargo_package::{check_yanked, package, PackageOpts};
pub use self::cargo_pkgid::pkgid;
pub use self::cargo_read_manifest::read_package;
pub use self::cargo_run::run;
Expand Down
Loading

0 comments on commit 28420d8

Please sign in to comment.