Skip to content

Commit 867bd4c

Browse files
committed
Add rbproject.toml basic support.
1 parent 7c0e88c commit 867bd4c

File tree

13 files changed

+1888
-432
lines changed

13 files changed

+1888
-432
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/rb-cli/src/bin/rb.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ fn main() {
119119
runtime_command(&butler_runtime);
120120
}
121121
Commands::Environment => {
122-
environment_command(&butler_runtime);
122+
environment_command(&butler_runtime, cli.project_file);
123123
}
124124
Commands::Exec { args } => {
125125
exec_command(butler_runtime, args);

crates/rb-cli/src/commands/environment.rs

Lines changed: 182 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
use colored::*;
2-
use log::{debug, info};
2+
use log::{debug, info, warn};
33
use rb_core::bundler::BundlerRuntime;
44
use rb_core::butler::ButlerRuntime;
5+
use rb_core::project::{ProjectRuntime, RbprojectDetector};
56
use rb_core::ruby::RubyType;
7+
use std::path::PathBuf;
68

7-
pub fn environment_command(butler_runtime: &ButlerRuntime) {
9+
pub fn environment_command(butler_runtime: &ButlerRuntime, project_file: Option<PathBuf>) {
810
info!("Presenting current Ruby environment from the working directory");
9-
present_current_environment(butler_runtime);
11+
present_current_environment(butler_runtime, project_file);
1012
}
1113

12-
fn present_current_environment(butler_runtime: &ButlerRuntime) {
14+
fn present_current_environment(butler_runtime: &ButlerRuntime, project_file: Option<PathBuf>) {
1315
println!("{}", "🌍 Your Current Ruby Environment".to_string().bold());
1416
println!();
1517

@@ -26,14 +28,59 @@ fn present_current_environment(butler_runtime: &ButlerRuntime) {
2628
// Get gem runtime from butler runtime
2729
let gem_runtime = butler_runtime.gem_runtime();
2830

31+
// Detect or load project runtime
32+
let project_runtime = if let Some(path) = project_file {
33+
// Use specified project file
34+
debug!(
35+
"Loading rbproject.toml from specified path: {}",
36+
path.display()
37+
);
38+
match ProjectRuntime::from_file(&path) {
39+
Ok(project) => {
40+
debug!(
41+
"Loaded rbproject.toml with {} scripts",
42+
project.scripts.len()
43+
);
44+
Some(project)
45+
}
46+
Err(e) => {
47+
warn!(
48+
"Failed to load specified rbproject.toml at {}: {}",
49+
path.display(),
50+
e
51+
);
52+
None
53+
}
54+
}
55+
} else {
56+
// Auto-detect project file
57+
RbprojectDetector::discover(current_dir)
58+
.ok()
59+
.flatten()
60+
.map(|project| {
61+
debug!(
62+
"Discovered rbproject.toml with {} scripts",
63+
project.scripts.len()
64+
);
65+
project
66+
})
67+
};
68+
2969
// Present the environment
30-
present_environment_details(ruby, gem_runtime, bundler_runtime, butler_runtime);
70+
present_environment_details(
71+
ruby,
72+
gem_runtime,
73+
bundler_runtime,
74+
project_runtime.as_ref(),
75+
butler_runtime,
76+
);
3177
}
3278

3379
fn present_environment_details(
3480
ruby: &rb_core::ruby::RubyRuntime,
3581
gem_runtime: Option<&rb_core::gems::GemRuntime>,
3682
bundler_runtime: Option<&BundlerRuntime>,
83+
project_runtime: Option<&ProjectRuntime>,
3784
butler: &ButlerRuntime,
3885
) {
3986
let label_width = [
@@ -189,6 +236,79 @@ fn present_environment_details(
189236
println!(" {}", "Bundler environment not detected".bright_black());
190237
}
191238

239+
// Present Project Environment (if detected)
240+
if let Some(project) = project_runtime {
241+
println!();
242+
println!("{}", "📋 Project".green().bold());
243+
244+
// Display project name if available
245+
if let Some(name) = &project.metadata.name {
246+
println!(
247+
" {:<width$}: {}",
248+
"Name".bright_blue().bold(),
249+
name.bright_black(),
250+
width = label_width
251+
);
252+
}
253+
254+
// Display project description if available
255+
if let Some(description) = &project.metadata.description {
256+
println!(
257+
" {:<width$}: {}",
258+
"Description".bright_blue().bold(),
259+
description.bright_black(),
260+
width = label_width
261+
);
262+
}
263+
264+
println!(
265+
" {:<width$}: {}",
266+
"Project file".bright_blue().bold(),
267+
project
268+
.rbproject_path()
269+
.display()
270+
.to_string()
271+
.bright_black(),
272+
width = label_width
273+
);
274+
275+
println!(
276+
" {:<width$}: {}",
277+
"Scripts loaded".bright_blue().bold(),
278+
format!("{}", project.scripts.len()).bright_black(),
279+
width = label_width
280+
);
281+
282+
if !project.scripts.is_empty() {
283+
println!();
284+
println!(" {}", "Available Scripts:".bright_blue().bold());
285+
286+
// Get sorted script names for consistent display
287+
let script_names = project.script_names();
288+
for name in script_names {
289+
let script = project.get_script(name).unwrap();
290+
let command = script.command();
291+
292+
// Always show: name → command
293+
println!(
294+
" {} {} {}",
295+
name.cyan().bold(),
296+
"→".bright_black(),
297+
command.to_string().bright_black()
298+
);
299+
300+
// Optionally show description on next line with more indent
301+
if let Some(description) = script.description() {
302+
println!(" {}", description.bright_black().italic());
303+
}
304+
}
305+
}
306+
} else {
307+
println!();
308+
println!("{}", "📋 Project Scripts".bright_black());
309+
println!(" {}", "No rbproject.toml detected".bright_black());
310+
}
311+
192312
// Present environment summary
193313
println!();
194314
println!("{}", "🎯 Environment Summary".green().bold());
@@ -262,7 +382,7 @@ mod tests {
262382
.expect("Failed to create butler runtime with test Ruby");
263383

264384
// This will handle the environment presentation gracefully
265-
environment_command(&butler_runtime);
385+
environment_command(&butler_runtime, None);
266386
}
267387

268388
#[test]
@@ -283,7 +403,7 @@ mod tests {
283403
let butler = ButlerRuntime::new(ruby.clone(), Some(gem_runtime.clone()));
284404

285405
// Test with no bundler environment
286-
present_environment_details(&ruby, Some(&gem_runtime), None, &butler);
406+
present_environment_details(&ruby, Some(&gem_runtime), None, None, &butler);
287407

288408
Ok(())
289409
}
@@ -310,7 +430,61 @@ mod tests {
310430
let butler = ButlerRuntime::new(ruby.clone(), Some(gem_runtime.clone()));
311431

312432
// Test with bundler environment
313-
present_environment_details(&ruby, Some(&gem_runtime), Some(&bundler_runtime), &butler);
433+
present_environment_details(
434+
&ruby,
435+
Some(&gem_runtime),
436+
Some(&bundler_runtime),
437+
None,
438+
&butler,
439+
);
440+
441+
Ok(())
442+
}
443+
444+
#[test]
445+
fn present_environment_details_with_project() -> std::io::Result<()> {
446+
use rb_core::gems::GemRuntime;
447+
use rb_core::project::{ProjectMetadata, ScriptDefinition};
448+
use rb_tests::RubySandbox;
449+
use std::collections::HashMap;
450+
451+
let ruby_sandbox = RubySandbox::new()?;
452+
let ruby_dir = ruby_sandbox.add_ruby_dir("3.2.5")?;
453+
let ruby = rb_core::ruby::RubyRuntime::new(
454+
rb_core::ruby::RubyType::CRuby,
455+
semver::Version::parse("3.2.5").unwrap(),
456+
&ruby_dir,
457+
);
458+
459+
// Create a project runtime with some scripts
460+
let mut scripts = HashMap::new();
461+
scripts.insert(
462+
"test".to_string(),
463+
ScriptDefinition::Detailed {
464+
command: "rspec".to_string(),
465+
description: Some("Run the test suite".to_string()),
466+
},
467+
);
468+
scripts.insert(
469+
"lint:fix".to_string(),
470+
ScriptDefinition::Simple("rubocop -a".to_string()),
471+
);
472+
473+
let metadata = ProjectMetadata::default();
474+
let project_runtime = ProjectRuntime::new(ruby_sandbox.root(), metadata, scripts);
475+
476+
// Use sandboxed gem directory
477+
let gem_runtime = GemRuntime::for_base_dir(&ruby_sandbox.gem_base_dir(), &ruby.version);
478+
let butler = ButlerRuntime::new(ruby.clone(), Some(gem_runtime.clone()));
479+
480+
// Test with project environment
481+
present_environment_details(
482+
&ruby,
483+
Some(&gem_runtime),
484+
None,
485+
Some(&project_runtime),
486+
&butler,
487+
);
314488

315489
Ok(())
316490
}

0 commit comments

Comments
 (0)