Skip to content

Commit 64652e9

Browse files
committed
dapp: remappings: deduplicate identical packages
1 parent dc92c39 commit 64652e9

File tree

2 files changed

+56
-9
lines changed

2 files changed

+56
-9
lines changed

src/dapp-tests/integration/tests.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ dapp_testnet
5252

5353
# tests the behaviour of the package local dapp remappings
5454
dapp_remappings() {
55+
REV="fde82bd3319f7a1407a21553d120927d99a95f26"
5556
TMPDIR=$(mktemp -d)
5657
git clone https://github.com/dapphub/remappings-test "$TMPDIR"
57-
(cd "$TMPDIR" && dapp update && dapp test)
58+
(cd "$TMPDIR" && git checkout "$REV" && dapp update && dapp test)
5859
}
5960

6061
dapp_remappings

src/dapp/libexec/dapp/dapp-remappings

+54-8
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,59 @@
11
#!/usr/bin/env node
2+
const PROGRAM_NAME = process.argv[1].replace(/.*\//, "")
23

3-
console.log(buildRemappings(".").join("\n"))
4+
const tree = buildDependencyTree(".")
5+
console.log(buildRemappings(deduplicate(mapHashes(tree), tree)).join("\n"))
6+
7+
// builds a in memory representation of the projects dependency tree
8+
//
9+
// A node in the tree looks like this:
10+
//
11+
// {
12+
// name: "",
13+
// path: "",
14+
// hash: "",
15+
// deps: []
16+
// }
17+
function buildDependencyTree(prefix) {
18+
if (ls(prefix).includes(".git") != true) {
19+
console.error(`${PROGRAM_NAME}: error: ${prefix} is not a Git repository`)
20+
console.error(`${PROGRAM_NAME}: error: try "dapp update" to initialize submodules`)
21+
process.exit(1)
22+
}
423

5-
function buildRemappings(prefix) {
624
const lib = `${prefix}/${process.env.DAPP_LIB}`
7-
const ctx = `${prefix}/${process.env.DAPP_SRC}`
25+
return {
26+
name: prefix.split("/").pop(),
27+
path: normalize(`${prefix}/${process.env.DAPP_SRC}`),
28+
hash: run("git", ["-C", prefix, "rev-parse", "HEAD"]),
29+
deps: ls(lib).map(p => buildDependencyTree(`${lib}/${p}`))
30+
}
31+
}
832

9-
const remappings = ls(lib).map(name => {
10-
return `${normalize(ctx)}:${name}/=${normalize(lib)}/${name}/${process.env.DAPP_SRC}/`
33+
// walk tree and build remappings
34+
function buildRemappings(pkg) {
35+
const remappings = pkg.deps.map(dep => {
36+
return `${pkg.path}/:${dep.name}/=${dep.path}/`
1137
})
38+
return pkg.deps.map(buildRemappings).concat(remappings).flat()
39+
}
1240

13-
return ls(lib).map(name => {
14-
return buildRemappings(`${lib}/${name}`)
15-
}).concat(remappings).flat()
41+
// walk tree and build a mapping from hash => path
42+
function mapHashes(pkg) {
43+
const go = (mapping, dep) => {
44+
mapping[dep.hash] = dep.path
45+
return dep.deps.reduce(go, mapping)
46+
}
47+
return tree.deps.reduce(go, { [pkg.hash]: pkg.path })
48+
}
49+
50+
// walk tree and rewrite paths so that all packages with the same hash have the same path
51+
function deduplicate(mapping, pkg) {
52+
return {
53+
...pkg,
54+
path: mapping[pkg.hash],
55+
deps: pkg.deps.map(dep => deduplicate(mapping, dep))
56+
}
1657
}
1758

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

72+
function run(cmd, args) {
73+
return require("child_process").execFileSync(cmd, args, {
74+
encoding: "utf-8"
75+
})
76+
}

0 commit comments

Comments
 (0)