Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow crates to opt-in to building a single target #632

Merged
merged 21 commits into from
Mar 14, 2020
Merged
Show file tree
Hide file tree
Changes from 7 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
45 changes: 45 additions & 0 deletions src/docbuilder/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use failure::err_msg;
/// all-features = true
/// no-default-features = true
/// default-target = "x86_64-unknown-linux-gnu"
/// extra-targets = [ "x86_64-apple-darwin", "x86_64-pc-windows-msvc" ]
/// rustc-args = [ "--example-rustc-arg" ]
/// rustdoc-args = [ "--example-rustdoc-arg" ]
/// ```
Expand All @@ -43,6 +44,13 @@ pub struct Metadata {
/// is always built on this target. You can change default target by setting this.
pub default_target: Option<String>,

/// If you want a crate to build only for specific targets,
/// set `extra-targets` to the list of targets to build, in addition to `default-target`.
///
/// If you do not set `extra_targets`, all of the tier 1 supported targets will be built.
/// If you set `extra_targets` to an empty array, only the default target will be built.
pub extra_targets: Option<Vec<String>>,
jyn514 marked this conversation as resolved.
Show resolved Hide resolved

/// List of command line arguments for `rustc`.
pub rustc_args: Option<Vec<String>>,

Expand Down Expand Up @@ -87,6 +95,7 @@ impl Metadata {
default_target: None,
rustc_args: None,
rustdoc_args: None,
extra_targets: None,
}
}

