Skip to content

Commit 807016d

Browse files
authored
feat(cli): pnpm config will now be stored in pnpm-workspace.yaml (#718)
* fix(tailwindcss): add `@tailwindcss/oxide` to approve-builds in `pnpm` * addd yaml utils * using yaml-workspace when possible * windows robustness * CI debug * more logs * !silent * CI & windows & I don't know * sniff * . * more and more logs * pnpm v * cleanup! * --silent * add changeset
1 parent b6ecec8 commit 807016d

File tree

16 files changed

+215
-57
lines changed

16 files changed

+215
-57
lines changed

.changeset/nasty-towns-crash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'sv': patch
3+
---
4+
5+
fix(tailwindcss): add `@tailwindcss/oxide` to approve-builds in `pnpm`

.changeset/solid-dragons-trade.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'sv': patch
3+
---
4+
5+
feat(cli): pnpm config will now be stored in `pnpm-workspace.yaml` (e.g. `onlyBuiltDependencies`)

community-addon-template/tests/setup/suite.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export function setupTest<Addons extends AddonMap>(addons: Addons) {
7878
options,
7979
packageManager: 'pnpm'
8080
});
81-
addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]);
81+
await addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]);
8282

8383
return cwd;
8484
};

package.json

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,5 @@
4040
"unplugin-isolated-decl": "^0.8.3",
4141
"vitest": "4.0.0-beta.6"
4242
},
43-
"packageManager": "[email protected]",
44-
"pnpm": {
45-
"onlyBuiltDependencies": [
46-
"esbuild"
47-
]
48-
}
43+
"packageManager": "[email protected]"
4944
}

packages/addons/_tests/_setup/suite.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export function setupTest<Addons extends AddonMap>(
9898
options: kind.options,
9999
packageManager: 'pnpm'
100100
});
101-
addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]);
101+
await addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]);
102102
}
103103

104104
execSync('pnpm install', { cwd: path.resolve(cwd, testName), stdio: 'pipe' });

