Skip to content

Commit

Permalink
feat: add --always-assist flag for canister call/install/deploy/sign (#…
Browse files Browse the repository at this point in the history
…3671)

* feat: add always-assist flag

* changelog
  • Loading branch information
chenyan-dfinity authored Mar 21, 2024
1 parent b0405ba commit 209f244
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 6 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ Note that the default value of `allow_raw_access` is still `true`.
Removed the logic for calling a different version of dfx based on DFX_VERSION or the `dfx` field in
dfx.json. This is now performed by dfxvm.

### feat: --always-assist flag for `dfx canister call/install/sign and dfx deploy`

When all the arguments are optional, dfx automatically provides a `null` value when no arguments are provided.
`--always-assist` flag enables the candid assist feature for optional arguments, instead of providing a default `null` value.

## Dependencies

### Replica
Expand Down
17 changes: 16 additions & 1 deletion src/dfx/src/commands/canister/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ pub struct CanisterCallOpts {
update: bool,

/// Specifies the config for generating random argument.
#[arg(long, conflicts_with("argument"), conflicts_with("argument_file"))]
#[arg(
long,
conflicts_with("argument"),
conflicts_with("argument_file"),
conflicts_with("always_assist")
)]
random: Option<String>,

/// Specifies the format for displaying the method's return result.
Expand All @@ -69,6 +74,15 @@ pub struct CanisterCallOpts {
/// for project canisters.
#[arg(long)]
candid: Option<PathBuf>,

/// Always use Candid assist when the argument types are all optional.
#[arg(
long,
conflicts_with("argument"),
conflicts_with("argument_file"),
conflicts_with("random")
)]
always_assist: bool,
}

#[derive(Clone, CandidType, Deserialize, Debug)]
Expand Down Expand Up @@ -282,6 +296,7 @@ pub async fn exec(
argument_type.as_deref(),
&method_type,
false,
opts.always_assist,
)?;

// amount has been validated by cycle_amount_validator
Expand Down
2 changes: 1 addition & 1 deletion src/dfx/src/commands/canister/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ async fn delete_canister(
"Installing temporary wallet in canister {} to enable transfer of cycles.",
canister
);
let args = blob_from_arguments(None, None, None, None, &None, false)?;
let args = blob_from_arguments(None, None, None, None, &None, false, false)?;
let mode = InstallMode::Reinstall;
let install_builder = mgr
.install_code(&canister_id, &wasm_module)
Expand Down
13 changes: 13 additions & 0 deletions src/dfx/src/commands/canister/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ pub struct CanisterInstallOpts {
/// Skips upgrading the asset canister, to only install the assets themselves.
#[arg(long)]
no_asset_upgrade: bool,

/// Always use Candid assist when the argument types are all optional.
#[arg(
long,
conflicts_with("argument"),
conflicts_with("argument_file"),
conflicts_with("yes")
)]
always_assist: bool,
}

pub async fn exec(
Expand Down Expand Up @@ -97,6 +106,7 @@ pub async fn exec(
argument_type.as_deref(),
&None,
true,
opts.always_assist,
)?;
let wasm_module = dfx_core::fs::read(wasm_path)?;
let mode = mode.context("The install mode cannot be auto when using --wasm")?;
Expand Down Expand Up @@ -157,6 +167,7 @@ pub async fn exec(
opts.yes,
None,
opts.no_asset_upgrade,
opts.always_assist,
)
.await
.map_err(Into::into)
Expand All @@ -176,6 +187,7 @@ pub async fn exec(
opts.yes,
env_file.as_deref(),
opts.no_asset_upgrade,
opts.always_assist,
)
.await
.map_err(Into::into)
Expand Down Expand Up @@ -219,6 +231,7 @@ pub async fn exec(
opts.yes,
env_file.as_deref(),
opts.no_asset_upgrade,
opts.always_assist,
)
.await?;
}
Expand Down
17 changes: 16 additions & 1 deletion src/dfx/src/commands/canister/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ pub struct CanisterSignOpts {
update: bool,

/// Specifies the config for generating random argument.
#[arg(long, conflicts_with("argument"), conflicts_with("argument_file"))]
#[arg(
long,
conflicts_with("argument"),
conflicts_with("argument_file"),
conflicts_with("always_assist")
)]
random: Option<String>,

/// Specifies how long the message will be valid in seconds, default to be 300s (5 minutes)
Expand All @@ -53,6 +58,15 @@ pub struct CanisterSignOpts {
/// Specifies the output file name.
#[arg(long, default_value = "message.json")]
file: PathBuf,

/// Always use Candid assist when the argument types are all optional.
#[arg(
long,
conflicts_with("argument"),
conflicts_with("argument_file"),
conflicts_with("random")
)]
always_assist: bool,
}

