//! Atomic operations on a cargo workspace //! //! This module contains operations that can be executed on a //! workspace. They take some set of inputs, modelled as fields, and //! produce a shared output which is represented by `Result` mod publish; pub(self) use publish::{versions, Publish, PublishMod, PublishType}; mod error; mod executor; mod parser; use crate::models::{CrateId, DepGraph}; pub use error::{OpError, Result}; use std::path::PathBuf; trait RenderHelp { fn render_help(c: i32) -> !; } /// Render the help-page for a particular command pub(crate) fn render_help(cmd: String) -> ! { match cmd.as_str() { "print" => Print::render_help(0), "publish" => Publish::render_help(0), c => { eprintln!("Unknown command `{}`", c); std::process::exit(2); } } } pub(crate) fn list_commands() { eprintln!("Available commands:\n"); eprintln!(" - print: echo the selected crate set"); eprintln!(" - publish: release new crates on crates.io"); } /// Differentiating operation enum pub enum Op { /// Publish a new version, according to some rules Publish(Publish), /// Print the query selection Print(Print), } impl Op { /// Parse an arg line into an operation to execute pub fn parse(line: Vec) -> Self { match parser::run(line) { Some(op) => op, None => std::process::exit(2), } } pub(crate) fn execute(self, set: Vec, root: PathBuf, g: &mut DepGraph) { match self { Self::Publish(p) => publish::run(p, set, g), Self::Print(p) => executor::print(p, set, root, g), } } } /// Ask the user to be sure pub(self) fn verify_user() { eprintln!("------"); use std::io::{stdin, stdout, Write}; let mut s = String::new(); print!("Execute operations? [N|y]: "); let _ = stdout().flush(); stdin().read_line(&mut s).expect("Failed to read term!"); match s.trim() { "Y" | "y" => {} _ => std::process::exit(0), } } /// Selection of which type to print pub enum Print { /// Default: just the package name Name, /// The path inside the repo Path { abs: bool }, /// Both the name and path Both { abs: bool }, } impl Default for Print { fn default() -> Self { Self::Name } } impl RenderHelp for Print { fn render_help(code: i32) -> ! { eprintln!("Print the selected set of crates"); eprintln!("Usage: cargo ws2 <...> print [OPTIONS]\n"); eprintln!("Available options:\n"); eprintln!(" - path: print the path of the crate, instead of the name"); eprintln!(" - both: print the both the path and the name"); eprintln!(" - abs: (If `path` or `both`) Use an absolute path, instead of relative"); std::process::exit(code) } }