Expand All @@ -111,6 +120,8 @@ impl Metadata {
.and_then(|v| v.as_bool()).unwrap_or(metadata.all_features);
metadata.default_target = table.get("default-target")
.and_then(|v| v.as_str()).map(|v| v.to_owned());
metadata.extra_targets = table.get("extra-targets").and_then(|f| f.as_array())
.and_then(|f| f.iter().map(|v| v.as_str().map(|v| v.to_owned())).collect());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have to do it in this PR, but it would be nice to just use #[derive(Deserialize)].

metadata.rustc_args = table.get("rustc-args").and_then(|f| f.as_array())
.and_then(|f| f.iter().map(|v| v.as_str().map(|v| v.to_owned())).collect());
metadata.rustdoc_args = table.get("rustdoc-args").and_then(|f| f.as_array())
Expand Down Expand Up @@ -140,6 +151,7 @@ mod test {
all-features = true
no-default-features = true
default-target = "x86_64-unknown-linux-gnu"
extra-targets = [ "x86_64-apple-darwin", "x86_64-pc-windows-msvc" ]
rustc-args = [ "--example-rustc-arg" ]
rustdoc-args = [ "--example-rustdoc-arg" ]
"#;
Expand All @@ -159,6 +171,11 @@ mod test {

assert_eq!(metadata.default_target.unwrap(), "x86_64-unknown-linux-gnu".to_owned());

let extra_targets = metadata.extra_targets.expect("should have explicit extra target");
assert_eq!(extra_targets.len(), 2);
assert_eq!(extra_targets[0], "x86_64-apple-darwin");
assert_eq!(extra_targets[1], "x86_64-pc-windows-msvc");

let rustc_args = metadata.rustc_args.unwrap();
assert_eq!(rustc_args.len(), 1);
assert_eq!(rustc_args[0], "--example-rustc-arg".to_owned());
Expand All @@ -167,4 +184,32 @@ mod test {
assert_eq!(rustdoc_args.len(), 1);
assert_eq!(rustdoc_args[0], "--example-rustdoc-arg".to_owned());
}

#[test]
fn test_no_extra_targets() {
// metadata section but no extra_targets
let manifest = r#"
[package]
name = "test"

[package.metadata.docs.rs]
features = [ "feature1", "feature2" ]
"#;
let metadata = Metadata::from_str(manifest);
assert!(metadata.extra_targets.is_none());

// no package.metadata.docs.rs section
let metadata = Metadata::from_str(r#"
[package]
name = "test"
"#);
assert!(metadata.extra_targets.is_none());

// extra targets explicitly set to empty array
let metadata = Metadata::from_str(r#"
[package.metadata.docs.rs]
extra-targets = []
"#);
assert!(metadata.extra_targets.unwrap().is_empty());
}
}
42 changes: 34 additions & 8 deletions src/docbuilder/rustwide_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ impl RustwideBuilder {
build_dir
.build(&self.toolchain, &krate, sandbox)
.run(|build| {
let res = self.execute_build(None, build, &limits)?;
let metadata = Metadata::from_source_dir(&build.host_source_dir())?;
let res = self.execute_build(None, build, &limits, &metadata)?;
if !res.result.successful {
bail!("failed to build dummy crate for {}", self.rustc_version);
}
Expand Down Expand Up @@ -312,9 +313,10 @@ impl RustwideBuilder {
let mut files_list = None;
let mut has_docs = false;
let mut successful_targets = Vec::new();
let metadata = Metadata::from_source_dir(&build.host_source_dir())?;

// Do an initial build and then copy the sources in the database
let res = self.execute_build(None, &build, &limits)?;
let res = self.execute_build(None, &build, &limits, &metadata)?;
if res.result.successful {
debug!("adding sources into database");
let prefix = format!("sources/{}/{}", name, version);
Expand All @@ -340,18 +342,41 @@ impl RustwideBuilder {
)?;

successful_targets.push(res.target.clone());

// this is a breaking change, don't enable it by default
let build_specific = std::env::var("DOCS_RS_BUILD_ONLY_SPECIFIED_TARGETS")
.map(|s| s == "true").unwrap_or(false);
let strs: Vec<_>;
// If the env variable is set, _only_ build the specified targets
// If no targets are specified, only build the default target.
let targets: &[&str] = if build_specific {
strs = metadata.extra_targets
.as_ref()
.map(|v| v.iter().map(|s| s.as_str()).collect())
.unwrap_or_default();
&strs
// Otherwise, let people opt-in to only having specific targets
} else if let Some(explicit_targets) = &metadata.extra_targets {
strs = explicit_targets.iter().map(|s| s.as_str()).collect();
&strs
// Otherwise, keep the existing behavior
} else {
TARGETS
};
jyn514 marked this conversation as resolved.
Show resolved Hide resolved

// Then build the documentation for all the targets
for target in TARGETS {
if *target == res.target {
for &target in targets {
if target == res.target {
jyn514 marked this conversation as resolved.
Show resolved Hide resolved
continue;
}
debug!("building package {} {} for {}", name, version, &target);
debug!("building package {} {} for {}", name, version, target);
self.build_target(
&target,
target,
&build,
&limits,
&local_storage.path(),
&mut successful_targets,
&metadata,
)?;
}
self.upload_docs(&conn, name, version, local_storage.path())?;
Expand Down Expand Up @@ -396,8 +421,9 @@ impl RustwideBuilder {
limits: &Limits,
local_storage: &Path,
successful_targets: &mut Vec<String>,
metadata: &Metadata,
) -> Result<()> {
let target_res = self.execute_build(Some(target), build, limits)?;
let target_res = self.execute_build(Some(target), build, limits, metadata)?;
if target_res.result.successful {
// Cargo is not giving any error and not generating documentation of some crates
// when we use a target compile options. Check documentation exists before
Expand All @@ -416,8 +442,8 @@ impl RustwideBuilder {
target: Option<&str>,
build: &Build,
limits: &Limits,
metadata: &Metadata,
) -> Result<FullBuildResult> {
let metadata = Metadata::from_source_dir(&build.host_source_dir())?;
let cargo_metadata =
CargoMetadata::load(&self.workspace, &self.toolchain, &build.host_source_dir())?;

Expand Down
5 changes: 5 additions & 0 deletions templates/about.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@ no-default-features = true
# - i686-pc-windows-msvc
default-target = "x86_64-unknown-linux-gnu"

# Targets to build in addition to `default-target` (default: all tier 1 targets)
# Same available targets as `default-target`.
# Set this to `[]` to only build the default target.
extra-targets = [ "x86_64-apple-darwin", "x86_64-pc-windows-msvc" ]

# Additional `RUSTFLAGS` to set (default: none)
rustc-args = [ "--example-rustc-arg" ]

Expand Down