Skip to content

Commit

Permalink
Add Buidler support
Browse files Browse the repository at this point in the history
  • Loading branch information
alcuadrado committed Sep 13, 2020
1 parent eaa0074 commit e1f2538
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 44 deletions.
26 changes: 6 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

[![npm](https://img.shields.io/npm/v/truffle-flattener.svg)](https://www.npmjs.com/package/truffle-flattener)

Truffle Flattener concats solidity files developed under Truffle with all of
their dependencies.
Truffle Flattener concats solidity files from Truffle and Buidler projects
with all of their dependencies.

This tool helps you to verify contracts developed with Truffle on
[Etherscan](https://etherscan.io), or debugging them on
This tool helps you to verify contracts developed with Truffle and Buidler
on [Etherscan](https://etherscan.io), or debugging them on
[Remix](https://remix.ethereum.org), by merging your files and their
dependencies in the right order.

Check out [Buidler](https://github.com/nomiclabs/buidler), our alternative to
Truffle. It's got flattening built-in, it's faster, and much more flexible.
If you are still using Truffle, we recommend you try [Buidler](https://github.com/nomiclabs/buidler),
our Ethereum development environment, which is much faster and flexible.

# Installation

Expand All @@ -22,21 +22,7 @@ Truffle. It's got flattening built-in, it's faster, and much more flexible.
Just intall it with npm in your truffle project and run
`truffle-flattener <solidity-files>`.

# Why not [Solidity Flattener](https://github.com/BlockCatIO/solidity-flattener)?

This project is a [Truffle](https://github.com/trufflesuite/truffle) specific
reimplementation of Solidity Flattener. By being closely coupled to Truffle it
can take advantage of its dependencies resolution logic making `--solc-paths` a
thing of the past. It also supports flattening more than one file at once,
concatenating everything in the right order, whithout duplicating any file.

# Limitations

If you deploy your contracts with truffle's migrations the output of
`truffle-flattener` may not match while verifying it in Etherscan. You
can use [Solidity Flattener](https://github.com/BlockCatIO/solidity-flattener)
in that case, or deploy your contracts from [Remix](https://remix.ethereum.org).


Aliased imports (eg: `import {symbol1 as alias, symbol2} from "filename";`) are
not supported by `truffle-flattener`.
55 changes: 31 additions & 24 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ async function dependenciesDfs(graph, visitedFiles, filePath) {
}
}

async function getSortedFilePaths(entryPoints, truffleRoot) {
async function getSortedFilePaths(entryPoints, projectRoot) {
const graph = tsort();
const visitedFiles = [];

Expand All @@ -100,7 +100,7 @@ async function getSortedFilePaths(entryPoints, truffleRoot) {
// add them and then dedup the array
const withEntries = topologicalSortedFiles
.concat(entryPoints)
.map(f => fileNameToGlobalName(f, truffleRoot));
.map(f => fileNameToGlobalName(f, projectRoot));

const files = unique(withEntries);

Expand All @@ -115,8 +115,8 @@ async function fileContentWithoutImports(filePath) {
return output.trim() + "\n";
}

function fileNameToGlobalName(fileName, truffleRoot) {
let globalName = getFilePathsFromTruffleRoot([fileName], truffleRoot)[0];
function fileNameToGlobalName(fileName, projectRoot) {
let globalName = getFilePathsFromProjectRoot([fileName], projectRoot)[0];
if (globalName.indexOf("node_modules/") !== -1) {
globalName = globalName.substr(
globalName.indexOf("node_modules/") + "node_modules/".length
Expand All @@ -127,52 +127,59 @@ function fileNameToGlobalName(fileName, truffleRoot) {
}

async function printContactenation(files, log) {
const parts = await Promise.all(files.map(async (file) => {
return "// File: " + file + "\n\n" + await fileContentWithoutImports(file);
}));
const parts = await Promise.all(
files.map(async file => {
return (
"// File: " + file + "\n\n" + (await fileContentWithoutImports(file))
);
})
);

// add a single empty line between parts
log(parts.join("\n"));
}

async function getTruffleRoot() {
let truffleConfigPath = await findUp(["truffle.js", "truffle-config.js"]);
if (!truffleConfigPath) {
async function getProjectRoot() {
let configFilePath = await findUp([
"truffle.js",
"truffle-config.js",
"buidler.config.js",
"buidler.config.ts"
]);
if (!configFilePath) {
throw new Error(`
Truffle Flattener must be run inside a Truffle project:
truffle.js or truffle-config.js not found
Truffle Flattener must be run inside a Truffle or Buidler project:
truffle.js, truffle-config.js, buidler.config.js, nor buidler.config.ts found
`);
}

return getDirPath(truffleConfigPath);
return getDirPath(configFilePath);
}

function getFilePathsFromTruffleRoot(filePaths, truffleRoot) {
return filePaths.map(f => path.relative(truffleRoot, path.resolve(f)));
function getFilePathsFromProjectRoot(filePaths, projectRoot) {
return filePaths.map(f => path.relative(projectRoot, path.resolve(f)));
}

async function flatten(filePaths, log, root) {
if (root && !fs.existsSync(root)) {
throw new Error(
"The specified root directory does not exist"
);
throw new Error("The specified root directory does not exist");
}

const truffleRoot = root || await getTruffleRoot();
const filePathsFromTruffleRoot = getFilePathsFromTruffleRoot(
const projectRoot = root || (await getProjectRoot());
const filePathsFromProjectRoot = getFilePathsFromProjectRoot(
filePaths,
truffleRoot
projectRoot
);

// TODO: Remove this WD manipulation.
// If this is used as a tool this is OK, but it's not right
// when used as a library.
const wd = process.cwd();
process.chdir(truffleRoot);
process.chdir(projectRoot);

const sortedFiles = await getSortedFilePaths(
filePathsFromTruffleRoot,
truffleRoot
filePathsFromProjectRoot,
projectRoot
);
await printContactenation(sortedFiles, log);

Expand Down

0 comments on commit e1f2538

Please sign in to comment.