Skip to content

Commit 3b5be0b

Browse files
work with pre-built bins
1 parent 4abc5bb commit 3b5be0b

File tree

7 files changed

+192
-60
lines changed

7 files changed

+192
-60
lines changed

.github/buildomat/jobs/check-features.sh

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
#: variety = "basic"
55
#: target = "helios-2.0"
66
#: rust_toolchain = true
7-
#: output_rules = []
7+
#: output_rules = [
8+
#: "/out/*",
9+
#: ]
810

911
# Run the check-features `xtask` on illumos, testing compilation of feature combinations.
1012

@@ -15,22 +17,18 @@ set -o xtrace
1517
cargo --version
1618
rustc --version
1719

18-
# NOTE: This version should be in sync with the recommended version in
19-
# ./dev-tools/xtask/src/check-features.rs.
20-
CARGO_HACK_VERSION='0.6.28'
21-
2220
#
2321
# Set up our PATH for use with this workspace.
2422
#
2523
source ./env.sh
24+
export PATH="$PATH:$PWD/out/cargo-hack"
2625

2726
banner prerequisites
2827
ptime -m bash ./tools/install_builder_prerequisites.sh -y
2928

3029
#
31-
# Check the feature set with the `cargo xtask check-features` command.
30+
# Check feature combinations with the `cargo xtask check-features` command.
3231
#
3332
banner hack-check
3433
export CARGO_INCREMENTAL=0
35-
ptime -m timeout 2h cargo xtask check-features --ci --install-version "$CARGO_HACK_VERSION"
36-
RUSTDOCFLAGS="--document-private-items -D warnings" ptime -m cargo doc --workspace --no-deps --no-default-features
34+
ptime -m timeout 2h cargo xtask check-features --ci

.github/workflows/rust.yml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ jobs:
8686
runs-on: ubuntu-22.04
8787
env:
8888
CARGO_INCREMENTAL: 0
89-
CARGO_HACK_VERSION: 0.6.28
9089
steps:
9190
# This repo is unstable and unnecessary: https://github.com/microsoft/linux-package-repositories/issues/34
9291
- name: Disable packages.microsoft.com repo
@@ -99,18 +98,17 @@ jobs:
9998
- name: Report cargo version
10099
run: cargo --version
101100
- name: Update PATH
102-
run: source "./env.sh"; echo "PATH=$PATH" >> "$GITHUB_ENV"
101+
run: |
102+
set -x
103+
export PATH="./out/cargo-hack:$PATH"
104+
source "./env.sh"; echo "PATH=$PATH" >> "$GITHUB_ENV"
103105
- name: Print PATH
104106
run: echo $PATH
105107
- name: Print GITHUB_ENV
106108
run: cat "$GITHUB_ENV"
107109
- name: Install Pre-Requisites
108110
run: ./tools/install_builder_prerequisites.sh -y
109-
# Uses manifest for install
110-
- uses: taiki-e/install-action@v2
111-
with:
112-
tool: cargo-hack@${{ env.CARGO_HACK_VERSION }}
113-
- name: Run Check on Features (Feature-Powerset, No-Dev-Deps)
111+
- name: Run Check on Feature Combinations (Feature-Powerset, No-Dev-Deps)
114112
timeout-minutes: 120 # 2 hours
115113
run: cargo xtask check-features --ci
116114

README.adoc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,13 @@ We check that certain system library dependencies are not leaked outside of thei
114114

115115
=== Checking feature flag combinations
116116

117-
To ensure that varying combinations of features compile, run `cargo xtask check-features`, which executes the https://github.com/taiki-e/cargo-hack[`cargo hack`] subcommand under the hood. This `xtask` is run in CI using the `--ci` parameter , which automatically exludes certain `image-*` features that purposefully cause compiler errors if set.
117+
To ensure that varying combinations of features compile, run `cargo xtask check-features`, which executes the https://github.com/taiki-e/cargo-hack[`cargo hack`] subcommand under the hood.
118118

