Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Replace project directory in metadata with "project://" #4137

Merged
merged 3 commits into from
Jun 29, 2021
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
21 changes: 14 additions & 7 deletions packages/compile-common/src/sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@ import * as path from "path";
*
* @param originalSources - { [originalSourcePath]: contents }
* @param originalTargets - originalSourcePath[]
* @param baseDirectory - a directory to remove as a prefix
* @param replacement - what to replace it with
* @return { sources, targets, originalSourcePaths }
*/
export function collectSources(
originalSources: Sources,
originalTargets: string[] = [],
contractsDirectory: string = "" //only used by Vyper atm
baseDirectory: string = "",
replacement: string = "/"
): CollectedSources {
const mappedResults = Object.entries(originalSources)
.map(([originalSourcePath, contents]) => ({
originalSourcePath,
contents,
sourcePath: getPortableSourcePath(
removeRootDirectory(originalSourcePath, contractsDirectory)
replaceRootDirectory(originalSourcePath, baseDirectory, replacement)
)
}))
.map(({ originalSourcePath, sourcePath, contents }) => ({
Expand Down Expand Up @@ -73,12 +76,16 @@ function getPortableSourcePath(sourcePath: string): string {
return replacement;
}

function removeRootDirectory(sourcePath: string, rootDirectory: string): string {
//make sure root directory doesn't end in a separator
if (rootDirectory.endsWith(path.sep)) {
rootDirectory = rootDirectory.slice(0, -1); //remove last character
function replaceRootDirectory(
sourcePath: string,
rootDirectory: string,
replacement: string
): string {
//make sure root directory ends in a separator
if (!rootDirectory.endsWith(path.sep)) {
rootDirectory = rootDirectory + path.sep;
}
return sourcePath.startsWith(rootDirectory)
? sourcePath.slice(rootDirectory.length) //remove prefix
? replacement + sourcePath.slice(rootDirectory.length) //remove prefix
: sourcePath;
}
9 changes: 8 additions & 1 deletion packages/compile-solidity/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@ async function run(rawSources, options, language = "Solidity") {

// Ensure sources have operating system independent paths
// i.e., convert backslashes to forward slashes; things like C: are left intact.
// we also strip the project root (to avoid it appearing in metadata)
// and replace it with "project://"
const {
sources,
targets,
originalSourcePaths
} = Common.Sources.collectSources(rawSources, options.compilationTargets);
} = Common.Sources.collectSources(
rawSources,
options.compilationTargets,
options.working_directory,
"project://"
);

// construct solc compiler input
const compilerInput = prepareCompilerInput({
Expand Down
72 changes: 72 additions & 0 deletions packages/compile-solidity/test/test_metadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const debug = require("debug")("compile:test:test_metadata");
const fs = require("fs");
const path = require("path");
const { Compile } = require("@truffle/compile-solidity");
const CompilerSupplier = require("../compilerSupplier");
const assert = require("assert");
const { findOne } = require("./helpers");
const workingDirectory = "/home/fakename/truffleproject";
const compileOptions = {
working_directory: workingDirectory,
compilers: {
solc: {
version: "0.4.25",
settings: {
optimizer: {
enabled: false,
runs: 200
}
}
}
},
quiet: true
};
const supplierOptions = {
solcConfig: compileOptions.compilers.solc,
events: {
emit: () => {}
}
};

describe("Compile - solidity ^0.4.0", function () {
this.timeout(5000); // solc
let source = null;
let solc = null; // gets loaded via supplier

before("get solc", async function () {
this.timeout(40000);

const supplier = new CompilerSupplier(supplierOptions);
({ solc } = await supplier.load());
});

describe("Metadata", function () {
before("get code", function () {
source = fs.readFileSync(
path.join(__dirname, "./sources/v0.4.x/SimpleOrdered.sol"),
"utf-8"
);
});

it("does not include absolute paths in metadata", async function () {
const sourcePath = `${workingDirectory}/contracts/SimpleOrdered.sol`;
const sources = { [sourcePath]: source };

const { compilations } = await Compile.sources({
sources,
options: compileOptions
});

const SimpleOrdered = findOne("SimpleOrdered", compilations[0].contracts);
const metadata = JSON.parse(SimpleOrdered.metadata);
const metadataSources = Object.keys(metadata.sources);
const metadataTargets = Object.keys(metadata.settings.compilationTarget);
const metadataPaths = metadataSources.concat(metadataTargets);
debug("metadataPaths: %O", metadataPaths);
assert(metadataPaths.every(
sourcePath => sourcePath.startsWith("project://") &&
!sourcePath.includes(workingDirectory)
));
});
});
});
9 changes: 4 additions & 5 deletions packages/compile-vyper/vyper-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ const partition = require("lodash.partition");
function compileJson({ sources: rawSources, options, version, command }) {
const compiler = { name: "vyper", version };

//in order to better support absolute Vyper imports, we pretend that
//the contracts directory is the root directory. note this means that
//if an imported source from somewhere other than FS uses an absolute
//import to refer to its own project root, it won't work. But, oh well.
const {
sources,
targets,
Expand All @@ -33,11 +37,6 @@ function compileJson({ sources: rawSources, options, version, command }) {
: sourcePath => !sourcePath.endsWith(".json")
);

//in order to better support absolute Vyper imports, we pretend that
//the contracts directory is the root directory. note this means that
//if an imported source from somewhere other than FS uses an absolute
//import to refer to its own project root, it won't work. But, oh well.

const properSources = Object.assign(
{},
...properSourcePaths.map(sourcePath => ({
Expand Down