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
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "star-setup"
version = "0.2.0"
version = "0.2.1"
edition = "2021"
repository = "https://github.com/star-setup/core"
description = "Lightweight CLI to clone, configure, and wire single or multi-repo CMake ecosystems"
description = "Lightweight CLI to clone, configure, and wire single or multi-repo ecosystems"
homepage = "https://github.com/star-setup/core"
authors = ["Mason L'Etoile <contact@masonletoile.ca>"]

Expand Down
7 changes: 6 additions & 1 deletion src/cli/args.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{
cli::{
flags::{BuildFlags, ConfigFlags, ConnectionFlags, MonoRepoFlags, ProfileFlags},
flags::{
BuildFlags, ConfigFlags, ConnectionFlags, DiagnosticFlags, MonoRepoFlags, ProfileFlags,
},
resolve::resolve_with_config,
resolved::ResolvedArgs,
},
Expand Down Expand Up @@ -37,6 +39,9 @@ pub struct Args {

#[command(flatten)]
pub profile: ProfileFlags,

#[command(flatten)]
pub diagnostic: DiagnosticFlags,
}

impl Args {
Expand Down
70 changes: 38 additions & 32 deletions src/cli/build/detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,26 @@ pub fn detect_build_system(
dir: &Path,
input: &mut impl BufRead,
output: &mut impl Write,
timing: bool,
) -> Result<BuildSystem, String> {
let has_cmake = dir.join("CMakeLists.txt").exists();
let has_meson = dir.join("meson.build").exists();
match (has_cmake, has_meson) {
(true, false) => Ok(BuildSystem::Cmake),
(false, true) => Ok(BuildSystem::Meson),
(true, true) => match ask_choice(
"Multiple build systems detected:",
&["CMake", "Meson"],
input,
output,
)? {
0 => Ok(BuildSystem::Cmake),
_ => Ok(BuildSystem::Meson),
},
(false, false) => Err("No supported build system found".into()),
}
crate::time!(timing, output, "Detect", {
let has_cmake = dir.join("CMakeLists.txt").exists();
let has_meson = dir.join("meson.build").exists();
match (has_cmake, has_meson) {
(true, false) => Ok(BuildSystem::Cmake),
(false, true) => Ok(BuildSystem::Meson),
(true, true) => match ask_choice(
"Multiple build systems detected:",
&["CMake", "Meson"],
input,
output,
)? {
0 => Ok(BuildSystem::Cmake),
_ => Ok(BuildSystem::Meson),
},
(false, false) => Err("No supported build system found".into()),
}
})
}

/// Detects the build system consistently across all repo directories.
Expand All @@ -37,22 +40,25 @@ pub fn detect_mono_build_system(
dirs: &[PathBuf],
input: &mut impl BufRead,
output: &mut impl Write,
timing: bool,
) -> Result<BuildSystem, String> {
writeln!(output, "Detecting build system\n").ok();
let all_cmake = dirs.iter().all(|d| d.join("CMakeLists.txt").exists());
let all_meson = dirs.iter().all(|d| d.join("meson.build").exists());
match (all_cmake, all_meson) {
(true, false) => Ok(BuildSystem::Cmake),
(false, true) => Ok(BuildSystem::Meson),
(true, true) => match ask_choice(
"Multiple build systems detected:",
&["CMake", "Meson"],
input,
output,
)? {
0 => Ok(BuildSystem::Cmake),
_ => Ok(BuildSystem::Meson),
},
(false, false) => Err("Repositories have inconsistent or missing build systems".into()),
}
crate::time!(timing, output, "Detect", {
let all_cmake = dirs.iter().all(|d| d.join("CMakeLists.txt").exists());
let all_meson = dirs.iter().all(|d| d.join("meson.build").exists());
match (all_cmake, all_meson) {
(true, false) => Ok(BuildSystem::Cmake),
(false, true) => Ok(BuildSystem::Meson),
(true, true) => match ask_choice(
"Multiple build systems detected:",
&["CMake", "Meson"],
input,
output,
)? {
0 => Ok(BuildSystem::Cmake),
_ => Ok(BuildSystem::Meson),
},
(false, false) => Err("Repositories have inconsistent or missing build systems".into()),
}
})
}
7 changes: 7 additions & 0 deletions src/cli/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,10 @@ pub struct ProfileFlags {
#[arg(long)]
pub list_profiles: bool,
}

#[derive(ClapArgs)]
pub struct DiagnosticFlags {
/// Show timing information for each phase
#[arg(long)]
pub timing: bool,
}
9 changes: 7 additions & 2 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ pub mod args;
pub use args::Args;
pub mod build;
pub mod flags;
pub use flags::{BuildFlags, ConfigFlags, ConnectionFlags, MonoRepoFlags, ProfileFlags};
pub use flags::{
BuildFlags, ConfigFlags, ConnectionFlags, DiagnosticFlags, MonoRepoFlags, ProfileFlags,
};
pub mod resolve;
pub use resolve::{resolve_bool, resolve_with_config};
pub mod resolved;
pub use resolved::{ResolvedArgs, ResolvedBuildFlags, ResolvedConnectionFlags, ResolvedMonoFlags};
pub use resolved::{
ResolvedArgs, ResolvedBuildFlags, ResolvedConnectionFlags, ResolvedDiagnosticFlags,
ResolvedMonoFlags,
};
12 changes: 11 additions & 1 deletion src/cli/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use crate::{
cli::{
args::Args,
build::BuildType,
resolved::{ResolvedArgs, ResolvedBuildFlags, ResolvedConnectionFlags, ResolvedMonoFlags},
resolved::{
ResolvedArgs, ResolvedBuildFlags, ResolvedConnectionFlags, ResolvedDiagnosticFlags,
ResolvedMonoFlags,
},
},
config::types::SetupConfig,
};
Expand Down Expand Up @@ -45,6 +48,12 @@ pub fn resolve_with_config(mut args: Args, config: &SetupConfig) -> Result<Resol
default.map(|e| e.verbose),
false,
);
let timing = resolve_bool(
args.diagnostic.timing,
false,
default.map(|e| e.timing),
false,
);
let no_build = resolve_bool(
args.build.no_build,
args.build.build,
Expand Down Expand Up @@ -72,6 +81,7 @@ pub fn resolve_with_config(mut args: Args, config: &SetupConfig) -> Result<Resol
repo: args.repo,
yes: args.yes,
connection: ResolvedConnectionFlags { ssh, verbose },
diagnostic: ResolvedDiagnosticFlags { timing },
build: ResolvedBuildFlags {
build_type: if let Some(s) = args.build.build_type {
s.parse::<BuildType>()?
Expand Down
6 changes: 6 additions & 0 deletions src/cli/resolved.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ pub struct ResolvedConnectionFlags {
pub verbose: bool,
}

/// Resolved diagnostic flags after applying config and CLI overrides.
pub struct ResolvedDiagnosticFlags {
pub timing: bool,
}

/// Resolved build flags after applying config and CLI overrides.
pub struct ResolvedBuildFlags {
pub build_type: BuildType,
Expand All @@ -32,6 +37,7 @@ pub struct ResolvedArgs {
pub repo: Option<String>,
pub yes: bool,
pub connection: ResolvedConnectionFlags,
pub diagnostic: ResolvedDiagnosticFlags,
pub build: ResolvedBuildFlags,
pub mono: ResolvedMonoFlags,
pub config: ConfigFlags,
Expand Down
74 changes: 44 additions & 30 deletions src/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub fn cmake_build(
build_path: &Path,
mono: bool,
output: &mut impl Write,
timing: bool,
) -> Result<(), String> {
let build_type_flag = format!("-DCMAKE_BUILD_TYPE={}", args.build.build_type.to_cmake());
let mut cmake_cmd = if mono {
Expand All @@ -26,26 +27,32 @@ pub fn cmake_build(
vec!["cmake", "..", &build_type_flag]
};
cmake_cmd.extend(args.build.cmake_flags.iter().map(String::as_str));
run_command(
&cmake_cmd,
Some(build_path),
args.connection.verbose,
output,
)?;
if !args.build.no_build {
writeln!(output, "Building project\n").ok();

crate::time!(timing, output, "CMake configure", {
run_command(
&[
"cmake",
"--build",
".",
"--config",
args.build.build_type.to_cmake(),
],
&cmake_cmd,
Some(build_path),
args.connection.verbose,
output,
)?;
});

if !args.build.no_build {
writeln!(output, "Building project\n").ok();
crate::time!(timing, output, "CMake build", {
run_command(
&[
"cmake",
"--build",
".",
"--config",
args.build.build_type.to_cmake(),
],
Some(build_path),
args.connection.verbose,
output,
)?;
});
}
Ok(())
}
Expand All @@ -58,27 +65,33 @@ pub fn meson_build(
build_path: &Path,
source_path: &Path,
output: &mut impl Write,
timing: bool,
) -> Result<(), String> {
let buildtype_flag = format!("--buildtype={}", args.build.build_type.to_meson());
let mut meson_cmd = vec!["meson", "setup"];
meson_cmd.push(&buildtype_flag);
meson_cmd.push(build_path.to_str().ok_or("Invalid build path")?);
meson_cmd.push(source_path.to_str().ok_or("Invalid source path")?);
meson_cmd.extend(args.build.meson_flags.iter().map(String::as_str));
run_command(&meson_cmd, None, args.connection.verbose, output)?;

crate::time!(timing, output, "Meson setup", {
run_command(&meson_cmd, None, args.connection.verbose, output)?;
});
if !args.build.no_build {
writeln!(output, "Building project\n").ok();
run_command(
&[
"meson",
"compile",
"-C",
build_path.to_str().ok_or("Invalid build path")?,
],
None,
args.connection.verbose,
output,
)?;
crate::time!(timing, output, "Meson compile", {
run_command(
&[
"meson",
"compile",
"-C",
build_path.to_str().ok_or("Invalid build path")?,
],
None,
args.connection.verbose,
output,
)?;
});
}
Ok(())
}
Expand All @@ -93,9 +106,10 @@ pub fn build_project(
mono: bool,
input: &mut impl BufRead,
output: &mut impl Write,
timing: bool,
) -> Result<(), String> {
match detect_build_system(source_path, input, output)? {
BuildSystem::Cmake => cmake_build(args, build_path, mono, output),
BuildSystem::Meson => meson_build(args, build_path, source_path, output),
match detect_build_system(source_path, input, output, timing)? {
BuildSystem::Cmake => cmake_build(args, build_path, mono, output, timing),
BuildSystem::Meson => meson_build(args, build_path, source_path, output, timing),
}
}
11 changes: 9 additions & 2 deletions src/commands/mono/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ fn write_mono_repo_config(
mono_dir: &Path,
repos: &[String],
output: &mut impl Write,
timing: bool,
filename: &str,
format_modules: impl Fn(&[String]) -> String,
render_template: impl Fn(&str) -> String,
) -> Result<(), String> {
let module_names: Vec<String> = repos.iter().map(|r| repo_dir_name(r)).collect();
let modules_str = format_modules(&module_names);

let content = render_template(&modules_str);
let file_path = mono_dir.join(filename);
fs::write(&file_path, content).map_err(|e| e.to_string())?;

crate::time!(timing, output, &format!("Generate {filename}"), {
fs::write(&file_path, content).map_err(|e| e.to_string())?;
});

// .to_string() is required to force an allocation and satisfy line coverage tracking
#[allow(clippy::to_string_in_format_args)]
Expand All @@ -37,12 +40,14 @@ pub fn create_mono_repo_cmakelists(
mono_dir: &Path,
repos: &[String],
output: &mut impl Write,
timing: bool,
) -> Result<(), String> {
writeln!(output, " Creating CMake configuration").ok();
write_mono_repo_config(
mono_dir,
repos,
output,
timing,
"CMakeLists.txt",
|modules| modules.join("\n "),
|modules_cmake| {
Expand Down Expand Up @@ -79,12 +84,14 @@ pub fn create_mono_repo_mesonbuild(
mono_dir: &Path,
repos: &[String],
output: &mut impl Write,
timing: bool,
) -> Result<(), String> {
writeln!(output, " Creating Meson configuration").ok();
write_mono_repo_config(
mono_dir,
repos,
output,
timing,
"meson.build",
|modules| {
modules
Expand Down
Loading
Loading