Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .yarn/versions/92c64300.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
releases:
"@yarnpkg/sdks": minor
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ The `yarn dlx @yarnpkg/sdks` command will look at the content of your *root* `pa
| [vscode-eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) | [eslint](https://yarnpkg.com/package/eslint) |
| [prettier-vscode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) | [prettier](https://yarnpkg.com/package/prettier) |
| [relay](https://marketplace.visualstudio.com/items?itemName=meta.relay) | [relay](https://relay.dev/)
| [oxc](https://marketplace.visualstudio.com/items?itemName=oxc.oxc-vscode) | [oxlint](https://yarnpkg.com/package/oxlint)
| [oxc](https://marketplace.visualstudio.com/items?itemName=oxc.oxc-vscode) | [oxfmt](https://yarnpkg.com/package/oxfmt)

If you'd like to contribute more, [take a look here!](https://github.com/yarnpkg/berry/blob/master/packages/yarnpkg-sdks/sources/generateSdk.ts)

Expand Down
23 changes: 22 additions & 1 deletion packages/yarnpkg-sdks/sources/generateSdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ const TEMPLATE = (relPnpApiPath: PortablePath, module: string, {setupEnv = false
`\n`,
` process.env.NODE_OPTIONS = process.env.NODE_OPTIONS || \`\`;\n`,
` process.env.NODE_OPTIONS += \` -r \${absPnpApiPath}\`;\n`,
` if (isPnpLoaderEnabled && register) {\n`,
` process.env.NODE_OPTIONS += \` --experimental-loader \${pathToFileURL(absPnpLoaderPath)}\`;\n`,
` }\n`,
` }\n`,
] : []),
...(usePnpify ? [
Expand Down Expand Up @@ -201,7 +204,10 @@ export type SupportedSdk =
| `typescript-language-server`
| `typescript`
| `svelte-language-server`
| `flow-bin`;
| `flow-bin`
| `oxfmt`
| `oxlint`
| `oxlint-tsgolint`;

export type BaseSdks = Array<[
SupportedSdk,
Expand Down Expand Up @@ -343,6 +349,21 @@ export class Wrapper {
return absWrapperPath;
}

async writeRaw(relPackagePath: PortablePath, content: string, options: {mode?: number} = {}) {
const topLevelInformation = this.pnpApi.getPackageInformation(this.pnpApi.topLevel)!;
const projectRoot = npath.toPortablePath(topLevelInformation.packageLocation);

const absPath = ppath.join(this.target, this.name, relPackagePath);
const relProjectPath = ppath.relative(projectRoot, absPath);

await xfs.mkdirPromise(ppath.dirname(absPath), {recursive: true});
await xfs.writeFilePromise(absPath, content, {mode: options.mode});

this.paths.set(relPackagePath, relProjectPath);

return absPath;
}

getProjectPathTo(relPackagePath: PortablePath) {
const relProjectPath = this.paths.get(relPackagePath);

Expand Down
64 changes: 64 additions & 0 deletions packages/yarnpkg-sdks/sources/sdks/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,67 @@ export const generateFlowBinBaseWrapper: GenerateBaseWrapper = async (pnpApi: Pn
return wrapper;
};

export const generateOxfmtBaseWrapper: GenerateBaseWrapper = async (pnpApi: PnpApi, target: PortablePath) => {
const wrapper = new Wrapper(`oxfmt` as PortablePath, {pnpApi, target});

const oxfmtMonkeyPatch = `
module => module;

const binPath = resolve(absRequire.resolve(\`oxfmt/package.json\`), \`..\`, \`${wrapper.manifest.bin.oxfmt}\`);
absRequire(binPath);
`;

await wrapper.writeDefaults();
await wrapper.writeBinary(`bin/oxfmt` as PortablePath, {
setupEnv: true,
requirePath: `` as PortablePath,
wrapModule: oxfmtMonkeyPatch,
});

return wrapper;
};

export const generateOxlintBaseWrapper: GenerateBaseWrapper = async (pnpApi: PnpApi, target: PortablePath) => {
const wrapper = new Wrapper(`oxlint` as PortablePath, {pnpApi, target});

// There are two workarounds here:
// 1. Injecting into PATH to enable tsgolint's PATH resolution strategy in the following tsgolint wrapper.
// 2. Direct file import to work around the top-level await and exports restrictions in oxlint.
const oxlintMonkeyPatch = `
module => module;

process.env.PATH += \`;\${resolve(__dirname, \`../../oxlint-tsgolint/bin\`)}\`;

const binPath = resolve(absRequire.resolve(\`oxlint/package.json\`), \`..\`, \`${wrapper.manifest.bin.oxlint}\`);
import(pathToFileURL(binPath));
`;

await wrapper.writeDefaults();
// This intentionally produces a dummy export; the main logic is in the import above.
// Originally, the binary does not export anything.
await wrapper.writeBinary(`bin/oxlint` as PortablePath, {requirePath: `` as PortablePath, wrapModule: oxlintMonkeyPatch});

return wrapper;
};

export const generateOxlintTsgolintBaseWrapper: GenerateBaseWrapper = async (pnpApi: PnpApi, target: PortablePath) => {
const wrapper = new Wrapper(`oxlint-tsgolint` as PortablePath, {pnpApi, target});

// We are using the oxc_linter tsgolint resolution mechanism via the PATH environment variable
// since it's the only realistic approach to correctly resolve the tsgolint binary when using Yarn PnP.
// Ref: https://github.com/oxc-project/oxc/blob/d3dcf5bc9718ebb4839be27062b5d82da2118e2e/crates/oxc_linter/src/tsgolint.rs#L1164-L1225
// With this approach, we need to manually create both Unix and Windows executable shim for tsgolint.js.
const tsgolintCmd = `
@goto #_undefined_# 2>NUL || @title %COMSPEC% & @setlocal & @"node" "%~dp0tsgolint.js" %*
`.trim().replace(/^ {4}/gm, ``);
Comment thread
slainless marked this conversation as resolved.

await wrapper.writeDefaults();
await wrapper.writeBinary(`bin/tsgolint` as PortablePath);
await wrapper.writeRaw(`bin/tsgolint.cmd` as PortablePath, tsgolintCmd, {mode: 0o755});

return wrapper;
};

export const BASE_SDKS: BaseSdks = [
[`@astrojs/language-server`, generateAstroLanguageServerBaseWrapper],
[`eslint`, generateEslintBaseWrapper],
Expand All @@ -294,4 +355,7 @@ export const BASE_SDKS: BaseSdks = [
[`typescript`, generateTypescriptBaseWrapper],
[`svelte-language-server`, generateSvelteLanguageServerBaseWrapper],
[`flow-bin`, generateFlowBinBaseWrapper],
[`oxfmt`, generateOxfmtBaseWrapper],
[`oxlint`, generateOxlintBaseWrapper],
[`oxlint-tsgolint`, generateOxlintTsgolintBaseWrapper],
];
22 changes: 22 additions & 0 deletions packages/yarnpkg-sdks/sources/sdks/cocvim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,29 @@ export const generateTypescriptWrapper: GenerateIntegrationWrapper = async (pnpA
});
};

export const generateOxfmtWrapper: GenerateIntegrationWrapper = async (pnpApi: PnpApi, target: PortablePath, wrapper: Wrapper) => {
await addCocVimWorkspaceConfiguration(pnpApi, CocVimConfiguration.settings, {
[`oxc.oxfmt.binPath`]: npath.fromPortablePath(
wrapper.getProjectPathTo(
ppath.normalize(wrapper.manifest.bin.oxfmt),
),
),
});
};

export const generateOxlintWrapper: GenerateIntegrationWrapper = async (pnpApi: PnpApi, target: PortablePath, wrapper: Wrapper) => {
await addCocVimWorkspaceConfiguration(pnpApi, CocVimConfiguration.settings, {
[`oxc.oxlint.binPath`]: npath.fromPortablePath(
wrapper.getProjectPathTo(
ppath.normalize(wrapper.manifest.bin.oxlint),
),
),
});
};

export const COC_VIM_SDKS: IntegrationSdks = [
[`eslint`, generateEslintWrapper],
[`typescript`, generateTypescriptWrapper],
[`oxfmt`, generateOxfmtWrapper],
[`oxlint`, generateOxlintWrapper],
];
38 changes: 38 additions & 0 deletions packages/yarnpkg-sdks/sources/sdks/vscode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,41 @@ export const generateFlowBinWrapper: GenerateIntegrationWrapper = async (pnpApi:
});
};

export const generateOxfmtWrapper: GenerateIntegrationWrapper = async (pnpApi: PnpApi, target: PortablePath, wrapper: Wrapper) => {
await addVSCodeWorkspaceConfiguration(pnpApi, VSCodeConfiguration.settings, {
[`oxc.path.oxfmt`]: npath.fromPortablePath(
wrapper.getProjectPathTo(
ppath.normalize(wrapper.manifest.bin.oxfmt),
),
),
});

await addVSCodeWorkspaceConfiguration(pnpApi, VSCodeConfiguration.extensions, {
[`recommendations`]: [
`oxc.oxc-vscode`,
],
});
};

export const generateOxlintWrapper: GenerateIntegrationWrapper = async (pnpApi: PnpApi, target: PortablePath, wrapper: Wrapper) => {
await addVSCodeWorkspaceConfiguration(pnpApi, VSCodeConfiguration.settings, {
[`oxc.path.oxlint`]: npath.fromPortablePath(
wrapper.getProjectPathTo(
ppath.normalize(wrapper.manifest.bin.oxlint),
),
),
});

await addVSCodeWorkspaceConfiguration(pnpApi, VSCodeConfiguration.extensions, {
[`recommendations`]: [
`oxc.oxc-vscode`,
],
});
};

export const generateOxlintTsgolintWrapper: GenerateIntegrationWrapper = async (pnpApi: PnpApi, target: PortablePath, wrapper: Wrapper) => {
};

export const VSCODE_SDKS: IntegrationSdks = [
[null, generateDefaultWrapper],
[`@astrojs/language-server`, generateAstroLanguageServerWrapper],
Expand All @@ -149,4 +184,7 @@ export const VSCODE_SDKS: IntegrationSdks = [
[`typescript`, generateTypescriptWrapper],
[`svelte-language-server`, generateSvelteLanguageServerWrapper],
[`flow-bin`, generateFlowBinWrapper],
[`oxfmt`, generateOxfmtWrapper],
[`oxlint`, generateOxlintWrapper],
[`oxlint-tsgolint`, generateOxlintTsgolintWrapper],
];
Loading