diff --git a/.yarn/versions/44a33643.yml b/.yarn/versions/44a33643.yml new file mode 100644 index 000000000000..2d6a48f178d8 --- /dev/null +++ b/.yarn/versions/44a33643.yml @@ -0,0 +1,34 @@ +releases: + "@yarnpkg/cli": patch + "@yarnpkg/core": patch + +declined: + - "@yarnpkg/plugin-compat" + - "@yarnpkg/plugin-constraints" + - "@yarnpkg/plugin-dlx" + - "@yarnpkg/plugin-essentials" + - "@yarnpkg/plugin-exec" + - "@yarnpkg/plugin-file" + - "@yarnpkg/plugin-git" + - "@yarnpkg/plugin-github" + - "@yarnpkg/plugin-http" + - "@yarnpkg/plugin-init" + - "@yarnpkg/plugin-interactive-tools" + - "@yarnpkg/plugin-link" + - "@yarnpkg/plugin-nm" + - "@yarnpkg/plugin-npm" + - "@yarnpkg/plugin-npm-cli" + - "@yarnpkg/plugin-pack" + - "@yarnpkg/plugin-patch" + - "@yarnpkg/plugin-pnp" + - "@yarnpkg/plugin-pnpm" + - "@yarnpkg/plugin-stage" + - "@yarnpkg/plugin-typescript" + - "@yarnpkg/plugin-version" + - "@yarnpkg/plugin-workspace-tools" + - "@yarnpkg/builder" + - "@yarnpkg/doctor" + - "@yarnpkg/extensions" + - "@yarnpkg/nm" + - "@yarnpkg/pnpify" + - "@yarnpkg/sdks" diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/features/plugins.test.ts b/packages/acceptance-tests/pkg-tests-specs/sources/features/plugins.test.ts index 141995b65ef7..5ca0d63478b0 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/features/plugins.test.ts +++ b/packages/acceptance-tests/pkg-tests-specs/sources/features/plugins.test.ts @@ -8,6 +8,7 @@ import {mockPluginServer} from './plugins.utility'; const COMMANDS_PLUGIN = (name: string, {async = false, printOnBoot = false, thirdParty = false} = {}) => ` const factory = ${async ? `async` : ``} r => { const {Command} = r('clipanion'); + const path = r('node:path'); if (${printOnBoot}) console.log('Booting ${name.toUpperCase()}'); @@ -22,6 +23,14 @@ const factory = ${async ? `async` : ``} r => { this.context.stdout.write('Executing ${name.toUpperCase()}\\n'); } }, + + class MyCommandPath extends Command { + static paths = [['${name}', 'path']]; + + async execute() { + this.context.stdout.write(path.posix.join('a', 'b') + '\\n'); + } + }, ], }, }; @@ -77,6 +86,19 @@ describe(`Features`, () => { }); })); + test(`it should support plugins using builtin modules`, makeTemporaryEnv({ + }, async ({path, run, source}) => { + await xfs.writeFilePromise(`${path}/plugin-a.js` as PortablePath, COMMANDS_PLUGIN(`a`)); + + await xfs.writeFilePromise(`${path}/.yarnrc.yml` as PortablePath, stringifySyml({ + plugins: [`./plugin-a.js`], + })); + + await expect(run(`a`, `path`)).resolves.toMatchObject({ + stdout: `a/b\n`, + }); + })); + test(`it should accept asynchronous plugins`, makeTemporaryEnv({ }, async ({path, run, source}) => { await xfs.writeFilePromise(`${path}/plugin-a.js` as PortablePath, COMMANDS_PLUGIN(`a`, {async: true})); diff --git a/packages/yarnpkg-core/sources/Configuration.ts b/packages/yarnpkg-core/sources/Configuration.ts index afdc21da250a..241f9bb9f1e3 100644 --- a/packages/yarnpkg-core/sources/Configuration.ts +++ b/packages/yarnpkg-core/sources/Configuration.ts @@ -5,7 +5,7 @@ import camelcase import {isCI, isPR, GITHUB_ACTIONS} from 'ci-info'; import {UsageError} from 'clipanion'; import {parse as parseDotEnv} from 'dotenv'; -import {builtinModules} from 'module'; +import {isBuiltin} from 'module'; import pLimit, {Limit} from 'p-limit'; import {PassThrough, Writable} from 'stream'; import {WriteStream} from 'tty'; @@ -1265,8 +1265,7 @@ export class Configuration { const thirdPartyPlugins = new Map([]); if (pluginConfiguration !== null) { const requireEntries = new Map(); - for (const request of builtinModules) - requireEntries.set(request, () => miscUtils.dynamicRequire(request)); + for (const [request, embedModule] of pluginConfiguration.modules) requireEntries.set(request, () => embedModule); @@ -1284,6 +1283,9 @@ export class Configuration { const pluginRequireEntries = new Map(requireEntries); const pluginRequire = (request: string) => { + if (isBuiltin(request)) + return miscUtils.dynamicRequire(request); + if (pluginRequireEntries.has(request)) { return pluginRequireEntries.get(request)(); } else {