@@ -56,8 +56,12 @@ struct NargoCli {
56
56
#[ derive( Args , Clone , Debug ) ]
57
57
pub ( crate ) struct NargoConfig {
58
58
// REMINDER: Also change this flag in the LSP test lens if renamed
59
- #[ arg( long, hide = true , global = true , default_value = "./" ) ]
59
+ #[ arg( long, hide = true , global = true , default_value = "./" , value_parser = parse_path ) ]
60
60
program_dir : PathBuf ,
61
+
62
+ /// Override the default target directory.
63
+ #[ arg( long, hide = true , global = true , value_parser = parse_path) ]
64
+ target_dir : Option < PathBuf > ,
61
65
}
62
66
63
67
/// Options for commands that work on either workspace or package scope.
@@ -130,14 +134,7 @@ enum LockType {
130
134
#[ cfg( not( feature = "codegen-docs" ) ) ]
131
135
#[ tracing:: instrument( level = "trace" ) ]
132
136
pub ( crate ) fn start_cli ( ) -> eyre:: Result < ( ) > {
133
- use fm:: NormalizePath ;
134
-
135
- let NargoCli { command, mut config } = NargoCli :: parse ( ) ;
136
-
137
- // If the provided `program_dir` is relative, make it absolute by joining it to the current directory.
138
- if !config. program_dir . is_absolute ( ) {
139
- config. program_dir = std:: env:: current_dir ( ) . unwrap ( ) . join ( config. program_dir ) . normalize ( ) ;
140
- }
137
+ let NargoCli { command, config } = NargoCli :: parse ( ) ;
141
138
142
139
match command {
143
140
NargoCommand :: New ( args) => new_cmd:: run ( args, config) ,
@@ -194,14 +191,17 @@ where
194
191
// or a specific package; if that's the case then parse the package name to select it in the workspace.
195
192
let selection = match cmd. package_selection ( ) {
196
193
PackageSelection :: DefaultOrAll if workspace_dir != package_dir => {
197
- let workspace = read_workspace ( & package_dir, PackageSelection :: DefaultOrAll ) ?;
198
- let package = workspace . into_iter ( ) . next ( ) . expect ( "there should be exactly 1 package" ) ;
194
+ let package = read_workspace ( & package_dir, PackageSelection :: DefaultOrAll ) ?;
195
+ let package = package . into_iter ( ) . next ( ) . expect ( "there should be exactly 1 package" ) ;
199
196
PackageSelection :: Selected ( package. name . clone ( ) )
200
197
}
201
198
other => other,
202
199
} ;
203
200
// Parse the top level workspace with the member selected.
204
- let workspace = read_workspace ( & workspace_dir, selection) ?;
201
+ let mut workspace = read_workspace ( & workspace_dir, selection) ?;
202
+ // Optionally override the target directory. It's only done here because most commands like the LSP and DAP
203
+ // don't read or write artifacts, so they don't use the target directory.
204
+ workspace. target_dir = config. target_dir . clone ( ) ;
205
205
// Lock manifests if the command needs it.
206
206
let _locks = match cmd. lock_type ( ) {
207
207
LockType :: None => None ,
@@ -249,18 +249,44 @@ fn lock_workspace(workspace: &Workspace, exclusive: bool) -> Result<Vec<impl Dro
249
249
Ok ( locks)
250
250
}
251
251
252
+ /// Parses a path and turns it into an absolute one by joining to the current directory.
253
+ fn parse_path ( path : & str ) -> Result < PathBuf , String > {
254
+ use fm:: NormalizePath ;
255
+ let mut path: PathBuf = path. parse ( ) . map_err ( |e| format ! ( "failed to parse path: {e}" ) ) ?;
256
+ if !path. is_absolute ( ) {
257
+ path = std:: env:: current_dir ( ) . unwrap ( ) . join ( path) . normalize ( ) ;
258
+ }
259
+ Ok ( path)
260
+ }
261
+
252
262
#[ cfg( test) ]
253
263
mod tests {
264
+ use super :: NargoCli ;
254
265
use clap:: Parser ;
266
+
255
267
#[ test]
256
268
fn test_parse_invalid_expression_width ( ) {
257
269
let cmd = "nargo --program-dir . compile --expression-width 1" ;
258
- let res = super :: NargoCli :: try_parse_from ( cmd. split_ascii_whitespace ( ) ) ;
270
+ let res = NargoCli :: try_parse_from ( cmd. split_ascii_whitespace ( ) ) ;
259
271
260
272
let err = res. expect_err ( "should fail because of invalid width" ) ;
261
273
assert ! ( err. to_string( ) . contains( "expression-width" ) ) ;
262
274
assert ! ( err
263
275
. to_string( )
264
276
. contains( acvm:: compiler:: MIN_EXPRESSION_WIDTH . to_string( ) . as_str( ) ) ) ;
265
277
}
278
+
279
+ #[ test]
280
+ fn test_parse_target_dir ( ) {
281
+ let cmd = "nargo --program-dir . --target-dir ../foo/bar execute" ;
282
+ let cli = NargoCli :: try_parse_from ( cmd. split_ascii_whitespace ( ) ) . expect ( "should parse" ) ;
283
+
284
+ let target_dir = cli. config . target_dir . expect ( "should parse target dir" ) ;
285
+ assert ! ( target_dir. is_absolute( ) , "should be made absolute" ) ;
286
+ assert ! ( target_dir. ends_with( "foo/bar" ) ) ;
287
+
288
+ let cmd = "nargo --program-dir . execute" ;
289
+ let cli = NargoCli :: try_parse_from ( cmd. split_ascii_whitespace ( ) ) . expect ( "should parse" ) ;
290
+ assert ! ( cli. config. target_dir. is_none( ) ) ;
291
+ }
266
292
}
0 commit comments