Skip to content

Commit

Permalink
Make oss cli more polymorphic & shuffle some code around (#1117)
Browse files Browse the repository at this point in the history
* Make oss cli more polymorphic & shuffle some code around

* remove unneeded polymorphism

* factory public again

* clients public again

* remove profile auth
  • Loading branch information
mschuwalow authored Dec 4, 2024
1 parent 088694c commit 42d5d3c
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 96 deletions.
75 changes: 73 additions & 2 deletions golem-cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,23 @@ pub mod profile;
pub mod worker;

use crate::command::api_security::ApiSecuritySchemeSubcommand;
use crate::completion;
use crate::config::ProfileName;
use crate::diagnose::{self, diagnose};
use crate::examples;
use crate::init::{init_profile, CliKind, DummyProfileAuth};
use crate::model::{ComponentUriArg, GolemError, GolemResult};
use crate::oss::model::OssContext;
use crate::stubgen::handle_stubgen;
use api_definition::ApiDefinitionSubcommand;
use api_deployment::ApiDeploymentSubcommand;
use clap::{self, Subcommand};
use clap::{self, Command, Subcommand};
use component::ComponentSubCommand;
use golem_common::uri::oss::uri::ComponentUri;
use plugin::PluginSubcommand;
use profile::ProfileSubCommand;
use profile::{ProfileSubCommand, UniversalProfileAdd};
use std::future::Future;
use std::path::PathBuf;
use worker::WorkerSubcommand;

pub trait ComponentRefSplit<ProjectRef> {
Expand Down Expand Up @@ -80,6 +84,19 @@ impl<Ctx> CliCommand<Ctx> for EmptyCommand {
}
}

/// convenience function to get both the clap::Command and the parsed struct in one pass
pub fn command_and_parsed<T: clap::Parser>() -> (clap::Command, T) {
let mut command = T::command();

let mut matches = command.clone().get_matches();
let res = <T as clap::FromArgMatches>::from_arg_matches_mut(&mut matches)
.map_err(|e| e.format(&mut command));
match res {
Ok(t) => (command, t),
Err(e) => e.exit(),
}
}

/// Commands that are supported by both the OSS and Cloud version and have the same implementation
#[derive(Debug, Subcommand)]
pub enum StaticSharedCommand {
Expand Down Expand Up @@ -198,3 +215,57 @@ pub enum SharedCommand<
generator: clap_complete::Shell,
},
}

/// Context before the user has initialized the profile.
pub struct NoProfileCommandContext {
pub config_dir: PathBuf,
pub command: Command,
pub cli_kind: CliKind,
}

impl NoProfileCommandContext {
// \! is an experimental type. Once stable, use in the return type.
pub fn fail_uninitialized(&self) -> Result<GolemResult, GolemError> {
Err(GolemError(
"Your Golem CLI is not configured. Please run `golem-cli init`".to_owned(),
))
}
}

impl<
ProjectRef: clap::Args,
ComponentRef: clap::Args,
WorkerRef: clap::Args,
PluginScopeRef: clap::Args,
ProfileAdd: clap::Args + Into<UniversalProfileAdd>,
> CliCommand<NoProfileCommandContext>
for SharedCommand<ProjectRef, ComponentRef, WorkerRef, PluginScopeRef, ProfileAdd>
{
async fn run(self, ctx: NoProfileCommandContext) -> Result<GolemResult, GolemError> {
match self {
SharedCommand::Init {} => {
let profile_name = ProfileName::default(ctx.cli_kind);

init_profile(
ctx.cli_kind,
profile_name,
&ctx.config_dir,
&DummyProfileAuth,
)
.await?;

Ok(GolemResult::Str("Profile created".to_string()))
}
SharedCommand::Profile { subcommand } => {
subcommand
.handle(ctx.cli_kind, &ctx.config_dir, &DummyProfileAuth)
.await
}
SharedCommand::Completion { generator } => {
completion::print_completion(ctx.command, generator);
Ok(GolemResult::Str("".to_string()))
}
_ => ctx.fail_uninitialized(),
}
}
}
29 changes: 16 additions & 13 deletions golem-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,16 @@ use crate::config::{NamedProfile, Profile};
use crate::init::CliKind;
use crate::model::text::fmt::format_error;
use crate::service::version::{VersionCheckResult, VersionService};
use clap::CommandFactory;
use clap::Parser;
use clap_verbosity_flag::Verbosity;
use colored::Colorize;
use command::CliCommand;
use command::profile::OssProfileAdd;
use command::{CliCommand, NoProfileCommandContext};
use config::{get_config_dir, Config};
use golem_common::golem_version;
use indoc::eprintdoc;
use lenient_bool::LenientBool;
use log::Level;
use oss::main::GolemOssCli;
use oss::cli::{GolemOssCli, OssCommandContext};
use std::process::ExitCode;
use tracing::{info, warn};
use tracing_subscriber::FmtSubscriber;
Expand Down Expand Up @@ -111,9 +110,10 @@ pub async fn check_for_newer_server_version(
}
}

pub fn run_main<
ExtraCommands: CliCommand<oss::main::OssCommandContext> + CliCommand<oss::main::UnintializedOssCommandContext>,
>() -> ExitCode {
pub fn oss_main<ExtraCommands>() -> ExitCode
where
ExtraCommands: CliCommand<OssCommandContext> + CliCommand<NoProfileCommandContext>,
{
let config_dir = get_config_dir();

let oss_profile = match Config::get_active_profile(CliKind::Oss, &config_dir) {
Expand Down Expand Up @@ -141,13 +141,14 @@ pub fn run_main<
None => None,
};

let command = GolemOssCli::<ExtraCommands>::command();
let parsed = GolemOssCli::<ExtraCommands>::parse();
let (command, parsed) =
command::command_and_parsed::<GolemOssCli<OssProfileAdd, ExtraCommands>>();

let format = parsed
.format
.or_else(|| oss_profile.as_ref().map(|(_, p)| p.config.default_format))
.unwrap_or_default();

init_tracing(parsed.verbosity.clone());

info!(
Expand All @@ -161,13 +162,15 @@ pub fn run_main<
.build()
.expect("Failed to build tokio runtime for cli main");

let cli_kind = CliKind::Oss;

let result = if let Some((_, profile)) = oss_profile {
runtime.block_on(oss::main::run_with_profile(
format, config_dir, profile, command, parsed,
runtime.block_on(oss::cli::run_with_profile(
format, config_dir, profile, command, parsed, cli_kind,
))
} else {
runtime.block_on(oss::main::run_without_profile(
format, config_dir, command, parsed,
runtime.block_on(oss::cli::run_without_profile(
config_dir, command, parsed, cli_kind,
))
};

Expand Down
3 changes: 1 addition & 2 deletions golem-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use golem_cli::run_main;
use std::process::ExitCode;

fn main() -> ExitCode {
crate::run_main::<golem_cli::command::EmptyCommand>()
golem_cli::oss_main::<golem_cli::command::EmptyCommand>()
}
4 changes: 2 additions & 2 deletions golem-cli/src/oss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

pub mod cli;
pub mod clients;
pub mod factory;
pub mod main;
pub mod model;
pub mod resource;
mod resource;
Loading

0 comments on commit 42d5d3c

Please sign in to comment.