Skip to content

Commit 3bbb781

Browse files
committed
Part 4 of RFC2906 - Add support for inheriting readme
1 parent 4ea1228 commit 3bbb781

File tree

4 files changed

+69
-13
lines changed

4 files changed

+69
-13
lines changed

src/cargo/core/workspace.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::util::errors::{CargoResult, ManifestError};
2323
use crate::util::interning::InternedString;
2424
use crate::util::lev_distance;
2525
use crate::util::toml::{
26-
read_manifest, StringOrBool, TomlDependency, TomlProfiles, VecStringOrBool,
26+
read_manifest, readme_for_project, StringOrBool, TomlDependency, TomlProfiles, VecStringOrBool,
2727
};
2828
use crate::util::{config::ConfigRelativePath, Config, Filesystem, IntoUrl};
2929
use cargo_util::paths;
@@ -1754,12 +1754,15 @@ impl InheritableFields {
17541754
)
17551755
}
17561756

1757-
pub fn readme(&self) -> CargoResult<StringOrBool> {
1758-
self.readme
1759-
.clone()
1760-
.map_or(Err(anyhow!("`workspace.readme` was not defined")), |d| {
1761-
Ok(d)
1762-
})
1757+
pub fn readme(&self, package_root: &Path) -> CargoResult<StringOrBool> {
1758+
readme_for_project(self.ws_root.as_path(), self.readme.clone()).map_or(
1759+
Err(anyhow!("`workspace.readme` was not defined")),
1760+
|readme| {
1761+
let rel_path =
1762+
resolve_relative_path("readme", &self.ws_root, package_root, &readme)?;
1763+
Ok(StringOrBool::String(rel_path))
1764+
},
1765+
)
17631766
}
17641767

17651768
pub fn keywords(&self) -> CargoResult<Vec<String>> {

src/cargo/ops/cargo_package.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,13 @@ fn build_ar_list(
286286
))?;
287287
}
288288
}
289+
if let Some(readme) = &pkg.manifest().metadata().readme {
290+
let readme_path = Path::new(readme);
291+
let abs_file_path = paths::normalize_path(&pkg.root().join(readme_path));
292+
if abs_file_path.exists() {
293+
check_for_file_and_add("readme", readme_path, abs_file_path, pkg, &mut result, ws)?;
294+
}
295+
}
289296
result.sort_unstable_by(|a, b| a.rel_path.cmp(&b.rel_path));
290297

291298
Ok(result)

