From d2d9c96bc3f7bf93e4ff225ac071146d9592c093 Mon Sep 17 00:00:00 2001 From: Mickael Jeanroy Date: Fri, 9 Aug 2019 18:41:12 +0200 Subject: [PATCH] refactor: deprecate thirdParty.encoding property --- src/license-plugin-option.js | 44 +++++++++++++- src/license-plugin.js | 10 ++-- test/integration/it.spec.js | 40 +++++++++++++ test/license-plugin-option.spec.js | 57 ++++++++++++++++++ test/license-plugin.spec.js | 92 ++++++++++++++++-------------- 5 files changed, 193 insertions(+), 50 deletions(-) diff --git a/src/license-plugin-option.js b/src/license-plugin-option.js index 33c06b31..844cd3c9 100644 --- a/src/license-plugin-option.js +++ b/src/license-plugin-option.js @@ -56,10 +56,13 @@ const SCHEMA = { thirdParty: Joi.object().keys({ includePrivate: Joi.boolean(), - encoding: Joi.string(), output: [ Joi.func(), Joi.string(), + Joi.object().keys({ + file: Joi.string(), + encoding: Joi.string(), + }), ], }), }; @@ -153,6 +156,43 @@ function fixBannerOptions(options) { }); } +/** + * Fix option object, replace `thirdParty.encoding` with `thirdParty.output.encoding`. + * + * @param {Object} options Original option object. + * @return {Object} The new fixed option object. + */ +function fixThirdPartyOptions(options) { + if (!_.hasIn(options, 'thirdParty')) { + return options; + } + + const thirdParty = options.thirdParty; + if (!_.hasIn(thirdParty, 'encoding')) { + return options; + } + + warn( + '"thirdParty.encoding" has been deprecated and will be removed in a future version, ' + + 'please use "thirdParty.output.encoding" instead.' + ); + + const newThirdParty = _.omitBy(thirdParty, (value, key) => ( + key === 'encoding' + )); + + if (_.isString(thirdParty.output)) { + newThirdParty.output = { + file: thirdParty.output, + encoding: thirdParty.encoding, + }; + } + + return _.extend({}, options, { + thirdParty: newThirdParty, + }); +} + /** * Normalize option object by removing deprecated options and migrate these to the new version. * @@ -160,7 +200,7 @@ function fixBannerOptions(options) { * @return {Object} Normalized option object. */ function normalizeOptions(options) { - return _.reduce([fixSourceMapOptions, fixBannerOptions], (acc, fn) => fn(acc), options); + return _.reduce([fixSourceMapOptions, fixBannerOptions, fixThirdPartyOptions], (acc, fn) => fn(acc), options); } /** diff --git a/src/license-plugin.js b/src/license-plugin.js index 431bdd97..f3919f61 100644 --- a/src/license-plugin.js +++ b/src/license-plugin.js @@ -282,15 +282,17 @@ class LicensePlugin { .trim() .value(); - const encoding = thirdParty.encoding || 'utf-8'; + const isOutputFile = _.isString(output); + const file = isOutputFile ? output : output.file; + const encoding = isOutputFile ? 'utf-8' : (output.encoding || 'utf-8'); - this.debug(`exporting third-party summary to ${output}`); + this.debug(`exporting third-party summary to ${file}`); this.debug(`use encoding: ${encoding}`); // Create directory if it does not already exist. - mkdirp.sync(path.parse(output).dir); + mkdirp.sync(path.parse(file).dir); - fs.writeFileSync(output, text || 'No third parties dependencies', { + fs.writeFileSync(file, text || 'No third parties dependencies', { encoding, }); } diff --git a/test/integration/it.spec.js b/test/integration/it.spec.js index e2bdfaa2..1131b482 100644 --- a/test/integration/it.spec.js +++ b/test/integration/it.spec.js @@ -84,6 +84,46 @@ describe('Dependency', () => { }); }); + it('should generate bundle with dependency output as an object', (done) => { + const bundleOutput = path.join(tmpDir.name, 'bundle.js'); + const thirdPartyOutput = path.join(tmpDir.name, 'dependencies.txt'); + + const rollupConfig = { + input: path.join(__dirname, 'bundle.js'), + + output: { + file: bundleOutput, + format: 'es', + }, + + plugins: [ + nodeResolve(), + commonjs(), + + licensePlugin({ + thirdParty: { + output: { + file: thirdPartyOutput, + }, + }, + }), + ], + }; + + rollup.rollup(rollupConfig) + .then((bundle) => bundle.write(rollupConfig.output)) + .then(() => { + fs.readFile(thirdPartyOutput, 'utf8', (err, data) => { + if (err) { + done.fail(err); + } + + expect(data.toString()).toContain('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-option.spec.js b/test/license-plugin-option.spec.js index 45744911..2eb85988 100644 --- a/test/license-plugin-option.spec.js +++ b/test/license-plugin-option.spec.js @@ -148,6 +148,40 @@ describe('licensePluginOptions', () => { }); }); + it('should normalize option object and fix deprecated "thirdParty.encoding" entry', () => { + const warn = spyOn(console, 'warn'); + const options = { + thirdParty: { + output: 'ThirdParty.txt', + encoding: 'utf-16', + }, + }; + + const result = licensePluginOptions(options); + + expect(warn).toHaveBeenCalledWith( + '[rollup-plugin-license] -- "thirdParty.encoding" has been deprecated and will be removed in a future version, ' + + 'please use "thirdParty.output.encoding" instead.' + ); + + expect(result).toEqual({ + thirdParty: { + output: { + file: 'ThirdParty.txt', + encoding: 'utf-16', + }, + }, + }); + + // Ensure original option object has not changed + expect(options).toEqual({ + thirdParty: { + output: 'ThirdParty.txt', + encoding: 'utf-16', + }, + }); + }); + it('should normalize option object and fix deprecated "banner.encoding" entry', () => { const warn = spyOn(console, 'warn'); const options = { @@ -185,11 +219,17 @@ describe('licensePluginOptions', () => { sourceMap: true, cwd: '.', debug: true, + banner: { file: 'LICENSE.md', encoding: 'utf-16', commentStyle: 'regular', }, + + thirdParty: { + output: 'ThirdParty.txt', + encoding: 'utf-8', + }, }; const result = licensePluginOptions(options); @@ -209,10 +249,16 @@ describe('licensePluginOptions', () => { 'please use "banner.content.encoding" instead.' ); + expect(warn).toHaveBeenCalledWith( + '[rollup-plugin-license] -- "thirdParty.encoding" has been deprecated and will be removed in a future version, ' + + 'please use "thirdParty.output.encoding" instead.' + ); + expect(result).toEqual({ sourcemap: true, cwd: '.', debug: true, + banner: { commentStyle: 'regular', content: { @@ -220,6 +266,13 @@ describe('licensePluginOptions', () => { encoding: 'utf-16', }, }, + + thirdParty: { + output: { + file: 'ThirdParty.txt', + encoding: 'utf-8', + }, + }, }); // Ensure original option object has not changed @@ -232,6 +285,10 @@ describe('licensePluginOptions', () => { encoding: 'utf-16', commentStyle: 'regular', }, + thirdParty: { + output: 'ThirdParty.txt', + encoding: 'utf-8', + }, }); }); }); diff --git a/test/license-plugin.spec.js b/test/license-plugin.spec.js index acb647d8..3019e3e9 100644 --- a/test/license-plugin.spec.js +++ b/test/license-plugin.spec.js @@ -466,9 +466,9 @@ describe('LicensePlugin', () => { }); it('should prepend banner to bundle with custom encoding', () => { - spyOn(fs, 'readFileSync').and.callThrough(); - + const readFileSync = spyOn(fs, 'readFileSync').and.callThrough(); const encoding = 'ascii'; + const code = 'var foo = 0;'; const instance = licensePlugin({ banner: { content: { @@ -478,11 +478,9 @@ describe('LicensePlugin', () => { }, }); - const code = 'var foo = 0;'; - const result = instance.prependBanner(code); - expect(fs.readFileSync).toHaveBeenCalledWith(jasmine.any(String), encoding); + expect(readFileSync).toHaveBeenCalledWith(jasmine.any(String), encoding); expect(result).toBeDefined(); expect(result.map).toBeDefined(); expect(result.code).toEqual(join([ @@ -498,13 +496,13 @@ describe('LicensePlugin', () => { it('should prepend banner to bundle from (deprecated) file option', () => { const warn = spyOn(console, 'warn'); + const code = 'var foo = 0;'; const instance = licensePlugin({ banner: { file: path.join(__dirname, 'fixtures', 'banner.js'), }, }); - const code = 'var foo = 0;'; const result = instance.prependBanner(code); @@ -654,6 +652,7 @@ describe('LicensePlugin', () => { }); it('should prepend banner and create block comment', () => { + const code = 'var foo = 0;'; const instance = licensePlugin({ banner: { content: { @@ -662,8 +661,6 @@ describe('LicensePlugin', () => { }, }); - const code = 'var foo = 0;'; - const result = instance.prependBanner(code); expect(result).toBeDefined(); @@ -1073,11 +1070,13 @@ describe('LicensePlugin', () => { it('should export list of dependencies with custom encoding to given file', (done) => { const file = path.join(tmpDir.name, 'third-party.txt'); - const encoding = 'ascii'; + const encoding = 'base64'; const instance = licensePlugin({ thirdParty: { - output: file, - encoding, + output: { + file, + encoding, + }, }, }); @@ -1086,54 +1085,59 @@ describe('LicensePlugin', () => { 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, encoding, (err, content) => { + if (err) { + done.fail(err); + return; + } + + expect(content).toBeDefined(); + expect(content).toContain('foo'); + + done(); + }); + }); + + it('should export list of dependencies with (deprecated) custom encoding to given file', (done) => { + const warn = spyOn(console, 'warn'); + const output = path.join(tmpDir.name, 'third-party.txt'); + const encoding = 'base64'; + const instance = licensePlugin({ + thirdParty: { + output, + encoding, }, }); instance.addDependency({ - name: 'bar', - version: '2.0.0', - description: 'Bar Package', - license: 'Apache 2.0', - private: false, + name: 'foo', + version: '1.0.0', + description: 'Foo Package', + license: 'MIT', }); - spyOn(fs, 'writeFileSync').and.callThrough(); - const result = instance.exportThirdParties(); expect(result).not.toBeDefined(); - expect(fs.writeFileSync).toHaveBeenCalledWith(jasmine.any(String), jasmine.any(String), { - encoding, - }); - fs.readFile(file, encoding, (err, content) => { + fs.readFile(output, encoding, (err, content) => { if (err) { done.fail(err); return; } - const txt = content.toString(); - expect(txt).toBeDefined(); - expect(txt).toEqual(join([ - 'Name: foo', - 'Version: 1.0.0', - 'License: MIT', - 'Private: false', - 'Description: Foo Package', - 'Author: Mickael Jeanroy ', - '', - '---', - '', - 'Name: bar', - 'Version: 2.0.0', - 'License: Apache 2.0', - 'Private: false', - 'Description: Bar Package', - ])); + expect(content).toBeDefined(); + expect(content).toContain('foo'); + expect(warn).toHaveBeenCalledWith( + '[rollup-plugin-license] -- "thirdParty.encoding" has been deprecated and will be removed in a future version, ' + + 'please use "thirdParty.output.encoding" instead.' + ); done(); });