pub async fn exec(
Expand Down Expand Up @@ -99,6 +113,7 @@ pub async fn exec(
argument_type.as_deref(),
&method_type,
false,
opts.always_assist,
)?;
let agent = env.get_agent();

Expand Down
10 changes: 10 additions & 0 deletions src/dfx/src/commands/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ pub struct DeployOpts {

#[command(flatten)]
subnet_selection: SubnetSelectionOpt,

/// Always use Candid assist when the argument types are all optional.
#[arg(
long,
conflicts_with("argument"),
conflicts_with("argument_file"),
conflicts_with("yes")
)]
always_assist: bool,
}

pub fn exec(env: &dyn Environment, opts: DeployOpts) -> DfxResult {
Expand Down Expand Up @@ -192,6 +201,7 @@ pub fn exec(env: &dyn Environment, opts: DeployOpts) -> DfxResult {
env_file,
opts.no_asset_upgrade,
&mut subnet_selection,
opts.always_assist,
))?;

if matches!(deploy_mode, NormalDeploy | ForceReinstallSingleCanister(_)) {
Expand Down
2 changes: 1 addition & 1 deletion src/dfx/src/lib/integrations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub async fn initialize_integration_canister(
};
try_create_canister(agent, logger, &canister_id, &pulled_canister).await?;

let install_arg = blob_from_arguments(None, Some(init_arg), None, None, &None, true)?;
let install_arg = blob_from_arguments(None, Some(init_arg), None, None, &None, true, false)?;
install_canister(agent, logger, &canister_id, wasm, install_arg, name).await
}

Expand Down
5 changes: 5 additions & 0 deletions src/dfx/src/lib/operations/canister/deploy_canisters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub enum DeployMode {
}

#[context("Failed while trying to deploy canisters.")]
#[allow(clippy::too_many_arguments)]
pub async fn deploy_canisters(
env: &dyn Environment,
some_canister: Option<&str>,
Expand All @@ -55,6 +56,7 @@ pub async fn deploy_canisters(
env_file: Option<PathBuf>,
no_asset_upgrade: bool,
subnet_selection: &mut SubnetSelectionType,
always_assist: bool,
) -> DfxResult {
let log = env.get_logger();

Expand Down Expand Up @@ -156,6 +158,7 @@ pub async fn deploy_canisters(
skip_consent,
env_file.as_deref(),
no_asset_upgrade,
always_assist,
)
.await?;
info!(log, "Deployed canisters.");
Expand Down Expand Up @@ -307,6 +310,7 @@ async fn install_canisters(
skip_consent: bool,
env_file: Option<&Path>,
no_asset_upgrade: bool,
always_assist: bool,
) -> DfxResult {
info!(env.get_logger(), "Installing canisters...");

Expand Down Expand Up @@ -340,6 +344,7 @@ async fn install_canisters(
skip_consent,
env_file,
no_asset_upgrade,
always_assist,
)
.await?;
}
Expand Down
12 changes: 10 additions & 2 deletions src/dfx/src/lib/operations/canister/install_canister.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub async fn install_canister(
skip_consent: bool,
env_file: Option<&Path>,
no_asset_upgrade: bool,
always_assist: bool,
) -> DfxResult {
let log = env.get_logger();
let agent = env.get_agent();
Expand Down Expand Up @@ -165,8 +166,15 @@ The command line value will be used.",
(None, Some(_)) => (argument_from_json, Some("idl")), // `init_arg` in dfx.json is always in Candid format
(None, None) => (None, None),
};
let install_args =
blob_from_arguments(Some(env), argument, None, argument_type, &init_type, true)?;
let install_args = blob_from_arguments(
Some(env),
argument,
None,
argument_type,
&init_type,
true,
always_assist,
)?;
if let Some(timestamp) = canister_id_store.get_timestamp(canister_info.get_name()) {
let new_timestamp = playground_install_code(
env,
Expand Down
2 changes: 2 additions & 0 deletions src/dfx/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ pub fn blob_from_arguments(
arg_type: Option<&str>,
method_type: &Option<(TypeEnv, Function)>,
is_init_arg: bool,
always_assist: bool,
) -> DfxResult<Vec<u8>> {
let arg_type = arg_type.unwrap_or("idl");
match arg_type {
Expand Down Expand Up @@ -226,6 +227,7 @@ pub fn blob_from_arguments(
.args
.iter()
.all(|t| matches!(t.as_ref(), TypeInner::Opt(_)))
&& !always_assist
{
// If the user provided no arguments, and if all the expected arguments are
// optional, then use null values.
Expand Down

0 comments on commit 209f244

Please sign in to comment.