aboutsummaryrefslogtreecommitdiff
path: root/mling/src
diff options
context:
space:
mode:
Diffstat (limited to 'mling/src')
-rw-r--r--mling/src/cli.rs7
-rw-r--r--mling/src/cli/list.rs24
-rw-r--r--mling/src/cli/read.rs9
-rw-r--r--mling/src/display.rs44
-rw-r--r--mling/src/namespace_manager.rs24
-rw-r--r--mling/src/project_installer.rs25
-rw-r--r--mling/src/project_solver.rs27
7 files changed, 95 insertions, 65 deletions
diff --git a/mling/src/cli.rs b/mling/src/cli.rs
index 705c6b4..b628021 100644
--- a/mling/src/cli.rs
+++ b/mling/src/cli.rs
@@ -17,6 +17,11 @@ pub use read::*;
pub mod install;
pub use install::*;
+/// Entry point for the CLI application.
+///
+/// # Panics
+///
+/// Panics on Windows if the virtual terminal processing cannot be enabled.
pub fn cli_entry() {
let mut program = ThisProgram::new();
@@ -62,7 +67,7 @@ pub fn cli_entry() {
#[cfg(windows)]
colored::control::set_virtual_terminal(true).unwrap();
- program.exec();
+ let _ = program.exec();
}
#[renderer]
diff --git a/mling/src/cli/list.rs b/mling/src/cli/list.rs
index ac9a65f..a2a9434 100644
--- a/mling/src/cli/list.rs
+++ b/mling/src/cli/list.rs
@@ -78,44 +78,44 @@ pub(crate) fn render_installed(prev: ResultInstalledNamespaces) {
match prev.option {
StateListInstalledOptions::All => {
print_list(
- "Trusted".bright_green().bold().to_string(),
- prev.trusted,
+ &"Trusted".bright_green().bold().to_string(),
+ &prev.trusted,
__renderer_inner_result,
);
print_list(
- "Untrusted".bright_red().bold().to_string(),
- prev.untrusted,
+ &"Untrusted".bright_red().bold().to_string(),
+ &prev.untrusted,
__renderer_inner_result,
);
print_list(
- "Untagged".bright_black().bold().to_string(),
- prev.untagged,
+ &"Untagged".bright_black().bold().to_string(),
+ &prev.untagged,
__renderer_inner_result,
);
}
StateListInstalledOptions::OnlyTrusted => {
print_list(
- "Trusted".bright_green().bold().to_string(),
- prev.trusted,
+ &"Trusted".bright_green().bold().to_string(),
+ &prev.trusted,
__renderer_inner_result,
);
}
StateListInstalledOptions::OnlyUntrusted => {
print_list(
- "Untrusted".bright_red().bold().to_string(),
- prev.untrusted,
+ &"Untrusted".bright_red().bold().to_string(),
+ &prev.untrusted,
__renderer_inner_result,
);
}
}
}
-fn print_list(title: String, list: Vec<String>, __renderer_inner_result: &mut RenderResult) {
+fn print_list(title: &str, list: &[String], __renderer_inner_result: &mut RenderResult) {
if list.is_empty() {
return;
}
- r_println!("{}", title);
+ r_println!("{title}");
for (i, namespace) in (1..).zip(list.iter()) {
r_println!(" {}. {}", i.to_string(), namespace.bold());
diff --git a/mling/src/cli/read.rs b/mling/src/cli/read.rs
index 82f8fd5..e51e78f 100644
--- a/mling/src/cli/read.rs
+++ b/mling/src/cli/read.rs
@@ -25,7 +25,8 @@ pub(crate) struct ResultBinaries {
}
#[chain]
-pub(crate) fn handle_target_dir_entry(_prev: ReadTargetDirEntry) -> Next {
+#[allow(unused_variables)]
+pub(crate) fn handle_target_dir_entry(entry: ReadTargetDirEntry) -> Next {
match solve_current_dir() {
Ok(solved) => {
let dir = solved.target_dir;
@@ -36,7 +37,8 @@ pub(crate) fn handle_target_dir_entry(_prev: ReadTargetDirEntry) -> Next {
}
#[chain]
-pub(crate) fn handle_workspace_root_entry(_prev: ReadWorkspaceRootEntry) -> Next {
+#[allow(unused_variables)]
+pub(crate) fn handle_workspace_root_entry(entry: ReadWorkspaceRootEntry) -> Next {
match solve_current_dir() {
Ok(solved) => {
let dir = solved.workspace_root;
@@ -47,7 +49,8 @@ pub(crate) fn handle_workspace_root_entry(_prev: ReadWorkspaceRootEntry) -> Next
}
#[chain]
-pub(crate) fn handle_binaries_entry(_prev: ReadBinariesEntry) -> Next {
+#[allow(unused_variables)]
+pub(crate) fn handle_binaries_entry(entry: ReadBinariesEntry) -> Next {
match solve_current_dir() {
Ok(solved) => {
let binaries = solved.binaries;
diff --git a/mling/src/display.rs b/mling/src/display.rs
index 9182692..3816d89 100644
--- a/mling/src/display.rs
+++ b/mling/src/display.rs
@@ -120,8 +120,7 @@ pub fn markdown(text: impl AsRef<str>) -> String {
// Format heading as white background, black text, bold
// ANSI codes: \x1b[1m for bold, \x1b[47m for white background, \x1b[30m for black text
- let formatted_heading =
- format!("\x1b[1m\x1b[47m\x1b[30m {} \x1b[0m", processed_content);
+ let formatted_heading = format!("\x1b[1m\x1b[47m\x1b[30m {processed_content} \x1b[0m");
// Add indentation to the heading line itself
// Heading indentation = level - 1
@@ -187,7 +186,7 @@ fn process_line_with_quote(line: &str) -> String {
let processed_rest = process_line(&rest_of_line);
// Combine the gray background space with the processed rest
- format!("{}{}", gray_bg_space, processed_rest)
+ format!("{gray_bg_space}{processed_rest}")
} else {
// No > at the beginning, process normally
process_line(line)
@@ -266,7 +265,7 @@ fn process_line(line: &str) -> String {
&& let Some(end) = find_matching(&chars, i + 1, "_")
{
let underline_text: String = chars[i + 1..end].iter().collect();
- let mut formatted_text = format!("\x1b[4m{}\x1b[0m", underline_text);
+ let mut formatted_text = format!("\x1b[4m{underline_text}\x1b[0m");
apply_color_stack(&mut formatted_text, &color_stack);
result.push_str(&formatted_text);
i = end + 1;
@@ -357,16 +356,18 @@ fn apply_color(text: impl AsRef<str>, color_name: impl AsRef<str>) -> String {
let text = text.as_ref();
let color_name = color_name.as_ref();
match color_name {
- // Normal colors
- "black" => text.black().to_string(),
- "red" => text.red().to_string(),
- "green" => text.green().to_string(),
- "yellow" => text.yellow().to_string(),
- "blue" => text.blue().to_string(),
- "magenta" => text.magenta().to_string(),
- "cyan" => text.cyan().to_string(),
- "white" => text.white().to_string(),
- "bright_black" => text.bright_black().to_string(),
+ // Normal colors and their bright short aliases
+ "black" | "b_black" => text.black().to_string(),
+ "red" | "b_red" => text.red().to_string(),
+ "green" | "b_green" => text.green().to_string(),
+ "yellow" | "b_yellow" => text.yellow().to_string(),
+ "blue" | "b_blue" => text.blue().to_string(),
+ "magenta" | "b_magenta" => text.magenta().to_string(),
+ "cyan" | "b_cyan" => text.cyan().to_string(),
+ "white" | "b_white" | "bright_gray" | "bright_grey" | "b_gray" | "b_grey" => {
+ text.white().to_string()
+ }
+ "bright_black" | "gray" | "grey" => text.bright_black().to_string(),
"bright_red" => text.bright_red().to_string(),
"bright_green" => text.bright_green().to_string(),
"bright_yellow" => text.bright_yellow().to_string(),
@@ -375,21 +376,6 @@ fn apply_color(text: impl AsRef<str>, color_name: impl AsRef<str>) -> String {
"bright_cyan" => text.bright_cyan().to_string(),
"bright_white" => text.bright_white().to_string(),
- // Short aliases for bright colors
- "b_black" => text.black().to_string(),
- "b_red" => text.red().to_string(),
- "b_green" => text.green().to_string(),
- "b_yellow" => text.yellow().to_string(),
- "b_blue" => text.blue().to_string(),
- "b_magenta" => text.magenta().to_string(),
- "b_cyan" => text.cyan().to_string(),
- "b_white" => text.white().to_string(),
-
- // Gray colors using truecolor
- "gray" | "grey" => text.bright_black().to_string(),
- "bright_gray" | "bright_grey" => text.white().to_string(),
- "b_gray" | "b_grey" => text.white().to_string(),
-
// Default to white if color not recognized
_ => text.to_string(),
}
diff --git a/mling/src/namespace_manager.rs b/mling/src/namespace_manager.rs
index 51181c3..d5176dd 100644
--- a/mling/src/namespace_manager.rs
+++ b/mling/src/namespace_manager.rs
@@ -2,6 +2,7 @@ use std::path::PathBuf;
use just_fmt::kebab_case;
+#[must_use]
pub fn list_namespaces(
show_trusted: bool,
show_untrusted: bool,
@@ -13,14 +14,12 @@ pub fn list_namespaces(
}
let mut namespaces = Vec::new();
- let entries = match std::fs::read_dir(&wdir) {
- Ok(entries) => entries,
- Err(_) => return Vec::new(),
+ let Ok(entries) = std::fs::read_dir(&wdir) else {
+ return Vec::new();
};
for entry in entries {
- let entry = match entry {
- Ok(e) => e,
- Err(_) => continue,
+ let Ok(entry) = entry else {
+ continue;
};
let path = entry.path();
if path.is_dir()
@@ -71,24 +70,34 @@ pub fn remove_namespace(namespace: String) {
}
}
+/// Returns the mingling data directory.
+///
+/// # Panics
+///
+/// Panics if the platform's data directory cannot be determined.
+#[must_use]
pub fn working_dir() -> PathBuf {
dirs::data_dir().unwrap().join("mingling")
}
+#[must_use]
pub fn namespace_dir(namespace: String) -> PathBuf {
working_dir().join(kebab_case!(namespace))
}
+#[must_use]
pub fn is_untrusted_namespace(namespace: String) -> bool {
let untrusted_file = namespace_dir(namespace).join("UNTRUSTED");
untrusted_file.exists()
}
+#[must_use]
pub fn is_trusted_namespace(namespace: String) -> bool {
let trusted = namespace_dir(namespace).join("TRUSTED");
trusted.exists()
}
+#[must_use]
pub fn is_untagged_namespace(namespace: String) -> bool {
let ndir = namespace_dir(namespace);
let trusted = ndir.join("TRUSTED");
@@ -96,14 +105,17 @@ pub fn is_untagged_namespace(namespace: String) -> bool {
!trusted.exists() && !untrusted.exists()
}
+#[must_use]
pub fn bin_dir(namespace: String) -> PathBuf {
namespace_dir(namespace).join("bin")
}
+#[must_use]
pub fn comp_dir(namespace: String) -> PathBuf {
namespace_dir(namespace).join("comp")
}
+#[must_use]
pub fn exe_path(namespace: String, bin_name_without_ext: String) -> PathBuf {
if cfg!(target_os = "windows") {
bin_dir(namespace).join(bin_name_without_ext + ".exe")
diff --git a/mling/src/project_installer.rs b/mling/src/project_installer.rs
index 2e9ca8d..983307f 100644
--- a/mling/src/project_installer.rs
+++ b/mling/src/project_installer.rs
@@ -1,5 +1,3 @@
-use std::path::PathBuf;
-
use mingling::{ShellFlag, build::build_comp_script_to};
use crate::{
@@ -21,15 +19,27 @@ struct Package {
name: String,
}
+/// Installs all projects and shell scripts.
+///
+/// # Errors
+///
+/// Returns an `io::Error` if the current directory cannot be determined, if the project
+/// installation fails, or if the shell scripts cannot be installed.
pub fn install_all(clean_before_build: bool) -> Result<(), std::io::Error> {
let current = std::env::current_dir()?;
- install_this_project(current, clean_before_build)?;
+ install_this_project(&current, clean_before_build)?;
install_shell_scripts()?;
Ok(())
}
+/// Installs a project from the given path.
+///
+/// # Errors
+///
+/// Returns an `io::Error` if the project installation fails, e.g., if `cargo build`
+/// fails, the Cargo.toml cannot be parsed, or file operations (copy, create dir) fail.
pub fn install_this_project(
- current: PathBuf,
+ current: &std::path::PathBuf,
clean_before_build: bool,
) -> Result<(), std::io::Error> {
// Obtain context data
@@ -95,6 +105,11 @@ pub fn install_this_project(
Ok(())
}
+/// Installs shell completion scripts for the `mling` command.
+///
+/// # Errors
+///
+/// Returns an `io::Error` if the shell scripts cannot be built or installed.
pub fn install_shell_scripts() -> Result<(), std::io::Error> {
// Get the working directory (mingling data dir)
let wdir = working_dir();
@@ -138,7 +153,7 @@ pub fn install_shell_scripts() -> Result<(), std::io::Error> {
.args(["+x", &dest.to_string_lossy()])
.status()?;
if !status.success() {
- eprintln!("Failed to chmod {}", filename);
+ eprintln!("Failed to chmod {filename}");
}
}
}
diff --git a/mling/src/project_solver.rs b/mling/src/project_solver.rs
index b6517b3..3aec2b4 100644
--- a/mling/src/project_solver.rs
+++ b/mling/src/project_solver.rs
@@ -17,13 +17,24 @@ pub struct BinaryItem {
pub path: PathBuf,
}
+/// Solves the current directory for project metadata.
+///
+/// # Errors
+///
+/// Returns an `io::Error` if the current directory cannot be determined
+/// or if `cargo metadata` fails.
pub fn solve_current_dir() -> Result<ProjectSolveResult, std::io::Error> {
let current = std::env::current_dir()?;
- solve(current)
+ solve(&current)
}
-pub fn solve(current: PathBuf) -> Result<ProjectSolveResult, std::io::Error> {
- let (target_dir, workspace_root, binaries) = solve_inner(&current)?;
+/// Solves the given directory path for project metadata.
+///
+/// # Errors
+///
+/// Returns an `io::Error` if `cargo metadata` fails for the given path.
+pub fn solve(current: &PathBuf) -> Result<ProjectSolveResult, std::io::Error> {
+ let (target_dir, workspace_root, binaries) = solve_inner(current)?;
Ok(ProjectSolveResult {
target_dir,
workspace_root,
@@ -40,9 +51,9 @@ fn solve_inner(current: &PathBuf) -> Result<(PathBuf, PathBuf, Vec<BinaryItem>),
.output()?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
- return Err(std::io::Error::other(
- format!("cargo metadata failed: {}", stderr),
- ));
+ return Err(std::io::Error::other(format!(
+ "cargo metadata failed: {stderr}"
+ )));
}
let metadata: serde_json::Value = serde_json::from_slice(&output.stdout)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
@@ -75,9 +86,7 @@ fn solve_inner(current: &PathBuf) -> Result<(PathBuf, PathBuf, Vec<BinaryItem>),
if let Some(targets) = pkg["targets"].as_array() {
for target in targets {
let kind = target["kind"].as_array();
- let is_bin = kind
- .map(|k| k.iter().any(|v| v.as_str() == Some("bin")))
- .unwrap_or(false);
+ let is_bin = kind.is_some_and(|k| k.iter().any(|v| v.as_str() == Some("bin")));
if is_bin {
let name = target["name"].as_str().ok_or_else(|| {
std::io::Error::new(