diff --git a/lib/compiler/saveOutput.ts b/lib/compiler/saveOutput.ts index 7db121fc0..eb84c508f 100644 --- a/lib/compiler/saveOutput.ts +++ b/lib/compiler/saveOutput.ts @@ -1,7 +1,8 @@ -import {join, dirname} from 'path'; +import {join} from 'path'; import fs from 'fs'; import {Config} from '../config/config'; import {getHumanReadableAbi} from './getHumanReadableAbi'; +import mkdirp from 'mkdirp'; export interface BytecodeJson { linkReferences: object; @@ -27,9 +28,16 @@ export interface ContractJson { evm: EvmJson; } -export async function saveOutput(output: any, config: Config, filesystem = fs) { +const fsOps = { + createDirectory: mkdirp.sync, + writeFile: fs.writeFileSync +}; + +export async function saveOutput(output: any, config: Config, filesystem = fsOps) { config.outputType = config.outputType || 'multiple'; + filesystem.createDirectory(config.targetPath); + if (['multiple', 'all'].includes(config.outputType)) { saveOutputSingletons(output, config, filesystem); } @@ -39,20 +47,16 @@ export async function saveOutput(output: any, config: Config, filesystem = fs) { } } -export async function saveOutputSingletons(output: any, config: Config, filesystem = fs) { +async function saveOutputSingletons(output: any, config: Config, filesystem = fsOps) { for (const [, file] of Object.entries(output.contracts)) { for (const [contractName, contractJson] of Object.entries(file)) { const filePath = join(config.targetPath, `${contractName}.json`); - const dirPath = dirname(filePath); - if (!filesystem.existsSync(dirPath)) { - filesystem.mkdirSync(dirPath); - } - filesystem.writeFileSync(filePath, getContent(contractJson, config)); + filesystem.writeFile(filePath, getContent(contractJson, config)); } } } -export async function saveOutputCombined(output: any, config: Config, filesystem = fs) { +async function saveOutputCombined(output: any, config: Config, filesystem = fsOps) { for (const [key, file] of Object.entries(output.contracts)) { for (const [contractName, contractJson] of Object.entries(file)) { contractJson.bin = contractJson.evm.bytecode.object; @@ -75,7 +79,7 @@ export async function saveOutputCombined(output: any, config: Config, filesystem output.sourceList = allSources; - filesystem.writeFileSync( + filesystem.writeFile( join(config.targetPath, 'Combined-Json.json'), JSON.stringify(output, null, 2) ); } diff --git a/package.json b/package.json index 5b018db4e..050b00ff5 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@types/ganache-core": "^2.7.0", "ethers": "^4.0.0", "ganache-core": "^2.8.0", + "mkdirp": "^0.5.1", "solc": "^0.5.10" }, "resolutions": { @@ -39,6 +40,7 @@ "@types/chai-as-promised": "^7.1.2", "@types/chai-string": "^1.4.2", "@types/fs-extra": "^8.0.1", + "@types/mkdirp": "^0.5.2", "@types/mocha": "^5.2.7", "@types/sinon": "^7.5.0", "@types/sinon-chai": "^3.2.3", diff --git a/test/compiler/e2e.ts b/test/compiler/e2e.ts index d0ce298fc..3bc86da7b 100644 --- a/test/compiler/e2e.ts +++ b/test/compiler/e2e.ts @@ -30,14 +30,14 @@ const artifacts = [ describe('E2E: Compiler integration', async () => { describe('docker: inside out directory structure', () => { before(async () => { - fsx.removeSync('test/projects/insideOut/build'); + fsx.removeSync('test/projects/insideOut/build/nested'); process.chdir('test/projects/insideOut/main'); }); it('compile and produce artifacts', async () => { await compileProject('config_docker.json'); for (const artefact of artifacts) { - const filePath = join('../build', artefact); + const filePath = join('../build/nested', artefact); expect(isFile(filePath), `Expected compilation artefact "${filePath}" to exist.`).to.equal(true); } }); diff --git a/test/compiler/wrappers/saveOutput.ts b/test/compiler/wrappers/saveOutput.ts index b37c00475..c620984dd 100644 --- a/test/compiler/wrappers/saveOutput.ts +++ b/test/compiler/wrappers/saveOutput.ts @@ -10,14 +10,14 @@ const config = {sourcesPath, npmPath, targetPath}; describe('UNIT: saveOutput', () => { it('calls the required fs methods', () => { - const fs = { - writeFileSync: sinon.spy(), - existsSync: sinon.spy(), - mkdirSync: sinon.spy() + const fsOps = { + writeFile: sinon.spy(), + createDirectory: sinon.spy() }; const output = JSON.parse(readFileContent('./test/compiler/wrappers/compilerOutput.json')); - saveOutput(output, config, fs as any); + saveOutput(output, config, fsOps); const expectedContent = JSON.stringify(output.contracts['One.sol'].One, null, 2); - expect(fs.writeFileSync).to.be.calledWith('buildtmp/One.json', expectedContent); + expect(fsOps.createDirectory).to.be.calledWith('./buildtmp'); + expect(fsOps.writeFile).to.be.calledWith('buildtmp/One.json', expectedContent); }); }); diff --git a/test/projects/insideOut/main/config_docker.json b/test/projects/insideOut/main/config_docker.json index b42843c42..fc1c7375c 100644 --- a/test/projects/insideOut/main/config_docker.json +++ b/test/projects/insideOut/main/config_docker.json @@ -1,7 +1,7 @@ { "name": "solidity 5, dokerized solc, inside out directory structure", "sourcesPath": "./contracts", - "targetPath": "../build", + "targetPath": "../build/nested", "npmPath": "../modules", "compiler": "dockerized-solc" } diff --git a/yarn.lock b/yarn.lock index 4b56b8c10..6a9de8f9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -144,6 +144,13 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A== +"@types/mkdirp@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" + integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== + dependencies: + "@types/node" "*" + "@types/mocha@^5.2.7": version "5.2.7" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea"