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

[xtask] New subcommand: Books #1192

Merged
merged 5 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion burn-book/src/building-blocks/tensor.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ let tensor_2 = Tensor::<Backend, 1>::from_data(Data::from([1.0, 2.0, 3.0]).conve
// Will be converted to Data internally. `.convert()` not needed as from_floats() defined for fixed ElementType
let tensor_3 = Tensor::<Backend, 1>::from_floats([1.0, 2.0, 3.0]);

// Initalization of Int Tensor from array slices
// Initialization of Int Tensor from array slices
let arr: [i32; 6] = [1, 2, 3, 4, 5, 6];
let tensor_4 = Tensor::<Backend, 1, Int>::from_data(Data::from(&arr[0..3]).convert());

Expand Down
4 changes: 3 additions & 1 deletion xtask/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ license = "MIT OR Apache-2.0"
[dependencies]
anyhow = "1.0.75"
clap = { version = "4.4.8", features = ["derive"] }
derive_more = { version = "0.99.17", features = ["display"], default-features = false }
env_logger = "0.10.0"
log = "0.4.17"
rand = { workspace = true, features = ["std"] }
serde_json = { version = "1" }

[dev-dependencies]
rstest.workspace = true
rstest = { workspace = true }
127 changes: 127 additions & 0 deletions xtask/src/books.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
use std::{collections::HashMap, path::Path, time::Instant};

use clap::{Args, Subcommand};
use derive_more::Display;

use crate::{
endgroup, group,
logging::init_logger,
utils::{
cargo::ensure_cargo_crate_is_installed, mdbook::run_mdbook_with_path, process::random_port,
time::format_duration, Params,
},
};

#[derive(Args)]
pub(crate) struct BooksArgs {
#[command(subcommand)]
book: BookKind,
}

#[derive(Subcommand)]
pub(crate) enum BookKind {
/// Burn Book, a.k.a. the guide, made for the Burn users.
Burn(BookKindArgs),
/// Contributor book, made for people willing to get all the technical understanding and advices to contribute actively to the project.
Contributor(BookKindArgs),
}

#[derive(Args)]
pub(crate) struct BookKindArgs {
#[command(subcommand)]
command: BookCommand,
}

#[derive(Subcommand, Display)]
pub(crate) enum BookCommand {
/// Build the book
Build,
/// Open the book on the specified port or random port and rebuild it automatically upon changes
Open(OpenArgs),
}

#[derive(Args, Display)]
pub(crate) struct OpenArgs {
/// Specify the port to open the book on (defaults to a random port if not specified)
#[clap(long, default_value_t = random_port())]
port: u16,
}

/// Book information
pub(crate) struct Book {
name: &'static str,
path: &'static Path,
}

impl BooksArgs {
pub(crate) fn parse(&self) -> anyhow::Result<()> {
init_logger().init();
let start = Instant::now();
Book::run(&self.book)?;
let duration = start.elapsed();
info!(
"\x1B[32;1mTime elapsed for the current execution: {}\x1B[0m",
format_duration(&duration)
);
Ok(())
}
}

impl Book {
const BURN_BOOK_NAME: &'static str = "Burn Book";
const BURN_BOOK_PATH: &'static str = "./burn-book";

const CONTRIBUTOR_BOOK_NAME: &'static str = "Contributor Book";
const CONTRIBUTOR_BOOK_PATH: &'static str = "./burn-book";

pub(crate) fn run(book_arg: &BookKind) -> anyhow::Result<()> {
let (book, command) = match book_arg {
BookKind::Burn(args) => (
Self {
name: Self::BURN_BOOK_NAME,
path: Path::new(Self::BURN_BOOK_PATH),
},
&args.command,
),
BookKind::Contributor(args) => (
Self {
name: Self::CONTRIBUTOR_BOOK_NAME,
path: Path::new(Self::CONTRIBUTOR_BOOK_PATH),
},
&args.command,
),
};
book.execute(command);
Ok(())
}

fn execute(&self, command: &BookCommand) {
ensure_cargo_crate_is_installed("mdbook");
group!("{}: {}", self.name, command);
match command {
BookCommand::Build => self.build(),
BookCommand::Open(args) => self.open(args),
};
endgroup!();
}

fn build(&self) {
run_mdbook_with_path(
"build",
Params::from([]),
HashMap::new(),
Some(self.path),
"mdbook should build the book successfully",
);
syl20bnr marked this conversation as resolved.
Show resolved Hide resolved
}

fn open(&self, args: &OpenArgs) {
run_mdbook_with_path(
"serve",
Params::from(["--open", "--port", &args.port.to_string()]),
HashMap::new(),
Some(self.path),
"mdbook should build the book successfully",
);
}
}
4 changes: 4 additions & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use clap::{Parser, Subcommand};

mod books;
mod dependencies;
mod logging;
mod publish;
Expand All @@ -19,6 +20,8 @@ struct Args {

#[derive(Subcommand)]
enum Command {
/// Run commands to manage Burn Books
Books(books::BooksArgs),
/// Run the specified dependencies check locally
Dependencies {
/// The dependency check to run
Expand Down Expand Up @@ -46,6 +49,7 @@ fn main() -> anyhow::Result<()> {
let args = Args::parse();

match args.command {
Command::Books(args) => args.parse(),
Command::Dependencies { dependency_check } => dependency_check.run(),
Command::Publish { name } => publish::run(name),
Command::RunChecks { env } => env.run(),
Expand Down
4 changes: 2 additions & 2 deletions xtask/src/utils/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ pub(crate) fn run_cargo_with_path<P: AsRef<Path>>(
/// Ensure that a cargo crate is installed
pub(crate) fn ensure_cargo_crate_is_installed(crate_name: &str) {
if !is_cargo_crate_installed(crate_name) {
group!("Cargo: install {} crate_name", crate_name);
group!("Cargo: install crate '{}'", crate_name);
run_cargo(
"install",
[crate_name].into(),
HashMap::new(),
&format!("{} should be installed", crate_name),
&format!("crate '{}' should be installed", crate_name),
);
endgroup!();
}
Expand Down
35 changes: 35 additions & 0 deletions xtask/src/utils/mdbook.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use std::{
collections::HashMap,
path::Path,
process::{Command, Stdio},
};

use crate::utils::process::handle_child_process;

use super::Params;

/// Run an mdbook command with the passed directory as the current directory
pub(crate) fn run_mdbook_with_path<P: AsRef<Path>>(
command: &str,
params: Params,
envs: HashMap<&str, String>,
path: Option<P>,
error: &str,
) {
info!("mdbook {} {}\n", command, params.params.join(" "));
let mut mdbook = Command::new("mdbook");
mdbook
.envs(&envs)
.arg(command)
.args(&params.params)
.stdout(Stdio::inherit()) // Send stdout directly to terminal
.stderr(Stdio::inherit()); // Send stderr directly to terminal

if let Some(path) = path {
mdbook.current_dir(path);
}

// Handle mdbook child process
let mdbook_process = mdbook.spawn().expect(error);
handle_child_process(mdbook_process, "mdbook process should run flawlessly");
}
1 change: 1 addition & 0 deletions xtask/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub(crate) mod cargo;
pub(crate) mod mdbook;
pub(crate) mod process;
pub(crate) mod rustup;
pub(crate) mod time;
Expand Down
11 changes: 9 additions & 2 deletions xtask/src/utils/process.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rand::Rng;
use std::process::{Child, Command, Stdio};

// Handle child process
/// Handle child process
pub(crate) fn handle_child_process(mut child: Child, error: &str) {
// Wait for the child process to finish
let status = child.wait().expect(error);
Expand All @@ -13,7 +14,7 @@ pub(crate) fn handle_child_process(mut child: Child, error: &str) {
}
}

// Run a command
/// Run a command
pub(crate) fn run_command(command: &str, args: &[&str], command_error: &str, child_error: &str) {
// Format command
info!("{command} {}\n\n", args.join(" "));
Expand All @@ -29,3 +30,9 @@ pub(crate) fn run_command(command: &str, args: &[&str], command_error: &str, chi
// Handle command child process
handle_child_process(command, child_error);
}

/// Return a random port between 3000 and 9999
pub(crate) fn random_port() -> u16 {
Luni-4 marked this conversation as resolved.
Show resolved Hide resolved
let mut rng = rand::thread_rng();
rng.gen_range(3000..=9999)
}
Loading