@@ -19,13 +19,42 @@ interface Command {
1919 * the hood.
2020 */
2121 help : string ;
22- fn : ( ) => Promise < void > ;
22+ fn : ( args : string [ ] ) => Promise < void > ;
2323}
2424
25- function buildCommands ( root : ReturnType < typeof $ . path > ) : Record < string , Command > {
25+ function cargoTestCommand (
26+ root : ReturnType < typeof $ . path > ,
27+ baseArgs : string [ ] ,
28+ opts : { description : string ; help : string ; stepName : string } ,
29+ ) : Command {
30+ return {
31+ description : opts . description ,
32+ help : opts . help ,
33+ async fn ( args : string [ ] ) {
34+ if ( args . includes ( "--list" ) ) {
35+ await $ `cargo test ${ baseArgs } -- --list` . cwd ( root ) ;
36+ return ;
37+ }
38+ if ( args . length === 0 ) {
39+ $ . logError (
40+ "A filter argument is required. Use --list to see available tests." ,
41+ ) ;
42+ Deno . exit ( 1 ) ;
43+ }
44+ $ . logStep ( `Running ${ opts . stepName } ...` ) ;
45+ await $ `cargo test ${ baseArgs } -- ${ args . join ( " " ) } ` . cwd ( root ) ;
46+ $ . logStep ( `${ opts . stepName } complete.` ) ;
47+ } ,
48+ } ;
49+ }
50+
51+ function buildCommands (
52+ root : ReturnType < typeof $ . path > ,
53+ ) : Record < string , Command > {
2654 const fmtCmd : Command = {
2755 description : "Format all code (JS/TS/Rust/etc. via dprint)" ,
28- help : `Formats the entire codebase using the project's formatting tool chain.
56+ help :
57+ `Formats the entire codebase using the project's formatting tool chain.
2958This runs dprint (configured in dprint.json) which handles JavaScript,
3059TypeScript, JSON, JSONC, Markdown, TOML, and Rust formatting.
3160
@@ -34,7 +63,7 @@ in the './x verify' pre-commit workflow.
3463
3564Under the hood:
3665 deno run -A tools/format.js` ,
37- async fn ( ) {
66+ async fn ( _args : string [ ] ) {
3867 $ . logStep ( "Formatting code..." ) ;
3968 await $ `deno run -A tools/format.js` . cwd ( root ) ;
4069 $ . logStep ( "Formatting complete." ) ;
@@ -49,7 +78,7 @@ not modified any Rust code.
4978
5079Under the hood:
5180 deno run -A tools/lint.js --js` ,
52- async fn ( ) {
81+ async fn ( _args : string [ ] ) {
5382 $ . logStep ( "Linting JavaScript/TypeScript..." ) ;
5483 await $ `deno run -A tools/lint.js --js` . cwd ( root ) ;
5584 $ . logStep ( "JS lint complete." ) ;
@@ -59,7 +88,8 @@ Under the hood:
5988 return {
6089 "setup" : {
6190 description : "Initial setup: build deno and test_server" ,
62- help : `Sets up the development environment by compiling both the main 'deno'
91+ help :
92+ `Sets up the development environment by compiling both the main 'deno'
6393binary and the 'test_server' binary used by the test suite.
6494
6595Run this once after cloning the repository, or after pulling changes that
@@ -68,7 +98,7 @@ testing.
6898
6999Under the hood:
70100 cargo build --bin deno --bin test_server` ,
71- async fn ( ) {
101+ async fn ( _args : string [ ] ) {
72102 $ . logStep ( "Setting up development environment..." ) ;
73103 $ . logStep ( "Building deno and test_server..." ) ;
74104 await $ `cargo build --bin deno --bin test_server` . cwd ( root ) ;
@@ -89,7 +119,7 @@ it skips the linking step.
89119
90120Under the hood:
91121 cargo build --bin deno` ,
92- async fn ( ) {
122+ async fn ( _args : string [ ] ) {
93123 $ . logStep ( "Building Deno..." ) ;
94124 await $ `cargo build --bin deno` . cwd ( root ) ;
95125 $ . logStep ( "Build complete." ) ;
@@ -107,83 +137,124 @@ of a full build.
107137
108138Under the hood:
109139 cargo check` ,
110- async fn ( ) {
140+ async fn ( _args : string [ ] ) {
111141 $ . logStep ( "Checking (no linking)..." ) ;
112142 await $ `cargo check` . cwd ( root ) ;
113143 $ . logStep ( "Check complete." ) ;
114144 } ,
115145 } ,
116- "test-unit" : {
117- description : "Run Deno runtime unit tests" ,
118- help : `Runs the Deno runtime unit tests. These are JavaScript/TypeScript tests
146+ "test-unit" : cargoTestCommand (
147+ root ,
148+ [ "-p" , "unit_tests" , "--test" , "unit" ] ,
149+ {
150+ description : "Run Deno runtime unit tests" ,
151+ stepName : "unit tests" ,
152+ help :
153+ `Runs the Deno runtime unit tests. These are JavaScript/TypeScript tests
119154that exercise Deno's built-in APIs (e.g. Deno.readFile, Deno.serve,
120155Web API implementations) by running them inside the Deno runtime itself.
121156
122157The test files live under tests/unit/ and are compiled into the
123158'unit_tests' crate.
124159
160+ Requires a filter argument to select which tests to run. The filter is
161+ a substring match against test names.
162+
163+ Usage:
164+ ./x test-unit <filter> Run tests matching the filter
165+ ./x test-unit --list List all available tests
166+
167+ Examples:
168+ ./x test-unit streams Run tests with "streams" in their name
169+ ./x test-unit fetch Run tests with "fetch" in their name
170+
125171Under the hood:
126- cargo test -p unit_tests --test unit` ,
127- async fn ( ) {
128- $ . logStep ( "Running unit tests..." ) ;
129- await $ `cargo test -p unit_tests --test unit` . cwd ( root ) ;
130- $ . logStep ( "Unit tests complete." ) ;
172+ cargo test -p unit_tests --test unit -- <filter>` ,
131173 } ,
132- } ,
133- "test-node" : {
174+ ) ,
175+ "test-node" : cargoTestCommand ( root , [
176+ "-p" ,
177+ "unit_node_tests" ,
178+ "--test" ,
179+ "unit_node" ,
180+ ] , {
134181 description : "Run Node.js API unit tests" ,
182+ stepName : "Node.js unit tests" ,
135183 help : `Runs unit tests for Deno's Node.js compatibility layer. These tests
136184verify that Deno's implementations of Node.js built-in modules (fs,
137185path, http, crypto, etc.) behave correctly.
138186
139187The test files live under tests/unit_node/ and are compiled into the
140188'unit_node_tests' crate.
141189
190+ Requires a filter argument to select which tests to run. The filter is
191+ a substring match against test names.
192+
193+ Usage:
194+ ./x test-node <filter> Run tests matching the filter
195+ ./x test-node --list List all available tests
196+
197+ Examples:
198+ ./x test-node crypto Run tests with "crypto" in their name
199+ ./x test-node http Run tests with "http" in their name
200+
142201Under the hood:
143- cargo test -p unit_node_tests --test unit_node` ,
144- async fn ( ) {
145- $ . logStep ( "Running Node.js unit tests..." ) ;
146- await $ `cargo test -p unit_node_tests --test unit_node` . cwd ( root ) ;
147- $ . logStep ( "Node.js unit tests complete." ) ;
148- } ,
149- } ,
150- "test-compat" : {
202+ cargo test -p unit_node_tests --test unit_node -- <filter>` ,
203+ } ) ,
204+ "test-compat" : cargoTestCommand ( root , [ "--test" , "node_compat" ] , {
151205 description : "Run Node.js compatibility tests" ,
206+ stepName : "Node.js compatibility tests" ,
152207 help : `Runs the Node.js compatibility test suite. These tests use actual
153208Node.js test cases (ported or adapted) to verify that Deno's node:*
154209module implementations match Node.js behavior.
155210
156211The test runner lives in tests/node_compat/runner/.
157212
213+ Requires a filter argument to select which tests to run. The filter is
214+ a substring match against test names.
215+
216+ Usage:
217+ ./x test-compat <filter> Run tests matching the filter
218+ ./x test-compat --list List all available tests
219+
220+ Examples:
221+ ./x test-compat fs Run tests with "fs" in their name
222+ ./x test-compat path Run tests with "path" in their name
223+
158224Under the hood:
159- deno task --cwd tests/ node_compat/runner test ` ,
160- async fn ( ) {
161- $ . logStep ( "Running Node.js compatibility tests..." ) ;
162- await $ `deno task --cwd tests/node_compat/runner test` . cwd ( root ) ;
163- $ . logStep ( "Node.js compatibility tests complete." ) ;
164- } ,
165- } ,
166- "test-spec" : {
225+ cargo test --test node_compat -- <filter> ` ,
226+ } ) ,
227+ "test-spec" : cargoTestCommand ( root , [
228+ "-p" ,
229+ "specs_tests" ,
230+ "--test" ,
231+ "specs" ,
232+ ] , {
167233 description : "Run spec (integration) tests" ,
168- help : `Runs the spec integration tests. These are the primary integration tests
234+ stepName : "spec tests" ,
235+ help :
236+ `Runs the spec integration tests. These are the primary integration tests
169237for Deno's CLI — each test defines CLI commands to execute and asserts
170238on their stdout/stderr output.
171239
172240Spec tests live under tests/specs/. Each test directory contains a
173241'__test__.jsonc' file describing the commands to run and expected output
174242(using wildcards like [WILDCARD], [WILDLINE], etc.).
175243
176- Use this to verify end-to-end CLI behavior after making changes to
177- subcommands, flag parsing, error messages, or module resolution.
244+ Requires a filter argument to select which tests to run. The filter is
245+ a substring match against test names.
246+
247+ Usage:
248+ ./x test-spec <filter> Run tests matching the filter
249+ ./x test-spec --list List all available tests
250+
251+ Examples:
252+ ./x test-spec fmt Run spec tests with "fmt" in their name
253+ ./x test-spec run Run spec tests with "run" in their name
178254
179255Under the hood:
180- cargo test -p specs_tests --test specs` ,
181- async fn ( ) {
182- $ . logStep ( "Running spec tests..." ) ;
183- await $ `cargo test -p specs_tests --test specs` . cwd ( root ) ;
184- $ . logStep ( "Spec tests complete." ) ;
185- } ,
186- } ,
256+ cargo test -p specs_tests --test specs -- <filter>` ,
257+ } ) ,
187258 "fmt" : fmtCmd ,
188259 "lint" : {
189260 description : "Lint all code (JS/TS + Rust)" ,
@@ -196,7 +267,7 @@ changed JS/TS files, './x lint-js' is faster.
196267
197268Under the hood:
198269 deno run -A tools/lint.js` ,
199- async fn ( ) {
270+ async fn ( _args : string [ ] ) {
200271 $ . logStep ( "Linting code..." ) ;
201272 await $ `deno run -A tools/lint.js` . cwd ( root ) ;
202273 $ . logStep ( "Linting complete." ) ;
@@ -205,7 +276,8 @@ Under the hood:
205276 "lint-js" : lintJsCmd ,
206277 "verify" : {
207278 description : "Pre-commit verification (fmt + lint-js)" ,
208- help : `Runs the recommended pre-commit checks: formats all code, then lints
279+ help :
280+ `Runs the recommended pre-commit checks: formats all code, then lints
209281JavaScript/TypeScript. This is the minimum verification you should do
210282before committing changes that only touch JS/TS files.
211283
@@ -216,10 +288,10 @@ compilation errors.
216288Equivalent to running:
217289 ./x fmt
218290 ./x lint-js` ,
219- async fn ( ) {
291+ async fn ( _args : string [ ] ) {
220292 $ . logStep ( "Running pre-commit verification..." ) ;
221- await fmtCmd . fn ( ) ;
222- await lintJsCmd . fn ( ) ;
293+ await fmtCmd . fn ( [ ] ) ;
294+ await lintJsCmd . fn ( [ ] ) ;
223295 $ . logStep ( "Verification complete." ) ;
224296 } ,
225297 } ,
@@ -232,16 +304,39 @@ Equivalent to running:
232304
233305function printHelp ( COMMANDS : Record < string , Command > ) {
234306 console . log ( ) ;
235- console . log ( ` ${ bold ( cyan ( "x" ) ) } ${ dim ( "-" ) } Developer CLI for contributing to Deno` ) ;
307+ console . log (
308+ ` ${ bold ( cyan ( "x" ) ) } ${ dim ( "-" ) } Developer CLI for contributing to Deno` ,
309+ ) ;
236310 console . log ( ) ;
237311 console . log ( ` ${ bold ( "USAGE" ) } ` ) ;
238312 console . log ( ` ${ dim ( "$" ) } ./x ${ green ( "<command>" ) } [options]` ) ;
239313 console . log ( ) ;
240314 console . log ( ` ${ bold ( "EXAMPLES" ) } ` ) ;
241- console . log ( ` ${ dim ( "$" ) } ./x ${ green ( "build" ) } ${ dim ( "# build the deno binary" ) } ` ) ;
242- console . log ( ` ${ dim ( "$" ) } ./x ${ green ( "test-spec" ) } ${ dim ( "# run spec integration tests" ) } ` ) ;
243- console . log ( ` ${ dim ( "$" ) } ./x ${ green ( "fmt" ) } ${ dim ( "# format the codebase" ) } ` ) ;
244- console . log ( ` ${ dim ( "$" ) } ./x ${ green ( "build --help" ) } ${ dim ( "# show detailed help for a command" ) } ` ) ;
315+ console . log (
316+ ` ${ dim ( "$" ) } ./x ${ green ( "build" ) } ${
317+ dim ( "# build the deno binary" )
318+ } `,
319+ ) ;
320+ console . log (
321+ ` ${ dim ( "$" ) } ./x ${ green ( "test-unit streams" ) } ${
322+ dim ( '# run unit tests matching "streams"' )
323+ } `,
324+ ) ;
325+ console . log (
326+ ` ${ dim ( "$" ) } ./x ${ green ( "test-spec --list" ) } ${
327+ dim ( "# list all available spec tests" )
328+ } `,
329+ ) ;
330+ console . log (
331+ ` ${ dim ( "$" ) } ./x ${ green ( "fmt" ) } ${
332+ dim ( "# format the codebase" )
333+ } `,
334+ ) ;
335+ console . log (
336+ ` ${ dim ( "$" ) } ./x ${ green ( "build --help" ) } ${
337+ dim ( "# show detailed help for a command" )
338+ } `,
339+ ) ;
245340 console . log ( ) ;
246341 console . log ( ` ${ bold ( "COMMANDS" ) } ` ) ;
247342 for ( const [ name , cmd ] of Object . entries ( COMMANDS ) ) {
@@ -251,13 +346,19 @@ function printHelp(COMMANDS: Record<string, Command>) {
251346 console . log ( ` ${ bold ( "OPTIONS" ) } ` ) ;
252347 console . log ( ` ${ yellow ( "--help, -h" ) } Show this help message` ) ;
253348 console . log ( ) ;
254- console . log ( ` Run ${ cyan ( "./x <command> --help" ) } for detailed information about a specific command.` ) ;
349+ console . log (
350+ ` Run ${
351+ cyan ( "./x <command> --help" )
352+ } for detailed information about a specific command.`,
353+ ) ;
255354 console . log ( ) ;
256355}
257356
258357function printCommandHelp ( name : string , cmd : Command ) {
259358 console . log ( ) ;
260- console . log ( ` ${ bold ( cyan ( "x" ) ) } ${ bold ( green ( name ) ) } ${ dim ( "-" ) } ${ cmd . description } ` ) ;
359+ console . log (
360+ ` ${ bold ( cyan ( "x" ) ) } ${ bold ( green ( name ) ) } ${ dim ( "-" ) } ${ cmd . description } ` ,
361+ ) ;
261362 console . log ( ) ;
262363 for ( const line of cmd . help . split ( "\n" ) ) {
263364 console . log ( ` ${ line } ` ) ;
@@ -297,5 +398,5 @@ export async function main(dirname: string) {
297398 Deno . exit ( 0 ) ;
298399 }
299400
300- await cmd . fn ( ) ;
401+ await cmd . fn ( args . slice ( 1 ) ) ;
301402}
0 commit comments