Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 34 additions & 20 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/dfx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ actix-cors = "0.4.0"
actix-files = "0.3.0"
actix-server = "1.0.4"
actix-web = { version = "3.0.2", features = [ "default", "openssl", "rustls" ] }
anyhow = "1.0.34"
atty = "0.2.13"
base64 = "0.11.0"
candid = "0.6.7"
chrono = "0.4.9"
clap = "2.33.0"
clap = "3.0.0-beta.2"
console = "0.7.7"
crossbeam = "0.7.3"
ctrlc = { version = "3.1.6", features = [ "termination" ] }
Expand Down
101 changes: 46 additions & 55 deletions src/dfx/src/commands/bootstrap.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use crate::config::dfinity::{ConfigDefaults, ConfigDefaultsBootstrap};
use crate::lib::environment::Environment;
use crate::lib::error::{DfxError, DfxResult};
use crate::lib::message::UserMessage;
use crate::lib::network::network_descriptor::NetworkDescriptor;
use crate::lib::provider::get_network_descriptor;
use crate::lib::webserver::webserver;
use crate::util::get_reusable_socket_addr;
use clap::{App, Arg, ArgMatches, SubCommand};
use clap::{App, ArgMatches, Clap, FromArgMatches, IntoApp};
use slog::info;
use std::default::Default;
use std::fs;
Expand All @@ -17,53 +16,48 @@ use std::str::FromStr;
use std::time::Duration;
use url::Url;

/// Constructs a sub-command to run the bootstrap server.
pub fn construct() -> App<'static, 'static> {
SubCommand::with_name("bootstrap")
.about(UserMessage::BootstrapCommand.to_str())
.arg(
Arg::with_name("ip")
.help(UserMessage::BootstrapIP.to_str())
.long("ip")
.takes_value(true),
)
.arg(
Arg::with_name("port")
.help(UserMessage::BootstrapPort.to_str())
.long("port")
.takes_value(true),
)
.arg(
Arg::with_name("network")
.help(UserMessage::CanisterComputeNetwork.to_str())
.long("network")
.takes_value(true),
)
.arg(
Arg::with_name("root")
.help(UserMessage::BootstrapRoot.to_str())
.long("root")
.takes_value(true),
)
.arg(
Arg::with_name("timeout")
.help(UserMessage::BootstrapTimeout.to_str())
.long("timeout")
.takes_value(true),
)
/// Starts the bootstrap server.
#[derive(Clap, Clone)]
pub struct BootstrapOpts {
/// Specifies the IP address that the bootstrap server listens on. Defaults to 127.0.0.1.
#[clap(long)]
ip: Option<String>,

/// Specifies the port number that the bootstrap server listens on. Defaults to 8081.
#[clap(long)]
port: Option<String>,

/// Override the compute network to connect to. By default, the local network is used.
#[clap(long)]
network: Option<String>,

/// Specifies the directory containing static assets served by the bootstrap server.
/// Defaults to $HOME/.cache/dfinity/versions/$DFX_VERSION/js-user-library/dist/bootstrap.",
#[clap(long)]
root: Option<String>,

/// Specifies the maximum number of seconds that the bootstrap server
/// will wait for upstream requests to complete. Defaults to 30.",
#[clap(long)]
timeout: Option<String>,
}

pub fn construct() -> App<'static> {
BootstrapOpts::into_app().name("bootstrap")
}

