Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "star-setup"
version = "0.4.2"
version = "0.4.3"
edition = "2021"
repository = "https://github.com/star-setup/core"
description = "Lightweight CLI to clone, configure, and wire single or multi-repo ecosystems"
Expand Down
6 changes: 3 additions & 3 deletions src/cli/flags.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::cli::BuildSystem;
use clap::Args as ClapArgs;
use clap::{ArgAction::Append, Args as ClapArgs};

#[allow(clippy::struct_excessive_bools)]
#[derive(ClapArgs)]
Expand Down Expand Up @@ -44,11 +44,11 @@ pub struct BuildFlags {
pub no_clean: bool,

/// Additional `CMake` arguments
#[arg(long = "cmake-arg", action = clap::ArgAction::Append)]
#[arg(long = "cmake-arg", action = Append)]
pub cmake_flags: Vec<String>,

/// Additional Meson arguments
#[arg(long = "meson-arg", action = clap::ArgAction::Append)]
#[arg(long = "meson-arg", action = Append)]
pub meson_flags: Vec<String>,

/// Automatically open watch scripts for npm mono-repo mode.
Expand Down
2 changes: 0 additions & 2 deletions src/commands/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//! Build system dispatch and per-system build functions.

use crate::{
cli::{BuildSystem, ResolvedArgs},
ctx::RunCtx,
Expand Down
23 changes: 10 additions & 13 deletions src/commands/handlers.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use crate::{
cli::{ConfigAction, ProfileAction, WorkspaceAction},
cli::{
ConfigAction, ProfileAction, WorkspaceAction,
WorkspaceAction::{Clean, Status, Update},
},
config::{
add_config, create_default_config, list_configs, remove_config, ConfigEntry, SetupConfig,
},
ctx::{with_runner, IoCtx, RunFlags},
profile::{add_profile, list_profiles, remove_profile},
workspace::resolve_workspace,
};
use std::{error::Error, path::PathBuf};
use std::{error::Error, iter::once, path::PathBuf};

/// Handles configuration-related subcommands.
/// # Errors
Expand Down Expand Up @@ -52,7 +55,7 @@ pub fn handle_profile_cmd(
ProfileAction::List => list_profiles(config, io),
ProfileAction::Remove { name } => remove_profile(config, &name, yes, io, flags)?,
ProfileAction::Add { name, repos } => {
let vals = std::iter::once(name).chain(repos).collect::<Vec<_>>();
let vals = once(name).chain(repos).collect::<Vec<_>>();
add_profile(config, &vals, yes, io, flags)?;
}
}
Expand All @@ -68,9 +71,7 @@ pub fn handle_workspace_cmd(
flags: RunFlags,
) -> Result<(), Box<dyn Error>> {
let target = match &action {
WorkspaceAction::Update { target }
| WorkspaceAction::Clean { target }
| WorkspaceAction::Status { target, .. } => target,
Update { target } | Clean { target } | Status { target, .. } => target,
};
let ws = resolve_workspace(
target.path.as_deref(),
Expand All @@ -81,14 +82,10 @@ pub fn handle_workspace_cmd(
)?;

match action {
WorkspaceAction::Update { .. } => {
with_runner(io, flags, |ctx| ws.update(ctx).map_err(Into::into))
}
WorkspaceAction::Status { fetch, .. } => {
Update { .. } => with_runner(io, flags, |ctx| ws.update(ctx).map_err(Into::into)),
Status { fetch, .. } => {
with_runner(io, flags, |ctx| ws.status(*fetch, ctx).map_err(Into::into))
}
WorkspaceAction::Clean { .. } => {
with_runner(io, flags, |ctx| ws.clean(ctx).map_err(Into::into))
}
Clean { .. } => with_runner(io, flags, |ctx| ws.clean(ctx).map_err(Into::into)),
}
}
2 changes: 0 additions & 2 deletions src/commands/header.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//! Mode header rendering

use crate::ctx::IoCtx;

/// Header information printed at the start of each command mode.
Expand Down
4 changes: 2 additions & 2 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ pub use header::{print_mode_header, ModeHeader};
pub mod mono;
pub use mono::{
build_repo_list, create_mono_repo_cmakelists, create_mono_repo_mesonbuild,
create_mono_repo_package_json, hoist_wraps, mono_repo_mode, resolve_repos_for_mono,
resolve_test_repo,
create_mono_repo_package_json, generate_mono_config, generate_watch_scripts, hoist_wraps,
mono_repo_mode, resolve_repos_for_mono, resolve_setup_paths, resolve_test_repo,
wraps::{parse_project_name, parse_provide_pairs},
};
pub mod single;
Expand Down
37 changes: 0 additions & 37 deletions src/commands/mono/clone.rs

This file was deleted.

10 changes: 7 additions & 3 deletions src/commands/mono/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use crate::{
repository::repo_dir_name,
utils::dry_run_or_do,
};
use std::{fs, path::Path};
use serde_json::{from_str, Value};
use std::{
fs::{self, read_to_string},
path::Path,
};

/// Shared helper to generate, write, and log monorepo build configuration files.
fn write_mono_repo_config(
Expand Down Expand Up @@ -170,8 +174,8 @@ pub fn create_mono_repo_package_json(
continue;
}
let pkg_path = repos_path.join(dir).join("package.json");
if let Ok(content) = fs::read_to_string(&pkg_path) {
match serde_json::from_str::<serde_json::Value>(&content) {
if let Ok(content) = read_to_string(&pkg_path) {
match from_str::<Value>(&content) {
Ok(json) => {
if let Some(name) = json.get("name").and_then(|n| n.as_str()) {
overrides.push(format!(" \"{name}\": \"*\""));
Expand Down
17 changes: 10 additions & 7 deletions src/commands/mono/display.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use crate::{
cli::BuildSystem,
cli::{BuildSystem, BuildSystem::Npm},
ctx::{IoCtx, RunFlags},
repository::repo_dir_name,
};
use dunce::canonicalize;
use std::{
collections::HashMap,
hash::BuildHasher,
path::{Path, PathBuf},
time::Instant,
};

/// Resolved display paths for the setup completion summary.
Expand All @@ -20,15 +23,15 @@ pub struct SetupPaths {

/// Resolves display paths for setup completion summary.
#[must_use]
pub fn resolve_setup_paths<S: std::hash::BuildHasher>(
pub fn resolve_setup_paths<S: BuildHasher>(
canonical_map: Option<&HashMap<String, String, S>>,
mono_repo_path: &Path,
build_path: &Path,
test_repo: &str,
build_system: Option<BuildSystem>,
) -> SetupPaths {
let mono_repo_disp =
dunce::canonicalize(mono_repo_path).unwrap_or_else(|_| mono_repo_path.to_path_buf());
canonicalize(mono_repo_path).unwrap_or_else(|_| mono_repo_path.to_path_buf());

let (exe_path, build_disp) = if let Some(map) = canonical_map {
let test_repo_name = repo_dir_name(test_repo);
Expand All @@ -45,14 +48,14 @@ pub fn resolve_setup_paths<S: std::hash::BuildHasher>(
.join("repos")
.join(&test_repo_name)
.join(&exe_name);
dunce::canonicalize(&p).unwrap_or(p)
canonicalize(&p).unwrap_or(p)
});
(exe_path, None)
} else {
let build_disp = if build_system == Some(BuildSystem::Npm) {
let build_disp = if build_system == Some(Npm) {
None
} else {
Some(dunce::canonicalize(build_path).unwrap_or_else(|_| build_path.to_path_buf()))
Some(canonicalize(build_path).unwrap_or_else(|_| build_path.to_path_buf()))
};
(None, build_disp)
};
Expand All @@ -67,7 +70,7 @@ pub fn resolve_setup_paths<S: std::hash::BuildHasher>(
/// Prints the setup completion summary.
pub fn print_setup_complete(
paths: &SetupPaths,
total: std::time::Instant,
total: Instant,
io: &mut IoCtx<'_>,
flags: RunFlags,
) {
Expand Down
4 changes: 1 addition & 3 deletions src/commands/mono/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
pub mod clone;
pub use clone::clone_mono_repos;
pub mod config;
pub use config::{
create_mono_repo_cmakelists, create_mono_repo_mesonbuild, create_mono_repo_package_json,
};
pub mod display;
pub use display::print_setup_complete;
pub use display::{print_setup_complete, resolve_setup_paths};
pub mod mode;
pub use mode::mono_repo_mode;
pub mod resolve;
Expand Down
16 changes: 8 additions & 8 deletions src/commands/mono/mode.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
use crate::{
cli::{detect_mono_build_system, BuildSystem, ResolvedArgs},
cli::{detect_mono_build_system, BuildSystem::Npm, ResolvedArgs},
commands::{
build_project, build_repo_list, extract_repo_input,
mono::{
clone_mono_repos,
display::{resolve_setup_paths, SetupPaths},
generate_mono_config, generate_watch_scripts, open_watch_scripts, print_setup_complete,
},
prepare_build_dir, print_mode_header, resolve_repos_for_mono, resolve_test_repo, ModeHeader,
},
config::SetupConfig,
ctx::RunCtx,
repository::repo_dir_name,
repository::{clone_repos, repo_dir_name},
utils::{dry_run::detect_or_dry_run, dry_run_or_do},
};
use std::{
fs,
path::{Path, PathBuf},
time::Instant,
};

/// Clones and configures a mono-repo ecosystem from a profile or explicit repository list.
Expand All @@ -28,7 +28,7 @@ pub fn mono_repo_mode(
base_dir: &Path,
ctx: &mut RunCtx<'_, '_>,
) -> Result<(), String> {
let total = std::time::Instant::now();
let total = Instant::now();
let repo_input = extract_repo_input(args)?;
let test_repo = resolve_test_repo(repo_input)?;
let deps = resolve_repos_for_mono(args, config, &mut ctx.io)?;
Expand Down Expand Up @@ -70,7 +70,7 @@ pub fn mono_repo_mode(
writeln!(ctx.io.output).ok();
}

clone_mono_repos(&repos, &repos_path, args.connection.ssh, ctx)?;
clone_repos(&repos, &repos_path, args.connection.ssh, args.yes, ctx)?;

let repo_dirs: Vec<PathBuf> = repos
.iter()
Expand All @@ -84,7 +84,7 @@ pub fn mono_repo_mode(

let canonical_map = if let Some(bs) = build_system {
let map = generate_mono_config(bs, &mono_repo_path, &repos_path, &repo_dirs, &repos, ctx)?;
if bs != BuildSystem::Npm {
if bs != Npm {
prepare_build_dir(build_path.as_path(), args.build.clean, ctx)?;
} else if args.build.clean && ctx.flags.verbose {
writeln!(ctx.io.output, " --clean has no effect for npm projects").ok();
Expand All @@ -95,7 +95,7 @@ pub fn mono_repo_mode(
None
};

if build_system == Some(BuildSystem::Npm)
if build_system == Some(Npm)
&& !args.build.no_watch
&& generate_watch_scripts(&mono_repo_path, &repos_path, &repos, &mut ctx.io, ctx.flags)?
&& args.build.watch
Expand All @@ -107,7 +107,7 @@ pub fn mono_repo_mode(
SetupPaths {
mono_repo_disp: mono_repo_path.clone(),
exe_path: None,
build_disp: if build_system == Some(BuildSystem::Npm) {
build_disp: if build_system == Some(Npm) {
None
} else {
Some(build_path.clone())
Expand Down
48 changes: 24 additions & 24 deletions src/commands/mono/resolve.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,5 @@
use crate::{cli::ResolvedArgs, config::SetupConfig, ctx::IoCtx, profile::list_profiles};

/// Resolves the list of repositories for mono-repo mode from a profile or explicit repo list.
/// # Errors
/// Returns an error if the specified profile does not exist, or has no repositories.
pub fn resolve_repos_for_mono(
args: &ResolvedArgs,
config: &SetupConfig,
io: &mut IoCtx<'_>,
) -> Result<Vec<String>, String> {
if let Some(profile_name) = &args.mono.profile {
let profile_repos = config.profiles.get(profile_name).ok_or_else(|| {
list_profiles(config, io);
format!("Profile '{profile_name}' not found")
})?;
if profile_repos.is_empty() {
return Err(format!("Profile '{profile_name}' has no repositories"));
}
Ok(profile_repos.clone())
} else if let Some(r) = &args.mono.repos {
Ok(r.clone())
} else {
Err("No repos or profile specified for mono-repo mode".to_string())
}
}

/// Normalizes a repository input to `username/repo` format.
/// # Errors
/// Returns an error if the input is not a recognizable GitHub URL or `username/repo` format.
Expand All @@ -47,3 +23,27 @@ pub fn resolve_test_repo(repo_input: &str) -> Result<String, String> {
Err("Repository must be in format 'username/repo' for mono-repo mode".to_string())
}
}

/// Resolves the list of repositories for mono-repo mode from a profile or explicit repo list.
/// # Errors
/// Returns an error if the specified profile does not exist, or has no repositories.
pub fn resolve_repos_for_mono(
args: &ResolvedArgs,
config: &SetupConfig,
io: &mut IoCtx<'_>,
) -> Result<Vec<String>, String> {
if let Some(profile_name) = &args.mono.profile {
let profile_repos = config.profiles.get(profile_name).ok_or_else(|| {
list_profiles(config, io);
format!("Profile '{profile_name}' not found")
})?;
if profile_repos.is_empty() {
return Err(format!("Profile '{profile_name}' has no repositories"));
}
Ok(profile_repos.clone())
} else if let Some(r) = &args.mono.repos {
Ok(r.clone())
} else {
Err("No repos or profile specified for mono-repo mode".to_string())
}
}
Loading
Loading