diff --git a/packages/abi-gen/CHANGELOG.json b/packages/abi-gen/CHANGELOG.json index f0a4d200e8..8ed7e92309 100644 --- a/packages/abi-gen/CHANGELOG.json +++ b/packages/abi-gen/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "2.0.11", + "changes": [ + { + "note": "Watch template files for changes", + "pr": 1875 + } + ] + }, { "timestamp": 1557507213, "version": "2.0.10", diff --git a/packages/abi-gen/src/index.ts b/packages/abi-gen/src/index.ts index 854dda4e0a..347ed6bd75 100644 --- a/packages/abi-gen/src/index.ts +++ b/packages/abi-gen/src/index.ts @@ -58,8 +58,12 @@ const args = yargs 'Full usage example', ).argv; -function registerPartials(partialsGlob: string): void { - const partialTemplateFileNames = globSync(partialsGlob); +const mainTemplate = utils.getNamedContent(args.template); +const template = Handlebars.compile(mainTemplate.content); +const abiFileNames = globSync(args.abis); +const partialTemplateFileNames = globSync(args.partials); + +function registerPartials(): void { logUtils.log(`Found ${chalk.green(`${partialTemplateFileNames.length}`)} ${chalk.bold('partial')} templates`); for (const partialTemplateFileName of partialTemplateFileNames) { const namedContent = utils.getNamedContent(partialTemplateFileName); @@ -70,12 +74,7 @@ function registerPartials(partialsGlob: string): void { Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input, args.backend)); Handlebars.registerHelper('assertionType', utils.solTypeToAssertion.bind(utils)); Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output, args.backend)); -if (args.partials) { - registerPartials(args.partials); -} -const mainTemplate = utils.getNamedContent(args.template); -const template = Handlebars.compile(mainTemplate.content); -const abiFileNames = globSync(args.abis); +registerPartials(); if (_.isEmpty(abiFileNames)) { logUtils.log(`${chalk.red(`No ABI files found.`)}`); @@ -109,7 +108,7 @@ for (const abiFileName of abiFileNames) { const outFileName = utils.makeOutputFileName(namedContent.name); const outFilePath = `${args.output}/${outFileName}.ts`; - if (utils.isOutputFileUpToDate(abiFileName, outFilePath)) { + if (utils.isOutputFileUpToDate(outFilePath, [abiFileName, args.template, ...partialTemplateFileNames])) { logUtils.log(`Already up to date: ${chalk.bold(outFilePath)}`); continue; } diff --git a/packages/abi-gen/src/utils.ts b/packages/abi-gen/src/utils.ts index 5ac860d3d3..b2f642f5bd 100644 --- a/packages/abi-gen/src/utils.ts +++ b/packages/abi-gen/src/utils.ts @@ -138,11 +138,11 @@ export const utils = { writeOutputFile(filePath: string, renderedTsCode: string): void { fs.writeFileSync(filePath, renderedTsCode); }, - isOutputFileUpToDate(abiFile: string, outputFile: string): boolean { - const abiFileModTimeMs = fs.statSync(abiFile).mtimeMs; + isOutputFileUpToDate(outputFile: string, sourceFiles: string[]): boolean { + const sourceFileModTimeMs = sourceFiles.map(file => fs.statSync(file).mtimeMs); try { const outFileModTimeMs = fs.statSync(outputFile).mtimeMs; - return outFileModTimeMs > abiFileModTimeMs; + return sourceFileModTimeMs.find(sourceMs => sourceMs > outFileModTimeMs) === undefined; } catch (err) { if (err.code === 'ENOENT') { return false; diff --git a/packages/abi-gen/test/utils_test.ts b/packages/abi-gen/test/utils_test.ts index 820c0c675c..f13d2ab227 100644 --- a/packages/abi-gen/test/utils_test.ts +++ b/packages/abi-gen/test/utils_test.ts @@ -42,7 +42,7 @@ describe('writeOutputFile()', () => { describe('isOutputFileUpToDate()', () => { it('should throw ENOENT when there is no abi file', () => { - expect(utils.isOutputFileUpToDate.bind('nonexistant1', 'nonexistant2')).to.throw('ENOENT'); + expect(utils.isOutputFileUpToDate.bind('', 'nonexistant1', ['nonexistant2'])).to.throw('ENOENT'); }); describe('when the abi input file exists', () => { @@ -55,7 +55,7 @@ describe('isOutputFileUpToDate()', () => { describe('without an existing output file', () => { it('should return false', () => { - expect(utils.isOutputFileUpToDate(abiFile, 'nonexistant_file')).to.be.false(); + expect(utils.isOutputFileUpToDate('nonexistant_file', [abiFile])).to.be.false(); }); }); @@ -71,7 +71,7 @@ describe('isOutputFileUpToDate()', () => { }); it('should return true when output file is newer than abi file', async () => { - expect(utils.isOutputFileUpToDate(abiFile, outputFile)).to.be.true(); + expect(utils.isOutputFileUpToDate(outputFile, [abiFile])).to.be.true(); }); it('should return false when output file exists but is older than abi file', () => { @@ -79,7 +79,19 @@ describe('isOutputFileUpToDate()', () => { const abiFileModTimeMs = outFileModTimeMs + 1; fs.utimesSync(abiFile, abiFileModTimeMs, abiFileModTimeMs); - expect(utils.isOutputFileUpToDate(abiFile, outputFile)).to.be.false(); + expect(utils.isOutputFileUpToDate(outputFile, [abiFile])).to.be.false(); + }); + it('should return false when any source file is newer than output file', () => { + const templateFile = tmp.fileSync( + { discardDescriptor: true }, // close file (set timestamp) + ).name; + + const templateFileModTimeMs = fs.statSync(outputFile).mtimeMs + 1; + const abiFileModTimeMs = fs.statSync(outputFile).mtimeMs; + fs.utimesSync(templateFile, templateFileModTimeMs, templateFileModTimeMs); + fs.utimesSync(abiFile, abiFileModTimeMs, abiFileModTimeMs); + + expect(utils.isOutputFileUpToDate(outputFile, [abiFile, templateFile])).to.be.false(); }); }); });