119-
If you don't have `cargo hack` installed locally, run the the `xtask` with the `install-version <VERSION>` option, which will install it into your user's `.cargo` directory:
119+
This `xtask` is run in CI using the `--ci` parameter , which automatically exludes certain `image-*` features that purposefully cause compiler errors if set and uses a pre-built binary.
120+
121+
If `cargo hack` is not already installed in omicron's `out/` directory, a pre-built binary will be installed automatically depending on your operating system and architecture.
122+
123+
You can also run the the `xtask` with the `install-version <VERSION>` option, which will install the cargo subcommand into your user's `.cargo` directory:
120124

121125
[source,text]
122126
----

dev-tools/xtask/src/check_features.rs

Lines changed: 94 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@
44

55
//! Subcommand: cargo xtask check-features
66
7-
use anyhow::{bail, Context, Result};
7+
use anyhow::{bail, Result};
8+
use camino::{Utf8Path, Utf8PathBuf};
89
use clap::Parser;
910
use std::{collections::HashSet, process::Command};
1011

11-
/// The default version of `cargo-hack` to install.
12-
/// We use a patch-floating version to avoid breaking the build when a new
13-
/// version is released (locally).
14-
const FLOAT_VERSION: &str = "~0.6.28";
15-
12+
const SUPPORTED_ARCHITECTURES: [&str; 1] = ["x86_64"];
1613
const CI_EXCLUDED_FEATURES: [&str; 2] = ["image-trampoline", "image-standard"];
1714

1815
#[derive(Parser)]
@@ -29,27 +26,31 @@ pub struct Args {
2926
/// Error format passed to `cargo hack check`.
3027
#[clap(long, value_name = "FMT")]
3128
message_format: Option<String>,
32-
/// Version of `cargo-hack` to install.
29+
/// Version of `cargo-hack` to install. By default, we download a pre-built
30+
/// version.
3331
#[clap(long, value_name = "VERSION")]
3432
install_version: Option<String>,
3533
}
3634

