Skip to content

Commit

Permalink
just use subcommands instead of dynamic subcommands
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuel Thomas authored and Samuel Thomas committed Aug 15, 2024
1 parent 1493874 commit 4e7c221
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 107 deletions.
61 changes: 20 additions & 41 deletions fud2/fud-core/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::config;
use crate::exec::{plan, Driver, Request, StateRef};
use crate::run::Run;
use anyhow::{anyhow, bail};
use argh::{DynamicSubCommand, FromArgs};
use argh::{FromArgs, SubCommand};
use camino::Utf8PathBuf;
use std::fmt::Display;
use std::str::FromStr;
Expand Down Expand Up @@ -104,33 +104,16 @@ pub struct GetResource {
#[argh(subcommand, name = "list")]
pub struct ListCommand {}

pub struct DefaultDynamic {}

pub trait FakeDynamic: DynamicSubCommand {
pub trait FakeSubCommand: SubCommand {
fn run(&self, driver: &Driver) -> anyhow::Result<()>;
}

impl DynamicSubCommand for DefaultDynamic {
fn commands() -> &'static [&'static argh::CommandInfo] {
&[]
}

fn try_redact_arg_values(
_command_name: &[&str],
_args: &[&str],
) -> Option<Result<Vec<String>, argh::EarlyExit>> {
None
}

fn try_from_args(
_command_name: &[&str],
_args: &[&str],
) -> Option<Result<Self, argh::EarlyExit>> {
None
}
}
/// no extra command
#[derive(FromArgs)]
#[argh(subcommand, name = "none")]
pub struct DefaultDynamic {}

impl FakeDynamic for DefaultDynamic {
impl FakeSubCommand for DefaultDynamic {
fn run(&self, _driver: &Driver) -> anyhow::Result<()> {
Ok(())
}
Expand All @@ -141,7 +124,7 @@ impl FakeDynamic for DefaultDynamic {
#[argh(subcommand)]
pub enum Subcommand<T>
where
T: FakeDynamic,
T: FakeSubCommand,
{
/// edit the configuration file
EditConfig(EditConfig),
Expand All @@ -152,15 +135,14 @@ where
/// list the available states and ops
List(ListCommand),

#[argh(dynamic)]
Dynamic(T),
Extended(T),
}

#[derive(FromArgs)]
/// A generic compiler driver.
pub struct FakeArgs<T>
where
T: FakeDynamic,
T: FakeSubCommand,
{
#[argh(subcommand)]
pub sub: Option<Subcommand<T>>,
Expand Down Expand Up @@ -246,7 +228,7 @@ fn get_states_with_errors(
Ok(states)
}

fn from_states<T: FakeDynamic>(
fn from_states<T: FakeSubCommand>(
driver: &Driver,
args: &FakeArgs<T>,
) -> anyhow::Result<Vec<StateRef>> {
Expand All @@ -260,7 +242,7 @@ fn from_states<T: FakeDynamic>(
)
}

fn to_state<T: FakeDynamic>(
fn to_state<T: FakeSubCommand>(
driver: &Driver,
args: &FakeArgs<T>,
) -> anyhow::Result<Vec<StateRef>> {
Expand All @@ -274,7 +256,7 @@ fn to_state<T: FakeDynamic>(
)
}

fn get_request<T: FakeDynamic>(
fn get_request<T: FakeSubCommand>(
driver: &Driver,
args: &FakeArgs<T>,
) -> anyhow::Result<Request> {
Expand Down Expand Up @@ -362,8 +344,10 @@ fn get_resource(driver: &Driver, cmd: GetResource) -> anyhow::Result<()> {
}

/// Given the name of a Driver, returns a config based on that name and CLI arguments.
pub fn config_from_cli(name: &str) -> anyhow::Result<figment::Figment> {
let args: FakeArgs<DefaultDynamic> = argh::from_env();
pub fn config_from_cli<T: FakeSubCommand>(
name: &str,
) -> anyhow::Result<figment::Figment> {
let args: FakeArgs<T> = argh::from_env();
let mut config = config::load_config(name);

// Use `--set` arguments to override configuration values.
Expand All @@ -380,16 +364,11 @@ pub fn config_from_cli(name: &str) -> anyhow::Result<figment::Figment> {
Ok(config)
}

pub fn cli(driver: &Driver, config: &figment::Figment) -> anyhow::Result<()> {
let args: FakeArgs<DefaultDynamic> = argh::from_env();
cli_dynamic(args, driver, config)
}

pub fn cli_dynamic<T: FakeDynamic>(
args: FakeArgs<T>,
pub fn cli<T: FakeSubCommand>(
driver: &Driver,
config: &figment::Figment,
) -> anyhow::Result<()> {
let args: FakeArgs<T> = argh::from_env();
// Configure logging.
env_logger::Builder::new()
.format_timestamp(None)
Expand All @@ -409,7 +388,7 @@ pub fn cli_dynamic<T: FakeDynamic>(
driver.print_info();
return Ok(());
}
Some(Subcommand::Dynamic(cmd)) => {
Some(Subcommand::Extended(cmd)) => {
return cmd.run(driver);
}
None => {}
Expand Down
1 change: 1 addition & 0 deletions fud2/fud-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ pub mod run;
pub mod script;
pub mod utils;

pub use cli::DefaultDynamic;
pub use exec::{Driver, DriverBuilder};
69 changes: 7 additions & 62 deletions fud2/src/cli_pyenv.rs
Original file line number Diff line number Diff line change
@@ -1,69 +1,14 @@
use std::{fs, path::Path, process::Command, sync::OnceLock};
use std::{fs, path::Path, process::Command};

use argh::{CommandInfo, DynamicSubCommand, EarlyExit};
use fud_core::{cli::FakeDynamic, config};
use argh::FromArgs;
use fud_core::{cli::FakeSubCommand, config};

#[derive(PartialEq, Debug)]
/// initialize a fud2 python environment
#[derive(FromArgs)]
#[argh(subcommand, name = "env")]
pub struct PyenvCommand {}

impl DynamicSubCommand for PyenvCommand {
fn commands() -> &'static [&'static CommandInfo] {
static RET: OnceLock<Vec<&'static CommandInfo>> = OnceLock::new();
RET.get_or_init(|| {
let mut commands = Vec::new();

let env_cmdinfo = CommandInfo {
name: "env",
description: "initialize fud2 python environment",
};

commands.push(&*Box::leak(Box::new(env_cmdinfo)));

commands
})
}

fn try_redact_arg_values(
command_name: &[&str],
args: &[&str],
) -> Option<Result<Vec<String>, EarlyExit>> {
for command in Self::commands() {
if command_name.last() == Some(&command.name) {
// Process arguments and redact values here.
if !args.is_empty() {
return Some(Err(
"Our example dynamic command never takes arguments!"
.to_string()
.into(),
));
}
return Some(Ok(Vec::new()));
}
}
None
}

fn try_from_args(
command_name: &[&str],
args: &[&str],
) -> Option<Result<Self, EarlyExit>> {
for command in Self::commands() {
if command_name.last() == Some(&command.name) {
if !args.is_empty() {
return Some(Err(
"Our example dynamic command never takes arguments!"
.to_string()
.into(),
));
}
return Some(Ok(PyenvCommand {}));
}
}
None
}
}

impl FakeDynamic for PyenvCommand {
impl FakeSubCommand for PyenvCommand {
fn run(&self, driver: &fud_core::Driver) -> anyhow::Result<()> {
let data_dir = config::data_dir(&driver.name);

Expand Down
7 changes: 3 additions & 4 deletions fud2/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use fud2::PyenvCommand;
use fud_core::{
cli::{self, FakeArgs},
cli::{self},
DriverBuilder,
};

Expand Down Expand Up @@ -41,14 +41,13 @@ fn main() -> anyhow::Result<()> {
}

// Get config values from cli.
let config = cli::config_from_cli(&bld.name)?;
let config = cli::config_from_cli::<PyenvCommand>(&bld.name)?;

#[cfg(feature = "migrate_to_scripts")]
{
bld = bld.load_plugins(&config)?;
}

let driver = bld.build();
let args: FakeArgs<PyenvCommand> = argh::from_env();
cli::cli_dynamic(args, &driver, &config)
cli::cli::<PyenvCommand>(&driver, &config)
}

0 comments on commit 4e7c221

Please sign in to comment.