117 lines
2.8 KiB
Rust
117 lines
2.8 KiB
Rust
//! See <https://github.com/matklad/cargo-xtask/>.
|
|
//!
|
|
//! This binary is integrated into the `cargo` command line by using an alias in
|
|
//! `.cargo/config`. Run commands as `cargo xtask [command]`.
|
|
|
|
#![allow(unreachable_pub)]
|
|
#![allow(clippy::exhaustive_structs)]
|
|
// https://github.com/rust-lang/rust-clippy/issues/9029
|
|
#![allow(clippy::derive_partial_eq_without_eq)]
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use clap::{Parser, Subcommand};
|
|
use serde::Deserialize;
|
|
use serde_json::from_str as from_json_str;
|
|
|
|
#[cfg(feature = "default")]
|
|
mod cargo;
|
|
mod ci;
|
|
mod doc;
|
|
#[cfg(feature = "default")]
|
|
mod release;
|
|
#[cfg(feature = "default")]
|
|
mod util;
|
|
|
|
use ci::{CiArgs, CiTask};
|
|
use doc::DocTask;
|
|
#[cfg(feature = "default")]
|
|
use release::{ReleaseArgs, ReleaseTask};
|
|
|
|
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
|
|
|
#[derive(Parser)]
|
|
struct Xtask {
|
|
#[clap(subcommand)]
|
|
cmd: Command,
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
enum Command {
|
|
/// Run continuous integration checks
|
|
Ci(CiArgs),
|
|
/// Build the docs
|
|
Doc(DocTask),
|
|
/// Publish a new version of a crate on crates.io, `publish` can be used as an alias
|
|
#[cfg(feature = "default")]
|
|
#[clap(alias = "publish")]
|
|
Release(ReleaseArgs),
|
|
}
|
|
|
|
fn main() -> Result<()> {
|
|
match Xtask::parse().cmd {
|
|
Command::Ci(args) => {
|
|
let ci = CiTask::new(args.cmd)?;
|
|
ci.run()
|
|
}
|
|
Command::Doc(doc) => doc.run(),
|
|
#[cfg(feature = "default")]
|
|
Command::Release(args) => {
|
|
let mut task = ReleaseTask::new(args.package, args.version, args.dry_run)?;
|
|
task.run()
|
|
}
|
|
}
|
|
}
|
|
|
|
/// The metadata of a cargo workspace.
|
|
#[derive(Clone, Debug, Deserialize)]
|
|
struct Metadata {
|
|
pub workspace_root: PathBuf,
|
|
#[cfg(feature = "default")]
|
|
pub packages: Vec<cargo::Package>,
|
|
}
|
|
|
|
impl Metadata {
|
|
/// Load a new `Metadata` from the command line.
|
|
pub fn load() -> Result<Metadata> {
|
|
let metadata_json = cmd!("cargo metadata --no-deps --format-version 1").read()?;
|
|
Ok(from_json_str(&metadata_json)?)
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "default")]
|
|
#[derive(Debug, Deserialize)]
|
|
struct Config {
|
|
/// Credentials to authenticate to GitHub.
|
|
github: GithubConfig,
|
|
}
|
|
|
|
#[cfg(feature = "default")]
|
|
impl Config {
|
|
/// Load a new `Config` from `config.toml`.
|
|
fn load() -> Result<Self> {
|
|
use std::{env, path::Path};
|
|
|
|
let path = Path::new(&env!("CARGO_MANIFEST_DIR")).join("config.toml");
|
|
let config = xshell::read_file(path)?;
|
|
Ok(toml::from_str(&config)?)
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "default")]
|
|
#[derive(Debug, Deserialize)]
|
|
struct GithubConfig {
|
|
/// The username to use for authentication.
|
|
user: String,
|
|
|
|
/// The personal access token to use for authentication.
|
|
token: String,
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! cmd {
|
|
($cmd:tt) => {
|
|
xshell::cmd!($cmd).echo_cmd(false)
|
|
};
|
|
}
|