3735
/// Run `cargo hack check`.
3836
pub fn run_cmd(args: Args) -> Result<()> {
39-
// Install `cargo-hack` if the `install-version` was specified.
40-
if let Some(version) = args.install_version {
41-
install_cargo_hack(Some(version))?;
37+
// We cannot specify both `--ci` and `--install-version`, as the former
38+
// implies we are using a pre-built version.
39+
if args.ci && args.install_version.is_some() {
40+
bail!("cannot specify --ci and --install-version together");
4241
}
4342

4443
let cargo =
4544
std::env::var("CARGO").unwrap_or_else(|_| String::from("cargo"));
45+
4646
let mut command = Command::new(&cargo);
4747

4848
// Add the `hack check` subcommand.
4949
command.args(&["hack", "check"]);
5050

51-
// Add the `--exclude-features` flag if we are running in CI mode.
5251
if args.ci {
52+
install_prebuilt_cargo_hack(&cargo)?;
53+
5354
let ex = if let Some(mut features) = args.exclude_features {
5455
// Extend the list of features to exclude with the CI defaults.
5556
features.extend(
@@ -64,8 +65,10 @@ pub fn run_cmd(args: Args) -> Result<()> {
6465
CI_EXCLUDED_FEATURES.join(",")
6566
};
6667

68+
// Add the `--exclude-features` flag if we are running in CI mode.
6769
command.args(["--exclude-features", &ex]);
6870
} else {
71+
install_cargo_hack(&cargo, args.install_version)?;
6972
// Add "only" the `--exclude-features` flag if it was provided.
7073
if let Some(features) = args.exclude_features {
7174
command.args(["--exclude-features", &features.join(",")]);
@@ -91,48 +94,96 @@ pub fn run_cmd(args: Args) -> Result<()> {
9194
// We will not check the dev-dependencies, which should covered by tests.
9295
.arg("--no-dev-deps");
9396

94-
eprintln!(
95-
"running: {:?} {}",
96-
&cargo,
97-
command
98-
.get_args()
99-
.map(|arg| format!("{:?}", arg.to_str().unwrap()))
100-
.collect::<Vec<_>>()
101-
.join(" ")
102-
);
103-
104-
let exit_status = command
105-
.spawn()
106-
.context("failed to spawn child process")?
107-
.wait()
108-
.context("failed to wait for child process")?;
109-
110-
if !exit_status.success() {
111-
bail!("check-features failed: {}", exit_status);
112-
}
97+
exec(command)
98+
}
11399

114-
Ok(())
100+
/// The supported operating systems.
101+
enum Os {
102+
Illumos,
103+
Linux,
104+
Mac,
115105
}
116106

117-
/// Install `cargo-hack` at the specified version or the default version.
118-
fn install_cargo_hack(version: Option<String>) -> Result<()> {
119-
let cargo =
120-
std::env::var("CARGO").unwrap_or_else(|_| String::from("cargo"));
107+
/// Get the current OS.
108+
fn os_name() -> Result<Os> {
109+
let os = match std::env::consts::OS {
110+
"linux" => Os::Linux,
111+
"macos" => Os::Mac,
112+
"solaris" | "illumos" => Os::Illumos,
113+
other => bail!("OS not supported: {other}"),
114+
};
115+
Ok(os)
116+
}
121117

122-
let mut command = Command::new(&cargo);
118+
/// Get the path to the `out` directory.
119+
fn out_dir() -> Utf8PathBuf {
120+
if let Ok(omicron_dir) = std::env::var("OMICRON") {
121+
Utf8Path::new(format!("{}/out/cargo-hack", omicron_dir).as_str())
122+
.to_path_buf()
123+
} else {
124+
Utf8Path::new("out/cargo-hack").to_path_buf()
125+
}
126+
}
123127

128+
/// Install `cargo-hack` if the `install-version` was specified; otherwise,
129+
/// download a pre-built version if it's not already in our `out` directory.
130+
fn install_cargo_hack(cargo: &str, version: Option<String>) -> Result<()> {
124131
if let Some(version) = version {
132+
let mut command = Command::new(cargo);
133+
134+
eprintln!(
135+
"installing cargo-hack at version {} to {}",
136+
version,
137+
env!("CARGO_HOME")
138+
);
125139
command.args(&["install", "cargo-hack", "--version", &version]);
140+
exec(command)
141+
} else if !out_dir().exists() {
142+
install_prebuilt_cargo_hack(cargo)
126143
} else {
127-
command.args(&[
128-
"install",
129-
"cargo-hack",
130-
"--locked",
131-
"--version",
132-
FLOAT_VERSION,
133-
]);
144+
let out_dir = out_dir();
145+
eprintln!("cargo-hack found in {}", out_dir);
146+
Ok(())
147+
}
148+
}
149+
150+
/// Download a pre-built version of `cargo-hack` to the `out` directory via the
151+
/// download `xtask`.
152+
fn install_prebuilt_cargo_hack(cargo: &str) -> Result<()> {
153+
let mut command = Command::new(cargo);
154+
155+
let out_dir = out_dir();
156+
eprintln!(
157+
"cargo-hack not found in {}, downloading a pre-built version",
158+
out_dir
159+
);
160+
161+
let os = os_name()?;
162+
match os {
163+
Os::Illumos | Os::Linux | Os::Mac
164+
if SUPPORTED_ARCHITECTURES.contains(&std::env::consts::ARCH) =>
165+
{
166+
// Download the pre-built version of `cargo-hack` via our
167+
// download `xtask`.
168+
command.args(&["xtask", "download", "cargo-hack"]);
169+
}
170+
_ => {
171+
bail!(
172+
"cargo-hack is not pre-built for this os {} / arch {}",
173+
std::env::consts::OS,
174+
std::env::consts::ARCH
175+
);
176+
}
134177
}
135178

179+
exec(command)
180+
}
181+
182+
/// Execute the command and check the exit status.
183+
fn exec(mut command: Command) -> Result<()> {
184+
let cargo =
185+
std::env::var("CARGO").unwrap_or_else(|_| String::from("cargo"));
186+
136187
eprintln!(
137188
"running: {:?} {}",
138189
&cargo,

0 commit comments

Comments
 (0)