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 2 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
15 changes: 11 additions & 4 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 {
function replaceRootDirectory(
sourcePath: string,
rootDirectory: string,
replacement: 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
}
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:/" //only one slash, other will already be present
Copy link
Contributor

@eggplantzzz eggplantzzz Jun 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is a little pedantic but is it technically more proper to have this argument be the complete replacement string? Then we should strip off the relative path portion and replace it with "exactly" what we will be using? Like what if (and yeah, I think this is pretty pedantic) one day we decide to use "project::" instead of "project:/"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree about replacement style - better to replace the whole thing

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on that as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I've changed this.

);

// 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