src/cargo/util/toml/mod.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,7 @@ pub struct TomlProject {
10731073
description: Option<MaybeWorkspace<String>>,
10741074
homepage: Option<MaybeWorkspace<String>>,
10751075
documentation: Option<MaybeWorkspace<String>>,
1076-
readme: Option<StringOrBool>,
1076+
readme: Option<MaybeWorkspace<StringOrBool>>,
10771077
keywords: Option<MaybeWorkspace<Vec<String>>>,
10781078
categories: Option<MaybeWorkspace<Vec<String>>>,
10791079
license: Option<MaybeWorkspace<String>>,
@@ -1175,6 +1175,31 @@ impl TomlManifest {
11751175
));
11761176
}
11771177
}
1178+
1179+
if let Some(readme) = &package.readme {
1180+
let readme = readme
1181+
.as_defined()
1182+
.context("readme should have been resolved before `prepare_for_publish()`")?;
1183+
match readme {
1184+
StringOrBool::String(readme) => {
1185+
let readme_path = Path::new(&readme);
1186+
let abs_readme_path = paths::normalize_path(&package_root.join(readme_path));
1187+
if abs_readme_path.strip_prefix(package_root).is_err() {
1188+
// This path points outside of the package root. `cargo package`
1189+
// will copy it into the root, so adjust the path to this location.
1190+
package.readme = Some(MaybeWorkspace::Defined(StringOrBool::String(
1191+
readme_path
1192+
.file_name()
1193+
.unwrap()
1194+
.to_str()
1195+
.unwrap()
1196+
.to_string(),
1197+
)));
1198+
}
1199+
}
1200+
StringOrBool::Bool(_) => {}
1201+
}
1202+
}
11781203
let all = |_d: &TomlDependency| true;
11791204
return Ok(TomlManifest {
11801205
package: Some(package),
@@ -1693,7 +1718,19 @@ impl TomlManifest {
16931718
})
16941719
})
16951720
.transpose()?,
1696-
readme: readme_for_project(package_root, project),
1721+
readme: readme_for_project(
1722+
package_root,
1723+
project
1724+
.readme
1725+
.clone()
1726+
.map(|mw| {
1727+
mw.resolve(&features, "readme", || {
1728+
get_ws(config, resolved_path.clone(), workspace_config.clone())?
1729+
.readme(package_root)
1730+
})
1731+
})
1732+
.transpose()?,
1733+
),
16971734
authors: project
16981735
.authors
16991736
.clone()
@@ -1778,6 +1815,10 @@ impl TomlManifest {
17781815
.documentation
17791816
.clone()
17801817
.map(|documentation| MaybeWorkspace::Defined(documentation));
1818+
project.readme = metadata
1819+
.readme
1820+
.clone()
1821+
.map(|readme| MaybeWorkspace::Defined(StringOrBool::String(readme)));
17811822
project.authors = project
17821823
.authors
17831824
.as_ref()
@@ -2164,8 +2205,8 @@ fn inheritable_from_path(
21642205
}
21652206

21662207
/// Returns the name of the README file for a `TomlProject`.
2167-
fn readme_for_project(package_root: &Path, project: &TomlProject) -> Option<String> {
2168-
match &project.readme {
2208+
pub fn readme_for_project(package_root: &Path, readme: Option<StringOrBool>) -> Option<String> {
2209+
match &readme {
21692210
None => default_readme_from_package_root(package_root),
21702211
Some(value) => match value {
21712212
StringOrBool::Bool(false) => None,

tests/testsuite/inheritable_workspace_fields.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,7 @@ fn inherit_workspace_fields() {
581581
authors = ["Rustaceans"]
582582
description = "This is a crate"
583583
documentation = "https://www.rust-lang.org/learn"
584+
readme = "README.md"
584585
homepage = "https://www.rust-lang.org"
585586
repository = "https://github.com/example/example"
586587
license = "MIT"
@@ -606,6 +607,7 @@ fn inherit_workspace_fields() {
606607
authors = { workspace = true }
607608
description = { workspace = true }
608609
documentation = { workspace = true }
610+
readme = { workspace = true }
609611
homepage = { workspace = true }
610612
repository = { workspace = true }
611613
license = { workspace = true }
@@ -617,6 +619,7 @@ fn inherit_workspace_fields() {
617619
"#,
618620
)
619621
.file("LICENSE", "license")
622+
.file("README.md", "README.md")
620623
.file("bar/src/main.rs", "fn main() {}")
621624
.build();
622625

@@ -642,8 +645,8 @@ fn inherit_workspace_fields() {
642645
"license_file": "../LICENSE",
643646
"links": null,
644647
"name": "bar",
645-
"readme": null,
646-
"readme_file": null,
648+
"readme": "README.md",
649+
"readme_file": "../README.md",
647650
"repository": "https://github.com/example/example",
648651
"vers": "1.2.3"
649652
}
@@ -654,6 +657,7 @@ fn inherit_workspace_fields() {
654657
"Cargo.toml",
655658
"Cargo.toml.orig",
656659
"src/main.rs",
660+
"README.md",
657661
"LICENSE",
658662
".cargo_vcs_info.json",
659663
],
@@ -672,6 +676,7 @@ publish = true
672676
description = "This is a crate"
673677
homepage = "https://www.rust-lang.org"
674678
documentation = "https://www.rust-lang.org/learn"
679+
readme = "README.md"
675680
keywords = ["cli"]
676681
categories = ["development-tools"]
677682
license = "MIT"

0 commit comments

Comments
 (0)