aboutsummaryrefslogtreecommitdiff
path: root/mingling_cli
diff options
context:
space:
mode:
Diffstat (limited to 'mingling_cli')
-rw-r--r--mingling_cli/Cargo.lock10
-rw-r--r--mingling_cli/Cargo.toml2
-rw-r--r--mingling_cli/src/lib.rs27
-rw-r--r--mingling_cli/src/pkg_mgr/cmd_install.rs86
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`)"
+ }
+}