/// Runs the bootstrap server.
pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
pub fn exec(env: &dyn Environment, args: &ArgMatches) -> DfxResult {
let opts: BootstrapOpts = BootstrapOpts::from_arg_matches(args);
let logger = env.get_logger();
let config = env
.get_config()
.ok_or(DfxError::CommandMustBeRunInAProject)?;
let config_defaults = get_config_defaults_from_file(env);
let base_config_bootstrap = config_defaults.get_bootstrap().to_owned();
let config_bootstrap = apply_arguments(&base_config_bootstrap, env, args)?;
let config_bootstrap = apply_arguments(&base_config_bootstrap, env, opts.clone())?;

let network_descriptor = get_network_descriptor(env, args)?;
let network_descriptor = get_network_descriptor(env, opts.network)?;
let build_output_root = config.get_temp_path().join(network_descriptor.name.clone());
let build_output_root = build_output_root.join("canisters");

Expand Down Expand Up @@ -118,12 +112,12 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
fn apply_arguments(
config: &ConfigDefaultsBootstrap,
env: &dyn Environment,
args: &ArgMatches<'_>,
opts: BootstrapOpts,
) -> DfxResult<ConfigDefaultsBootstrap> {
let ip = get_ip(&config, args)?;
let port = get_port(&config, args)?;
let root = get_root(&config, env, args)?;
let timeout = get_timeout(&config, args)?;
let ip = get_ip(&config, opts.ip)?;
let port = get_port(&config, opts.port)?;
let root = get_root(&config, env, opts.root)?;
let timeout = get_timeout(&config, opts.timeout)?;
Ok(ConfigDefaultsBootstrap {
ip: Some(ip),
port: Some(port),
Expand All @@ -143,9 +137,8 @@ fn get_config_defaults_from_file(env: &dyn Environment) -> ConfigDefaults {
/// Gets the IP address that the bootstrap server listens on. First checks if the IP address was
/// specified on the command-line using --ip, otherwise checks if the IP address was specified in
/// the dfx configuration file, otherise defaults to 127.0.0.1.
fn get_ip(config: &ConfigDefaultsBootstrap, args: &ArgMatches<'_>) -> DfxResult<IpAddr> {
args.value_of("ip")
.map(|ip| ip.parse())
fn get_ip(config: &ConfigDefaultsBootstrap, ip: Option<String>) -> DfxResult<IpAddr> {
ip.map(|ip| ip.parse())
.unwrap_or_else(|| {
let default = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
Ok(config.ip.unwrap_or(default))
Expand All @@ -156,9 +149,8 @@ fn get_ip(config: &ConfigDefaultsBootstrap, args: &ArgMatches<'_>) -> DfxResult<
/// Gets the port number that the bootstrap server listens on. First checks if the port number was
/// specified on the command-line using --port, otherwise checks if the port number was specified
/// in the dfx configuration file, otherise defaults to 8081.
fn get_port(config: &ConfigDefaultsBootstrap, args: &ArgMatches<'_>) -> DfxResult<u16> {
args.value_of("port")
.map(|port| port.parse())
fn get_port(config: &ConfigDefaultsBootstrap, port: Option<String>) -> DfxResult<u16> {
port.map(|port| port.parse())
.unwrap_or_else(|| {
let default = 8081;
Ok(config.port.unwrap_or(default))
Expand All @@ -182,10 +174,9 @@ fn get_providers(network_descriptor: &NetworkDescriptor) -> DfxResult<Vec<String
fn get_root(
config: &ConfigDefaultsBootstrap,
env: &dyn Environment,
args: &ArgMatches<'_>,
root: Option<String>,
) -> DfxResult<PathBuf> {
args.value_of("root")
.map(|root| parse_dir(root))
root.map(|root| parse_dir(root.as_str()))
.unwrap_or_else(|| {
config
.root
Expand All @@ -205,8 +196,8 @@ fn get_root(
/// requests to complete. First checks if the timeout was specified on the command-line using
/// --timeout, otherwise checks if the timeout was specified in the dfx configuration file,
/// otherise defaults to 30.
fn get_timeout(config: &ConfigDefaultsBootstrap, args: &ArgMatches<'_>) -> DfxResult<u64> {
args.value_of("timeout")
fn get_timeout(config: &ConfigDefaultsBootstrap, timeout: Option<String>) -> DfxResult<u64> {
timeout
.map(|timeout| timeout.parse())
.unwrap_or_else(|| {
let default = 30;
Expand Down
69 changes: 31 additions & 38 deletions src/dfx/src/commands/build.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1,38 @@
use crate::lib::builders::BuildConfig;
use crate::lib::environment::Environment;
use crate::lib::error::{DfxError, DfxResult};
use crate::lib::message::UserMessage;
use crate::lib::models::canister::CanisterPool;
use crate::lib::models::canister_id_store::CanisterIdStore;
use crate::lib::provider::create_agent_environment;
use clap::{App, Arg, ArgMatches, SubCommand};

pub fn construct() -> App<'static, 'static> {
SubCommand::with_name("build")
.about(UserMessage::BuildCanister.to_str())
.arg(
Arg::with_name("canister_name")
.takes_value(true)
.conflicts_with("all")
.help(UserMessage::BuildCanisterName.to_str())
.required(false),
)
.arg(
Arg::with_name("all")
.long("all")
.conflicts_with("canister_name")
.help(UserMessage::BuildAll.to_str())
.takes_value(false),
)
.arg(
Arg::with_name("check")
.long("check")
.takes_value(false)
.help(UserMessage::BuildCheck.to_str()),
)
.arg(
Arg::with_name("network")
.help(UserMessage::CanisterComputeNetwork.to_str())
.long("network")
.takes_value(true),
)
use clap::{App, ArgMatches, Clap, FromArgMatches, IntoApp};

/// Builds all or specific canisters from the code in your project. By default, all canisters are built.
#[derive(Clap)]
pub struct CanisterBuildOpts {
/// Specifies the name of the canister to build.
/// You must specify either a canister name or the --all option.",
canister_name: Option<String>,

/// Builds all canisters configured in the dfx.json file.
#[clap(long, conflicts_with("canister-name"))]
all: bool,

/// Build canisters without creating them. This can be used to check that canisters build ok.
#[clap(long)]
check: bool,

/// Override the compute network to connect to. By default, the local network is used.
#[clap(long)]
network: Option<String>,
}

pub fn construct() -> App<'static> {
CanisterBuildOpts::into_app().name("build")
}

pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
let env = create_agent_environment(env, args)?;
pub fn exec(env: &dyn Environment, args: &ArgMatches) -> DfxResult {
let opts: CanisterBuildOpts = CanisterBuildOpts::from_arg_matches(args);
let env = create_agent_environment(env, opts.network)?;

let logger = env.get_logger();

Expand All @@ -52,19 +45,19 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
// already.
env.get_cache().install()?;

let build_mode_check = args.is_present("check");
let build_mode_check = opts.check;
let _all = opts.all;

// Option can be None in which case --all was specified
let some_canister = args.value_of("canister_name");
let canister_names = config
.get_config()
.get_canister_names_with_dependencies(some_canister)?;
.get_canister_names_with_dependencies(opts.canister_name.as_deref())?;

// Get pool of canisters to build
let canister_pool = CanisterPool::load(&env, build_mode_check, &canister_names)?;

// Create canisters on the replica and associate canister ids locally.
if args.is_present("check") {
if build_mode_check {
slog::warn!(
env.get_logger(),
"Building canisters to check they build ok. Canister IDs might be hard coded."
Expand Down
Loading