diff --git a/.circleci/config.yml b/.circleci/config.yml index f6450c2b..7bd7aaa3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,14 +8,19 @@ workflows: pr-checks: jobs: - check-coding-style - - node-v10 - node-v12 + - node-v12: + name: node-v12-min-dependencies + min_dependencies: true - node-v14 - node-v16 - node-v18 - node-v20 - node-current: run_coveralls: true + - node-current: + name: node-current-min-dependencies + min_dependencies: true - build-package - hardhat-sample-project: *requires_package - cli-smoke-test: *requires_package @@ -168,10 +173,31 @@ jobs: run_coveralls: type: boolean default: false + min_dependencies: + description: "Install the oldest dependencies still matching ranges specified in package.json" + type: boolean + default: false steps: # We want the default npm here. Older one might not work with older node.js - show-npm-version - checkout + - when: + condition: <> + steps: + - run: + name: Install the semver utility + command: | + # NOTE: Newer cimg/node images require sudo here, older don't. Try both. + sudo npm install semver --global || npm install semver --global + - run: + name: Force oldest supported dependency versions in package.json + command: | + min_package_json=$(.circleci/package-json-with-min-dependencies.sh) + echo "$min_package_json" > package.json + - run: + name: "Show selected dependency versions" + command: | + jq 'with_entries(select(.key == "dependencies" or .key == "devDependencies"))' package.json --indent 4 - install-dependencies: cache-id: solc-js - run: @@ -345,10 +371,6 @@ jobs: - run: cd solidity/ && curl "https://binaries.soliditylang.org/bin/soljson-nightly.js" --location --output soljson.js - run: cd solidity/ && test/externalTests/solc-js/solc-js.sh "$(realpath soljson.js)" "$(scripts/get_version.sh)" "$(realpath ../solc-js/)" - node-v10: - <<: *node-base - docker: - - image: cimg/node:10.24 node-v12: <<: *node-base docker: diff --git a/.circleci/package-json-with-min-dependencies.sh b/.circleci/package-json-with-min-dependencies.sh new file mode 100755 index 00000000..7fd959dd --- /dev/null +++ b/.circleci/package-json-with-min-dependencies.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# Creates a variant of package.json, hard-coded to use the oldest version of each dependency in +# the supported range. +# +# package.json is taken from the current working directory. The script does not modify the file - +# the new version is instead printed to the standard output. +# +# Dependencies: npm, jq, semver + +set -euo pipefail + +function fail { >&2 echo "$@"; exit 1; } + +function find_min_supported_versions { + local packages_json min_versions packages supported_range available_versions min_version + + # The function expects a JSON dict with package names and versions, extracted from package.json by the caller. + packages_json=$(cat -) + + # Use @tsv filter to get tab-separated package names. We assume that neither packages, nor + # available versions contain spaces. Spaces in version range are fine though. + packages=$(echo "$packages_json" | jq --raw-output 'keys | @tsv') + min_versions=() + for package in $packages; do + available_versions=$(npm view "$package" versions --json | jq --raw-output @tsv) + supported_range=$(echo "$packages_json" | jq --raw-output ".\"${package}\"") + + # shellcheck disable=SC2086 + # semver prints versions matching the range, one per line, in semver order, oldest first + min_version=$(semver $available_versions --range "$supported_range" | head --lines 1) + [[ $min_version != "" ]] || fail "No version matching ${supported_range} found for package ${package}." + + # Debug info. It goes to stderr not to interfere with actual output. + >&2 echo "Package ${package}:" + >&2 echo " minimum version: ${min_version}" + >&2 echo " supported range: ${supported_range}" + >&2 echo " available versions: ${available_versions}" + >&2 echo + + min_versions+=("{\"${package}\": \"${min_version}\"}") + done + + # Actual output: min_versions merged into a single dict. + echo "${min_versions[@]}" | jq --slurp add +} + +dependencies=$(jq .dependencies package.json | find_min_supported_versions) +dev_dependencies=$(jq .devDependencies package.json | find_min_supported_versions) + +# Print package.json with overwritten dependency versions +cat <=1.1.0", + "commander": ">=8.0.0 <12.0.0", + "follow-redirects": ">=1.0.0", + "js-sha3": ">=0.8.0", + "memorystream": ">=0.3.0", + "semver": ">=5.0.0", + "tmp": ">=0.0.26" }, "devDependencies": { - "@types/node": "^16.11.7", - "@types/semver": "^7.3.9", - "@types/tape": "^4.13.2", - "@types/tmp": "^0.2.3", - "@typescript-eslint/eslint-plugin": "^5.8.0", - "@typescript-eslint/parser": "^5.8.0", - "coveralls": "^3.0.0", - "eslint": "^7.32.0", - "eslint-config-standard": "^16.0.3", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^5.1.1", - "nyc": "^15.1.0", - "tape": "^4.11.0", - "tape-spawn": "^1.4.2", - "ts-node": "^10.4.0", - "typescript": "^4.5.4" + "@types/node": ">=16.11.7", + "@types/semver": ">=7.1.0", + "@types/tape": ">=4.2.27", + "@types/tmp": ">=0.2.0", + "@typescript-eslint/eslint-plugin": ">=5.0.0 <6.0.0", + "@typescript-eslint/parser": ">=5.0.0 <6.0.0", + "coveralls": ">=3.0.0", + "eslint": ">=7.12.1 <8.0.0", + "eslint-config-standard": ">=16.0.3 <17.0.0", + "eslint-plugin-import": ">=2.25.0", + "eslint-plugin-node": ">=11.1.0", + "eslint-plugin-promise": ">=5.0.0 <7.0.0", + "nyc": ">=15.0.0", + "tape": ">=4.11.0", + "tape-spawn": ">=1.0.0", + "ts-node": ">=10.0.0", + "typescript": ">=4.2.2 <5.0.0" }, "nyc": { "exclude": [ diff --git a/smtsolver.ts b/smtsolver.ts index 29993a18..2e444d26 100644 --- a/smtsolver.ts +++ b/smtsolver.ts @@ -44,7 +44,7 @@ function solve (query, solver) { encoding: 'utf8', maxBuffer: 1024 * 1024 * 1024, stdio: 'pipe', - timeout: timeout // Enforce timeout on the process, since solvers can sometimes go around it. + timeout // Enforce timeout on the process, since solvers can sometimes go around it. } ).toString(); } catch (e) { diff --git a/solc.ts b/solc.ts index 10dc8ed3..9d4f8bfb 100755 --- a/solc.ts +++ b/solc.ts @@ -26,7 +26,6 @@ const commanderParseInt = function (value) { program.name('solcjs'); program.version(solc.version()); program - .option('--version', 'Show version and exit.') .option('--optimize', 'Enable bytecode optimizer.', false) .option( '--optimize-runs ', @@ -201,7 +200,7 @@ const cliInput = { } } }, - sources: sources + sources }; if (program.verbose) { console.log('>>> Compiling:\n' + toFormattedJson(cliInput) + '\n'); } const output = JSON.parse(solc.compile(JSON.stringify(cliInput), callbacks)); diff --git a/test/smtcallback.ts b/test/smtcallback.ts index 726cc87e..7133cfec 100644 --- a/test/smtcallback.ts +++ b/test/smtcallback.ts @@ -85,7 +85,7 @@ tape('SMTCheckerCallback', function (t) { const inputJSON = JSON.stringify({ language: 'Solidity', sources: input, - settings: settings + settings }); let tests; @@ -192,7 +192,7 @@ tape('SMTCheckerCallback', function (t) { expectations: expected, solidity: { test: { content: preamble + source } }, ignoreCex: source.includes('// SMTIgnoreCex: yes'), - engine: engine + engine }; } @@ -214,7 +214,7 @@ tape('SMTCheckerCallback', function (t) { const engine = test.engine !== undefined ? test.engine : 'all'; settings = { modelChecker: { - engine: engine, + engine, solvers: [ 'smtlib2' ] @@ -225,7 +225,7 @@ tape('SMTCheckerCallback', function (t) { JSON.stringify({ language: 'Solidity', sources: test.solidity, - settings: settings + settings }), // This test needs z3 specifically. { smtSolver: smtchecker.smtCallback(smtsolver.smtSolver, z3HornSolvers[0]) } diff --git a/test/smtchecker.ts b/test/smtchecker.ts index 70193339..ea71db72 100644 --- a/test/smtchecker.ts +++ b/test/smtchecker.ts @@ -84,7 +84,7 @@ tape('SMTCheckerWithSolver', function (t) { const input = { language: 'Solidity', sources: source, - settings: settings + settings }; const output = JSON.parse(solc.compile(JSON.stringify(input))); diff --git a/translate.ts b/translate.ts index ca0c39f7..fe0d2f4c 100644 --- a/translate.ts +++ b/translate.ts @@ -38,7 +38,7 @@ function translateErrors (ret, errors) { type = 'Error'; } ret.push({ - type: type, + type, component: 'general', severity: (type === 'Warning') ? 'warning' : 'error', message: errors[error], diff --git a/wrapper.ts b/wrapper.ts index e9bf471e..ce6a9ccc 100755 --- a/wrapper.ts +++ b/wrapper.ts @@ -101,13 +101,13 @@ function compileStandardWrapper (compile, inputRaw, readCallback) { // Try to wrap around old versions if (!isNil(compile.compileJsonCallback)) { - const inputJson = JSON.stringify({ sources: sources }); + const inputJson = JSON.stringify({ sources }); const output = compile.compileJsonCallback(inputJson, optimize, readCallback); return translateOutput(output, libraries); } if (!isNil(compile.compileJsonMulti)) { - const output = compile.compileJsonMulti(JSON.stringify({ sources: sources }), optimize); + const output = compile.compileJsonMulti(JSON.stringify({ sources }), optimize); return translateOutput(output, libraries); }