feat(esm): convert to esm (#2569)
for #2543 BREAKING CHANGE: semantic-release is now ESM-only. since it is used through its own executable, the impact on consuming projects should be minimal BREAKING CHANGE: references to plugin files in configs need to include the file extension because of executing in an ESM context
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
const test = require('ava');
|
||||
const {noop} = require('lodash');
|
||||
const {stub} = require('sinon');
|
||||
const normalize = require('../../lib/plugins/normalize');
|
||||
import test from 'ava';
|
||||
import {noop} from 'lodash-es';
|
||||
import {stub} from 'sinon';
|
||||
import normalize from '../../lib/plugins/normalize.js';
|
||||
|
||||
const cwd = process.cwd();
|
||||
|
||||
@@ -23,37 +23,37 @@ test('Normalize and load plugin from string', async (t) => {
|
||||
const plugin = await normalize(
|
||||
{cwd, options: {}, logger: t.context.logger},
|
||||
'verifyConditions',
|
||||
'./test/fixtures/plugin-noop',
|
||||
'./test/fixtures/plugin-noop.cjs',
|
||||
{}
|
||||
);
|
||||
|
||||
t.is(plugin.pluginName, './test/fixtures/plugin-noop');
|
||||
t.is(plugin.pluginName, './test/fixtures/plugin-noop.cjs');
|
||||
t.is(typeof plugin, 'function');
|
||||
t.deepEqual(t.context.success.args[0], ['Loaded plugin "verifyConditions" from "./test/fixtures/plugin-noop"']);
|
||||
t.deepEqual(t.context.success.args[0], ['Loaded plugin "verifyConditions" from "./test/fixtures/plugin-noop.cjs"']);
|
||||
});
|
||||
|
||||
test('Normalize and load plugin from object', async (t) => {
|
||||
const plugin = await normalize(
|
||||
{cwd, options: {}, logger: t.context.logger},
|
||||
'publish',
|
||||
{path: './test/fixtures/plugin-noop'},
|
||||
{path: './test/fixtures/plugin-noop.cjs'},
|
||||
{}
|
||||
);
|
||||
|
||||
t.is(plugin.pluginName, './test/fixtures/plugin-noop');
|
||||
t.is(plugin.pluginName, './test/fixtures/plugin-noop.cjs');
|
||||
t.is(typeof plugin, 'function');
|
||||
t.deepEqual(t.context.success.args[0], ['Loaded plugin "publish" from "./test/fixtures/plugin-noop"']);
|
||||
t.deepEqual(t.context.success.args[0], ['Loaded plugin "publish" from "./test/fixtures/plugin-noop.cjs"']);
|
||||
});
|
||||
|
||||
test('Normalize and load plugin from a base file path', async (t) => {
|
||||
const plugin = await normalize({cwd, options: {}, logger: t.context.logger}, 'verifyConditions', './plugin-noop', {
|
||||
'./plugin-noop': './test/fixtures',
|
||||
const plugin = await normalize({cwd, options: {}, logger: t.context.logger}, 'verifyConditions', './plugin-noop.cjs', {
|
||||
'./plugin-noop.cjs': './test/fixtures',
|
||||
});
|
||||
|
||||
t.is(plugin.pluginName, './plugin-noop');
|
||||
t.is(plugin.pluginName, './plugin-noop.cjs');
|
||||
t.is(typeof plugin, 'function');
|
||||
t.deepEqual(t.context.success.args[0], [
|
||||
'Loaded plugin "verifyConditions" from "./plugin-noop" in shareable config "./test/fixtures"',
|
||||
'Loaded plugin "verifyConditions" from "./plugin-noop.cjs" in shareable config "./test/fixtures"',
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -72,7 +72,7 @@ test('Wrap plugin in a function that add the "pluginName" to multiple errors"',
|
||||
'./plugin-errors': './test/fixtures',
|
||||
});
|
||||
|
||||
const errors = [...(await t.throwsAsync(plugin({options: {}})))];
|
||||
const errors = [...(await t.throwsAsync(plugin({options: {}}))).errors];
|
||||
for (const error of errors) {
|
||||
t.is(error.pluginName, './plugin-errors');
|
||||
}
|
||||
@@ -90,12 +90,12 @@ test('Normalize and load plugin that retuns multiple functions', async (t) => {
|
||||
const plugin = await normalize(
|
||||
{cwd, options: {}, logger: t.context.logger},
|
||||
'verifyConditions',
|
||||
'./test/fixtures/multi-plugin',
|
||||
'./test/fixtures/multi-plugin.cjs',
|
||||
{}
|
||||
);
|
||||
|
||||
t.is(typeof plugin, 'function');
|
||||
t.deepEqual(t.context.success.args[0], ['Loaded plugin "verifyConditions" from "./test/fixtures/multi-plugin"']);
|
||||
t.deepEqual(t.context.success.args[0], ['Loaded plugin "verifyConditions" from "./test/fixtures/multi-plugin.cjs"']);
|
||||
});
|
||||
|
||||
test('Wrap "analyzeCommits" plugin in a function that validate the output of the plugin', async (t) => {
|
||||
@@ -258,7 +258,7 @@ test('Always pass a defined "pluginConfig" for plugin defined with path', async
|
||||
|
||||
test('Throws an error if the plugin return an object without the expected plugin function', async (t) => {
|
||||
const error = await t.throwsAsync(() =>
|
||||
normalize({cwd, options: {}, logger: t.context.logger}, 'inexistantPlugin', './test/fixtures/multi-plugin', {})
|
||||
normalize({cwd, options: {}, logger: t.context.logger}, 'nonExistentPlugin', './test/fixtures/multi-plugin.cjs', {})
|
||||
);
|
||||
|
||||
t.is(error.code, 'EPLUGIN');
|
||||
@@ -269,7 +269,7 @@ test('Throws an error if the plugin return an object without the expected plugin
|
||||
|
||||
test('Throws an error if the plugin is not found', async (t) => {
|
||||
await t.throwsAsync(
|
||||
() => normalize({cwd, options: {}, logger: t.context.logger}, 'inexistantPlugin', 'non-existing-path', {}),
|
||||
() => normalize({cwd, options: {}, logger: t.context.logger}, 'nonExistentPlugin', 'non-existing-path', {}),
|
||||
{
|
||||
message: /Cannot find module 'non-existing-path'/,
|
||||
code: 'MODULE_NOT_FOUND',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const test = require('ava');
|
||||
const {stub} = require('sinon');
|
||||
const AggregateError = require('aggregate-error');
|
||||
const pipeline = require('../../lib/plugins/pipeline');
|
||||
import test from 'ava';
|
||||
import {stub} from 'sinon';
|
||||
import AggregateError from 'aggregate-error';
|
||||
import pipeline from '../../lib/plugins/pipeline.js';
|
||||
|
||||
test('Execute each function in series passing the same input', async (t) => {
|
||||
const step1 = stub().resolves(1);
|
||||
@@ -116,9 +116,9 @@ test('Throw all errors from the first step throwing an AggregateError', async (t
|
||||
const step2 = stub().rejects(new AggregateError([error1, error2]));
|
||||
const step3 = stub().resolves(3);
|
||||
|
||||
const errors = await t.throwsAsync(pipeline([step1, step2, step3])(0));
|
||||
const error = await t.throwsAsync(pipeline([step1, step2, step3])(0));
|
||||
|
||||
t.deepEqual([...errors], [error1, error2]);
|
||||
t.deepEqual([...error.errors], [error1, error2]);
|
||||
t.true(step1.calledWith(0));
|
||||
t.true(step2.calledWith(0));
|
||||
t.true(step3.notCalled);
|
||||
@@ -131,9 +131,9 @@ test('Execute all even if a Promise rejects', async (t) => {
|
||||
const step2 = stub().rejects(error1);
|
||||
const step3 = stub().rejects(error2);
|
||||
|
||||
const errors = await t.throwsAsync(pipeline([step1, step2, step3], {settleAll: true})(0));
|
||||
const error = await t.throwsAsync(pipeline([step1, step2, step3], {settleAll: true})(0));
|
||||
|
||||
t.deepEqual([...errors], [error1, error2]);
|
||||
t.deepEqual([...error.errors], [error1, error2]);
|
||||
t.true(step1.calledWith(0));
|
||||
t.true(step2.calledWith(0));
|
||||
t.true(step3.calledWith(0));
|
||||
@@ -147,9 +147,9 @@ test('Throw all errors from all steps throwing an AggregateError', async (t) =>
|
||||
const step1 = stub().rejects(new AggregateError([error1, error2]));
|
||||
const step2 = stub().rejects(new AggregateError([error3, error4]));
|
||||
|
||||
const errors = await t.throwsAsync(pipeline([step1, step2], {settleAll: true})(0));
|
||||
const error = await t.throwsAsync(pipeline([step1, step2], {settleAll: true})(0));
|
||||
|
||||
t.deepEqual([...errors], [error1, error2, error3, error4]);
|
||||
t.deepEqual([...error.errors], [error1, error2, error3, error4]);
|
||||
t.true(step1.calledWith(0));
|
||||
t.true(step2.calledWith(0));
|
||||
});
|
||||
@@ -163,9 +163,9 @@ test('Execute each function in series passing a transformed input even if a step
|
||||
const step4 = stub().resolves(4);
|
||||
const getNextInput = (previousResult, result) => previousResult + result;
|
||||
|
||||
const errors = await t.throwsAsync(pipeline([step1, step2, step3, step4], {settleAll: true, getNextInput})(0));
|
||||
const error = await t.throwsAsync(pipeline([step1, step2, step3, step4], {settleAll: true, getNextInput})(0));
|
||||
|
||||
t.deepEqual([...errors], [error2, error3]);
|
||||
t.deepEqual([...error.errors], [error2, error3]);
|
||||
t.true(step1.calledWith(0));
|
||||
t.true(step2.calledWith(0 + 1));
|
||||
t.true(step3.calledWith(0 + 1 + error2));
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
const path = require('path');
|
||||
const test = require('ava');
|
||||
const {copy, outputFile} = require('fs-extra');
|
||||
const {stub} = require('sinon');
|
||||
const tempy = require('tempy');
|
||||
const getPlugins = require('../../lib/plugins');
|
||||
import path from 'path';
|
||||
import test from 'ava';
|
||||
import {copy, outputFile} from 'fs-extra';
|
||||
import {stub} from 'sinon';
|
||||
import {temporaryDirectory} from 'tempy';
|
||||
import getPlugins from '../../lib/plugins/index.js';
|
||||
|
||||
// Save the current working diretory
|
||||
// Save the current working directory
|
||||
const cwd = process.cwd();
|
||||
|
||||
test.beforeEach((t) => {
|
||||
@@ -35,9 +35,9 @@ test('Export plugins based on steps config', async (t) => {
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: {
|
||||
verifyConditions: ['./test/fixtures/plugin-noop', {path: './test/fixtures/plugin-noop'}],
|
||||
generateNotes: './test/fixtures/plugin-noop',
|
||||
analyzeCommits: {path: './test/fixtures/plugin-noop'},
|
||||
verifyConditions: ['./test/fixtures/plugin-noop.cjs', {path: './test/fixtures/plugin-noop.cjs'}],
|
||||
generateNotes: './test/fixtures/plugin-noop.cjs',
|
||||
analyzeCommits: {path: './test/fixtures/plugin-noop.cjs'},
|
||||
verifyRelease: () => {},
|
||||
},
|
||||
},
|
||||
@@ -137,9 +137,9 @@ test('Unknown steps of plugins configured in "plugins" are ignored', async (t) =
|
||||
});
|
||||
|
||||
test('Export plugins loaded from the dependency of a shareable config module', async (t) => {
|
||||
const cwd = tempy.directory();
|
||||
const cwd = temporaryDirectory();
|
||||
await copy(
|
||||
'./test/fixtures/plugin-noop.js',
|
||||
'./test/fixtures/plugin-noop.cjs',
|
||||
path.resolve(cwd, 'node_modules/shareable-config/node_modules/custom-plugin/index.js')
|
||||
);
|
||||
await outputFile(path.resolve(cwd, 'node_modules/shareable-config/index.js'), '');
|
||||
@@ -170,8 +170,8 @@ test('Export plugins loaded from the dependency of a shareable config module', a
|
||||
});
|
||||
|
||||
test('Export plugins loaded from the dependency of a shareable config file', async (t) => {
|
||||
const cwd = tempy.directory();
|
||||
await copy('./test/fixtures/plugin-noop.js', path.resolve(cwd, 'plugin/plugin-noop.js'));
|
||||
const cwd = temporaryDirectory();
|
||||
await copy('./test/fixtures/plugin-noop.cjs', path.resolve(cwd, 'plugin/plugin-noop.cjs'));
|
||||
await outputFile(path.resolve(cwd, 'shareable-config.js'), '');
|
||||
|
||||
const plugins = await getPlugins(
|
||||
@@ -179,9 +179,9 @@ test('Export plugins loaded from the dependency of a shareable config file', asy
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: {
|
||||
verifyConditions: ['./plugin/plugin-noop', {path: './plugin/plugin-noop'}],
|
||||
generateNotes: './plugin/plugin-noop',
|
||||
analyzeCommits: {path: './plugin/plugin-noop'},
|
||||
verifyConditions: ['./plugin/plugin-noop.cjs', {path: './plugin/plugin-noop.cjs'}],
|
||||
generateNotes: './plugin/plugin-noop.cjs',
|
||||
analyzeCommits: {path: './plugin/plugin-noop.cjs'},
|
||||
verifyRelease: () => {},
|
||||
},
|
||||
},
|
||||
@@ -269,7 +269,7 @@ test('Throw an error for each invalid plugin configuration', async (t) => {
|
||||
},
|
||||
{}
|
||||
)
|
||||
)),
|
||||
)).errors,
|
||||
];
|
||||
|
||||
t.is(errors[0].name, 'SemanticReleaseError');
|
||||
@@ -289,11 +289,11 @@ test('Throw EPLUGINSCONF error if the "plugins" option contains an old plugin de
|
||||
{
|
||||
cwd,
|
||||
logger: t.context.logger,
|
||||
options: {plugins: ['./test/fixtures/multi-plugin', './test/fixtures/plugin-noop', () => {}]},
|
||||
options: {plugins: ['./test/fixtures/multi-plugin.cjs', './test/fixtures/plugin-noop.cjs', () => {}]},
|
||||
},
|
||||
{}
|
||||
)
|
||||
)),
|
||||
)).errors,
|
||||
];
|
||||
|
||||
t.is(errors[0].name, 'SemanticReleaseError');
|
||||
@@ -306,7 +306,7 @@ test('Throw EPLUGINSCONF error for each invalid definition if the "plugins" opti
|
||||
const errors = [
|
||||
...(await t.throwsAsync(() =>
|
||||
getPlugins({cwd, logger: t.context.logger, options: {plugins: [1, {path: 1}, [() => {}, {}, {}]]}}, {})
|
||||
)),
|
||||
)).errors,
|
||||
];
|
||||
|
||||
t.is(errors[0].name, 'SemanticReleaseError');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const test = require('ava');
|
||||
const {validatePlugin, validateStep, loadPlugin, parseConfig} = require('../../lib/plugins/utils');
|
||||
import test from 'ava';
|
||||
import {loadPlugin, parseConfig, validatePlugin, validateStep} from '../../lib/plugins/utils.js';
|
||||
|
||||
test('validatePlugin', (t) => {
|
||||
const path = 'plugin-module';
|
||||
@@ -193,10 +193,10 @@ test('loadPlugin', async (t) => {
|
||||
const cwd = process.cwd();
|
||||
const func = () => {};
|
||||
|
||||
t.is(require('../fixtures/plugin-noop'), await loadPlugin({cwd: './test/fixtures'}, './plugin-noop', {}), 'From cwd');
|
||||
t.is((await import('../fixtures/plugin-noop.cjs')).default, await loadPlugin({cwd: './test/fixtures'}, './plugin-noop.cjs', {}), 'From cwd');
|
||||
t.is(
|
||||
require('../fixtures/plugin-noop'),
|
||||
await loadPlugin({cwd}, './plugin-noop', {'./plugin-noop': './test/fixtures'}),
|
||||
(await import('../fixtures/plugin-noop.cjs')).default,
|
||||
await loadPlugin({cwd}, './plugin-noop.cjs', {'./plugin-noop.cjs': './test/fixtures'}),
|
||||
'From a shareable config context'
|
||||
);
|
||||
t.is(func, await loadPlugin({cwd}, func, {}), 'Defined as a function');
|
||||
|
||||
Reference in New Issue
Block a user