rust/rhg/src/main.rs
changeset 48353 8960295b9246
parent 48340 d71b9902e2de
child 48355 6d4daf51283c
equal deleted inserted replaced
48352:a71a2f72f5d8 48353:8960295b9246
   177         .load_cli_args_config(early_args.config)
   177         .load_cli_args_config(early_args.config)
   178         .unwrap_or_else(|error| {
   178         .unwrap_or_else(|error| {
   179             exit(
   179             exit(
   180                 &initial_current_dir,
   180                 &initial_current_dir,
   181                 &ui,
   181                 &ui,
   182                 OnUnsupported::from_config(&ui, &non_repo_config),
   182                 OnUnsupported::from_config(&non_repo_config),
   183                 Err(error.into()),
   183                 Err(error.into()),
   184                 non_repo_config
   184                 non_repo_config
   185                     .get_bool(b"ui", b"detailed-exit-code")
   185                     .get_bool(b"ui", b"detailed-exit-code")
   186                     .unwrap_or(false),
   186                     .unwrap_or(false),
   187             )
   187             )
   195         }
   195         }
   196         if SCHEME_RE.is_match(&repo_path_bytes) {
   196         if SCHEME_RE.is_match(&repo_path_bytes) {
   197             exit(
   197             exit(
   198                 &initial_current_dir,
   198                 &initial_current_dir,
   199                 &ui,
   199                 &ui,
   200                 OnUnsupported::from_config(&ui, &non_repo_config),
   200                 OnUnsupported::from_config(&non_repo_config),
   201                 Err(CommandError::UnsupportedFeature {
   201                 Err(CommandError::UnsupportedFeature {
   202                     message: format_bytes!(
   202                     message: format_bytes!(
   203                         b"URL-like --repository {}",
   203                         b"URL-like --repository {}",
   204                         repo_path_bytes
   204                         repo_path_bytes
   205                     ),
   205                     ),
   285             Err(NoRepoInCwdError { cwd: at })
   285             Err(NoRepoInCwdError { cwd: at })
   286         }
   286         }
   287         Err(error) => exit(
   287         Err(error) => exit(
   288             &initial_current_dir,
   288             &initial_current_dir,
   289             &ui,
   289             &ui,
   290             OnUnsupported::from_config(&ui, &non_repo_config),
   290             OnUnsupported::from_config(&non_repo_config),
   291             Err(error.into()),
   291             Err(error.into()),
   292             // TODO: show a warning or combine with original error if
   292             // TODO: show a warning or combine with original error if
   293             // `get_bool` returns an error
   293             // `get_bool` returns an error
   294             non_repo_config
   294             non_repo_config
   295                 .get_bool(b"ui", b"detailed-exit-code")
   295                 .get_bool(b"ui", b"detailed-exit-code")
   300     let config = if let Ok(repo) = &repo_result {
   300     let config = if let Ok(repo) = &repo_result {
   301         repo.config()
   301         repo.config()
   302     } else {
   302     } else {
   303         &non_repo_config
   303         &non_repo_config
   304     };
   304     };
   305     let on_unsupported = OnUnsupported::from_config(&ui, config);
   305     let on_unsupported = OnUnsupported::from_config(config);
   306 
   306 
   307     let result = main_with_result(
   307     let result = main_with_result(
   308         &process_start_time,
   308         &process_start_time,
   309         &ui,
   309         &ui,
   310         repo_result.as_ref(),
   310         repo_result.as_ref(),
   360         OnUnsupported::Fallback { executable },
   360         OnUnsupported::Fallback { executable },
   361         Err(CommandError::UnsupportedFeature { .. }),
   361         Err(CommandError::UnsupportedFeature { .. }),
   362     ) = (&on_unsupported, &result)
   362     ) = (&on_unsupported, &result)
   363     {
   363     {
   364         let mut args = std::env::args_os();
   364         let mut args = std::env::args_os();
       
   365         let executable = match executable {
       
   366             None => {
       
   367                 exit_no_fallback(
       
   368                     ui,
       
   369                     OnUnsupported::Abort,
       
   370                     Err(CommandError::abort(
       
   371                         "abort: 'rhg.on-unsupported=fallback' without \
       
   372                                 'rhg.fallback-executable' set.",
       
   373                     )),
       
   374                     false,
       
   375                 );
       
   376             }
       
   377             Some(executable) => executable,
       
   378         };
   365         let executable_path = get_path_from_bytes(&executable);
   379         let executable_path = get_path_from_bytes(&executable);
   366         let this_executable = args.next().expect("exepcted argv[0] to exist");
   380         let this_executable = args.next().expect("exepcted argv[0] to exist");
   367         if executable_path == &PathBuf::from(this_executable) {
   381         if executable_path == &PathBuf::from(this_executable) {
   368             // Avoid spawning infinitely many processes until resource
   382             // Avoid spawning infinitely many processes until resource
   369             // exhaustion.
   383             // exhaustion.
   372                 points to `rhg` itself.\n",
   386                 points to `rhg` itself.\n",
   373                 executable
   387                 executable
   374             ));
   388             ));
   375             on_unsupported = OnUnsupported::Abort
   389             on_unsupported = OnUnsupported::Abort
   376         } else {
   390         } else {
   377             // `args` is now `argv[1..]` since we’ve already consumed `argv[0]`
   391             // `args` is now `argv[1..]` since we’ve already consumed
       
   392             // `argv[0]`
   378             let mut command = Command::new(executable_path);
   393             let mut command = Command::new(executable_path);
   379             command.args(args);
   394             command.args(args);
   380             if let Some(initial) = initial_current_dir {
   395             if let Some(initial) = initial_current_dir {
   381                 command.current_dir(initial);
   396                 command.current_dir(initial);
   382             }
   397             }
   547     /// and exit with code 252.
   562     /// and exit with code 252.
   548     Abort,
   563     Abort,
   549     /// Silently exit with code 252.
   564     /// Silently exit with code 252.
   550     AbortSilent,
   565     AbortSilent,
   551     /// Try running a Python implementation
   566     /// Try running a Python implementation
   552     Fallback { executable: Vec<u8> },
   567     Fallback { executable: Option<Vec<u8>> },
   553 }
   568 }
   554 
   569 
   555 impl OnUnsupported {
   570 impl OnUnsupported {
   556     const DEFAULT: Self = OnUnsupported::Abort;
   571     const DEFAULT: Self = OnUnsupported::Abort;
   557 
   572 
   558     fn from_config(ui: &Ui, config: &Config) -> Self {
   573     fn from_config(config: &Config) -> Self {
   559         match config
   574         match config
   560             .get(b"rhg", b"on-unsupported")
   575             .get(b"rhg", b"on-unsupported")
   561             .map(|value| value.to_ascii_lowercase())
   576             .map(|value| value.to_ascii_lowercase())
   562             .as_deref()
   577             .as_deref()
   563         {
   578         {
   564             Some(b"abort") => OnUnsupported::Abort,
   579             Some(b"abort") => OnUnsupported::Abort,
   565             Some(b"abort-silent") => OnUnsupported::AbortSilent,
   580             Some(b"abort-silent") => OnUnsupported::AbortSilent,
   566             Some(b"fallback") => OnUnsupported::Fallback {
   581             Some(b"fallback") => OnUnsupported::Fallback {
   567                 executable: config
   582                 executable: config
   568                     .get(b"rhg", b"fallback-executable")
   583                     .get(b"rhg", b"fallback-executable")
   569                     .unwrap_or_else(|| {
   584                     .map(|x| x.to_owned()),
   570                         exit_no_fallback(
       
   571                             ui,
       
   572                             Self::Abort,
       
   573                             Err(CommandError::abort(
       
   574                                 "abort: 'rhg.on-unsupported=fallback' without \
       
   575                                 'rhg.fallback-executable' set."
       
   576                             )),
       
   577                             false,
       
   578                         )
       
   579                     })
       
   580                     .to_owned(),
       
   581             },
   585             },
   582             None => Self::DEFAULT,
   586             None => Self::DEFAULT,
   583             Some(_) => {
   587             Some(_) => {
   584                 // TODO: warn about unknown config value
   588                 // TODO: warn about unknown config value
   585                 Self::DEFAULT
   589                 Self::DEFAULT