aboutsummaryrefslogtreecommitdiff
path: root/mingling_cli
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-08-17 00:59:39 +0800
committer魏曹先生 <1992414357@qq.com>2026-08-17 00:59:39 +0800
commit3ff0404be20633d8546758adc05b5075c3227019 (patch)
tree59f6f19fdddb6be2686d739b488e5a39ea5165f0 /mingling_cli
parentbb9ecf31850c9495d1e51a1f5d0af7d5e9284f0e (diff)
feat(install): add --enable flag to run pkg-enable after installHEADmain
Diffstat (limited to 'mingling_cli')
-rw-r--r--mingling_cli/src/pkg_mgr/cmd_install.rs86
1 files changed, 83 insertions, 3 deletions
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`)"
+ }
+}