Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dapp: package local remappings #719

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
dapp: remappings: deduplicate identical packages
  • Loading branch information
d-xo committed Sep 8, 2021
commit c2613b1f6d757800691fc95e1e3812aaee556fe4
3 changes: 2 additions & 1 deletion src/dapp-tests/integration/tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ dapp_testnet

# tests the behaviour of the package local dapp remappings
dapp_remappings() {
REV="fde82bd3319f7a1407a21553d120927d99a95f26"
TMPDIR=$(mktemp -d)
git clone https://github.com/dapphub/remappings-test "$TMPDIR"
(cd "$TMPDIR" && dapp update && dapp test)
(cd "$TMPDIR" && git checkout "$REV" && dapp update && dapp test)
}

dapp_remappings
Expand Down
62 changes: 54 additions & 8 deletions src/dapp/libexec/dapp/dapp-remappings
Original file line number Diff line number Diff line change
@@ -1,18 +1,59 @@
#!/usr/bin/env node
const PROGRAM_NAME = process.argv[1].replace(/.*\//, "")

console.log(buildRemappings(".").join("\n"))
const tree = buildDependencyTree(".")
console.log(buildRemappings(deduplicate(mapHashes(tree), tree)).join("\n"))

// builds a in memory representation of the projects dependency tree
//
// A node in the tree looks like this:
//
// {
// name: "",
// path: "",
// hash: "",
// deps: []
// }
function buildDependencyTree(prefix) {
if (ls(prefix).includes(".git") != true) {
console.error(`${PROGRAM_NAME}: error: ${prefix} is not a Git repository`)
console.error(`${PROGRAM_NAME}: error: try "dapp update" to initialize submodules`)
process.exit(1)
}

function buildRemappings(prefix) {
const lib = `${prefix}/${process.env.DAPP_LIB}`
const ctx = `${prefix}/${process.env.DAPP_SRC}`
return {
name: prefix.split("/").pop(),
path: normalize(`${prefix}/${process.env.DAPP_SRC}`),
hash: run("git", ["-C", prefix, "rev-parse", "HEAD"]),
deps: ls(lib).map(p => buildDependencyTree(`${lib}/${p}`))
}
}

const remappings = ls(lib).map(name => {
return `${normalize(ctx)}:${name}/=${normalize(lib)}/${name}/${process.env.DAPP_SRC}/`
// walk tree and build remappings
function buildRemappings(pkg) {
const remappings = pkg.deps.map(dep => {
return `${pkg.path}/:${dep.name}/=${dep.path}/`
})
return pkg.deps.map(buildRemappings).concat(remappings).flat()
}

return ls(lib).map(name => {
return buildRemappings(`${lib}/${name}`)
}).concat(remappings).flat()
// walk tree and build a mapping from hash => path
function mapHashes(pkg) {
const go = (mapping, dep) => {
mapping[dep.hash] = dep.path
return dep.deps.reduce(go, mapping)
}
return tree.deps.reduce(go, { [pkg.hash]: pkg.path })
}

// walk tree and rewrite paths so that all packages with the same hash have the same path
function deduplicate(mapping, pkg) {
return {
...pkg,
path: mapping[pkg.hash],
deps: pkg.deps.map(dep => deduplicate(mapping, dep))
}
}

// strip the leading `.` or `./` from a path
Expand All @@ -28,3 +69,8 @@ function ls(dir) {
}
}

function run(cmd, args) {
return require("child_process").execFileSync(cmd, args, {
encoding: "utf-8"
})
}