diff options
Diffstat (limited to 'mingling_cli')
| -rw-r--r-- | mingling_cli/Cargo.lock | 10 | ||||
| -rw-r--r-- | mingling_cli/Cargo.toml | 2 | ||||
| -rw-r--r-- | mingling_cli/src/lib.rs | 27 | ||||
| -rw-r--r-- | mingling_cli/src/pkg_mgr/cmd_install.rs | 86 |
4 files changed, 113 insertions, 12 deletions
diff --git a/mingling_cli/Cargo.lock b/mingling_cli/Cargo.lock index fd3fb1d..c738a0e 100644 --- a/mingling_cli/Cargo.lock +++ b/mingling_cli/Cargo.lock @@ -812,7 +812,7 @@ dependencies = [ [[package]] name = "mingling" -version = "0.4.0" +version = "0.5.0" dependencies = [ "arg-picker", "mingling_core", @@ -821,7 +821,7 @@ dependencies = [ [[package]] name = "mingling-cli" -version = "0.4.0" +version = "0.5.0" dependencies = [ "annotate-snippets", "cargo_metadata", @@ -846,7 +846,7 @@ dependencies = [ [[package]] name = "mingling_core" -version = "0.4.0" +version = "0.5.0" dependencies = [ "just_fmt 0.2.0", "just_template", @@ -856,7 +856,7 @@ dependencies = [ [[package]] name = "mingling_macros" -version = "0.4.0" +version = "0.5.0" dependencies = [ "just_fmt 0.2.0", "proc-macro2", @@ -866,7 +866,7 @@ dependencies = [ [[package]] name = "mingling_pathf" -version = "0.4.0" +version = "0.5.0" dependencies = [ "just_fmt 0.2.0", "proc-macro2", diff --git a/mingling_cli/Cargo.toml b/mingling_cli/Cargo.toml index 009b334..dfc686d 100644 --- a/mingling_cli/Cargo.toml +++ b/mingling_cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mingling-cli" -version = "0.4.0" +version = "0.5.0" edition = "2024" license = "MIT OR Apache-2.0" repository = "https://github.com/mingling-rs/mingling/tree/main/mingling_cli" diff --git a/mingling_cli/src/lib.rs b/mingling_cli/src/lib.rs index ae3b0e0..902ab32 100644 --- a/mingling_cli/src/lib.rs +++ b/mingling_cli/src/lib.rs @@ -1,7 +1,7 @@ use mingling::{ - ShellContext, Suggest, + RenderResult, ShellContext, Suggest, consts::HELP_FLAG, - macros::{completion, gen_program, help, suggest}, + macros::{completion, gen_program, help, renderer, suggest}, }; use crate::{ @@ -26,7 +26,7 @@ pub mod utils; #[help] pub fn help_global(_: EntryFallback) -> String { - include_str!("../help/help.txt").parse_color_code() + format!("{}\n", include_str!("../help/help.txt").parse_color_code()) } #[completion(EntryFallback)] @@ -42,4 +42,25 @@ pub fn complete_global(_ctx: &ShellContext) -> Suggest { } } +#[renderer] +pub fn handle_fallback(args: EntryFallback) -> RenderResult { + let mut r = RenderResult::new(); + let args = args.inner; + if !args.is_empty() { + eprintln_cargo!( + r, + "{}", + format!("Unknown command `{}`", args.join(" ")).parse_color_code() + ) + } else { + hprintln_cargo!( + r, + "{}", + "Welcome to MinglingCLI, please use `mling -h` to see available commands" + .parse_color_code(), + ); + } + r +} + gen_program!(); diff --git a/mingling_cli/src/pkg_mgr/cmd_install.rs b/mingling_cli/src/pkg_mgr/cmd_install.rs index ddcef7d..731ba98 100644 --- a/mingling_cli/src/pkg_mgr/cmd_install.rs +++ b/mingling_cli/src/pkg_mgr/cmd_install.rs @@ -2,9 +2,10 @@ use std::{env, fs, io, path::PathBuf, process::Command}; use cargo_metadata::TargetKind; use mingling::{ - Grouped, LazyRes, RenderResult, Routable, - macros::{chain, command, metadata, pack_err, renderer, routeify}, + Grouped, LazyRes, RenderResult, Routable, ShellContext, Suggest, + macros::{arg, chain, command, completion, metadata, pack_err, renderer, routeify, suggest}, metadata::Description, + picker::{EntryPicker, PickerArg, value::Flag}, }; use crate::{ @@ -16,6 +17,11 @@ use crate::{ pack_err!(ErrorBuildFailed = String); pack_err!(ErrorBinaryNotFound = String); +pack_err!(ErrorPkgEnableFailed = String); + +/// Flag: `--enable` — run `mling pkg-enable` after a successful install +/// to enable the package being installed. +pub static ARG_ENABLE: PickerArg<Flag> = arg![enable: Flag]; /// Resolved install paths, used by the build step. #[derive(Debug, Default, Grouped)] @@ -24,6 +30,7 @@ pub struct StateInstallBuild { pub install_dir: PathBuf, pub release_dir: PathBuf, pub exe_suffix: &'static str, + pub enable: bool, } /// State after `cargo build --release`, used by the copy step. @@ -33,6 +40,16 @@ pub struct StateInstallCopy { pub release_dir: PathBuf, pub exe_suffix: &'static str, pub installed: Vec<PathBuf>, + pub enable: bool, +} + +/// State after the copy step when `--enable` was given: run `mling pkg-enable`. +#[derive(Debug, Default, Grouped)] +pub struct StateInstallEnable { + pub install_dir: PathBuf, + pub installed: Vec<PathBuf>, + pub name: String, + pub version: String, } #[derive(Debug, Default, Grouped)] @@ -49,7 +66,12 @@ pub fn desc_install() -> Description { } #[command(routeify)] -pub fn install(packages_dir: &ResPackagesDir, metadata: &mut LazyRes<ResMetadata>) -> Next { +pub fn install( + args: EntryInstall, + packages_dir: &ResPackagesDir, + metadata: &mut LazyRes<ResMetadata>, +) -> Next { + let enable = args.pick(&ARG_ENABLE).to_result()?; let metadata = metadata.get_ref().data(); let packages_dir = &packages_dir.path; if packages_dir.as_os_str().is_empty() { @@ -69,6 +91,7 @@ pub fn install(packages_dir: &ResPackagesDir, metadata: &mut LazyRes<ResMetadata .join("release") .into_std_path_buf(), exe_suffix: env::consts::EXE_SUFFIX, + enable: enable.bool(), } .to_chain() } @@ -93,6 +116,7 @@ pub fn handle_state_install_build(state: StateInstallBuild) -> Next { release_dir: state.release_dir, exe_suffix: state.exe_suffix, installed: vec![], + enable: state.enable, } .to_chain() } @@ -153,6 +177,45 @@ pub fn handle_state_install_copy( } } + if state.enable { + let root_package = metadata + .root_package() + .or_else(|| metadata.workspace_packages().first().copied()) + .ok_or(ErrorRootPackageNotFound::default())?; + return StateInstallEnable { + install_dir: state.install_dir, + installed: state.installed, + name: root_package.name.to_string(), + version: root_package.version.to_string(), + } + .to_chain(); + } + + ResultInstall { + install_dir: state.install_dir, + installed: state.installed, + } + .to_chain() +} + +/// Step 3 (optional): enable the installed package via `mling pkg-enable` +/// when `--enable` was given. +#[chain(routeify)] +pub fn handle_state_install_enable(state: StateInstallEnable) -> Next { + let spec = format!("{}@{}", state.name, state.version); + let status = Command::new("mling") + .args(["pkg-enable", &spec]) + .status() + .map_err(|e| { + ErrorPkgEnableFailed::new(format!("failed to run `mling pkg-enable {spec}`: {e}")) + })?; + if !status.success() { + return ErrorPkgEnableFailed::new(format!( + "`mling pkg-enable {spec}` failed with {status}" + )) + .to_chain(); + } + ResultInstall { install_dir: state.install_dir, installed: state.installed, @@ -183,3 +246,20 @@ pub fn render_error_binary_not_found(err: ErrorBinaryNotFound) -> RenderResult { eprintln_cargo!(r, "binary not found: {}", err.info); r } + +#[renderer] +pub fn render_error_pkg_enable_failed(err: ErrorPkgEnableFailed) -> RenderResult { + let mut r = RenderResult::new(); + eprintln_cargo!(r, "{}", err.info); + r +} + +#[completion(EntryInstall)] +pub fn complete_install(ctx: &ShellContext) -> Suggest { + if ctx.previous_word != "install" { + return Suggest::FileCompletion; + } + suggest! { + ARG_ENABLE: "Enable the package after installing (runs `mling pkg-enable`)" + } +} |
