Skip to content
Merged
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
2 changes: 1 addition & 1 deletion distributed-canisters.nix
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pkgs.runCommandNoCCLocal "distributed-canisters" {} ''

for ext in did wasm
do
cp $canister_root/canisters/$canister_name/$canister_name.$ext $output_dir
cp $canister_root/.dfx/local/canisters/$canister_name/$canister_name.$ext $output_dir
done
done
''
4 changes: 2 additions & 2 deletions e2e/bats/bootstrap.bash
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ teardown() {
ID=$(dfx canister id hello)

assert_command curl http://localhost:8000/_/candid?canisterId="$ID" -o ./web.txt
assert_command diff canisters/hello/hello.did ./web.txt
assert_command diff .dfx/local/canisters/hello/hello.did ./web.txt
assert_command curl http://localhost:8000/_/candid?canisterId="$ID"\&format=js -o ./web.txt
# Relax diff as it's produced by two different compilers.
assert_command diff --ignore-all-space --ignore-blank-lines canisters/hello/hello.did.js ./web.txt
assert_command diff --ignore-all-space --ignore-blank-lines .dfx/local/canisters/hello/hello.did.js ./web.txt
}

@test "forbid starting webserver with a forwarded port" {
Expand Down
22 changes: 20 additions & 2 deletions e2e/bats/build.bash
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ teardown() {
dfx_start
dfx canister create --all
assert_command dfx build
cp canisters/e2e_project/main.wasm ./old.wasm
cp .dfx/local/canisters/e2e_project/main.wasm ./old.wasm
assert_command dfx build
assert_command diff canisters/e2e_project/main.wasm ./old.wasm
assert_command diff .dfx/local/canisters/e2e_project/main.wasm ./old.wasm
}

@test "build outputs warning" {
Expand Down Expand Up @@ -97,3 +97,21 @@ teardown() {
assert_command dfx canister --network tungsten create --all
assert_command dfx build --network tungsten
}

@test "build output for local network is in expected directory" {
dfx_start
dfx canister create --all
assert_command dfx build
assert_command ls .dfx/local/canisters/e2e_project/
assert_command ls .dfx/local/canisters/e2e_project/main.wasm
}

@test "build output for non-local network is in expected directory" {
dfx_start
assert_command dfx config networks.tungsten.providers '[ "http://127.0.0.1:8000" ]'
dfx canister --network tungsten create --all
assert_command dfx build --network tungsten
assert_command ls .dfx/tungsten/canisters/e2e_project/
assert_command ls .dfx/tungsten/canisters/e2e_project/main.wasm
}

14 changes: 12 additions & 2 deletions src/dfx/src/commands/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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::provider::{get_network_context, get_network_descriptor};
use crate::lib::webserver::webserver;
use clap::{App, Arg, ArgMatches, SubCommand};
use slog::info;
Expand Down Expand Up @@ -55,12 +55,22 @@ pub fn construct() -> App<'static, 'static> {
/// Runs the bootstrap server.
pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
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 build_output_root = PathBuf::from(config_defaults.get_build().get_output());
let network_descriptor = get_network_descriptor(env, args)?;

let network_name = get_network_context()?;

let build_root = config_defaults.get_build().get_output();

let build_output_root = config.get_temp_path().join(network_name);
let build_output_root = build_output_root.join(build_root);

let providers = get_providers(&network_descriptor)?;

let (sender, receiver) = crossbeam::unbounded();
Expand Down
2 changes: 1 addition & 1 deletion src/dfx/src/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {

// TODO: remove the forcing of generating canister id once we have an update flow.
canister_pool.build_or_fail(
BuildConfig::from_config(&config)
BuildConfig::from_config(&config)?
.with_skip_frontend(args.is_present("skip-frontend"))
.with_build_mode_check(build_mode_check),
)?;
Expand Down
12 changes: 8 additions & 4 deletions src/dfx/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::config::dfinity::Config;
use crate::lib::environment::Environment;
use crate::lib::error::{DfxError, DfxResult};
use crate::lib::message::UserMessage;
use crate::lib::provider::get_network_descriptor;
use crate::lib::provider::{get_network_context, get_network_descriptor};
use crate::lib::proxy::{CoordinateProxy, ProxyConfig};
use crate::lib::proxy_process::spawn_and_update_proxy;
use crate::lib::replica_config::ReplicaConfig;
Expand Down Expand Up @@ -157,11 +157,15 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
// By default we reach to no external IC nodes.
let providers = Vec::new();

let build_output_root =
PathBuf::from(config.get_config().get_defaults().get_build().get_output());

let network_descriptor = get_network_descriptor(env, args)?;

let network_name = get_network_context()?;

let build_root = config.get_config().get_defaults().get_build().get_output();

let build_output_root = config.get_temp_path().join(network_name);
let build_output_root = build_output_root.join(build_root);

let proxy_config = ProxyConfig {
logger: env.get_logger().clone(),
client_api_port: address_and_port.port(),
Expand Down
3 changes: 3 additions & 0 deletions src/dfx/src/config/dfinity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@ impl Config {
pub fn get_path(&self) -> &PathBuf {
&self.path
}
pub fn get_temp_path(&self) -> PathBuf {
self.get_path().parent().unwrap().join(".dfx")
}
pub fn get_json(&self) -> &Value {
&self.json
}
Expand Down
19 changes: 11 additions & 8 deletions src/dfx/src/lib/builders/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use crate::config::dfinity::{Config, Profile};
use crate::lib::canister_info::CanisterInfo;
use crate::lib::environment::Environment;
use crate::lib::error::DfxResult;

use crate::lib::models::canister::CanisterPool;
use crate::lib::provider::get_network_context;
use ic_agent::CanisterId;
use std::path::PathBuf;
use std::sync::Arc;
Expand Down Expand Up @@ -84,17 +86,18 @@ pub struct BuildConfig {
}

impl BuildConfig {
pub fn from_config(config: &Config) -> Self {
let workspace_root = config.get_path().parent().unwrap();
let config = config.get_config();
let build_root = workspace_root.join(config.get_defaults().get_build().get_output());

BuildConfig {
profile: config.profile.unwrap_or(Profile::Debug),
pub fn from_config(config: &Config) -> DfxResult<Self> {
let config_intf = config.get_config();
let network_name = get_network_context()?;
let build_root = config.get_temp_path().join(network_name);
let build_root = build_root.join(config_intf.get_defaults().get_build().get_output());

Ok(BuildConfig {
profile: config_intf.profile.unwrap_or(Profile::Debug),
skip_frontend: false,
build_mode_check: false,
idl_root: build_root.join("idl/"),
}
})
}

pub fn with_skip_frontend(self, skip_frontend: bool) -> Self {
Expand Down
5 changes: 4 additions & 1 deletion src/dfx/src/lib/canister_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::lib::canister_info::assets::AssetsCanisterInfo;
use crate::lib::canister_info::custom::CustomCanisterInfo;
use crate::lib::canister_info::motoko::MotokoCanisterInfo;
use crate::lib::error::{DfxError, DfxResult};
use crate::lib::provider::get_network_context;
use ic_agent::CanisterId;
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -47,7 +48,9 @@ impl CanisterInfo {
) -> DfxResult<CanisterInfo> {
let workspace_root = config.get_path().parent().unwrap();
let build_defaults = config.get_config().get_defaults().get_build();
let build_root = workspace_root.join(build_defaults.get_output());
let network_name = get_network_context()?;
let build_root = config.get_temp_path().join(network_name);
let build_root = build_root.join(build_defaults.get_output());
std::fs::create_dir_all(&build_root)?;

let canister_map = (&config.get_config().canisters).as_ref().ok_or_else(|| {
Expand Down
6 changes: 6 additions & 0 deletions src/dfx/src/lib/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ pub enum DfxError {
/// Could not parse an URL for some reason.
InvalidUrl(String, url::ParseError),

/// The value of the --network argument was not set.
ComputeNetworkNotSet,

/// The value of the --network argument was not found in dfx.json.
ComputeNetworkNotFound(String),

Expand Down Expand Up @@ -182,6 +185,9 @@ impl Display for DfxError {
"The `_language-service` command is meant to be run by editors to start a language service. You probably don't want to run it from a terminal.\nIf you _really_ want to, you can pass the --force-tty flag.",
)?;
}
DfxError::ComputeNetworkNotSet => {
f.write_str("Expected to find a network context, but found none")?;
}
DfxError::NoLocalNetworkProviderFound => {
f.write_str("Expected there to be a local network with a bind address")?;
}
Expand Down
24 changes: 23 additions & 1 deletion src/dfx/src/lib/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,40 @@ use crate::lib::environment::{AgentEnvironment, Environment};
use crate::lib::error::{DfxError, DfxResult};
use crate::lib::network::network_descriptor::NetworkDescriptor;
use clap::ArgMatches;
use lazy_static::lazy_static;
use std::sync::{Arc, RwLock};
use url::Url;

lazy_static! {
static ref NETWORK_CONTEXT: Arc<RwLock<Option<String>>> = Arc::new(RwLock::new(None));
}

fn set_network_context(args: &ArgMatches<'_>) {
let name = args.value_of("network").unwrap_or("local").to_string();

let mut n = NETWORK_CONTEXT.write().unwrap();
*n = Some(name);
}

pub fn get_network_context() -> DfxResult<String> {
NETWORK_CONTEXT
.read()
.unwrap()
.clone()
.ok_or_else(|| DfxError::ComputeNetworkNotSet)
}

// always returns at least one url
pub fn get_network_descriptor<'a>(
env: &'a (dyn Environment + 'a),
args: &ArgMatches<'_>,
) -> DfxResult<NetworkDescriptor> {
let network_name = args.value_of("network").unwrap_or("local");
set_network_context(args);
let config = env
.get_config()
.ok_or(DfxError::CommandMustBeRunInAProject)?;
let config = config.as_ref().get_config();
let network_name = get_network_context()?;
match config.get_network(&network_name) {
Some(ConfigNetwork::ConfigNetworkProvider(network_provider)) => {
let provider_urls = match &network_provider.providers {
Expand Down