diff --git a/src/license-plugin-option.js b/src/license-plugin-option.js index b903108f..d18f3b86 100644 --- a/src/license-plugin-option.js +++ b/src/license-plugin-option.js @@ -64,6 +64,10 @@ const SCHEMA = { Joi.object().keys({ file: Joi.string(), encoding: Joi.string(), + template: [ + Joi.string(), + Joi.func(), + ], }), ], }), diff --git a/src/license-plugin.js b/src/license-plugin.js index 14e337bb..95ba442e 100644 --- a/src/license-plugin.js +++ b/src/license-plugin.js @@ -290,12 +290,18 @@ class LicensePlugin { } // Default is to export to given file. - const text = _.chain(dependencies) - .map((dependency) => dependency.text()) - .join(`${EOL}${EOL}---${EOL}${EOL}`) - .trim() - .value(); + // Allow custom formatting of output using given template option. + const template = _.isString(output.template) ? (dependencies) => _.template(output.template)({dependencies}) : output.template; + const defaultTemplate = (dependencies) => { + if (_.isEmpty(dependencies)) { + return 'No third parties dependencies'; + } + + return _.chain(dependencies).map((dependency) => dependency.text()).join(`${EOL}${EOL}---${EOL}${EOL}`).value(); + }; + + const text = _.isFunction(template) ? template(dependencies) : defaultTemplate(dependencies); const isOutputFile = _.isString(output); const file = isOutputFile ? output : output.file; const encoding = isOutputFile ? 'utf-8' : (output.encoding || 'utf-8'); @@ -306,7 +312,7 @@ class LicensePlugin { // Create directory if it does not already exist. mkdirp.sync(path.parse(file).dir); - fs.writeFileSync(file, text || 'No third parties dependencies', { + fs.writeFileSync(file, text.trim(), { encoding, }); } diff --git a/test/integration/it.spec.js b/test/integration/it.spec.js index 1131b482..28477fc9 100644 --- a/test/integration/it.spec.js +++ b/test/integration/it.spec.js @@ -124,6 +124,53 @@ describe('Dependency', () => { }); }); + it('should generate bundle with dependency output as a JSON file', (done) => { + const bundleOutput = path.join(tmpDir.name, 'bundle.js'); + const thirdPartyOutput = path.join(tmpDir.name, 'dependencies.json'); + const rollupConfig = { + input: path.join(__dirname, 'bundle.js'), + + output: { + file: bundleOutput, + format: 'es', + }, + + plugins: [ + nodeResolve(), + commonjs(), + + licensePlugin({ + thirdParty: { + output: { + file: thirdPartyOutput, + template(dependencies) { + return JSON.stringify(dependencies); + }, + }, + }, + }), + ], + }; + + rollup.rollup(rollupConfig) + .then((bundle) => bundle.write(rollupConfig.output)) + .then(() => { + fs.readFile(thirdPartyOutput, 'utf8', (err, data) => { + if (err) { + done.fail(err); + } + + const content = data.toString(); + const json = JSON.parse(content); + expect(json).toBeDefined(); + expect(json.length).toBe(1); + expect(json[0].name).toBe('lodash'); + + done(); + }); + }); + }); + it('should generate bundle and export dependencies to given function', (done) => { const bundleOutput = path.join(tmpDir.name, 'bundle.js'); const thirdPartyOutput = jasmine.createSpy('thirdPartyOutput'); diff --git a/test/license-plugin.spec.js b/test/license-plugin.spec.js index 3a37defe..9bf45353 100644 --- a/test/license-plugin.spec.js +++ b/test/license-plugin.spec.js @@ -1458,6 +1458,143 @@ describe('LicensePlugin', () => { }); }); + it('should export list of dependencies to output file using given template', (done) => { + const file = path.join(tmpDir.name, 'third-party.txt'); + const template = + '<% _.forEach(dependencies, function (dependency) {%>' + + '<%= dependency.name %> => <%= dependency.version %> (<%= dependency.license %>)' + + '<% }) %>'; + + const instance = licensePlugin({ + thirdParty: { + output: { + template, + file, + }, + }, + }); + + instance.addDependency({ + name: 'foo', + version: '1.0.0', + description: 'Foo Package', + license: 'MIT', + private: false, + author: { + name: 'Mickael Jeanroy', + email: 'mickael.jeanroy@gmail.com', + }, + }); + + const result = instance.exportThirdParties(); + + expect(result).not.toBeDefined(); + + fs.readFile(file, 'utf-8', (err, content) => { + if (err) { + done.fail(err); + return; + } + + const txt = content.toString(); + expect(txt).toBeDefined(); + expect(txt).toEqual('foo => 1.0.0 (MIT)'); + + done(); + }); + }); + + it('should export list of dependencies to output JSON file using given template', (done) => { + const file = path.join(tmpDir.name, 'third-party.json'); + const template = jasmine.createSpy('template').and.callFake((dependencies) => JSON.stringify(dependencies)); + const instance = licensePlugin({ + thirdParty: { + output: { + template, + file, + }, + }, + }); + + instance.addDependency({ + name: 'foo', + version: '1.0.0', + description: 'Foo Package', + license: 'MIT', + private: false, + author: { + name: 'Mickael Jeanroy', + email: 'mickael.jeanroy@gmail.com', + }, + }); + + const result = instance.exportThirdParties(); + + expect(result).not.toBeDefined(); + + fs.readFile(file, 'utf-8', (err, content) => { + if (err) { + done.fail(err); + return; + } + + const txt = content.toString(); + const json = JSON.parse(txt); + + expect(json).toBeDefined(); + expect(json.length).toBe(1); + expect(json[0].name).toBe('foo'); + + done(); + }); + }); + + it('should export list of dependencies to output file using given template function', (done) => { + const file = path.join(tmpDir.name, 'third-party.txt'); + const template = jasmine.createSpy('template').and.callFake((dependencies) => ( + dependencies.map((dependency) => `${dependency.name} => ${dependency.version} (${dependency.license})`).join('\n') + )); + + const instance = licensePlugin({ + thirdParty: { + output: { + template, + file, + }, + }, + }); + + instance.addDependency({ + name: 'foo', + version: '1.0.0', + description: 'Foo Package', + license: 'MIT', + private: false, + author: { + name: 'Mickael Jeanroy', + email: 'mickael.jeanroy@gmail.com', + }, + }); + + const result = instance.exportThirdParties(); + + expect(result).not.toBeDefined(); + + fs.readFile(file, 'utf-8', (err, content) => { + if (err) { + done.fail(err); + return; + } + + const txt = content.toString(); + expect(txt).toBeDefined(); + expect(txt).toEqual('foo => 1.0.0 (MIT)'); + expect(template).toHaveBeenCalled(); + + done(); + }); + }); + it('should not try to export dependencies without output configuration', () => { const instance = licensePlugin();