Skip to content

Commit ee04d1e

Browse files
committed
Migrate to new CLI structure.
1 parent 57b007f commit ee04d1e

35 files changed

Lines changed: 843 additions & 298 deletions

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ resolver = "2"
33
members = ["crates/*"]
44

55
[workspace.package]
6-
version = "0.2.0"
6+
version = "0.3.0"
77
edition = "2024"
88
authors = ["RubyElders.com"]
99
description = "A sophisticated Ruby environment manager that orchestrates installations and gem collections with distinguished precision"
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
pub mod config;
2+
pub mod env;
3+
pub mod project;
4+
pub mod runtime;
5+
6+
use rb_core::butler::{ButlerError, ButlerRuntime};
7+
use std::path::PathBuf;
8+
9+
use crate::InfoCommands;
10+
use crate::config::TrackedConfig;
11+
12+
pub fn info_command(
13+
command: &InfoCommands,
14+
butler_runtime: &ButlerRuntime,
15+
project_file: Option<PathBuf>,
16+
) -> Result<(), ButlerError> {
17+
match command {
18+
InfoCommands::Runtime => runtime::runtime_command(butler_runtime),
19+
InfoCommands::Env => env::environment_command(butler_runtime, project_file),
20+
InfoCommands::Project => project::project_command(butler_runtime, project_file),
21+
InfoCommands::Config => {
22+
// Config command doesn't actually need the runtime, but we have it available
23+
// For now, return an error - this will be handled specially in dispatch
24+
Err(ButlerError::General(
25+
"Config command should be handled in dispatch".to_string(),
26+
))
27+
}
28+
}
29+
}
30+
31+
/// Info command for config specifically (doesn't need runtime)
32+
pub fn info_config_command(config: &TrackedConfig) -> Result<(), ButlerError> {
33+
config::config_command(config)
34+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
use colored::*;
2+
use log::{debug, info};
3+
use rb_core::butler::{ButlerError, ButlerRuntime};
4+
use rb_core::project::{ProjectRuntime, RbprojectDetector};
5+
use std::path::PathBuf;
6+
7+
pub fn project_command(
8+
butler_runtime: &ButlerRuntime,
9+
project_file: Option<PathBuf>,
10+
) -> Result<(), ButlerError> {
11+
info!("Inspecting project configuration");
12+
present_project_info(butler_runtime, project_file)?;
13+
Ok(())
14+
}
15+
16+
fn present_project_info(
17+
butler_runtime: &ButlerRuntime,
18+
project_file: Option<PathBuf>,
19+
) -> Result<(), ButlerError> {
20+
println!("{}", "📁 Project Configuration".to_string().bold());
21+
println!();
22+
23+
// Load project file - either specified or discovered
24+
let project_runtime = if let Some(path) = project_file {
25+
debug!(
26+
"Loading project config from specified path: {}",
27+
path.display()
28+
);
29+
ProjectRuntime::from_file(&path).ok()
30+
} else {
31+
let current_dir = std::env::current_dir()
32+
.map_err(|e| ButlerError::General(format!("Failed to get current directory: {}", e)))?;
33+
RbprojectDetector::discover(current_dir.as_path())
34+
.ok()
35+
.flatten()
36+
};
37+
38+
match project_runtime {
39+
Some(project_runtime) => {
40+
println!(
41+
" {} {}",
42+
"Project File:".bold(),
43+
project_runtime.rbproject_path().display()
44+
);
45+
println!();
46+
47+
if let Some(name) = &project_runtime.metadata.name {
48+
println!(" {} {}", "Name:".bold(), name.cyan());
49+
}
50+
51+
if let Some(description) = &project_runtime.metadata.description {
52+
println!(" {} {}", "Description:".bold(), description.dimmed());
53+
}
54+
55+
if !project_runtime.scripts.is_empty() {
56+
println!();
57+
println!(" {}", "Scripts:".bold());
58+
for (name, script) in &project_runtime.scripts {
59+
if let Some(desc) = script.description() {
60+
println!(
61+
" {} → {} {}",
62+
name.cyan(),
63+
script.command().dimmed(),
64+
format!("({})", desc).bright_black()
65+
);
66+
} else {
67+
println!(" {} → {}", name.cyan(), script.command().dimmed());
68+
}
69+
}
70+
}
71+
}
72+
None => {
73+
println!(
74+
" {}",
75+
"No rbproject.toml found in current directory or parents".dimmed()
76+
);
77+
println!();
78+
println!(" {} Run {} to create one.", "Tip:".bold(), "rb new".cyan());
79+
}
80+
}
81+
82+
println!();
83+
84+
// Show effective configuration
85+
println!("{}", "🔧 Effective Configuration".to_string().bold());
86+
println!();
87+
println!(
88+
" {} {}",
89+
"Rubies Directory:".bold(),
90+
butler_runtime.rubies_dir().display()
91+
);
92+
93+
if let Some(gem_base) = butler_runtime.gem_base_dir() {
94+
println!(" {} {}", "Gem Home:".bold(), gem_base.display());
95+
}
96+
97+
if let Some(requested) = butler_runtime.requested_ruby_version() {
98+
println!(" {} {}", "Requested Ruby:".bold(), requested);
99+
}
100+
101+
println!();
102+
Ok(())
103+
}
File renamed without changes.

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

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
1-
pub mod config;
2-
pub mod environment;
31
pub mod exec;
42
pub mod help;
5-
pub mod init;
3+
pub mod info;
4+
pub mod new;
65
pub mod run;
7-
pub mod runtime;
86
pub mod shell_integration;
97
pub mod sync;
108
pub mod version;
119

12-
pub use config::config_command;
13-
pub use environment::environment_command;
1410
pub use exec::exec_command;
1511
pub use help::help_command;
16-
pub use init::init_command;
12+
pub use info::info_command;
13+
pub use new::init_command as new_command;
1714
pub use run::run_command;
18-
pub use runtime::runtime_command;
1915
pub use shell_integration::shell_integration_command;
2016
pub use sync::sync_command;
2117
pub use version::version_command;

crates/rb-cli/src/dispatch.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use crate::Commands;
2+
use crate::InfoCommands;
3+
use crate::commands::info::info_config_command;
24
use crate::commands::{
3-
config_command, environment_command, exec_command, help_command, run_command, runtime_command,
4-
sync_command, version_command,
5+
exec_command, help_command, info_command, run_command, sync_command, version_command,
56
};
67
use crate::runtime_helpers::CommandContext;
78
use rb_core::butler::ButlerError;
89

910
use crate::runtime_helpers::{
10-
bash_complete_command, init_command_wrapper, shell_integration_command_wrapper,
11+
bash_complete_command, new_command_wrapper, shell_integration_command_wrapper,
1112
with_butler_runtime,
1213
};
1314

@@ -20,28 +21,35 @@ pub fn dispatch_command(
2021
// Utility commands - no runtime needed
2122
Commands::Version => version_command(),
2223
Commands::Help { command: help_cmd } => help_command(help_cmd),
23-
Commands::Init => init_command_wrapper(),
24-
Commands::Config => config_command(&context.config),
24+
Commands::New => new_command_wrapper(),
2525
Commands::ShellIntegration { shell } => shell_integration_command_wrapper(shell),
2626
Commands::BashComplete { line, point } => bash_complete_command(context, &line, &point),
2727

28-
// Runtime commands - create ButlerRuntime lazily
29-
Commands::Runtime => with_butler_runtime(context, runtime_command),
30-
Commands::Environment => {
28+
// Workflow commands - create ButlerRuntime
29+
Commands::Run { script, args } => {
3130
let project_file = context.project_file.clone();
3231
with_butler_runtime(context, |runtime| {
33-
environment_command(runtime, project_file)
32+
run_command(runtime.clone(), script, args, project_file)
3433
})
3534
}
3635
Commands::Exec { args } => {
3736
with_butler_runtime(context, |runtime| exec_command(runtime.clone(), args))
3837
}
39-
Commands::Run { script, args } => {
40-
let project_file = context.project_file.clone();
41-
with_butler_runtime(context, |runtime| {
42-
run_command(runtime.clone(), script, args, project_file)
43-
})
44-
}
4538
Commands::Sync => with_butler_runtime(context, |runtime| sync_command(runtime.clone())),
39+
40+
// Diagnostic commands
41+
Commands::Info { command } => match command {
42+
InfoCommands::Config => {
43+
// Config doesn't need runtime, just the config
44+
info_config_command(&context.config)
45+
}
46+
_ => {
47+
// Other info commands need runtime
48+
let project_file = context.project_file.clone();
49+
with_butler_runtime(context, |runtime| {
50+
info_command(&command, runtime, project_file)
51+
})
52+
}
53+
},
4654
}
4755
}

0 commit comments

Comments
 (0)