Skip to content

Commit e18c2c5

Browse files
committed
Newtype CargoTomlPath
When reading code, it is not always clear, what path is Cargo.toml path, and what path is directory path.
1 parent 62d7317 commit e18c2c5

File tree

10 files changed

+199
-154
lines changed

10 files changed

+199
-154
lines changed

crate_universe/private/srcs.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ CARGO_BAZEL_SRCS = [
2323
Label("//crate_universe:src/main.rs"),
2424
Label("//crate_universe:src/metadata.rs"),
2525
Label("//crate_universe:src/metadata/cargo_bin.rs"),
26+
Label("//crate_universe:src/metadata/cargo_toml_path.rs"),
2627
Label("//crate_universe:src/metadata/cargo_tree_resolver.rs"),
2728
Label("//crate_universe:src/metadata/cargo_tree_rustc_wrapper.bat"),
2829
Label("//crate_universe:src/metadata/cargo_tree_rustc_wrapper.sh"),

crate_universe/src/cli/generate.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use clap::Parser;
1313
use crate::config::Config;
1414
use crate::context::Context;
1515
use crate::lockfile::{lock_context, write_lockfile};
16-
use crate::metadata::{load_metadata, Annotations, Cargo, SourceAnnotation};
16+
use crate::metadata::{load_metadata, Annotations, Cargo, CargoTomlPath, SourceAnnotation};
1717
use crate::rendering::{write_outputs, Renderer};
1818
use crate::splicing::SplicingManifest;
1919
use crate::utils::normalize_cargo_file_paths;
@@ -236,7 +236,7 @@ fn update_cargo_lockfile(path: &Path, cargo_lockfile: Lockfile) -> Result<()> {
236236
fn write_paths_to_track<
237237
'a,
238238
SourceAnnotations: Iterator<Item = &'a SourceAnnotation>,
239-
Paths: Iterator<Item = Utf8PathBuf>,
239+
Paths: Iterator<Item = CargoTomlPath>,
240240
UnusedPatches: Iterator<Item = &'a cargo_lock::Dependency>,
241241
>(
242242
output_file: &Path,
@@ -248,7 +248,7 @@ fn write_paths_to_track<
248248
let source_annotation_manifests: BTreeSet<_> = source_annotations
249249
.filter_map(|v| {
250250
if let SourceAnnotation::Path { path } = v {
251-
Some(path.join("Cargo.toml"))
251+
Some(CargoTomlPath::for_dir(path))
252252
} else {
253253
None
254254
}

crate_universe/src/cli/splice.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ pub fn splice(opt: SpliceOptions) -> Result<()> {
9999

100100
let resolver_data = TreeResolver::new(cargo.clone())
101101
.generate(
102-
manifest_path.as_path_buf(),
102+
manifest_path.cargo_toml_path(),
103103
&config.supported_platform_triples,
104104
)
105105
.context("Failed to generate features")?;
@@ -108,8 +108,8 @@ pub fn splice(opt: SpliceOptions) -> Result<()> {
108108
&cargo,
109109
&cargo_lockfile,
110110
resolver_data,
111-
manifest_path.as_path_buf(),
112-
manifest_path.as_path_buf(),
111+
manifest_path.cargo_toml_path(),
112+
manifest_path.cargo_toml_path(),
113113
)
114114
.context("Failed to write registry URLs and feature map")?;
115115

@@ -119,19 +119,10 @@ pub fn splice(opt: SpliceOptions) -> Result<()> {
119119
let (cargo_metadata, _) = Generator::new()
120120
.with_cargo(cargo)
121121
.with_rustc(opt.rustc)
122-
.generate(manifest_path.as_path_buf())
122+
.generate(manifest_path.cargo_toml_path())
123123
.context("Failed to generate cargo metadata")?;
124124

125-
let cargo_lockfile_path = manifest_path
126-
.as_path_buf()
127-
.parent()
128-
.with_context(|| {
129-
format!(
130-
"The path {} is expected to have a parent directory",
131-
manifest_path.as_path_buf()
132-
)
133-
})?
134-
.join("Cargo.lock");
125+
let cargo_lockfile_path = manifest_path.cargo_toml_path().parent().join("Cargo.lock");
135126

136127
// Generate the consumable outputs of the splicing process
137128
std::fs::create_dir_all(&output_dir)

crate_universe/src/cli/vendor.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ pub fn vendor(opt: VendorOptions) -> anyhow::Result<()> {
227227
let config = Config::try_from_path(&opt.config)?;
228228

229229
let resolver_data = TreeResolver::new(cargo.clone()).generate(
230-
manifest_path.as_path_buf(),
230+
manifest_path.cargo_toml_path(),
231231
&config.supported_platform_triples,
232232
)?;
233233

@@ -236,15 +236,15 @@ pub fn vendor(opt: VendorOptions) -> anyhow::Result<()> {
236236
&cargo,
237237
&cargo_lockfile,
238238
resolver_data,
239-
manifest_path.as_path_buf(),
240-
manifest_path.as_path_buf(),
239+
manifest_path.cargo_toml_path(),
240+
manifest_path.cargo_toml_path(),
241241
)?;
242242

243243
// Write metadata to the workspace for future reuse
244244
let (cargo_metadata, cargo_lockfile) = Generator::new()
245245
.with_cargo(cargo.clone())
246246
.with_rustc(opt.rustc.clone())
247-
.generate(manifest_path.as_path_buf())?;
247+
.generate(manifest_path.cargo_toml_path())?;
248248

249249
// Annotate metadata
250250
let annotations = Annotations::new(
@@ -281,7 +281,7 @@ pub fn vendor(opt: VendorOptions) -> anyhow::Result<()> {
281281

282282
if matches!(config.rendering.vendor_mode, Some(VendorMode::Local)) {
283283
VendorGenerator::new(cargo, opt.rustc.clone())
284-
.generate(manifest_path.as_path_buf(), &vendor_dir)
284+
.generate(manifest_path.cargo_toml_path(), &vendor_dir)
285285
.context("Failed to vendor dependencies")?;
286286
}
287287

crate_universe/src/metadata.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Tools for gathering various kinds of metadata (Cargo.lock, Cargo metadata, Crate Index info).
22
33
mod cargo_bin;
4+
mod cargo_toml_path;
45
mod cargo_tree_resolver;
56
mod dependency;
67
mod metadata_annotation;
@@ -12,12 +13,12 @@ use std::path::{Path, PathBuf};
1213
use std::str::FromStr;
1314

1415
use anyhow::{bail, Context, Result};
15-
use camino::Utf8Path;
1616
use cargo_lock::Lockfile as CargoLockfile;
1717
use cargo_metadata::Metadata as CargoMetadata;
1818
use tracing::debug;
1919

2020
pub(crate) use self::cargo_bin::*;
21+
pub(crate) use self::cargo_toml_path::*;
2122
pub(crate) use self::cargo_tree_resolver::*;
2223
pub(crate) use self::dependency::*;
2324
pub(crate) use self::metadata_annotation::*;
@@ -190,13 +191,13 @@ impl LockGenerator {
190191
#[tracing::instrument(name = "LockGenerator::generate", skip_all)]
191192
pub(crate) fn generate(
192193
&self,
193-
manifest_path: &Utf8Path,
194+
manifest_path: &CargoTomlPath,
194195
existing_lock: &Option<PathBuf>,
195196
update_request: &Option<CargoUpdateRequest>,
196197
) -> Result<cargo_lock::Lockfile> {
197198
debug!("Generating Cargo Lockfile for {}", manifest_path);
198199

199-
let manifest_dir = manifest_path.parent().unwrap();
200+
let manifest_dir = manifest_path.parent();
200201
let generated_lockfile_path = manifest_dir.join("Cargo.lock");
201202

202203
if let Some(lock) = existing_lock {
@@ -304,9 +305,9 @@ impl VendorGenerator {
304305
}
305306
}
306307
#[tracing::instrument(name = "VendorGenerator::generate", skip_all)]
307-
pub(crate) fn generate(&self, manifest_path: &Utf8Path, output_dir: &Path) -> Result<()> {
308+
pub(crate) fn generate(&self, manifest_path: &CargoTomlPath, output_dir: &Path) -> Result<()> {
308309
debug!("Vendoring {} to {}", manifest_path, output_dir.display());
309-
let manifest_dir = manifest_path.parent().unwrap();
310+
let manifest_dir = manifest_path.parent();
310311

311312
// Simply invoke `cargo generate-lockfile`
312313
let output = self
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use anyhow::{anyhow, Result};
2+
use camino::{Utf8Path, Utf8PathBuf};
3+
use serde::{Deserialize, Serialize};
4+
use std::fmt;
5+
use std::fmt::Display;
6+
use std::path::Path;
7+
8+
/// Path that is know to end with `/Cargo.toml`.
9+
#[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd, Serialize, Deserialize)]
10+
#[serde(transparent)]
11+
pub(crate) struct CargoTomlPath(Utf8PathBuf);
12+
13+
impl Display for CargoTomlPath {
14+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15+
Display::fmt(&self.0, f)
16+
}
17+
}
18+
19+
impl CargoTomlPath {
20+
pub(crate) fn unchecked_new(path: impl Into<Utf8PathBuf>) -> Self {
21+
CargoTomlPath(path.into())
22+
}
23+
24+
pub(crate) fn new(path: impl Into<Utf8PathBuf>) -> Result<Self> {
25+
let path = path.into();
26+
if !path.ends_with("Cargo.toml") {
27+
return Err(anyhow!("Path does not end with Cargo.toml: {path}"));
28+
}
29+
Ok(Self::unchecked_new(path))
30+
}
31+
32+
pub(crate) fn for_dir(dir: impl Into<Utf8PathBuf>) -> Self {
33+
let mut path = dir.into();
34+
path.push("Cargo.toml");
35+
CargoTomlPath::unchecked_new(path)
36+
}
37+
38+
/// Directory of `Cargo.toml` path.
39+
pub(crate) fn parent(&self) -> &Utf8Path {
40+
self.0.parent().expect("Validated in constructor")
41+
}
42+
43+
pub(crate) fn ancestors(&self) -> impl Iterator<Item = &Utf8Path> {
44+
self.0.ancestors()
45+
}
46+
47+
pub(crate) fn as_path(&self) -> &Utf8Path {
48+
self.0.as_path()
49+
}
50+
51+
pub(crate) fn as_std_path(&self) -> &Path {
52+
self.0.as_std_path()
53+
}
54+
}
55+
56+
impl AsRef<Path> for CargoTomlPath {
57+
fn as_ref(&self) -> &Path {
58+
self.0.as_ref()
59+
}
60+
}

crate_universe/src/metadata/cargo_tree_resolver.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ use std::path::{Path, PathBuf};
66
use std::process::Child;
77

88
use anyhow::{anyhow, bail, Context, Result};
9-
use camino::Utf8Path;
109
use semver::Version;
1110
use serde::{Deserialize, Serialize};
1211
use tracing::{debug, trace};
1312
use url::Url;
1413

1514
use crate::config::CrateId;
1615
use crate::metadata::cargo_bin::Cargo;
16+
use crate::metadata::CargoTomlPath;
1717
use crate::select::{Select, SelectableScalar};
1818
use crate::utils::symlink::symlink;
1919
use crate::utils::target_triple::TargetTriple;
@@ -307,7 +307,7 @@ impl TreeResolver {
307307
#[tracing::instrument(name = "TreeResolver::generate", skip_all)]
308308
pub(crate) fn generate(
309309
&self,
310-
pristine_manifest_path: &Utf8Path,
310+
pristine_manifest_path: &CargoTomlPath,
311311
target_triples: &BTreeSet<TargetTriple>,
312312
) -> Result<TreeResolverMetadata> {
313313
debug!(
@@ -450,14 +450,14 @@ impl TreeResolver {
450450
// and if we don't have this fake root injection, cross-compiling from Darwin to Linux won't work because features don't get correctly resolved for the exec=darwin case.
451451
fn copy_project_with_explicit_deps_on_all_transitive_proc_macros(
452452
&self,
453-
pristine_manifest_path: &Utf8Path,
453+
pristine_manifest_path: &CargoTomlPath,
454454
output_dir: &Path,
455455
) -> Result<PathBuf> {
456456
if !output_dir.exists() {
457457
std::fs::create_dir_all(output_dir)?;
458458
}
459459

460-
let pristine_root = pristine_manifest_path.parent().unwrap();
460+
let pristine_root = pristine_manifest_path.parent();
461461
for file in std::fs::read_dir(pristine_root).context("Failed to read dir")? {
462462
let source_path = file?.path();
463463
let file_name = source_path.file_name().unwrap();

0 commit comments

Comments
 (0)