Skip to content

Commit 35ec207

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

35 files changed

Lines changed: 816 additions & 301 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::config::TrackedConfig;
10+
use crate::InfoCommands;
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: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
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(butler_runtime: &ButlerRuntime, project_file: Option<PathBuf>) -> Result<(), ButlerError> {
8+
info!("Inspecting project configuration");
9+
present_project_info(butler_runtime, project_file)?;
10+
Ok(())
11+
}
12+
13+
fn present_project_info(butler_runtime: &ButlerRuntime, project_file: Option<PathBuf>) -> Result<(), ButlerError> {
14+
println!("{}", "📁 Project Configuration".to_string().bold());
15+
println!();
16+
17+
// Load project file - either specified or discovered
18+
let project_runtime = if let Some(path) = project_file {
19+
debug!("Loading project config from specified path: {}", path.display());
20+
ProjectRuntime::from_file(&path).ok()
21+
} else {
22+
let current_dir = std::env::current_dir().map_err(|e| {
23+
ButlerError::General(format!("Failed to get current directory: {}", e))
24+
})?;
25+
RbprojectDetector::discover(current_dir.as_path()).ok().flatten()
26+
};
27+
28+
match project_runtime {
29+
Some(project_runtime) => {
30+
println!(
31+
" {} {}",
32+
"Project File:".bold(),
33+
project_runtime.rbproject_path().display()
34+
);
35+
println!();
36+
37+
if let Some(name) = &project_runtime.metadata.name {
38+
println!(" {} {}", "Name:".bold(), name.cyan());
39+
}
40+
41+
if let Some(description) = &project_runtime.metadata.description {
42+
println!(" {} {}", "Description:".bold(), description.dimmed());
43+
}
44+
45+
if !project_runtime.scripts.is_empty() {
46+
println!();
47+
println!(" {}", "Scripts:".bold());
48+
for (name, script) in &project_runtime.scripts {
49+
if let Some(desc) = script.description() {
50+
println!(
51+
" {} → {} {}",
52+
name.cyan(),
53+
script.command().dimmed(),
54+
format!("({})", desc).bright_black()
55+
);
56+
} else {
57+
println!(" {} → {}", name.cyan(), script.command().dimmed());
58+
}
59+
}
60+
}
61+
}
62+
None => {
63+
println!(
64+
" {}",
65+
"No rbproject.toml found in current directory or parents".dimmed()
66+
);
67+
println!();
68+
println!(" {} Run {} to create one.", "Tip:".bold(), "rb new".cyan());
69+
}
70+
}
71+
72+
println!();
73+
74+
// Show effective configuration
75+
println!("{}", "🔧 Effective Configuration".to_string().bold());
76+
println!();
77+
println!(
78+
" {} {}",
79+
"Rubies Directory:".bold(),
80+
butler_runtime.rubies_dir().display()
81+
);
82+
83+
if let Some(gem_base) = butler_runtime.gem_base_dir() {
84+
println!(" {} {}", "Gem Home:".bold(), gem_base.display());
85+
}
86+
87+
if let Some(requested) = butler_runtime.requested_ruby_version() {
88+
println!(" {} {}", "Requested Ruby:".bold(), requested);
89+
}
90+
91+
println!();
92+
Ok(())
93+
}
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: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
use crate::Commands;
2-
use crate::commands::{
3-
config_command, environment_command, exec_command, help_command, run_command, runtime_command,
4-
sync_command, version_command,
5-
};
2+
use crate::commands::{exec_command, help_command, info_command, run_command, sync_command, version_command};
3+
use crate::commands::info::info_config_command;
64
use crate::runtime_helpers::CommandContext;
5+
use crate::InfoCommands;
76
use rb_core::butler::ButlerError;
87

98
use crate::runtime_helpers::{
10-
bash_complete_command, init_command_wrapper, shell_integration_command_wrapper,
9+
bash_complete_command, new_command_wrapper, shell_integration_command_wrapper,
1110
with_butler_runtime,
1211
};
1312

@@ -20,28 +19,33 @@ pub fn dispatch_command(
2019
// Utility commands - no runtime needed
2120
Commands::Version => version_command(),
2221
Commands::Help { command: help_cmd } => help_command(help_cmd),
23-
Commands::Init => init_command_wrapper(),
24-
Commands::Config => config_command(&context.config),
22+
Commands::New => new_command_wrapper(),
2523
Commands::ShellIntegration { shell } => shell_integration_command_wrapper(shell),
2624
Commands::BashComplete { line, point } => bash_complete_command(context, &line, &point),
2725

28-
// Runtime commands - create ButlerRuntime lazily
29-
Commands::Runtime => with_butler_runtime(context, runtime_command),
30-
Commands::Environment => {
26+
// Workflow commands - create ButlerRuntime
27+
Commands::Run { script, args } => {
3128
let project_file = context.project_file.clone();
3229
with_butler_runtime(context, |runtime| {
33-
environment_command(runtime, project_file)
30+
run_command(runtime.clone(), script, args, project_file)
3431
})
3532
}
3633
Commands::Exec { args } => {
3734
with_butler_runtime(context, |runtime| exec_command(runtime.clone(), args))
3835
}
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-
}
4536
Commands::Sync => with_butler_runtime(context, |runtime| sync_command(runtime.clone())),
37+
38+
// Diagnostic commands
39+
Commands::Info { command } => match command {
40+
InfoCommands::Config => {
41+
// Config doesn't need runtime, just the config
42+
info_config_command(&context.config)
43+
}
44+
_ => {
45+
// Other info commands need runtime
46+
let project_file = context.project_file.clone();
47+
with_butler_runtime(context, |runtime| info_command(&command, runtime, project_file))
48+
}
49+
},
4650
}
4751
}

0 commit comments

Comments
 (0)