@@ -162,6 +162,13 @@ pub struct UpgradeFlags {
162162 pub ca_file : Option < String > ,
163163}
164164
165+ #[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
166+ pub struct VendorFlags {
167+ pub specifiers : Vec < String > ,
168+ pub output_path : Option < PathBuf > ,
169+ pub force : bool ,
170+ }
171+
165172#[ derive( Clone , Debug , PartialEq , Deserialize , Serialize ) ]
166173pub enum DenoSubcommand {
167174 Bundle ( BundleFlags ) ,
@@ -182,6 +189,7 @@ pub enum DenoSubcommand {
182189 Test ( TestFlags ) ,
183190 Types ,
184191 Upgrade ( UpgradeFlags ) ,
192+ Vendor ( VendorFlags ) ,
185193}
186194
187195impl Default for DenoSubcommand {
@@ -481,6 +489,7 @@ pub fn flags_from_vec(args: Vec<String>) -> clap::Result<Flags> {
481489 Some ( ( "lint" , m) ) => lint_parse ( & mut flags, m) ,
482490 Some ( ( "compile" , m) ) => compile_parse ( & mut flags, m) ,
483491 Some ( ( "lsp" , m) ) => lsp_parse ( & mut flags, m) ,
492+ Some ( ( "vendor" , m) ) => vendor_parse ( & mut flags, m) ,
484493 _ => handle_repl_flags ( & mut flags, ReplFlags { eval : None } ) ,
485494 }
486495
@@ -552,6 +561,7 @@ If the flag is set, restrict these messages to errors.",
552561 . subcommand ( test_subcommand ( ) )
553562 . subcommand ( types_subcommand ( ) )
554563 . subcommand ( upgrade_subcommand ( ) )
564+ . subcommand ( vendor_subcommand ( ) )
555565 . long_about ( DENO_HELP )
556566 . after_help ( ENV_VARIABLES_HELP )
557567}
@@ -1413,6 +1423,52 @@ update to a different location, use the --output flag
14131423 . arg ( ca_file_arg ( ) )
14141424}
14151425
1426+ fn vendor_subcommand < ' a > ( ) -> App < ' a > {
1427+ App :: new ( "vendor" )
1428+ . about ( "Vendor remote modules into a local directory" )
1429+ . long_about (
1430+ "Vendor remote modules into a local directory.
1431+
1432+ Analyzes the provided modules along with their dependencies, downloads
1433+ remote modules to the output directory, and produces an import map that
1434+ maps remote specifiers to the downloaded files.
1435+
1436+ deno vendor main.ts
1437+ deno run --import-map vendor/import_map.json main.ts
1438+
1439+ Remote modules and multiple modules may also be specified:
1440+
1441+ deno vendor main.ts test.deps.ts https://deno.land/std/path/mod.ts" ,
1442+ )
1443+ . arg (
1444+ Arg :: new ( "specifiers" )
1445+ . takes_value ( true )
1446+ . multiple_values ( true )
1447+ . multiple_occurrences ( true )
1448+ . required ( true ) ,
1449+ )
1450+ . arg (
1451+ Arg :: new ( "output" )
1452+ . long ( "output" )
1453+ . help ( "The directory to output the vendored modules to" )
1454+ . takes_value ( true ) ,
1455+ )
1456+ . arg (
1457+ Arg :: new ( "force" )
1458+ . long ( "force" )
1459+ . short ( 'f' )
1460+ . help (
1461+ "Forcefully overwrite conflicting files in existing output directory" ,
1462+ )
1463+ . takes_value ( false ) ,
1464+ )
1465+ . arg ( config_arg ( ) )
1466+ . arg ( import_map_arg ( ) )
1467+ . arg ( lock_arg ( ) )
1468+ . arg ( reload_arg ( ) )
1469+ . arg ( ca_file_arg ( ) )
1470+ }
1471+
14161472fn compile_args ( app : App ) -> App {
14171473 app
14181474 . arg ( import_map_arg ( ) )
@@ -2237,6 +2293,23 @@ fn upgrade_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
22372293 } ) ;
22382294}
22392295
2296+ fn vendor_parse ( flags : & mut Flags , matches : & clap:: ArgMatches ) {
2297+ ca_file_arg_parse ( flags, matches) ;
2298+ config_arg_parse ( flags, matches) ;
2299+ import_map_arg_parse ( flags, matches) ;
2300+ lock_arg_parse ( flags, matches) ;
2301+ reload_arg_parse ( flags, matches) ;
2302+
2303+ flags. subcommand = DenoSubcommand :: Vendor ( VendorFlags {
2304+ specifiers : matches
2305+ . values_of ( "specifiers" )
2306+ . map ( |p| p. map ( ToString :: to_string) . collect ( ) )
2307+ . unwrap_or_default ( ) ,
2308+ output_path : matches. value_of ( "output" ) . map ( PathBuf :: from) ,
2309+ force : matches. is_present ( "force" ) ,
2310+ } ) ;
2311+ }
2312+
22402313fn compile_args_parse ( flags : & mut Flags , matches : & clap:: ArgMatches ) {
22412314 import_map_arg_parse ( flags, matches) ;
22422315 no_remote_arg_parse ( flags, matches) ;
@@ -2443,13 +2516,17 @@ fn no_check_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
24432516}
24442517
24452518fn lock_args_parse ( flags : & mut Flags , matches : & clap:: ArgMatches ) {
2519+ lock_arg_parse ( flags, matches) ;
2520+ if matches. is_present ( "lock-write" ) {
2521+ flags. lock_write = true ;
2522+ }
2523+ }
2524+
2525+ fn lock_arg_parse ( flags : & mut Flags , matches : & clap:: ArgMatches ) {
24462526 if matches. is_present ( "lock" ) {
24472527 let lockfile = matches. value_of ( "lock" ) . unwrap ( ) ;
24482528 flags. lock = Some ( PathBuf :: from ( lockfile) ) ;
24492529 }
2450- if matches. is_present ( "lock-write" ) {
2451- flags. lock_write = true ;
2452- }
24532530}
24542531
24552532fn config_arg_parse ( flags : & mut Flags , matches : & ArgMatches ) {
@@ -2512,8 +2589,8 @@ mod tests {
25122589
25132590 /// Creates vector of strings, Vec<String>
25142591 macro_rules! svec {
2515- ( $( $x: expr) ,* ) => ( vec![ $( $x. to_string( ) ) ,* ] ) ;
2516- }
2592+ ( $( $x: expr) ,* $ ( , ) ? ) => ( vec![ $( $x. to_string( ) ) ,* ] ) ;
2593+ }
25172594
25182595 #[ test]
25192596 fn global_flags ( ) {
@@ -4895,4 +4972,55 @@ mod tests {
48954972 . contains( "error: The following required arguments were not provided:" ) ) ;
48964973 assert ! ( & error_message. contains( "--watch=<FILES>..." ) ) ;
48974974 }
4975+
4976+ #[ test]
4977+ fn vendor_minimal ( ) {
4978+ let r = flags_from_vec ( svec ! [ "deno" , "vendor" , "mod.ts" , ] ) ;
4979+ assert_eq ! (
4980+ r. unwrap( ) ,
4981+ Flags {
4982+ subcommand: DenoSubcommand :: Vendor ( VendorFlags {
4983+ specifiers: svec![ "mod.ts" ] ,
4984+ force: false ,
4985+ output_path: None ,
4986+ } ) ,
4987+ ..Flags :: default ( )
4988+ }
4989+ ) ;
4990+ }
4991+
4992+ #[ test]
4993+ fn vendor_all ( ) {
4994+ let r = flags_from_vec ( svec ! [
4995+ "deno" ,
4996+ "vendor" ,
4997+ "--config" ,
4998+ "deno.json" ,
4999+ "--import-map" ,
5000+ "import_map.json" ,
5001+ "--lock" ,
5002+ "lock.json" ,
5003+ "--force" ,
5004+ "--output" ,
5005+ "out_dir" ,
5006+ "--reload" ,
5007+ "mod.ts" ,
5008+ "deps.test.ts" ,
5009+ ] ) ;
5010+ assert_eq ! (
5011+ r. unwrap( ) ,
5012+ Flags {
5013+ subcommand: DenoSubcommand :: Vendor ( VendorFlags {
5014+ specifiers: svec![ "mod.ts" , "deps.test.ts" ] ,
5015+ force: true ,
5016+ output_path: Some ( PathBuf :: from( "out_dir" ) ) ,
5017+ } ) ,
5018+ config_path: Some ( "deno.json" . to_string( ) ) ,
5019+ import_map_path: Some ( "import_map.json" . to_string( ) ) ,
5020+ lock: Some ( PathBuf :: from( "lock.json" ) ) ,
5021+ reload: true ,
5022+ ..Flags :: default ( )
5023+ }
5024+ ) ;
5025+ }
48985026}
0 commit comments