@@ -50,10 +50,24 @@ pub enum Error {
50
50
#[ source_code]
51
51
text : NamedSource ,
52
52
} ,
53
- #[ error( "Could not find workspace \" {package}\" from task \" {task_id}\" in project" ) ]
54
- MissingWorkspaceFromTask { package : String , task_id : String } ,
55
- #[ error( "Could not find \" {task_id}\" in root turbo.json or \" {task_name}\" in workspace" ) ]
56
- MissingWorkspaceTask { task_id : String , task_name : String } ,
53
+ #[ error( "Could not find package \" {package}\" from task \" {task_id}\" in project" ) ]
54
+ MissingPackageFromTask {
55
+ #[ label]
56
+ span : Option < SourceSpan > ,
57
+ #[ source_code]
58
+ text : NamedSource ,
59
+ package : String ,
60
+ task_id : String ,
61
+ } ,
62
+ #[ error( "Could not find \" {task_id}\" in root turbo.json or \" {task_name}\" in package" ) ]
63
+ MissingPackageTask {
64
+ #[ label]
65
+ span : Option < SourceSpan > ,
66
+ #[ source_code]
67
+ text : NamedSource ,
68
+ task_id : String ,
69
+ task_name : String ,
70
+ } ,
57
71
#[ error( transparent) ]
58
72
#[ diagnostic( transparent) ]
59
73
Config ( #[ from] crate :: config:: Error ) ,
@@ -64,8 +78,15 @@ pub enum Error {
64
78
} ,
65
79
#[ error( transparent) ]
66
80
Graph ( #[ from] graph:: Error ) ,
67
- #[ error( "Invalid task name {task_name}: {reason}" ) ]
68
- InvalidTaskName { task_name : String , reason : String } ,
81
+ #[ error( "invalid task name: {reason}" ) ]
82
+ InvalidTaskName {
83
+ #[ label]
84
+ span : Option < SourceSpan > ,
85
+ #[ source_code]
86
+ text : NamedSource ,
87
+ task_name : String ,
88
+ reason : String ,
89
+ } ,
69
90
}
70
91
71
92
pub struct EngineBuilder < ' a > {
@@ -160,7 +181,8 @@ impl<'a> EngineBuilder<'a> {
160
181
// workspace is acceptable)
161
182
if !matches ! ( workspace, PackageName :: Root ) || self . root_enabled_tasks . contains ( task)
162
183
{
163
- traversal_queue. push_back ( task. to ( task_id) ) ;
184
+ let task_id = task. to ( task_id) ;
185
+ traversal_queue. push_back ( task_id) ;
164
186
}
165
187
}
166
188
}
@@ -187,6 +209,11 @@ impl<'a> EngineBuilder<'a> {
187
209
let mut engine = Engine :: default ( ) ;
188
210
189
211
while let Some ( task_id) = traversal_queue. pop_front ( ) {
212
+ {
213
+ let ( task_id, span) = task_id. clone ( ) . split ( ) ;
214
+ engine. add_task_location ( task_id. into_owned ( ) , span) ;
215
+ }
216
+
190
217
if task_id. package ( ) == ROOT_PKG_NAME
191
218
&& !self
192
219
. root_enabled_tasks
@@ -200,7 +227,7 @@ impl<'a> EngineBuilder<'a> {
200
227
} ) ;
201
228
}
202
229
203
- validate_task_name ( task_id. task ( ) ) ?;
230
+ validate_task_name ( task_id. to ( task_id . task ( ) ) ) ?;
204
231
205
232
if task_id. package ( ) != ROOT_PKG_NAME
206
233
&& self
@@ -210,9 +237,12 @@ impl<'a> EngineBuilder<'a> {
210
237
{
211
238
// If we have a pkg it should be in PackageGraph.
212
239
// If we're hitting this error something has gone wrong earlier when building
213
- // PackageGraph or the workspace really doesn't exist and
240
+ // PackageGraph or the package really doesn't exist and
214
241
// turbo.json is misconfigured.
215
- return Err ( Error :: MissingWorkspaceFromTask {
242
+ let ( span, text) = task_id. span_and_text ( "turbo.json" ) ;
243
+ return Err ( Error :: MissingPackageFromTask {
244
+ span,
245
+ text,
216
246
package : task_id. package ( ) . to_string ( ) ,
217
247
task_id : task_id. to_string ( ) ,
218
248
} ) ;
@@ -275,7 +305,8 @@ impl<'a> EngineBuilder<'a> {
275
305
engine
276
306
. task_graph
277
307
. add_edge ( to_task_index, from_task_index, ( ) ) ;
278
- traversal_queue. push_back ( span. to ( from_task_id) ) ;
308
+ let from_task_id = span. to ( from_task_id) ;
309
+ traversal_queue. push_back ( from_task_id) ;
279
310
}
280
311
} ) ;
281
312
@@ -289,11 +320,11 @@ impl<'a> EngineBuilder<'a> {
289
320
engine
290
321
. task_graph
291
322
. add_edge ( to_task_index, from_task_index, ( ) ) ;
292
- traversal_queue. push_back ( span. to ( from_task_id) ) ;
323
+ let from_task_id = span. to ( from_task_id) ;
324
+ traversal_queue. push_back ( from_task_id) ;
293
325
}
294
326
295
327
engine. add_definition ( task_id. as_inner ( ) . clone ( ) . into_owned ( ) , task_definition) ;
296
-
297
328
if !has_deps && !has_topo_deps {
298
329
engine. connect_to_root ( & to_task_id) ;
299
330
}
@@ -395,7 +426,10 @@ impl<'a> EngineBuilder<'a> {
395
426
}
396
427
397
428
if task_definitions. is_empty ( ) {
398
- return Err ( Error :: MissingWorkspaceTask {
429
+ let ( span, text) = task_id. span_and_text ( "turbo.json" ) ;
430
+ return Err ( Error :: MissingPackageTask {
431
+ span,
432
+ text,
399
433
task_id : task_id. to_string ( ) ,
400
434
task_name : task_name. to_string ( ) ,
401
435
} ) ;
@@ -447,12 +481,15 @@ impl Error {
447
481
// we can expand the patterns here.
448
482
const INVALID_TOKENS : & [ & str ] = & [ "$colon$" ] ;
449
483
450
- fn validate_task_name ( task : & str ) -> Result < ( ) , Error > {
484
+ fn validate_task_name ( task : Spanned < & str > ) -> Result < ( ) , Error > {
451
485
INVALID_TOKENS
452
486
. iter ( )
453
487
. find ( |token| task. contains ( * * token) )
454
488
. map ( |found_token| {
489
+ let ( span, text) = task. span_and_text ( "turbo.json" ) ;
455
490
Err ( Error :: InvalidTaskName {
491
+ span,
492
+ text,
456
493
task_name : task. to_string ( ) ,
457
494
reason : format ! ( "task contains invalid string '{found_token}'" ) ,
458
495
} )
@@ -1106,7 +1143,7 @@ mod test {
1106
1143
#[ test_case( "build:prod" , None ) ]
1107
1144
#[ test_case( "build$colon$prod" , Some ( "task contains invalid string '$colon$'" ) ) ]
1108
1145
fn test_validate_task_name ( task_name : & str , reason : Option < & str > ) {
1109
- let result = validate_task_name ( task_name)
1146
+ let result = validate_task_name ( Spanned :: new ( task_name) )
1110
1147
. map_err ( |e| {
1111
1148
if let Error :: InvalidTaskName { reason, .. } = e {
1112
1149
reason
0 commit comments