Skip to content

Commit

Permalink
xtask without worksapce fix rust-lang-nursery#715, fix rust-lang-nurs…
Browse files Browse the repository at this point in the history
…ery#712 (maybe?)

- reworked book operations in xtask
- updated readme for new build command
- updated contribution.md for new test commands
- fixed missing dictionary
- added contributor tests to xtask (`cargo test`, `mdbook serve -o`, `./ci/spellcheck.sh`, `link-checker ./book` (moved to Lychee))
- updated ci .sh files for the new cookbook dir
- fixed broken link
  • Loading branch information
Arteiii committed Dec 16, 2024
1 parent 526cfcb commit 35e3d71
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[alias]
xtask = "run --manifest-path ./xtask/Cargo.toml --"
7 changes: 2 additions & 5 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ No worries if anything in these lists is unclear. Just submit the PR and ask awa
--------------------------
### Things to check before submitting a PR

- [ ] the tests are passing locally with `cargo test`
- [ ] cookbook renders correctly in `mdbook serve -o`
- [ ] the tests are passing locally with `cargo xtask test all`
- [ ] commits are squashed into one and rebased to latest master
- [ ] PR contains correct "fixes #ISSUE_ID" clause to autoclose the issue on PR merge
- if issue does not exist consider creating it or remove the clause
- [ ] spell check runs without errors `./ci/spellcheck.sh`
- [ ] link check runs without errors `link-checker ./book`
- [ ] non rendered items are in sorted order (links, reference, identifiers, Cargo.toml)
- [ ] links to docs.rs have wildcard version `https://docs.rs/tar/*/tar/struct.Entry.html`
- [ ] example has standard [error handling](https://rust-lang-nursery.github.io/rust-cookbook/about.html#a-note-about-error-handling)
Expand All @@ -25,4 +22,4 @@ No worries if anything in these lists is unclear. Just submit the PR and ask awa
### Things to do after submitting PR
- [ ] check if CI is happy with your PR

Thank you for reading, you may now delete this text! Thank you! :smile:
Thank you for reading, you may now delete this text! Thank you! :smile:
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ If you'd like to read it locally:
$ git clone https://github.com/rust-lang-nursery/rust-cookbook
$ cd rust-cookbook
$ cargo install mdbook --vers "0.4.43"
$ mdbook serve --open
$ cargo xtask book build
```

The output can also be opened from the `book` subdirectory in your web browser.
Expand Down
3 changes: 3 additions & 0 deletions ci/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -346,3 +346,6 @@ XRateLimitReset
YAML
YYYY
zurich
enum
thiserror
tempfile
2 changes: 1 addition & 1 deletion src/database/postgres/aggregate_data.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ fn main() -> Result<(), Error> {
}
```

[`Museum of Modern Art`]: https://github.com/MuseumofModernArt/collection/blob/master/Artists.csv
[`Museum of Modern Art`]: https://github.com/MuseumofModernArt/collection/blob/main/Artists.csv
6 changes: 6 additions & 0 deletions xtask/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "xtask"
version = "0.1.0"
edition = "2021"

[dependencies]
57 changes: 57 additions & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
mod tests;
mod mdbook;

use std::path::{Path, PathBuf};
use std::{env, error::Error};

fn main() {
if let Err(e) = try_main() {
eprintln!("{}", e);
std::process::exit(-1);
}
}

fn try_main() -> Result<(), Box<dyn Error>> {
let task = env::args().nth(1);
match task.as_deref() {
Some("test") => {
let sub_task = env::args().nth(2).unwrap_or_else(|| "all".to_string());
tests::run_test(&sub_task)?
}
Some("book") => {
let sub_task = env::args().nth(2).unwrap_or_else(|| "build".to_string());
mdbook::run_book(&sub_task)?
}
_ => print_help(),
}
Ok(())
}

fn project_root() -> PathBuf {
Path::new(&env!("CARGO_MANIFEST_DIR"))
.ancestors()
.nth(1)
.unwrap()
.to_path_buf()
}

fn print_help() {
eprintln!("Available tasks:");
eprintln!(
" test [all|cargo|spellcheck|link] - Run the tests. Use 'all' to run all tests (default), or specify individual tests."
);
eprintln!(
" book [build] - Build the book using mdbook. Default if no subcommand is specified."
);
eprintln!(" book serve - Serve the book using mdbook and open it in a browser.");
eprintln!();
eprintln!("Usage:");
eprintln!(" cargo xtask <task> [subcommand]");
eprintln!();
eprintln!("Examples:");
eprintln!(" cargo xtask test");
eprintln!(" cargo xtask test all");
eprintln!(" cargo xtask test cargo");
eprintln!(" cargo xtask book");
eprintln!(" cargo xtask book serve");
}
44 changes: 44 additions & 0 deletions xtask/src/mdbook.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use crate::project_root;
use std::{error::Error, path::PathBuf, process::Command};

pub fn run_book(task: &str) -> Result<(), Box<dyn Error>> {
let args: &[&str] = if task == "serve" { &["--open"] } else { &[] };

execute_mdbook_command(task, args)?;

Ok(())
}

fn execute_mdbook_command(command: &str, additional_args: &[&str]) -> Result<(), Box<dyn Error>> {
check_mdbook_version()?;

let book_dest = project_root().join("book").to_str().unwrap().to_string();

let mut args = vec![command, "--dest-dir", &book_dest];
args.extend_from_slice(additional_args);

let status = Command::new("mdbook")
.current_dir(project_root())
.args(&args)
.status()?;

if !status.success() {
return Err(format!("`mdbook {command}` failed to run successfully!").into());
}

Ok(())
}

fn check_mdbook_version() -> Result<(), Box<dyn Error>> {
if Command::new("mdbook").arg("--version").status().is_err() {
println!("Error: `mdbook` not found. Please ensure it is installed!");
println!("You can install it using:");
println!(" cargo install mdbook");
return Err(Box::new(std::io::Error::new(
std::io::ErrorKind::NotFound,
"`mdbook` is not installed",
)));
}

Ok(())
}
104 changes: 104 additions & 0 deletions xtask/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
use crate::project_root;
use std::error::Error;
use std::process::Command;

pub fn run_test(task: &str) -> Result<(), Box<dyn Error>> {
match task {
"all" => run_all_tests()?,
"cargo" => cargo_test()?,
"spellcheck" => spellcheck()?,
"link" => link_checker()?,
_ => run_all_tests()?,
}
Ok(())
}

fn run_all_tests() -> Result<(), Box<dyn Error>> {
let mut failures = Vec::new();

if cargo_test().is_err() {
failures.push("cargo_test".to_string());
}

if spellcheck().is_err() {
failures.push("spellcheck".to_string());
}

if link_checker().is_err() {
failures.push("link".to_string());
}

if !failures.is_empty() {
println!("\n--- Test Summary ---");
for name in failures {
println!("❌ {name} failed! Re-run with the command:");
println!(" cargo xtask test {name}");
}
} else {
println!("\n🎉 All tests passed!");
}

Ok(())
}

fn cargo_test() -> Result<(), Box<dyn Error>> {
let status = Command::new("cargo")
.current_dir(project_root())
.args(["test", "--package", "rust-cookbook"])
.status()?;

if !status.success() {
return Err("failed to run cargo test!".into());
}

Ok(())
}

fn spellcheck() -> Result<(), Box<dyn Error>> {
let status = Command::new("./ci/spellcheck.sh")
.current_dir(project_root())
.status()?;

if !status.success() {
return Err("failed to run spellcheck!".into());
}

Ok(())
}

fn link_checker() -> Result<(), Box<dyn Error>> {
if Command::new("lychee").arg("--version").status().is_err() {
return Err(
"The `lychee` tool is not installed. Please install it using:\n cargo install lychee".into(),
);
}

let book_dir = project_root().join("book");
if !book_dir.is_dir() {
return Err(format!(
"The book directory could not be found in the root directory: {:?}\n\
You can build it using:\n cargo xtask book build",
book_dir
)
.into());
}

let status = Command::new("lychee")
.current_dir(project_root())
.args([
"./book",
"--retry-wait-time",
"20",
"--max-retries",
"3",
"--accept",
"429", // accept 429 (ratelimit) errors as valid
])
.status()?;

if !status.success() {
return Err("Failed to run link checker!".into());
}

Ok(())
}

0 comments on commit 35e3d71

Please sign in to comment.