Skip to content
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.3"
version = "0.4.4"
edition = "2021"
repository = "https://github.com/star-setup/core"
description = "Lightweight CLI to clone, configure, and wire single or multi-repo ecosystems"
Expand Down
88 changes: 42 additions & 46 deletions src/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ use crate::{
};
use std::path::Path;

/// Runs `cmd`, timing it if `ctx.flags.timing` is set.
/// # Errors
/// Returns an error if the command fails.
fn run_timed(
cmd: &[&str],
cwd: Option<&Path>,
label: &str,
ctx: &mut RunCtx<'_, '_>,
) -> Result<(), String> {
crate::time!(ctx.flags.timing, ctx.io.output, label, {
ctx.runner.run(cmd, cwd, ctx.flags, ctx.io.output)?;
});
Ok(())
}

/// Runs `CMake` configuration and optionally builds the project in `build_path`.
/// # Errors
/// Returns an error if any `CMake` command fails.
Expand All @@ -21,28 +36,22 @@ pub fn cmake_build(
};
cmake_cmd.extend(args.build.cmake_flags.iter().map(String::as_str));

crate::time!(ctx.flags.timing, ctx.io.output, "CMake configure", {
ctx
.runner
.run(&cmake_cmd, Some(build_path), ctx.flags, ctx.io.output)?;
});
run_timed(&cmake_cmd, Some(build_path), "CMake configure", ctx)?;

if !args.build.no_build {
writeln!(ctx.io.output, "Building project").ok();
crate::time!(ctx.flags.timing, ctx.io.output, "CMake build", {
ctx.runner.run(
&[
"cmake",
"--build",
".",
"--config",
args.build.build_type.to_cmake(),
],
Some(build_path),
ctx.flags,
ctx.io.output,
)?;
});
run_timed(
&[
"cmake",
"--build",
".",
"--config",
args.build.build_type.to_cmake(),
],
Some(build_path),
"CMake build",
ctx,
)?;
}
Ok(())
}
Expand All @@ -69,19 +78,15 @@ pub fn meson_build(
meson_cmd.push(to_str(source_path)?);
meson_cmd.extend(args.build.meson_flags.iter().map(String::as_str));

crate::time!(ctx.flags.timing, ctx.io.output, "Meson setup", {
ctx.runner.run(&meson_cmd, None, ctx.flags, ctx.io.output)?;
});
run_timed(&meson_cmd, None, "Meson setup", ctx)?;
if !args.build.no_build {
writeln!(ctx.io.output, "Building project").ok();
crate::time!(ctx.flags.timing, ctx.io.output, "Meson compile", {
ctx.runner.run(
&["meson", "compile", "-C", to_str(build_path)?],
None,
ctx.flags,
ctx.io.output,
)?;
});
run_timed(
&["meson", "compile", "-C", to_str(build_path)?],
None,
"Meson compile",
ctx,
)?;
}
Ok(())
}
Expand All @@ -96,24 +101,15 @@ pub fn npm_build(
ctx: &mut RunCtx<'_, '_>,
) -> Result<(), String> {
writeln!(ctx.io.output, "Installing dependencies").ok();
crate::time!(ctx.flags.timing, ctx.io.output, "npm install", {
ctx.runner.run(
&["npm", "install"],
Some(source_path),
ctx.flags,
ctx.io.output,
)?;
});
run_timed(&["npm", "install"], Some(source_path), "npm install", ctx)?;
if !args.build.no_build && !is_mono {
writeln!(ctx.io.output, "Building project").ok();
crate::time!(ctx.flags.timing, ctx.io.output, "npm build", {
ctx.runner.run(
&["npm", "run", "build"],
Some(source_path),
ctx.flags,
ctx.io.output,
)?;
});
run_timed(
&["npm", "run", "build"],
Some(source_path),
"npm build",
ctx,
)?;
}
Ok(())
}
Expand Down
3 changes: 2 additions & 1 deletion src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ pub mod mono;
pub use mono::{
build_repo_list, create_mono_repo_cmakelists, create_mono_repo_mesonbuild,
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,
mono_repo_mode, read_package_json, resolve_repos_for_mono, resolve_setup_paths,
resolve_test_repo,
wraps::{parse_project_name, parse_provide_pairs},
};
pub mod single;
Expand Down
90 changes: 20 additions & 70 deletions src/commands/mono/config.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use crate::{
commands::read_package_json,
ctx::{IoCtx, RunFlags},
repository::repo_dir_name,
utils::dry_run_or_do,
};
use serde_json::{from_str, Value};
use std::{
fs::{self, read_to_string},
path::Path,
utils::{dry_run_or_do, report_summary},
};
use std::{fs::write, path::Path};

