Skip to content

Commit 9617754

Browse files
committed
Build packages with tsup (#2120)
This changes all packages to be built with `tsup`, instead of SWC. `tsup` uses `esbuild` under the hood, so performance should be comparable. More context here: MetaMask/utils#144.
1 parent 0047c06 commit 9617754

File tree

80 files changed

+1660
-956
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+1660
-956
lines changed

.github/workflows/build-lint-test.yml

Lines changed: 11 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -37,43 +37,14 @@ jobs:
3737
id: workspace-package-names
3838
run: |
3939
{
40-
echo "test-workspace-package-names=$(yarn workspaces filter --include 'packages/*' --exclude 'packages/examples' --json)"
41-
echo "e2e-workspace-package-names=$(yarn workspaces filter --include 'packages/examples/packages/**' --exclude 'packages/examples/packages/invoke-snap' --json)"
42-
echo "all-workspace-package-names=$(yarn workspaces filter --include '{.,packages/**}' --exclude 'packages/snaps-cli/test/snap' --json)"
40+
echo "test-workspace-package-names=$(yarn workspaces filter list --include 'packages/*' --exclude 'packages/examples' --json)"
41+
echo "e2e-workspace-package-names=$(yarn workspaces filter list --include 'packages/examples/packages/**' --exclude 'packages/examples/packages/invoke-snap' --json)"
42+
echo "all-workspace-package-names=$(yarn workspaces filter list --include '{.,packages/**}' --exclude 'packages/snaps-cli/test/snap' --json)"
4343
} >> "$GITHUB_OUTPUT"
4444
shell: bash
4545

46-
build-source:
47-
name: Build source
48-
runs-on: ubuntu-latest
49-
needs: prepare
50-
steps:
51-
- uses: actions/checkout@v3
52-
- name: Setup Node
53-
uses: actions/setup-node@v3
54-
with:
55-
node-version-file: '.nvmrc'
56-
cache: yarn
57-
- run: yarn --immutable --immutable-cache
58-
- name: Build source
59-
run: yarn build:source
60-
- name: Cache build files
61-
uses: actions/cache@v3
62-
with:
63-
path: |
64-
packages/*/dist/esm
65-
packages/*/dist/cjs
66-
key: build-source-${{ runner.os }}-${{ github.sha }}
67-
- name: Require clean working directory
68-
shell: bash
69-
run: |
70-
if ! git diff --exit-code; then
71-
echo "Working tree dirty at end of job"
72-
exit 1
73-
fi
74-
75-
build-types:
76-
name: Build types
46+
build:
47+
name: Build
7748
runs-on: ubuntu-latest
7849
needs: prepare
7950
steps:
@@ -84,14 +55,16 @@ jobs:
8455
node-version-file: '.nvmrc'
8556
cache: yarn
8657
- run: yarn --immutable --immutable-cache
58+
- name: Build
59+
run: yarn build:ci
8760
- name: Build types
8861
run: yarn build:types
8962
- name: Cache build files
9063
uses: actions/cache@v3
9164
with:
9265
path: |
93-
packages/*/dist/types
94-
key: build-types-${{ runner.os }}-${{ github.sha }}
66+
packages/*/dist
67+
key: build-source-${{ runner.os }}-${{ github.sha }}
9568
- name: Require clean working directory
9669
shell: bash
9770
run: |
@@ -100,38 +73,6 @@ jobs:
10073
exit 1
10174
fi
10275
103-
post-build:
104-
name: Post-build
105-
runs-on: ubuntu-latest
106-
needs:
107-
- build-source
108-
- build-types
109-
steps:
110-
- uses: actions/checkout@v3
111-
- name: Setup Node
112-
uses: actions/setup-node@v3
113-
with:
114-
node-version-file: '.nvmrc'
115-
cache: yarn
116-
- run: yarn --immutable --immutable-cache
117-
- name: Restore build files
118-
uses: actions/cache@v3
119-
with:
120-
path: |
121-
packages/*/dist/esm
122-
packages/*/dist/cjs
123-
key: build-source-${{ runner.os }}-${{ github.sha }}
124-
fail-on-cache-miss: true
125-
- name: Restore types files
126-
uses: actions/cache@v3
127-
with:
128-
path: |
129-
packages/*/dist/types
130-
key: build-types-${{ runner.os }}-${{ github.sha }}
131-
fail-on-cache-miss: true
132-
- name: Post-build
133-
run: yarn build:post-tsc:ci
134-
13576
build-simulator:
13677
name: Build "@metamask/snaps-simulator"
13778
runs-on: ubuntu-latest
@@ -318,8 +259,7 @@ jobs:
318259
runs-on: ubuntu-latest
319260
needs:
320261
- prepare
321-
- build-source
322-
- build-types
262+
- build
323263
strategy:
324264
fail-fast: false
325265
matrix:
@@ -343,17 +283,9 @@ jobs:
343283
uses: actions/cache@v3
344284
with:
345285
path: |
346-
packages/*/dist/esm
347-
packages/*/dist/cjs
286+
packages/*/dist
348287
key: build-source-${{ runner.os }}-${{ github.sha }}
349288
fail-on-cache-miss: true
350-
- name: Restore types files
351-
uses: actions/cache@v3
352-
with:
353-
path: |
354-
packages/*/dist/types
355-
key: build-types-${{ runner.os }}-${{ github.sha }}
356-
fail-on-cache-miss: true
357289
- run: yarn --immutable --immutable-cache
358290
- name: Build snap
359291
run: yarn workspace ${{ matrix.package-name }} run build

.yarn/plugins/local/plugin-workspaces-filter.js

Lines changed: 156 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ module.exports = {
66
const { Command, Option, UsageError } = require('clipanion');
77
const { isString, isBoolean } = require('typanion');
88

9-
class FilterCommand extends BaseCommand {
10-
static paths = [['workspaces', 'filter']];
9+
class FilterListCommand extends BaseCommand {
10+
static paths = [['workspaces', 'filter', 'list']];
1111

1212
static usage = Command.Usage({
1313
description: 'Filter workspaces',
@@ -18,11 +18,11 @@ module.exports = {
1818
examples: [
1919
[
2020
`List workspaces based on a glob pattern`,
21-
`yarn workspaces filter --include "packages/*"`,
21+
`yarn workspaces filter list --include "packages/*"`,
2222
],
2323
[
2424
'Exclude workspaces based on a glob pattern',
25-
`yarn workspaces filter --exclude "packages/*/foo"`,
25+
`yarn workspaces filter list --exclude "packages/*/foo"`,
2626
],
2727
],
2828
});
@@ -42,6 +42,34 @@ module.exports = {
4242
validator: isBoolean,
4343
});
4444

