Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(get-config): add support for defining plugins as an object
This implementation allows the plugins to be defined as an object instead of an array. The benefit is readability and usability, especially when using yaml format, where empty objects can be left out. In Javascript, the benefit is more limited since it is necessary to put in the empty objects, but even then the configuration should be more intuitive. This is implemented in backwards compatible way, where the original format is still used internally, so nothing should break.
- Loading branch information
Showing
3 changed files
with
115 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// The idea is to still use internally the old format, but to allow the plugins to be object in the configuration. | ||
// This buys some time to figure out what is the format to be used internally, if the old is optimal, or if some | ||
// refactoring would improve the semantic-release somehow (readability, maintainability etc.) | ||
module.exports = (config) => { | ||
if (!config.plugins) return config; // No idea if this is possible, but if it is, then handle the situation the old way | ||
|
||
if (Array.isArray(config.plugins)) { | ||
return config; // The configuration is already in the internally used format | ||
} | ||
|
||
if (config.plugins.constructor === Object) { | ||
const normalizedPlugins = Object.keys(config.plugins).map((key) => { | ||
if (Object.keys(config.plugins[key]).length > 0) { | ||
return [key, config.plugins[key]]; | ||
} | ||
|
||
return key; | ||
}); | ||
return {...config, plugins: normalizedPlugins}; | ||
} | ||
|
||
return config; // Again, if the config object is something unpredictable, just return it and handle it the old way. | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
const test = require('ava'); | ||
const {gitRepo} = require('./helpers/git-utils'); | ||
const {outputJson, writeFile} = require('fs-extra'); | ||
const path = require('path'); | ||
const yaml = require('js-yaml'); | ||
const {stub} = require('sinon'); | ||
const proxyquire = require('proxyquire'); | ||
|
||
test.beforeEach((t) => { | ||
t.context.plugins = stub().returns({}); | ||
t.context.getConfig = proxyquire('../lib/get-config', {'./plugins': t.context.plugins}); | ||
}); | ||
|
||
test('Read options from package.json when plugins are an object', async (t) => { | ||
// Create a git repository, set the current working directory at the root of the repo | ||
const {cwd} = await gitRepo(); | ||
const options = { | ||
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'}, | ||
generateNotes: 'generateNotes', | ||
branches: ['test_branch'], | ||
repositoryUrl: 'https://host.null/owner/module.git', | ||
tagFormat: `v\${version}`, | ||
plugins: { | ||
'plugin-1': {}, | ||
'plugin-2': {plugin2Opt: 'value'}, | ||
}, | ||
}; | ||
// Create package.json in repository root | ||
await outputJson(path.resolve(cwd, 'package.json'), {release: options}); | ||
|
||
const {options: result} = await t.context.getConfig({cwd}); | ||
|
||
const expected = {...options, branches: ['test_branch'], plugins: ['plugin-1', ['plugin-2', {plugin2Opt: 'value'}]]}; | ||
// Verify the options contains the plugin config from package.json | ||
t.deepEqual(result, expected); | ||
// Verify the plugins module is called with the plugin options from package.json | ||
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd}); | ||
}); | ||
|
||
test('Read options from .releaserc.yml when plugins are an object', async (t) => { | ||
// Create a git repository, set the current working directory at the root of the repo | ||
const {cwd} = await gitRepo(); | ||
const options = { | ||
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'}, | ||
branches: ['test_branch'], | ||
repositoryUrl: 'https://host.null/owner/module.git', | ||
tagFormat: `v\${version}`, | ||
plugins: { | ||
'plugin-1': {}, | ||
'plugin-2': {plugin2Opt: 'value'}, | ||
}, | ||
}; | ||
// Create package.json in repository root | ||
await writeFile(path.resolve(cwd, '.releaserc.yml'), yaml.dump(options)); | ||
|
||
const {options: result} = await t.context.getConfig({cwd}); | ||
|
||
const expected = {...options, branches: ['test_branch'], plugins: ['plugin-1', ['plugin-2', {plugin2Opt: 'value'}]]}; | ||
// Verify the options contains the plugin config from package.json | ||
t.deepEqual(result, expected); | ||
// Verify the plugins module is called with the plugin options from package.json | ||
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd}); | ||
}); | ||
|
||
test('Read options from .releaserc.json when plugins are an object', async (t) => { | ||
// Create a git repository, set the current working directory at the root of the repo | ||
const {cwd} = await gitRepo(); | ||
const options = { | ||
analyzeCommits: {path: 'analyzeCommits', param: 'analyzeCommits_param'}, | ||
branches: ['test_branch'], | ||
repositoryUrl: 'https://host.null/owner/module.git', | ||
tagFormat: `v\${version}`, | ||
plugins: { | ||
'plugin-1': {}, | ||
'plugin-2': {plugin2Opt: 'value'}, | ||
}, | ||
}; | ||
// Create package.json in repository root | ||
await outputJson(path.resolve(cwd, '.releaserc.json'), options); | ||
|
||
const {options: result} = await t.context.getConfig({cwd}); | ||
|
||
const expected = {...options, branches: ['test_branch'], plugins: ['plugin-1', ['plugin-2', {plugin2Opt: 'value'}]]}; | ||
// Verify the options contains the plugin config from package.json | ||
t.deepEqual(result, expected); | ||
// Verify the plugins module is called with the plugin options from package.json | ||
t.deepEqual(t.context.plugins.args[0][0], {options: expected, cwd}); | ||
}); |