From c955d9ded0de46e0fa64885a0b655921218867ae Mon Sep 17 00:00:00 2001 From: Hans Larsen Date: Fri, 10 Jan 2020 08:40:43 -0800 Subject: [PATCH] feat: add a --client flag to the canister This means it be invoked like so: ``` dfx canister --client http://client_host:1234 install --all ``` (or any canister subcommand). --- src/dfx/src/commands/canister/mod.rs | 28 +++++++++++++++++-- src/dfx/src/lib/environment.rs | 42 ++++++++++++++++++++++++++++ src/dfx/src/lib/message.rs | 1 + 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/dfx/src/commands/canister/mod.rs b/src/dfx/src/commands/canister/mod.rs index 5f19f62dca..fc3562f556 100644 --- a/src/dfx/src/commands/canister/mod.rs +++ b/src/dfx/src/commands/canister/mod.rs @@ -1,8 +1,8 @@ use crate::commands::CliCommand; -use crate::lib::environment::Environment; +use crate::lib::environment::{ClientEnvironment, Environment}; use crate::lib::error::{DfxError, DfxResult}; use crate::lib::message::UserMessage; -use clap::{App, ArgMatches, SubCommand}; +use clap::{App, Arg, ArgMatches, ArgSettings, SubCommand}; mod call; mod install; @@ -21,12 +21,36 @@ fn builtins() -> Vec { pub fn construct() -> App<'static, 'static> { SubCommand::with_name("canister") .about(UserMessage::ManageCanister.to_str()) + .arg( + Arg::with_name("client") + .set(ArgSettings::Global) + .help(UserMessage::CanisterClient.to_str()) + .long("client") + .validator(|v| { + reqwest::Url::parse(&v) + .map(|_| ()) + .map_err(|_| "should be a valid URL.".to_string()) + }) + .takes_value(true), + ) .subcommands(builtins().into_iter().map(|x| x.get_subcommand().clone())) } pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult { let subcommand = args.subcommand(); + // Need storage for ClientEnvironment ownership. + let mut _client_env: Option> = None; + let env = if args.is_present("client") { + _client_env = Some(ClientEnvironment::new( + env, + args.value_of("client").expect("Could not find client."), + )); + _client_env.as_ref().unwrap() + } else { + env + }; + if let (name, Some(subcommand_args)) = subcommand { match builtins().into_iter().find(|x| name == x.get_name()) { Some(cmd) => cmd.execute(env, subcommand_args), diff --git a/src/dfx/src/lib/environment.rs b/src/dfx/src/lib/environment.rs index 7a669f3c29..f543228428 100644 --- a/src/dfx/src/lib/environment.rs +++ b/src/dfx/src/lib/environment.rs @@ -116,3 +116,45 @@ impl Environment for EnvironmentImpl { self.get_client() } } + +pub struct ClientEnvironment<'a> { + backend: &'a dyn Environment, + client: Client, +} + +impl<'a> ClientEnvironment<'a> { + pub fn new(backend: &'a dyn Environment, client_url: &str) -> Self { + ClientEnvironment { + backend, + client: Client::new(ClientConfig { + url: client_url.to_string(), + }), + } + } +} + +impl<'a> Environment for ClientEnvironment<'a> { + fn get_cache(&self) -> Rc { + self.backend.get_cache() + } + + fn get_config(&self) -> Option> { + self.backend.get_config() + } + + fn is_in_project(&self) -> bool { + self.backend.is_in_project() + } + + fn get_temp_dir(&self) -> &Path { + self.backend.get_temp_dir() + } + + fn get_version(&self) -> &Version { + self.backend.get_version() + } + + fn get_client(&self) -> Option { + Some(self.client.clone()) + } +} diff --git a/src/dfx/src/lib/message.rs b/src/dfx/src/lib/message.rs index 20f02a9e9b..6b09c48de6 100644 --- a/src/dfx/src/lib/message.rs +++ b/src/dfx/src/lib/message.rs @@ -39,6 +39,7 @@ user_message!( // dfx canister mod ManageCanister => "Manages canisters deployed on a network client.", + CanisterClient => "Override the client to connect to. By default uses the client set in dfx configuration.", // dfx canister query QueryCanister => "Sends a query request to a canister.",