Skip to content

Commit 5412b10

Browse files
jneemtorhovlandepage
committed
Multi-package publishing
Co-authored-by: Tor Hovland <[email protected]> Co-authored-by: Ed Page <[email protected]>
1 parent 384e256 commit 5412b10

File tree

6 files changed

+485
-124
lines changed

6 files changed

+485
-124
lines changed

src/cargo/ops/cargo_package.rs

+39-35
Original file line numberDiff line numberDiff line change
@@ -93,30 +93,6 @@ struct GitVcsInfo {
9393
dirty: bool,
9494
}
9595

96-
/// Packages a single package in a workspace, returning the resulting tar file.
97-
///
98-
/// # Panics
99-
/// Panics if `opts.list` is true. In that case you probably don't want to
100-
/// actually build the package tarball; you should just make and print the list
101-
/// of files. (We don't currently provide a public API for that, but see how
102-
/// [`package`] does it.)
103-
pub fn package_one(
104-
ws: &Workspace<'_>,
105-
pkg: &Package,
106-
opts: &PackageOpts<'_>,
107-
) -> CargoResult<FileLock> {
108-
assert!(!opts.list);
109-
110-
let ar_files = prepare_archive(ws, pkg, opts)?;
111-
let tarball = create_package(ws, pkg, ar_files, None)?;
112-
113-
if opts.verify {
114-
run_verify(ws, pkg, &tarball, None, opts)?;
115-
}
116-
117-
Ok(tarball)
118-
}
119-
12096
// Builds a tarball and places it in the output directory.
12197
fn create_package(
12298
ws: &Workspace<'_>,
@@ -193,6 +169,34 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Vec<Fi
193169
// So we need filter
194170
pkgs.retain(|(pkg, _feats)| specs.iter().any(|spec| spec.matches(pkg.package_id())));
195171

172+
Ok(do_package(ws, opts, pkgs)?
173+
.into_iter()
174+
.map(|x| x.2)
175+
.collect())
176+
}
177+
178+
/// Packages an entire workspace.
179+
///
180+
/// Returns the generated package files and the dependencies between them. If
181+
/// `opts.list` is true, skips generating package files and returns an empty
182+
/// list.
183+
pub(crate) fn package_with_dep_graph(
184+
ws: &Workspace<'_>,
185+
opts: &PackageOpts<'_>,
186+
pkgs: Vec<(&Package, CliFeatures)>,
187+
) -> CargoResult<LocalDependencies<(CliFeatures, FileLock)>> {
188+
let output = do_package(ws, opts, pkgs)?;
189+
190+
Ok(local_deps(output.into_iter().map(
191+
|(pkg, opts, tarball)| (pkg, (opts.cli_features, tarball)),
192+
)))
193+
}
194+
195+
fn do_package<'a>(
196+
ws: &Workspace<'_>,
197+
opts: &PackageOpts<'a>,
198+
pkgs: Vec<(&Package, CliFeatures)>,
199+
) -> CargoResult<Vec<(Package, PackageOpts<'a>, FileLock)>> {
196200
if ws
197201
.lock_root()
198202
.as_path_unlocked()
@@ -264,7 +268,7 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Vec<Fi
264268
}
265269
}
266270

267-
Ok(outputs.into_iter().map(|x| x.2).collect())
271+
Ok(outputs)
268272
}
269273

270274
/// Determine which registry the packages are for.
@@ -308,15 +312,14 @@ fn get_registry(
308312
}
309313

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

318-
impl LocalDependencies {
319-
fn sort(&self) -> Vec<(Package, CliFeatures)> {
321+
impl<T: Clone> LocalDependencies<T> {
322+
pub fn sort(&self) -> Vec<(Package, T)> {
320323
self.graph
321324
.sort()
322325
.into_iter()
@@ -335,9 +338,10 @@ impl LocalDependencies {
335338
/// ignoring dev dependencies.
336339
///
337340
/// We assume that the packages all belong to this workspace.
338-
fn local_deps(packages: impl Iterator<Item = (Package, CliFeatures)>) -> LocalDependencies {
339-
let packages: HashMap<PackageId, (Package, CliFeatures)> =
340-
packages.map(|pkg| (pkg.0.package_id(), pkg)).collect();
341+
fn local_deps<T>(packages: impl Iterator<Item = (Package, T)>) -> LocalDependencies<T> {
342+
let packages: HashMap<PackageId, (Package, T)> = packages
343+
.map(|(pkg, payload)| (pkg.package_id(), (pkg, payload)))
344+
.collect();
341345

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

351355
let mut graph = Graph::new();
352-
for (pkg, _features) in packages.values() {
356+
for (pkg, _payload) in packages.values() {
353357
graph.add(pkg.package_id());
354358
for dep in pkg.dependencies() {
355359
// Ignore local dev-dependencies because they aren't needed for intra-workspace

src/cargo/ops/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub use self::cargo_fetch::{fetch, FetchOptions};
1010
pub use self::cargo_install::{install, install_list};
1111
pub use self::cargo_new::{init, new, NewOptions, NewProjectKind, VersionControl};
1212
pub use self::cargo_output_metadata::{output_metadata, ExportInfo, OutputMetadataOptions};
13-
pub use self::cargo_package::{check_yanked, package, package_one, PackageOpts};
13+
pub use self::cargo_package::{check_yanked, package, PackageOpts};
1414
pub use self::cargo_pkgid::pkgid;
1515
pub use self::cargo_read_manifest::read_package;
1616
pub use self::cargo_run::run;

0 commit comments

Comments
 (0)