/// Shared helper to generate, write, and log monorepo build configuration files.
fn write_mono_repo_config(
Expand All @@ -31,31 +28,15 @@ fn write_mono_repo_config(
io,
flags,
&format!("Generate {filename}"),
|| fs::write(&file_path, content).map_err(|e| e.to_string()),
|| write(&file_path, content).map_err(|e| e.to_string()),
)?;

// .to_string() is required to force an allocation and satisfy line coverage tracking
if flags.dry_run {
if flags.verbose {
#[allow(clippy::to_string_in_format_args)]
writeln!(
io.output,
" Would create root {} at {}\n",
filename.to_string(),
mono_dir.display()
)
.ok();
}
} else {
#[allow(clippy::to_string_in_format_args)]
writeln!(
io.output,
" Created root {} at {}\n",
filename.to_string(),
mono_dir.display()
)
.ok();
}
report_summary(
io,
flags,
&format!("create root {filename} at {}\n", mono_dir.display()),
&format!("Created root {filename} at {}\n", mono_dir.display()),
);

Ok(())
}
Expand Down Expand Up @@ -173,30 +154,10 @@ pub fn create_mono_repo_package_json(
if i == 0 {
continue;
}
let pkg_path = repos_path.join(dir).join("package.json");
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}\": \"*\""));
}
}
Err(_) => {
if flags.verbose {
writeln!(
io.output,
" Warning: malformed {dir}/package.json, skipping override"
)
.ok();
}
}
if let Some(json) = read_package_json(repos_path, dir, "skipping override", io, flags) {
if let Some(name) = json.get("name").and_then(|n| n.as_str()) {
overrides.push(format!(" \"{name}\": \"*\""));
}
} else if flags.verbose {
writeln!(
io.output,
" Warning: could not read {dir}/package.json, skipping override"
)
.ok();
}
}

Expand All @@ -218,26 +179,15 @@ pub fn create_mono_repo_package_json(
io,
flags,
"Generate package.json",
|| fs::write(&file_path, content).map_err(|e| e.to_string()),
|| write(&file_path, content).map_err(|e| e.to_string()),
)?;

if flags.dry_run {
if flags.verbose {
writeln!(
io.output,
" Would create root package.json at {}\n",
mono_dir.display()
)
.ok();
}
} else {
writeln!(
io.output,
" Created root package.json at {}\n",
mono_dir.display()
)
.ok();
}
report_summary(
io,
flags,
&format!("create root package.json at {}\n", mono_dir.display()),
&format!("Created root package.json at {}\n", mono_dir.display()),
);

Ok(())
}
2 changes: 2 additions & 0 deletions src/commands/mono/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ pub mod setup;
pub use setup::{build_repo_list, generate_mono_config};
pub mod watch;
pub use watch::{generate_watch_scripts, open_watch_scripts};
pub mod npm;
pub use npm::read_package_json;
2 changes: 1 addition & 1 deletion src/commands/mono/mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
config::SetupConfig,
ctx::RunCtx,
repository::{clone_repos, repo_dir_name},
utils::{dry_run::detect_or_dry_run, dry_run_or_do},
utils::{detect_or_dry_run, dry_run_or_do},
};
use std::{
fs,
Expand Down
40 changes: 40 additions & 0 deletions src/commands/mono/npm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use crate::ctx::{IoCtx, RunFlags};
use serde_json::{from_str, Value};
use std::{fs::read_to_string, path::Path};

/// Reads and parses `{repos_path}/{dir}/package.json`, warning (if verbose) and
/// returning `None` on I/O or parse failure.
pub fn read_package_json(
repos_path: &Path,
dir: &str,
skip_suffix: &str,
io: &mut IoCtx<'_>,
flags: RunFlags,
) -> Option<Value> {
let pkg_path = repos_path.join(dir).join("package.json");
match read_to_string(&pkg_path) {
Err(_) => {
if flags.verbose {
writeln!(
io.output,
" Warning: could not read {dir}/package.json, {skip_suffix}"
)
.ok();
}
None
}
Ok(content) => match from_str::<Value>(&content) {
Err(_) => {
if flags.verbose {
writeln!(
io.output,
" Warning: malformed {dir}/package.json, {skip_suffix}"
)
.ok();
}
None
}
Ok(json) => Some(json),
},
}
}
Loading
Loading