diff --git a/src/dapp-tests/integration/tests.sh b/src/dapp-tests/integration/tests.sh index 28a3db872..5160a7bea 100755 --- a/src/dapp-tests/integration/tests.sh +++ b/src/dapp-tests/integration/tests.sh @@ -60,13 +60,12 @@ dapp_remappings() { dapp_remappings -# tests dapp remappings on a large legacy project with many implicit imports +# tests dapp remappings on a large legacy project with many transitive imports dapp_remappings_compat() { REV="bc6d7657f0f5190f65051543199e1b47bf29932b" TMPDIR=$(mktemp -d) git clone https://github.com/dapp-org/tinlake-tests "$TMPDIR" - export DAPP_ALLOW_IMPLICIT_IMPORTS=yes - (cd "$TMPDIR" && git checkout "$REV" && dapp update && dapp --use solc:0.7.6 build) + (cd "$TMPDIR" && git checkout "$REV" && dapp update && dapp --use solc:0.7.6 build --allow-transitive-imports) } dapp_remappings_compat diff --git a/src/dapp/CHANGELOG.md b/src/dapp/CHANGELOG.md index 0f9b6ce2c..bd3eff339 100644 --- a/src/dapp/CHANGELOG.md +++ b/src/dapp/CHANGELOG.md @@ -10,8 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `dapp --use` now uses the solc binaries from https://binaries.soliditylang.org/ instead of the versions built from source via nix -- `dapp remappings` now issues a warning instead of failing with a hard error in case of mistmatched - package versions in the dependency tree +- `dapp remappings` now generates a unique set of remappings for each package in the dependency + tree that point into that pacakge's lib dir, allowing for multiple versions of the same package + to coexist in the dependency tree. More information in the [README](./README.md#package-structure-and-dependency-management). ## [0.33.0] - 2021-07-01 diff --git a/src/dapp/README.md b/src/dapp/README.md index 407494122..5b9d85d6b 100644 --- a/src/dapp/README.md +++ b/src/dapp/README.md @@ -9,8 +9,6 @@ that isn't available in `rpc`, such as [fuzz testing](#property-based-testing), -**Table of Contents** - - [Installing](#installing) - [Basic usage: a tutorial](#basic-usage-a-tutorial) - [Building](#building) @@ -21,7 +19,12 @@ that isn't available in `rpc`, such as [fuzz testing](#property-based-testing), - [Testing against RPC state](#testing-against-rpc-state) - [Deployment](#deployment) - [Configuration](#configuration) + - [Precedence](#precedence) - [solc version](#solc-version) +- [Package Structure and Dependency Management](#package-structure-and-dependency-management) + - [Import Syntax](#import-syntax) + - [Deduplication](#deduplication) + - [Importing from Transitive Dependencies](#importing-from-transitive-dependencies) - [Commands](#commands) - [`dapp init`](#dapp-init) - [`dapp build`](#dapp-build) @@ -34,6 +37,7 @@ that isn't available in `rpc`, such as [fuzz testing](#property-based-testing), - [`dapp upgrade`](#dapp-upgrade) - [`dapp testnet`](#dapp-testnet) - [`dapp verify-contract`](#dapp-verify-contract) + - [`dapp remappings`](#dapp-remappings) - [`dapp mk-standard-json`](#dapp-mk-standard-json) @@ -281,44 +285,45 @@ Below is a list of the environment variables recognized by `dapp`. You can addit various block parameters when running unit tests by using the [hevm specific environment variables](../hevm/README.md#environment-variables). -| Variable | Default | Synopsis | -| -------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -| `DAPP_SRC` | `src` | Directory for the project's Solidity contracts | -| `DAPP_LIB` | `lib` | Directory for installed Dapp packages | -| `DAPP_OUT` | `out` | Directory for compilation artifacts | -| `DAPP_ROOT` | `.` | Root directory of compilation | -| `DAPP_SOLC_VERSION` | `0.8.6` | Solidity compiler version to use | -| `DAPP_SOLC` | n/a | solc binary to use | -| `DAPP_LIBRARIES` | automatically deployed | Library addresses to link to | -| `DAPP_SKIP_BUILD` | n/a | Avoid compiling this time | -| `DAPP_LINK_TEST_LIBRARIES` | `1` when testing; else `0` | Compile with libraries | -| `DAPP_VERIFY_CONTRACT` | `yes` | Attempt Etherscan verification | -| `DAPP_ASYNC` | n/a | Set to `yes` to skip waiting for etherscan verification to succeed | -| `DAPP_STANDARD_JSON` | `$(dapp mk-standard-json)` | [Solidity compilation options](https://docs.soliditylang.org/en/latest/using-the-compiler.html#compiler-input-and-output-json-description) | -| `DAPP_REMAPPINGS` | `$(dapp remappings)` | [Solidity remappings](https://docs.soliditylang.org/en/latest/using-the-compiler.html#path-remapping) | -| `DAPP_BUILD_OPTIMIZE` | `0` | Activate Solidity optimizer (`0` or `1`) | -| `DAPP_BUILD_OPTIMIZE_RUNS` | `200` | Set the optimizer runs | -| `DAPP_TEST_MATCH` | n/a | Only run test methods matching a regex | -| `DAPP_TEST_VERBOSITY` | `0` | Sets how much detail `dapp test` logs. Verbosity `1` shows traces for failing tests, `2` shows logs for all tests, `3` shows traces for all tests | -| `DAPP_TEST_FFI ` | `0` | Allow use of the ffi cheatcode in tests (`0` or `1`) | -| `DAPP_TEST_FUZZ_RUNS` | `200` | How many iterations to use for each property test in your project | -| `DAPP_TEST_SMTTIMEOUT` | `60000` | Timeout passed to the smt solver for symbolic tests (in ms, and per smt query) | -| `DAPP_TEST_MAX_ITERATIONS` | n/a | The number of times hevm will revisit a particular branching point when symbolically executing | -| `DAPP_TEST_SOLVER ` | `z3` | Solver to use for symbolic execution (`cvc4` or `z3`) | -| `DAPP_TEST_MATCH ` | n/a | Regex used to determine test methods to run | -| `DAPP_TEST_REPLAY` | n/a | Calldata for a specific property test case to replay in the debugger | -| `HEVM_RPC` | n/a | Set to `yes` to have `hevm` fetch state from rpc when running unit tests | -| `ETH_RPC_URL` | n/a | The url of the rpc server that should be used for any rpc calls | -| `DAPP_TESTNET_RPC_PORT` | `8545` | Which port to expose the rpc server on when running `dapp testnet` | -| `DAPP_TESTNET_RPC_ADDRESS` | `127.0.0.1` | Which ip address to bind the rpc server to when running `dapp testnet` | -| `DAPP_TESTNET_CHAINID` | `99` | Which chain id to use when running `dapp testnet` | -| `DAPP_TESTNET_PERIOD` | `0` | Blocktime to use for `dapp testnet`. `0` means blocks are produced instantly as soon as a transaction is received | -| `DAPP_TESTNET_ACCOUNTS` | `0` | How many extra accounts to create when running `dapp testnet` (At least one is always created) | -| `DAPP_TESTNET_gethdir` | `$HOME/.dapp/testnet` | Root directory that should be used for `dapp testnet` data | -| `DAPP_TESTNET_SAVE` | n/a | Name of the subdirectory under `${DAPP_TESTNET_gethdir}/snapshots` where the chain data from the current `dapp testnet` invocation should be saved | -| `DAPP_TESTNET_LOAD` | n/a | Name of the subdirectory under `${DAPP_TESTNET_gethdir}/snapshots` from which `dapp testnet` chain data should be loaded | -| `DAPP_BUILD_EXTRACT` | n/a | Set to a non null value to output `.abi`, `.bin` and `.bin-runtime` when using `dapp build`. Uses legacy build mode | -| `DAPP_BUILD_LEGACY` | n/a | Set to a non null value to compile using the `--combined-json` flag. This is provided for compatibility with older workflows | +| Variable | Default | Synopsis | +| ------------------------------ | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| `DAPP_SRC` | `src` | Directory for the project's Solidity contracts | +| `DAPP_LIB` | `lib` | Directory for installed Dapp packages | +| `DAPP_OUT` | `out` | Directory for compilation artifacts | +| `DAPP_ROOT` | `.` | Root directory of compilation | +| `DAPP_SOLC_VERSION` | `0.8.6` | Solidity compiler version to use | +| `DAPP_SOLC` | n/a | solc binary to use | +| `DAPP_LIBRARIES` | automatically deployed | Library addresses to link to | +| `DAPP_SKIP_BUILD` | n/a | Avoid compiling this time | +| `DAPP_LINK_TEST_LIBRARIES` | `1` when testing; else `0` | Compile with libraries | +| `DAPP_VERIFY_CONTRACT` | `yes` | Attempt Etherscan verification | +| `DAPP_ASYNC` | n/a | Set to `yes` to skip waiting for etherscan verification to succeed | +| `DAPP_ALLOW_TRANSITIVE_IMPORTS`| n/a | Set to `1` to allow imports using the short syntax from transitive dependencies | +| `DAPP_STANDARD_JSON` | `$(dapp mk-standard-json)` | [Solidity compilation options](https://docs.soliditylang.org/en/latest/using-the-compiler.html#compiler-input-and-output-json-description) | +| `DAPP_REMAPPINGS` | `$(dapp remappings)` | [Solidity remappings](https://docs.soliditylang.org/en/latest/using-the-compiler.html#path-remapping) | +| `DAPP_BUILD_OPTIMIZE` | `0` | Activate Solidity optimizer (`0` or `1`) | +| `DAPP_BUILD_OPTIMIZE_RUNS` | `200` | Set the optimizer runs | +| `DAPP_TEST_MATCH` | n/a | Only run test methods matching a regex | +| `DAPP_TEST_VERBOSITY` | `0` | Sets how much detail `dapp test` logs. Verbosity `1` shows traces for failing tests, `2` shows logs for all tests, `3` shows traces for all tests | +| `DAPP_TEST_FFI ` | `0` | Allow use of the ffi cheatcode in tests (`0` or `1`) | +| `DAPP_TEST_FUZZ_RUNS` | `200` | How many iterations to use for each property test in your project | +| `DAPP_TEST_SMTTIMEOUT` | `60000` | Timeout passed to the smt solver for symbolic tests (in ms, and per smt query) | +| `DAPP_TEST_MAX_ITERATIONS` | n/a | The number of times hevm will revisit a particular branching point when symbolically executing | +| `DAPP_TEST_SOLVER ` | `z3` | Solver to use for symbolic execution (`cvc4` or `z3`) | +| `DAPP_TEST_MATCH ` | n/a | Regex used to determine test methods to run | +| `DAPP_TEST_REPLAY` | n/a | Calldata for a specific property test case to replay in the debugger | +| `HEVM_RPC` | n/a | Set to `yes` to have `hevm` fetch state from rpc when running unit tests | +| `ETH_RPC_URL` | n/a | The url of the rpc server that should be used for any rpc calls | +| `DAPP_TESTNET_RPC_PORT` | `8545` | Which port to expose the rpc server on when running `dapp testnet` | +| `DAPP_TESTNET_RPC_ADDRESS` | `127.0.0.1` | Which ip address to bind the rpc server to when running `dapp testnet` | +| `DAPP_TESTNET_CHAINID` | `99` | Which chain id to use when running `dapp testnet` | +| `DAPP_TESTNET_PERIOD` | `0` | Blocktime to use for `dapp testnet`. `0` means blocks are produced instantly as soon as a transaction is received | +| `DAPP_TESTNET_ACCOUNTS` | `0` | How many extra accounts to create when running `dapp testnet` (At least one is always created) | +| `DAPP_TESTNET_gethdir` | `$HOME/.dapp/testnet` | Root directory that should be used for `dapp testnet` data | +| `DAPP_TESTNET_SAVE` | n/a | Name of the subdirectory under `${DAPP_TESTNET_gethdir}/snapshots` where the chain data from the current `dapp testnet` invocation should be saved | +| `DAPP_TESTNET_LOAD` | n/a | Name of the subdirectory under `${DAPP_TESTNET_gethdir}/snapshots` from which `dapp testnet` chain data should be loaded | +| `DAPP_BUILD_EXTRACT` | n/a | Set to a non null value to output `.abi`, `.bin` and `.bin-runtime` when using `dapp build`. Uses legacy build mode | +| `DAPP_BUILD_LEGACY` | n/a | Set to a non null value to compile using the `--combined-json` flag. This is provided for compatibility with older workflows | A global (always loaded) config file is located in `~/.dapprc`. A local `.dapprc` can also be defined in your project's root, which overrides variables in the global config. @@ -369,6 +374,105 @@ nix-env -iA solc-static-versions.solc_x_y_z \ For a list of the supported `solc` versions, check [`solc-static-versions.nix`](/nix/solc-static-versions.nix). +## Package Structure and Dependency Management + +`dapp` packages have a libraries directory (by default under `lib`) where dependencies are stored as +git submodules, and a source diretory (by default under `src`) where the source code is stored. + +If you want to add a new dependency to the project you can install it to the lib dir as a submodule +using [`dapp install`](#dapp-install). Dependencies can be uninstalled using [`dapp uninstall`](#dapp-uninstall), +and upgraded to the latest version with [`dapp upgrade`](#dapp-upgrade). Running [`dapp update`](#dapp-update) +will recursively fetch all the project submodules. + +As dependencies are just git submodules under the hood you can also use the standard git tooling to +modify dependencies, e.g. check out a specific branch or commit, update the remote, or examine +the commit history. + +You can use the `DAPP_SRC` and `DAPP_LIB` variables to customize the location of the source and +library directories. + +### Import Syntax + +Projects compiled with `dapp build` can use a shortened import syntax to refer to packages in their +local `lib` directory. + +An import of the form `import "/"` will effectivley desugar to `import +"///"`, where `` is always the location of the +current packages library directory. + +To put it more concretely, consider the following project layout: + +``` +├── lib +│ ├── ds-auth +│ │ ├── lib +│ │ │ └── ds-test +│ │ │ └── src +│ │ │ └── test.sol +│ │ └── src +│ │ ├── auth.sol +│ │ └── auth.t.sol +│ │ import {DSTest} from "ds-test/test.sol" +│ └── ds-test +│ └── src +│ └── test.sol +└── src + └── test.t.sol + import {DSTest} from "ds-test/test.sol" + import {DSAuth} from "ds-auth/auth.sol" +``` + +Both `test.t.sol` and `auth.t.sol` import an instance of `DSTest` using exactly the same syntax, +however, each will resolve to a different path in the dependency tree: + +- `auth.t.sol`: resolves to `import {DSTest} from "lib/ds-auth/lib/ds-test/src/test.sol"` +- `test.t.sol`: resolves to `import {DSTest} from "lib/ds-test/src/test.sol"` + +### Deduplication + +`solc` treats identical contracts imported from different paths on disk as distinct, and this can +cause compiler errors due to name clashes when two copies of the same contract are present in an +inheritance hieracry. + +For this reason imports of contracts from identical package versions are always resolved to the same +path on disk, e.g. in the example above, if both `ds-test` packages had an identical git hash, the +imports would both resolve to `import {DSTest} from "lib/ds-test/src/test.sol"`. + +### Importing from Transitive Dependencies + +By default imports from transitive dependencies are forbidden, i.e. each package can only import +using the shortened syntax from a dependency that lives in it's local `lib` dir (standard solc +relative imports are of course still valid). + +This was however allowed in older versions, and a legacy compatibility flag is provided that should +allow compilation of older `dapp` projects that rely on this behaviour: `--allow-transitive-imports`. +This flag allows imports from transitive dependencies if there exists a single version of that +package throughout the entire dependency tree for the current package. + +As an example, consider the following project: + +``` +├── lib +│ └── ds-auth +│ ├── lib +│ │ └── ds-test +│ │ └── src +│ │ └── test.sol +│ └── src +│ ├── auth.sol +│ └── auth.t.sol +│ import {DSTest} from "ds-test/test.sol" +└── src + └── test.t.sol + import {DSTest} from "ds-test/test.sol" + import {DSAuth} from "ds-auth/auth.sol" +``` + +Compilation would fail with a plain `dapp build` as there is no `ds-test` project in the top level +`lib` directory. However if we try again with `dapp build --allow-transitive-imports`, compilation +will succeed as the import of `ds-test/test.sol` from the top level is resolved to +`lib/ds-auth/lib/ds-test/src/test.sol`. + ## Commands ### `dapp init` @@ -398,7 +502,7 @@ The compiler options of the build are generated by the [`dapp mk-standard-json`] which infers most options from the project structure. For more customizability, you can define your own configuration json by setting the file to the environment variable `DAPP_STANDARD_JSON`. -By default, `dapp build` uses [`dapp remappings`](#dapp-remappings) to resolve Solidity import paths. +By default, `dapp build` uses [`dapp remappings`](#dapp-remappings) to resolve Solidity import paths (see also [Package Structure and Dependency Management](#package-structure-and-dependency-management)). You can override this with the `DAPP_REMAPPINGS` environment variable. @@ -548,6 +652,63 @@ Requires `ETHERSCAN_API_KEY` to be set. Automatically run when the `--verify` flag is passed to `dapp create`. +### `dapp remappings` + +Generates the [solc compiler +remappings](https://docs.soliditylang.org/en/v0.8.6/path-resolution.html?highlight=remappings#import-remapping). +These resolve the dapp style imports (e.g. `import "ds-test/test.sol"`) into concrete paths on disk +(e.g. `lib/ds-test/src/test.sol`). + +Remappings are generated in the following format: `:=`, where `context` +defines the prefix of the on disk locations where the remappings will be applied, the `prefix` +defines the prefix of an import path that will be remapped, and `target` defines the result of the +remapping. + +For example a remapping of the form: `src/:ds-test/=lib/ds-test/src/` will apply to any file under +the root `src` directory, and will remap any import starting with `ds-test/` into an import starting +with `lib/ds-test/src/`. + +By default a unique set of remappings are generated for each `src` dir in the dependency tree that +remap imports into the local `lib` dir for that package. + +For example, given the following project structure: + +``` +├── lib +│ ├── ds-auth +│ │ ├── lib +│ │ │ └── ds-test +│ │ │ └── src +│ │ │ └── test.sol +│ │ └── src +│ │ ├── auth.sol +│ │ └── auth.t.sol +│ └── ds-test +│ └── src +│ └── test.sol +└── src + └── test.t.sol +``` + +`dapp remappings` would generate the following remappings: + +``` +lib/ds-auth/src/:ds-test/=lib/ds-auth/lib/ds-test/src/ +src/:ds-auth/=lib/ds-auth/src/ +src/:ds-test/=lib/ds-test/src/ +``` + +Imports to identical package versions are deduplicated to always resolve to the same on disk +location (this helps to avoid some solc compiler errors when multiple instances of the same project +are present in an inheritance hierarchy), so if both instances of `ds-test` have the same git hash, +the following remappings would be generated: + +``` +lib/ds-auth/src/:ds-test/=lib/ds-test/src/ +src/:ds-auth/=lib/ds-auth/src/ +src/:ds-test/=lib/ds-test/src/ +``` + ### `dapp mk-standard-json` Generates a Solidity settings input json using the structure of the current directory. diff --git a/src/dapp/libexec/dapp/dapp b/src/dapp/libexec/dapp/dapp index 1952b84d6..8eb1d4379 100755 --- a/src/dapp/libexec/dapp/dapp +++ b/src/dapp/libexec/dapp/dapp @@ -8,23 +8,24 @@ ### dapp --help ### -- ### Compilation options: -### optimize activate solidity optimizer -### legacy compile using the '--combined-json' format -### extract after building, write the .abi, .bin and .bin-runtime. Implies '--legacy' +### optimize activate solidity optimizer +### legacy compile using the '--combined-json' format +### extract after building, write the .abi, .bin and .bin-runtime. Implies '--legacy' +### allow-transitive-imports allow imports with the short syntax from transitive dependencies ### ### Testing options: -### verbosity= verbosity of 'dapp test' output (0-3) -### v,verbose sets verbosity to 1 -### fuzz-runs= number of times to run fuzzing tests -### replay= rerun a particular test case -### m,match= only run test methods matching regex -### cache= use the cache at directory -### ffi allow the use of the ffi cheatcode (WARNING: allows test authors to execute arbitrary code on your machine) +### verbosity= verbosity of 'dapp test' output (0-3) +### v,verbose sets verbosity to 1 +### fuzz-runs= number of times to run fuzzing tests +### replay= rerun a particular test case +### m,match= only run test methods matching regex +### cache= use the cache at directory +### ffi allow the use of the ffi cheatcode (WARNING: allows test authors to execute arbitrary code on your machine) ### ### RPC options: -### rpc fetch remote state via ETH_RPC_URL -### rpc-url= fetch remote state via -### rpc-block= block number (latest if not specified) +### rpc fetch remote state via ETH_RPC_URL +### rpc-url= fetch remote state via +### rpc-block= block number (latest if not specified) ### ### SMT options: ### smttimeout= timeout passed to the smt solver in ms (default 60000) @@ -39,59 +40,60 @@ ### async don't wait for confirmation ### Dapp testnet options: -### rpc-port=port change RPC port (default: 8545) -### rpc-addr=address change RPC address (default: 127.0.0.1) -### chain-id=number change chain ID (default: 99) -### period=seconds use a block time instead of instamine -### accounts=number create multiple accounts (default: 1) -### save=name after finishing, save snapshot -### load=name start from a previously saved snapshot -### dir=directory testnet directory +### rpc-port=port change RPC port (default: 8545) +### rpc-addr=address change RPC address (default: 127.0.0.1) +### chain-id=number change chain ID (default: 99) +### period=seconds use a block time instead of instamine +### accounts=number create multiple accounts (default: 1) +### save=name after finishing, save snapshot +### load=name start from a previously saved snapshot +### dir=directory testnet directory OPTS="dapp [] [] dapp --help -- Compilation options: -optimize activate solidity optimizer -legacy compile using the '--combined-json' format -extract after building, write the .abi, .bin and .bin-runtime. Implies '--legacy' +optimize activate solidity optimizer +legacy compile using the '--combined-json' format +extract after building, write the .abi, .bin and .bin-runtime. Implies '--legacy' +allow-transitive-imports allow imports with the short syntax from transitive dependencies Testing options: -verbosity= verbosity of 'dapp test' output (0-3) -v,verbose sets verbosity to 1 -fuzz-runs= number of times to run fuzzing tests -replay= rerun a particular test case -m,match= only run test methods matching regex -cache= use the cache at directory -ffi allow the use of the ffi cheatcode (WARNING: allows test authors to execute arbitrary code on your machine) +verbosity= verbosity of 'dapp test' output (0-3) +v,verbose sets verbosity to 1 +fuzz-runs= number of times to run fuzzing tests +replay= rerun a particular test case +m,match= only run test methods matching regex +cache= use the cache at directory +ffi allow the use of the ffi cheatcode (WARNING: allows test authors to execute arbitrary code on your machine) RPC options: -rpc fetch remote state via ETH_RPC_URL -rpc-url= fetch remote state via -rpc-block= block number (latest if not specified) +rpc fetch remote state via ETH_RPC_URL +rpc-url= fetch remote state via +rpc-block= block number (latest if not specified) SMT options: -smttimeout= timeout passed to the smt solver in ms (default 60000) -solver= name of the smt solver to use (either 'z3' or 'cvc4') -max-iterations= number of times we may revisit a particular branching point -smtdebug print the SMT queries produced by hevm +smttimeout= timeout passed to the smt solver in ms (default 60000) +solver= name of the smt solver to use (either 'z3' or 'cvc4') +max-iterations= number of times we may revisit a particular branching point +smtdebug print the SMT queries produced by hevm Deployment options: -verify verify contract on etherscan +verify verify contract on etherscan Contract verifying options: -async don't wait for confirmation +async don't wait for confirmation Dapp testnet options: -rpc-port=port change RPC port (default: 8545) -rpc-addr=address change RPC address (default: 127.0.0.1) -chain-id=number change chain ID (default: 99) -period=seconds use a block time instead of instamine -accounts=number create multiple accounts (default: 1) -save=name after finishing, save snapshot -load=name start from a previously saved snapshot -dir=directory testnet directory +rpc-port=port change RPC port (default: 8545) +rpc-addr=address change RPC address (default: 127.0.0.1) +chain-id=number change chain ID (default: 99) +period=seconds use a block time instead of instamine +accounts=number create multiple accounts (default: 1) +save=name after finishing, save snapshot +load=name start from a previously saved snapshot +dir=directory testnet directory " set -e @@ -133,41 +135,41 @@ shopt -s extglob while [[ $1 ]]; do case $1 in - --) shift; break;; - --extract) export DAPP_BUILD_EXTRACT=1;; - --optimize) export DAPP_BUILD_OPTIMIZE=1;; - --legacy) export DAPP_BUILD_LEGACY=1;; - - -m|--match) shift; export DAPP_TEST_MATCH=$1;; - -v|--verbose) export DAPP_TEST_VERBOSITY=1;; - --verbosity) shift; export DAPP_TEST_VERBOSITY=$1;; - --fuzz-runs) shift; export DAPP_TEST_FUZZ_RUNS=$1;; - - --smttimeout) shift; export DAPP_TEST_SMTTIMEOUT=$1;; - --solver) shift; export DAPP_TEST_SOLVER=$1;; - --max-iterations) shift; export DAPP_TEST_MAX_ITERATIONS=$1;; - --smtdebug) export DAPP_TEST_SMTDEBUG=$1;; - - --replay) shift; export DAPP_TEST_REPLAY=$1;; - --cache) shift; export DAPP_TEST_CACHE=$1;; - --ffi) export DAPP_TEST_FFI=1;; - --rpc-url) shift; export HEVM_RPC=yes; export ETH_RPC_URL=$1;; - --rpc-block) shift; export HEVM_RPC=yes; export DAPP_TEST_NUMBER=$1;; - --rpc) [ -n "$ETH_RPC_URL" ] || fail "ETH_RPC_URL not set."; - export HEVM_RPC=yes;; - - --verify) export DAPP_VERIFY_CONTRACT=yes;; - - --async) export DAPP_ASYNC=yes;; - - --rpc-port) shift; export DAPP_TESTNET_RPC_PORT=$1;; - --rpc-addr) shift; export DAPP_TESTNET_RPC_ADDRESS=$1;; - --chain-id) shift; export DAPP_TESTNET_CHAINID=$1;; - --period) shift; export DAPP_TESTNET_PERIOD=$1;; - --accounts) shift; export DAPP_TESTNET_ACCOUNTS=$(($1 - 1));; - --save) shift; export DAPP_TESTNET_SAVE=$1;; - --load) shift; export DAPP_TESTNET_LOAD=$1;; - --dir) shift; export DAPP_TESTNET_gethdir=$1;; + --) shift; break;; + --extract) export DAPP_BUILD_EXTRACT=1;; + --optimize) export DAPP_BUILD_OPTIMIZE=1;; + --legacy) export DAPP_BUILD_LEGACY=1;; + --allow-transitive-imports) export DAPP_ALLOW_TRANSITIVE_IMPORTS=1;; + + -m|--match) shift; export DAPP_TEST_MATCH=$1;; + -v|--verbose) export DAPP_TEST_VERBOSITY=1;; + --verbosity) shift; export DAPP_TEST_VERBOSITY=$1;; + --fuzz-runs) shift; export DAPP_TEST_FUZZ_RUNS=$1;; + + --smttimeout) shift; export DAPP_TEST_SMTTIMEOUT=$1;; + --solver) shift; export DAPP_TEST_SOLVER=$1;; + --max-iterations) shift; export DAPP_TEST_MAX_ITERATIONS=$1;; + --smtdebug) export DAPP_TEST_SMTDEBUG=$1;; + + --replay) shift; export DAPP_TEST_REPLAY=$1;; + --cache) shift; export DAPP_TEST_CACHE=$1;; + --ffi) export DAPP_TEST_FFI=1;; + --rpc-url) shift; export HEVM_RPC=yes; export ETH_RPC_URL=$1;; + --rpc-block) shift; export HEVM_RPC=yes; export DAPP_TEST_NUMBER=$1;; + --rpc) [ -n "$ETH_RPC_URL" ] || fail "ETH_RPC_URL not set."; export HEVM_RPC=yes;; + + --verify) export DAPP_VERIFY_CONTRACT=yes;; + + --async) export DAPP_ASYNC=yes;; + + --rpc-port) shift; export DAPP_TESTNET_RPC_PORT=$1;; + --rpc-addr) shift; export DAPP_TESTNET_RPC_ADDRESS=$1;; + --chain-id) shift; export DAPP_TESTNET_CHAINID=$1;; + --period) shift; export DAPP_TESTNET_PERIOD=$1;; + --accounts) shift; export DAPP_TESTNET_ACCOUNTS=$(($1 - 1));; + --save) shift; export DAPP_TESTNET_SAVE=$1;; + --load) shift; export DAPP_TESTNET_LOAD=$1;; + --dir) shift; export DAPP_TESTNET_gethdir=$1;; *) printf "${0##*/}: internal error: %q\\n" "$1"; exit 1 diff --git a/src/dapp/libexec/dapp/dapp-remappings b/src/dapp/libexec/dapp/dapp-remappings index 30acd026c..0a1ea5a46 100755 --- a/src/dapp/libexec/dapp/dapp-remappings +++ b/src/dapp/libexec/dapp/dapp-remappings @@ -25,15 +25,16 @@ function buildDependencyTree(prefix) { // walk tree and build remappings function buildRemappings(pkg) { - const paths = mapHashes(pkg) let implicits = [] - if (process.env.DAPP_ALLOW_IMPLICIT_IMPORTS == "yes") { + if (process.env.DAPP_ALLOW_TRANSITIVE_IMPORTS == "1") { + // get the names of the direct dependencies const directs = pkg.deps.map(p => p.name) // get the transitive deps with exactly one version that are not direct deps const uniques = Object.entries(pkg.deps.reduce(buildVersionMap, {})) .filter(([name, vs]) => vs.size == 1 && !directs.includes(name)) // build remappings that allow importing these deps from `pkg` + const paths = mapHashes(pkg) implicits = uniques.map(([name, v]) => `${pkg.path}/:${name}/=${paths[([...v][0])]}/`) } @@ -67,9 +68,7 @@ function buildVersionMap(map, pkg) { return map } - return pkg.deps.reduce((versions, dep) => { - return update(versions, dep) - }, update(map, pkg)) + return pkg.deps.reduce(update, update(map, pkg)) } // strip the leading `.` or `./` from a path