45+
/**
46+
* List the names of the workspaces. If `--json` is set, the names will be
47+
* printed as a JSON array.
48+
*
49+
* @param {Workspace[]} workspaces
50+
* @param {Configuration} configuration
51+
* @returns {Promise<number>}
52+
*/
53+
async list(workspaces, configuration) {
54+
const report = await StreamReport.start(
55+
{
56+
configuration,
57+
json: this.json,
58+
stdout: this.context.stdout,
59+
},
60+
async (report) => {
61+
for (const workspace of workspaces) {
62+
report.reportInfo(null, workspace.relativeCwd);
63+
}
64+
65+
const result = workspaces.map((workspace) => workspace.manifest.raw.name);
66+
report.reportJson(result);
67+
},
68+
);
69+
70+
return report.exitCode();
71+
}
72+
4573
async execute() {
4674
// Note: We have to import `minimatch` here, because Yarn will always
4775
// load the plugin, even if the command is not used, and `minimatch`
@@ -61,37 +89,137 @@ module.exports = {
6189
);
6290
}
6391

64-
const report = await StreamReport.start(
65-
{
66-
configuration,
67-
json: this.json,
68-
stdout: this.context.stdout,
69-
},
70-
async (report) => {
71-
const filteredWorkspaces = workspaces.filter((workspace) => {
72-
return (
73-
(!this.include ||
74-
minimatch(workspace.relativeCwd, this.include)) &&
75-
(!this.exclude ||
76-
!minimatch(workspace.relativeCwd, this.exclude))
77-
);
78-
});
79-
80-
for (const workspace of filteredWorkspaces) {
81-
report.reportInfo(null, workspace.relativeCwd);
82-
}
92+
const filteredWorkspaces = workspaces.filter((workspace) => {
93+
return (
94+
(!this.include ||
95+
minimatch(workspace.relativeCwd, this.include)) &&
96+
(!this.exclude ||
97+
!minimatch(workspace.relativeCwd, this.exclude))
98+
);
99+
});
83100

84-
const result = filteredWorkspaces.map((workspace) => workspace.manifest.raw.name);
85-
report.reportJson(result);
86-
},
101+
return await this.list(filteredWorkspaces, configuration);
102+
}
103+
}
104+
105+
class FilterRunCommand extends BaseCommand {
106+
static paths = [['workspaces', 'filter']];
107+
108+
static usage = Command.Usage({
109+
description: 'Filter workspaces',
110+
details: `
111+
This command will run a command in workspaces based on the given
112+
criteria. It's like \`yarn workspaces foreach\` but on steroids.
113+
`,
114+
examples: [
115+
[
116+
`List workspaces based on a glob pattern`,
117+
`yarn workspaces filter --include "packages/*" run build`,
118+
],
119+
[
120+
'Exclude workspaces based on a glob pattern',
121+
`yarn workspaces filter --exclude "packages/*/foo" run build`,
122+
],
123+
],
124+
});
125+
126+
commandName = Option.String({
127+
required: true,
128+
description: `The name of the command to run`,
129+
validator: isString,
130+
});
131+
132+
args = Option.Proxy({
133+
required: false,
134+
});
135+
136+
parallel = Option.Boolean(`--parallel`, {
137+
default: false,
138+
description: `Run the commands in parallel`,
139+
validator: isBoolean,
140+
});
141+
142+
topological = Option.Boolean(`--topological`, false, {
143+
description: `Run the commands in topological order`,
144+
validator: isBoolean,
145+
});
146+
147+
include = Option.String('--include', {
148+
description: `List workspaces based on a glob pattern`,
149+
validator: isString,
150+
});
151+
152+
exclude = Option.String('--exclude', {
153+
description: `Exclude workspaces based on a glob pattern`,
154+
validator: isString,
155+
});
156+
157+
noPrivate = Option.Boolean(`--no-private`, false, {
158+
description: `Exclude private workspaces`,
159+
validator: isBoolean,
160+
});
161+
162+
/**
163+
* Run the given command on the workspaces.
164+
*
165+
* @param workspaces - The workspaces to run the command on.
166+
* @param commandName - The name of the command to run.
167+
* @param args - The arguments to pass to the command.
168+
* @return {Promise<void>}
169+
*/
170+
async run(workspaces, commandName, args) {
171+
let extraArgs = [];
172+
if (this.parallel) {
173+
extraArgs.push('--parallel');
174+
}
175+
176+
if (this.topological) {
177+
extraArgs.push('--topological');
178+
extraArgs.push('--topological-dev');
179+
}
180+
181+
const includes = workspaces.map((workspace) => workspace.manifest.name)
182+
.flatMap(({ scope, name }) => ['--include', `@${scope}/${name}`]);
183+
184+
await this.cli.run(['workspaces', 'foreach', '--verbose', ...includes, ...extraArgs, commandName, ...args], this.context);
185+
}
186+
187+
async execute() {
188+
// Note: We have to import `minimatch` here, because Yarn will always
189+
// load the plugin, even if the command is not used, and `minimatch`
190+
// may not be installed.
191+
const { minimatch } = await import('minimatch');
192+
193+
const configuration = await Configuration.find(
194+
this.context.cwd,
195+
this.context.plugins,
87196
);
197+
const { project } = await Project.find(configuration, this.context.cwd);
198+
const { workspaces } = project;
88199

89-
return report.exitCode();
200+
if (!this.include && !this.exclude) {
201+
throw new UsageError(
202+
`This command requires at least one of --include or --exclude to be specified.`,
203+
);
204+
}
205+
206+
const filteredWorkspaces = workspaces.filter((workspace) => {
207+
return (
208+
(!this.include ||
209+
minimatch(workspace.relativeCwd, this.include)) &&
210+
(!this.exclude ||
211+
!minimatch(workspace.relativeCwd, this.exclude))
212+
);
213+
}).filter((workspace) => {
214+
return !this.noPrivate || !workspace.manifest.private;
215+
});
216+
217+
return await this.run(filteredWorkspaces, this.commandName, this.args);
90218
}
91219
}
92220

93221
return {
94-
commands: [FilterCommand],
222+
commands: [FilterListCommand, FilterRunCommand],
95223
};
96224
},
97225
};

0 commit comments

Comments
 (0)