packages/addons/tailwindcss/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export default defineAddon({
3737

3838
sv.devDependency('tailwindcss', '^4.0.0');
3939
sv.devDependency('@tailwindcss/vite', '^4.0.0');
40+
sv.pnpmBuildDependency('@tailwindcss/oxide');
4041

4142
if (prettierInstalled) sv.devDependency('prettier-plugin-tailwindcss', '^0.6.11');
4243

packages/cli/commands/add/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ export async function runAddCommand(
559559
if (packageManager) {
560560
workspace.packageManager = packageManager;
561561

562-
addPnpmBuildDependencies(workspace.cwd, packageManager, [
562+
await addPnpmBuildDependencies(workspace.cwd, packageManager, [
563563
'esbuild',
564564
...addonPnpmBuildDependencies
565565
]);

packages/cli/commands/create.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ async function createProject(cwd: ProjectPath, options: Options) {
204204

205205
const installDeps = async (install: true | AgentName) => {
206206
packageManager = install === true ? await packageManagerPrompt(projectPath) : install;
207-
addPnpmBuildDependencies(projectPath, packageManager, ['esbuild']);
207+
await addPnpmBuildDependencies(projectPath, packageManager, ['esbuild']);
208208
if (packageManager) await installDependencies(packageManager, projectPath);
209209
};
210210

packages/cli/lib/testing.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import fs from 'node:fs';
22
import path from 'node:path';
33
import process from 'node:process';
44
import degit from 'degit';
5-
import { exec } from 'tinyexec';
5+
import { x, exec } from 'tinyexec';
66
import { create } from '@sveltejs/create';
77

88
export { addPnpmBuildDependencies } from '../utils/package-manager.ts';
@@ -83,7 +83,7 @@ export function createProject({ cwd, testName, templatesDir }: CreateOptions): C
8383
type PreviewOptions = { cwd: string; command?: string };
8484
export async function startPreview({
8585
cwd,
86-
command = 'npm run preview'
86+
command = 'pnpm preview'
8787
}: PreviewOptions): Promise<{ url: string; close: () => Promise<void> }> {
8888
const [cmd, ...args] = command.split(' ');
8989
const proc = exec(cmd, args, {
@@ -124,7 +124,7 @@ export async function startPreview({
124124
async function terminate(pid: number) {
125125
try {
126126
if (process.platform === 'win32') {
127-
await exec(`taskkill /pid ${pid} /T /F`); // on windows, use taskkill to terminate the process tree
127+
await x('taskkill', ['/PID', `${pid}`, '/T', '/F']); // on windows, use taskkill to terminate the process tree
128128
} else {
129129
process.kill(-pid, 'SIGTERM'); // Kill the process group
130130
}

packages/cli/utils/package-manager.ts

Lines changed: 65 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import fs from 'node:fs';
22
import path from 'node:path';
33
import process from 'node:process';
44
import * as find from 'empathic/find';
5-
import { exec } from 'tinyexec';
5+
import { x } from 'tinyexec';
66
import { Option } from 'commander';
77
import * as p from '@clack/prompts';
88
import {
@@ -12,7 +12,8 @@ import {
1212
detect,
1313
type AgentName
1414
} from 'package-manager-detector';
15-
import { parseJson } from '@sveltejs/cli-core/parsers';
15+
import { parseJson, parseYaml } from '@sveltejs/cli-core/parsers';
16+
import { isVersionUnsupportedBelow } from '@sveltejs/cli-core';
1617

1718
export const AGENT_NAMES = AGENTS.filter((agent): agent is AgentName => !agent.includes('@'));
1819
const agentOptions: PackageManagerOptions = AGENT_NAMES.map((pm) => ({ value: pm, label: pm }));
@@ -55,19 +56,16 @@ export async function installDependencies(agent: AgentName, cwd: string): Promis
5556

5657
try {
5758
const { command, args } = constructCommand(COMMANDS[agent].install, [])!;
58-
const proc = exec(command, args, {
59+
60+
const proc = x(command, args, {
5961
nodeOptions: { cwd, stdio: 'pipe' },
6062
throwOnError: true
6163
});
6264

63-
proc.process?.stdout?.on('data', (data) => {
64-
task.message(data.toString(), { raw: true });
65-
});
66-
proc.process?.stderr?.on('data', (data) => {
67-
task.message(data.toString(), { raw: true });
68-
});
69-
70-
await proc;
65+
for await (const line of proc) {
66+
// line will be from stderr/stdout in the order you'd see it in a term
67+
task.message(line, { raw: true });
68+
}
7169

7270
task.success('Successfully installed dependencies');
7371
} catch {
@@ -87,35 +85,69 @@ export function getUserAgent(): AgentName | undefined {
8785
return AGENTS.includes(name) ? name : undefined;
8886
}
8987

90-
export function addPnpmBuildDependencies(
88+
export async function addPnpmBuildDependencies(
9189
cwd: string,
9290
packageManager: AgentName | null | undefined,
9391
allowedPackages: string[]
9492
) {
9593
// other package managers are currently not affected by this change
96-
if (!packageManager || packageManager !== 'pnpm') return;
94+
if (!packageManager || packageManager !== 'pnpm' || allowedPackages.length === 0) return;
95+
96+
let confIn: 'package.json' | 'pnpm-workspace.yaml' = 'package.json';
97+
const pnpmVersion = await getPnpmVersion();
98+
if (pnpmVersion) {
99+
confIn = isVersionUnsupportedBelow(pnpmVersion, '10.5')
100+
? 'package.json'
101+
: 'pnpm-workspace.yaml';
102+
}
97103

98104
// find the workspace root (if present)
99-
const pnpmWorkspacePath = find.up('pnpm-workspace.yaml', { cwd });
100-
let packageDirectory;
101-
102-
if (pnpmWorkspacePath) packageDirectory = path.dirname(pnpmWorkspacePath);
103-
else packageDirectory = cwd;
104-
105-
// load the package.json
106-
const pkgPath = path.join(packageDirectory, 'package.json');
107-
const content = fs.readFileSync(pkgPath, 'utf-8');
108-
const { data, generateCode } = parseJson(content);
109-
110-
// add the packages where we install scripts should be executed
111-
data.pnpm ??= {};
112-
data.pnpm.onlyBuiltDependencies ??= [];
113-
for (const allowedPackage of allowedPackages) {
114-
if (data.pnpm.onlyBuiltDependencies.includes(allowedPackage)) continue;
115-
data.pnpm.onlyBuiltDependencies.push(allowedPackage);
105+
const found = find.up('pnpm-workspace.yaml', { cwd });
106+
const dir = found ? path.dirname(found) : cwd;
107+
108+
if (confIn === 'pnpm-workspace.yaml') {
109+
const content = found ? fs.readFileSync(found, 'utf-8') : '';
110+
const { data, generateCode } = parseYaml(content);
111+
112+
const onlyBuiltDependencies = data.get('onlyBuiltDependencies');
113+
const items: Array<{ value: string } | string> = onlyBuiltDependencies?.items ?? [];
114+
115+
for (const item of allowedPackages) {
116+
if (items.includes(item)) continue;
117+
if (items.some((y) => typeof y === 'object' && y.value === item)) continue;
118+
items.push(item);
119+
}
120+
data.set('onlyBuiltDependencies', new Set(items));
121+
122+
const newContent = generateCode();
123+
124+
const pnpmWorkspacePath = found ?? path.join(cwd, 'pnpm-workspace.yaml');
125+
if (newContent !== content) fs.writeFileSync(pnpmWorkspacePath, newContent);
126+
} else {
127+
// else is package.json (fallback)
128+
const pkgPath = path.join(dir, 'package.json');
129+
const content = fs.readFileSync(pkgPath, 'utf-8');
130+
const { data, generateCode } = parseJson(content);
131+
132+
// add the packages where we install scripts should be executed
133+
data.pnpm ??= {};
134+
data.pnpm.onlyBuiltDependencies ??= [];
135+
for (const allowedPackage of allowedPackages) {
136+
if (data.pnpm.onlyBuiltDependencies.includes(allowedPackage)) continue;
137+
data.pnpm.onlyBuiltDependencies.push(allowedPackage);
138+
}
139+
140+
// save the updated package.json
141+
const newContent = generateCode();
142+
if (newContent !== content) fs.writeFileSync(pkgPath, newContent);
116143
}
144+
}
117145

118-
// save the updated package.json
119-
const newContent = generateCode();
120-
fs.writeFileSync(pkgPath, newContent);
146+
async function getPnpmVersion(): Promise<string | undefined> {
147+
let v: string | undefined = undefined;
148+
try {
149+
const proc = await x('pnpm', ['--version'], { throwOnError: true });
150+
v = proc.stdout.trim();
151+
} catch {}
152+
return v;
121153
}

0 commit comments

Comments
 (0)