rust/rhg/src/main.rs
author Pulkit Goyal <7895pulkit@gmail.com>
Sat, 20 Mar 2021 02:03:57 +0530
changeset 46820 821929d59e01
parent 46748 bde90e9b4507
child 46822 c71e8d9e7f2a
permissions -rw-r--r--
rhg: add support for detailed exit code for ConfigParseError This patch adds basic support for detailed exit code to rhg with support for ConfigParseError. For now, if parsing the config results in error, we silently fallbacks to `false`. The python version in this case emits a traceback. Differential Revision: https://phab.mercurial-scm.org/D10253
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
45530
b1cea0dc9db0 rhg: Add debug timing
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45529
diff changeset
     1
extern crate log;
46592
80840b651721 rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46591
diff changeset
     2
use crate::ui::Ui;
45050
18f8d3b31baa rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
     3
use clap::App;
18f8d3b31baa rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
     4
use clap::AppSettings;
46503
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46502
diff changeset
     5
use clap::Arg;
45529
f17caf8f3fef rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
     6
use clap::ArgMatches;
46733
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
     7
use format_bytes::{format_bytes, join};
46592
80840b651721 rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46591
diff changeset
     8
use hg::config::Config;
46593
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
     9
use hg::repo::{Repo, RepoError};
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
    10
use hg::utils::files::{get_bytes_from_os_str, get_path_from_bytes};
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
    11
use hg::utils::SliceExt;
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
    12
use std::ffi::OsString;
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
    13
use std::path::PathBuf;
46667
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
    14
use std::process::Command;
45050
18f8d3b31baa rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    15
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    16
mod blackbox;
44982
bacf6c7ef01b rhg: add Command trait for subcommands implemented by rhg
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44981
diff changeset
    17
mod error;
44981
cf04f62d1579 rhg: add rhg crate
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    18
mod exitcode;
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44982
diff changeset
    19
mod ui;
45529
f17caf8f3fef rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
    20
use error::CommandError;
44981
cf04f62d1579 rhg: add rhg crate
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    21
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    22
fn main_with_result(
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
    23
    process_start_time: &blackbox::ProcessStartTime,
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    24
    ui: &ui::Ui,
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
    25
    repo: Result<&Repo, &NoRepoInCwdError>,
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
    26
    config: &Config,
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    27
) -> Result<(), CommandError> {
46733
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
    28
    check_extensions(config)?;
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
    29
45529
f17caf8f3fef rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
    30
    let app = App::new("rhg")
46608
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    31
        .global_setting(AppSettings::AllowInvalidUtf8)
46746
eb14264b98e8 rhg: Fall back to Python for --version
Simon Sapin <simon.sapin@octobus.net>
parents: 46744
diff changeset
    32
        .global_setting(AppSettings::DisableVersion)
45050
18f8d3b31baa rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    33
        .setting(AppSettings::SubcommandRequired)
18f8d3b31baa rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    34
        .setting(AppSettings::VersionlessSubcommands)
46608
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    35
        .arg(
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    36
            Arg::with_name("repository")
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    37
                .help("repository root directory")
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    38
                .short("-R")
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    39
                .long("--repository")
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    40
                .value_name("REPO")
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    41
                .takes_value(true)
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    42
                // Both ok: `hg -R ./foo log` or `hg log -R ./foo`
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    43
                .global(true),
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    44
        )
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    45
        .arg(
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    46
            Arg::with_name("config")
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    47
                .help("set/override config option (use 'section.name=value')")
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    48
                .long("--config")
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    49
                .value_name("CONFIG")
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    50
                .takes_value(true)
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    51
                .global(true)
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    52
                // Ok: `--config section.key1=val --config section.key2=val2`
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    53
                .multiple(true)
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    54
                // Not ok: `--config section.key1=val section.key2=val2`
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    55
                .number_of_values(1),
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
    56
        )
46736
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
    57
        .arg(
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
    58
            Arg::with_name("cwd")
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
    59
                .help("change working directory")
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
    60
                .long("--cwd")
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
    61
                .value_name("DIR")
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
    62
                .takes_value(true)
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
    63
                .global(true),
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
    64
        )
46502
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
    65
        .version("0.0.1");
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
    66
    let app = add_subcommand_args(app);
45050
18f8d3b31baa rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    67
46591
21d3b40b4c0e rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    68
    let matches = app.clone().get_matches_safe()?;
46503
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46502
diff changeset
    69
46502
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
    70
    let (subcommand_name, subcommand_matches) = matches.subcommand();
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
    71
    let run = subcommand_run_fn(subcommand_name)
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
    72
        .expect("unknown subcommand name from clap despite AppSettings::SubcommandRequired");
46592
80840b651721 rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46591
diff changeset
    73
    let subcommand_args = subcommand_matches
46502
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
    74
        .expect("no subcommand arguments from clap despite AppSettings::SubcommandRequired");
45050
18f8d3b31baa rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    75
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    76
    let invocation = CliInvocation {
46592
80840b651721 rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46591
diff changeset
    77
        ui,
80840b651721 rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46591
diff changeset
    78
        subcommand_args,
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
    79
        config,
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
    80
        repo,
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    81
    };
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    82
    let blackbox = blackbox::Blackbox::new(&invocation, process_start_time)?;
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    83
    blackbox.log_command_start();
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    84
    let result = run(&invocation);
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
    85
    blackbox.log_command_end(exit_code(
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
    86
        &result,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
    87
        // TODO: show a warning or combine with original error if `get_bool`
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
    88
        // returns an error
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
    89
        config
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
    90
            .get_bool(b"ui", b"detailed-exit-code")
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
    91
            .unwrap_or(false),
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
    92
    ));
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    93
    result
46591
21d3b40b4c0e rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    94
}
46502
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
    95
46591
21d3b40b4c0e rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    96
fn main() {
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    97
    // Run this first, before we find out if the blackbox extension is even
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    98
    // enabled, in order to include everything in-between in the duration
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
    99
    // measurements. Reading config files can be slow if they’re on NFS.
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   100
    let process_start_time = blackbox::ProcessStartTime::now();
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   101
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   102
    env_logger::init();
46593
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   103
    let ui = ui::Ui::new();
46591
21d3b40b4c0e rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   104
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   105
    let early_args = EarlyArgs::parse(std::env::args_os());
46736
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   106
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   107
    let initial_current_dir = early_args.cwd.map(|cwd| {
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   108
        let cwd = get_path_from_bytes(&cwd);
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   109
        std::env::current_dir()
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   110
            .and_then(|initial| {
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   111
                std::env::set_current_dir(cwd)?;
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   112
                Ok(initial)
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   113
            })
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   114
            .unwrap_or_else(|error| {
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   115
                exit(
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   116
                    &None,
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   117
                    &ui,
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   118
                    OnUnsupported::Abort,
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   119
                    Err(CommandError::abort(format!(
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   120
                        "abort: {}: '{}'",
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   121
                        error,
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   122
                        cwd.display()
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   123
                    ))),
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   124
                    false,
46736
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   125
                )
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   126
            })
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   127
    });
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   128
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   129
    let non_repo_config =
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   130
        Config::load(early_args.config).unwrap_or_else(|error| {
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   131
            // Normally this is decided based on config, but we don’t have that
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   132
            // available. As of this writing config loading never returns an
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   133
            // "unsupported" error but that is not enforced by the type system.
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   134
            let on_unsupported = OnUnsupported::Abort;
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   135
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   136
            exit(
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   137
                &initial_current_dir,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   138
                &ui,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   139
                on_unsupported,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   140
                Err(error.into()),
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   141
                false,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   142
            )
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   143
        });
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   144
46729
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   145
    if let Some(repo_path_bytes) = &early_args.repo {
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   146
        lazy_static::lazy_static! {
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   147
            static ref SCHEME_RE: regex::bytes::Regex =
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   148
                // Same as `_matchscheme` in `mercurial/util.py`
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   149
                regex::bytes::Regex::new("^[a-zA-Z0-9+.\\-]+:").unwrap();
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   150
        }
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   151
        if SCHEME_RE.is_match(&repo_path_bytes) {
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   152
            exit(
46736
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   153
                &initial_current_dir,
46729
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   154
                &ui,
46748
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   155
                OnUnsupported::from_config(&ui, &non_repo_config),
46729
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   156
                Err(CommandError::UnsupportedFeature {
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   157
                    message: format_bytes!(
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   158
                        b"URL-like --repository {}",
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   159
                        repo_path_bytes
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   160
                    ),
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   161
                }),
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   162
                // TODO: show a warning or combine with original error if
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   163
                // `get_bool` returns an error
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   164
                non_repo_config
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   165
                    .get_bool(b"ui", b"detailed-exit-code")
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   166
                    .unwrap_or(false),
46729
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   167
            )
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   168
        }
6cd9f53aaed8 rhg: Fall back to Python on --repository with an URL
Simon Sapin <simon.sapin@octobus.net>
parents: 46667
diff changeset
   169
    }
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   170
    let repo_path = early_args.repo.as_deref().map(get_path_from_bytes);
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   171
    let repo_result = match Repo::find(&non_repo_config, repo_path) {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   172
        Ok(repo) => Ok(repo),
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   173
        Err(RepoError::NotFound { at }) if repo_path.is_none() => {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   174
            // Not finding a repo is not fatal yet, if `-R` was not given
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   175
            Err(NoRepoInCwdError { cwd: at })
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   176
        }
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   177
        Err(error) => exit(
46736
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   178
            &initial_current_dir,
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   179
            &ui,
46748
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   180
            OnUnsupported::from_config(&ui, &non_repo_config),
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   181
            Err(error.into()),
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   182
            // TODO: show a warning or combine with original error if
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   183
            // `get_bool` returns an error
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   184
            non_repo_config
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   185
                .get_bool(b"ui", b"detailed-exit-code")
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   186
                .unwrap_or(false),
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   187
        ),
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   188
    };
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   189
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   190
    let config = if let Ok(repo) = &repo_result {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   191
        repo.config()
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   192
    } else {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   193
        &non_repo_config
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   194
    };
46748
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   195
    let on_unsupported = OnUnsupported::from_config(&ui, config);
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   196
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   197
    let result = main_with_result(
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   198
        &process_start_time,
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   199
        &ui,
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   200
        repo_result.as_ref(),
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   201
        config,
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   202
    );
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   203
    exit(
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   204
        &initial_current_dir,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   205
        &ui,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   206
        on_unsupported,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   207
        result,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   208
        // TODO: show a warning or combine with original error if `get_bool`
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   209
        // returns an error
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   210
        config
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   211
            .get_bool(b"ui", b"detailed-exit-code")
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   212
            .unwrap_or(false),
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   213
    )
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   214
}
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   215
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   216
fn exit_code(
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   217
    result: &Result<(), CommandError>,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   218
    use_detailed_exit_code: bool,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   219
) -> i32 {
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   220
    match result {
46591
21d3b40b4c0e rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   221
        Ok(()) => exitcode::OK,
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   222
        Err(CommandError::Abort {
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   223
            message: _,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   224
            detailed_exit_code,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   225
        }) => {
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   226
            if use_detailed_exit_code {
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   227
                *detailed_exit_code
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   228
            } else {
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   229
                exitcode::ABORT
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   230
            }
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   231
        }
46744
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46736
diff changeset
   232
        Err(CommandError::Unsuccessful) => exitcode::UNSUCCESSFUL,
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 45923
diff changeset
   233
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 45923
diff changeset
   234
        // Exit with a specific code and no error message to let a potential
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 45923
diff changeset
   235
        // wrapper script fallback to Python-based Mercurial.
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   236
        Err(CommandError::UnsupportedFeature { .. }) => {
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   237
            exitcode::UNIMPLEMENTED
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   238
        }
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   239
    }
44981
cf04f62d1579 rhg: add rhg crate
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   240
}
45529
f17caf8f3fef rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
   241
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   242
fn exit(
46736
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   243
    initial_current_dir: &Option<PathBuf>,
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   244
    ui: &Ui,
46667
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   245
    mut on_unsupported: OnUnsupported,
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   246
    result: Result<(), CommandError>,
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   247
    use_detailed_exit_code: bool,
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   248
) -> ! {
46667
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   249
    if let (
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   250
        OnUnsupported::Fallback { executable },
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   251
        Err(CommandError::UnsupportedFeature { .. }),
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   252
    ) = (&on_unsupported, &result)
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   253
    {
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   254
        let mut args = std::env::args_os();
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   255
        let executable_path = get_path_from_bytes(&executable);
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   256
        let this_executable = args.next().expect("exepcted argv[0] to exist");
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   257
        if executable_path == &PathBuf::from(this_executable) {
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   258
            // Avoid spawning infinitely many processes until resource
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   259
            // exhaustion.
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   260
            let _ = ui.write_stderr(&format_bytes!(
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   261
                b"Blocking recursive fallback. The 'rhg.fallback-executable = {}' config \
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   262
                points to `rhg` itself.\n",
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   263
                executable
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   264
            ));
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   265
            on_unsupported = OnUnsupported::Abort
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   266
        } else {
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   267
            // `args` is now `argv[1..]` since we’ve already consumed `argv[0]`
46736
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   268
            let mut command = Command::new(executable_path);
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   269
            command.args(args);
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   270
            if let Some(initial) = initial_current_dir {
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   271
                command.current_dir(initial);
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   272
            }
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   273
            let result = command.status();
46667
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   274
            match result {
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   275
                Ok(status) => std::process::exit(
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   276
                    status.code().unwrap_or(exitcode::ABORT),
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   277
                ),
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   278
                Err(error) => {
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   279
                    let _ = ui.write_stderr(&format_bytes!(
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   280
                        b"tried to fall back to a '{}' sub-process but got error {}\n",
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   281
                        executable, format_bytes::Utf8(error)
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   282
                    ));
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   283
                    on_unsupported = OnUnsupported::Abort
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   284
                }
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   285
            }
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   286
        }
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   287
    }
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   288
    exit_no_fallback(ui, on_unsupported, result, use_detailed_exit_code)
46748
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   289
}
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   290
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   291
fn exit_no_fallback(
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   292
    ui: &Ui,
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   293
    on_unsupported: OnUnsupported,
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   294
    result: Result<(), CommandError>,
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   295
    use_detailed_exit_code: bool,
46748
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   296
) -> ! {
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   297
    match &result {
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   298
        Ok(_) => {}
46744
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46736
diff changeset
   299
        Err(CommandError::Unsuccessful) => {}
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   300
        Err(CommandError::Abort {
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   301
            message,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   302
            detailed_exit_code: _,
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   303
        }) => {
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   304
            if !message.is_empty() {
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   305
                // Ignore errors when writing to stderr, we’re already exiting
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   306
                // with failure code so there’s not much more we can do.
46731
3d692e724d06 rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46729
diff changeset
   307
                let _ = ui.write_stderr(&format_bytes!(b"{}\n", message));
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   308
            }
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   309
        }
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   310
        Err(CommandError::UnsupportedFeature { message }) => {
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   311
            match on_unsupported {
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   312
                OnUnsupported::Abort => {
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   313
                    let _ = ui.write_stderr(&format_bytes!(
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   314
                        b"unsupported feature: {}\n",
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   315
                        message
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   316
                    ));
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   317
                }
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   318
                OnUnsupported::AbortSilent => {}
46667
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   319
                OnUnsupported::Fallback { .. } => unreachable!(),
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   320
            }
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   321
        }
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   322
    }
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   323
    std::process::exit(exit_code(&result, use_detailed_exit_code))
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   324
}
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   325
46502
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   326
macro_rules! subcommands {
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   327
    ($( $command: ident )+) => {
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   328
        mod commands {
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   329
            $(
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   330
                pub mod $command;
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   331
            )+
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   332
        }
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   333
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   334
        fn add_subcommand_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   335
            app
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   336
            $(
46608
4e4c70401028 rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
   337
                .subcommand(commands::$command::args())
46502
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   338
            )+
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   339
        }
46484
a6e4e4650bac rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
   340
46592
80840b651721 rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46591
diff changeset
   341
        pub type RunFn = fn(&CliInvocation) -> Result<(), CommandError>;
80840b651721 rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46591
diff changeset
   342
80840b651721 rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46591
diff changeset
   343
        fn subcommand_run_fn(name: &str) -> Option<RunFn> {
46502
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   344
            match name {
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   345
                $(
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   346
                    stringify!($command) => Some(commands::$command::run),
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   347
                )+
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   348
                _ => None,
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   349
            }
45542
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
   350
        }
46502
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   351
    };
45529
f17caf8f3fef rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
   352
}
46502
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   353
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   354
subcommands! {
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   355
    cat
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   356
    debugdata
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   357
    debugrequirements
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   358
    files
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   359
    root
46505
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46504
diff changeset
   360
    config
46502
95d37db31479 rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
   361
}
46592
80840b651721 rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46591
diff changeset
   362
pub struct CliInvocation<'a> {
80840b651721 rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46591
diff changeset
   363
    ui: &'a Ui,
80840b651721 rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46591
diff changeset
   364
    subcommand_args: &'a ArgMatches<'a>,
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   365
    config: &'a Config,
46593
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   366
    /// References inside `Result` is a bit peculiar but allow
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   367
    /// `invocation.repo?` to work out with `&CliInvocation` since this
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   368
    /// `Result` type is `Copy`.
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   369
    repo: Result<&'a Repo, &'a NoRepoInCwdError>,
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   370
}
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   371
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   372
struct NoRepoInCwdError {
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   373
    cwd: PathBuf,
46592
80840b651721 rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents: 46591
diff changeset
   374
}
46593
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   375
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   376
/// CLI arguments to be parsed "early" in order to be able to read
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   377
/// configuration before using Clap. Ideally we would also use Clap for this,
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   378
/// see <https://github.com/clap-rs/clap/discussions/2366>.
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   379
///
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   380
/// These arguments are still declared when we do use Clap later, so that Clap
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   381
/// does not return an error for their presence.
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   382
struct EarlyArgs {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   383
    /// Values of all `--config` arguments. (Possibly none)
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   384
    config: Vec<Vec<u8>>,
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   385
    /// Value of the `-R` or `--repository` argument, if any.
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   386
    repo: Option<Vec<u8>>,
46736
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   387
    /// Value of the `--cwd` argument, if any.
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   388
    cwd: Option<Vec<u8>>,
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   389
}
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   390
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   391
impl EarlyArgs {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   392
    fn parse(args: impl IntoIterator<Item = OsString>) -> Self {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   393
        let mut args = args.into_iter().map(get_bytes_from_os_str);
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   394
        let mut config = Vec::new();
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   395
        let mut repo = None;
46736
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   396
        let mut cwd = None;
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   397
        // Use `while let` instead of `for` so that we can also call
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   398
        // `args.next()` inside the loop.
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   399
        while let Some(arg) = args.next() {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   400
            if arg == b"--config" {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   401
                if let Some(value) = args.next() {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   402
                    config.push(value)
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   403
                }
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   404
            } else if let Some(value) = arg.drop_prefix(b"--config=") {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   405
                config.push(value.to_owned())
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   406
            }
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   407
46736
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   408
            if arg == b"--cwd" {
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   409
                if let Some(value) = args.next() {
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   410
                    cwd = Some(value)
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   411
                }
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   412
            } else if let Some(value) = arg.drop_prefix(b"--cwd=") {
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   413
                cwd = Some(value.to_owned())
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   414
            }
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   415
46665
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   416
            if arg == b"--repository" || arg == b"-R" {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   417
                if let Some(value) = args.next() {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   418
                    repo = Some(value)
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   419
                }
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   420
            } else if let Some(value) = arg.drop_prefix(b"--repository=") {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   421
                repo = Some(value.to_owned())
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   422
            } else if let Some(value) = arg.drop_prefix(b"-R") {
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   423
                repo = Some(value.to_owned())
7284b524b441 rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents: 46608
diff changeset
   424
            }
46593
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   425
        }
46736
2255e7eb39e5 rhg: Add support for --cwd
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
   426
        Self { config, repo, cwd }
46593
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   427
    }
5ce2aa7c2ad5 rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents: 46592
diff changeset
   428
}
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   429
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   430
/// What to do when encountering some unsupported feature.
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   431
///
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   432
/// See `HgError::UnsupportedFeature` and `CommandError::UnsupportedFeature`.
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   433
enum OnUnsupported {
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   434
    /// Print an error message describing what feature is not supported,
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   435
    /// and exit with code 252.
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   436
    Abort,
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   437
    /// Silently exit with code 252.
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   438
    AbortSilent,
46667
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   439
    /// Try running a Python implementation
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   440
    Fallback { executable: Vec<u8> },
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   441
}
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   442
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   443
impl OnUnsupported {
46667
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   444
    const DEFAULT: Self = OnUnsupported::Abort;
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   445
46748
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   446
    fn from_config(ui: &Ui, config: &Config) -> Self {
46667
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   447
        match config
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   448
            .get(b"rhg", b"on-unsupported")
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   449
            .map(|value| value.to_ascii_lowercase())
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   450
            .as_deref()
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   451
        {
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   452
            Some(b"abort") => OnUnsupported::Abort,
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   453
            Some(b"abort-silent") => OnUnsupported::AbortSilent,
46667
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   454
            Some(b"fallback") => OnUnsupported::Fallback {
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   455
                executable: config
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   456
                    .get(b"rhg", b"fallback-executable")
46748
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   457
                    .unwrap_or_else(|| {
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   458
                        exit_no_fallback(
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   459
                            ui,
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   460
                            Self::Abort,
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   461
                            Err(CommandError::abort(
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   462
                                "abort: 'rhg.on-unsupported=fallback' without \
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   463
                                'rhg.fallback-executable' set."
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   464
                            )),
46820
821929d59e01 rhg: add support for detailed exit code for ConfigParseError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46748
diff changeset
   465
                            false,
46748
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   466
                        )
bde90e9b4507 rhg: Remove `rhg.fallback-executable=hg` default configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46746
diff changeset
   467
                    })
46667
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   468
                    .to_owned(),
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   469
            },
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   470
            None => Self::DEFAULT,
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   471
            Some(_) => {
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   472
                // TODO: warn about unknown config value
46667
93e9f448273c rhg: Add support for automatic fallback to Python
Simon Sapin <simon.sapin@octobus.net>
parents: 46666
diff changeset
   473
                Self::DEFAULT
46666
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   474
            }
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   475
        }
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   476
    }
33f2d56acc73 rhg: Add a `rhg.on-unsupported` configuration key
Simon Sapin <simon.sapin@octobus.net>
parents: 46665
diff changeset
   477
}
46733
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   478
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   479
const SUPPORTED_EXTENSIONS: &[&[u8]] = &[b"blackbox", b"share"];
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   480
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   481
fn check_extensions(config: &Config) -> Result<(), CommandError> {
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   482
    let enabled = config.get_section_keys(b"extensions");
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   483
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   484
    let mut unsupported = enabled;
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   485
    for supported in SUPPORTED_EXTENSIONS {
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   486
        unsupported.remove(supported);
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   487
    }
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   488
46734
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
   489
    if let Some(ignored_list) =
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
   490
        config.get_simple_list(b"rhg", b"ignored-extensions")
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
   491
    {
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
   492
        for ignored in ignored_list {
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
   493
            unsupported.remove(ignored);
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
   494
        }
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
   495
    }
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
   496
46733
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   497
    if unsupported.is_empty() {
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   498
        Ok(())
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   499
    } else {
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   500
        Err(CommandError::UnsupportedFeature {
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   501
            message: format_bytes!(
46734
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
   502
                b"extensions: {} (consider adding them to 'rhg.ignored-extensions' config)",
46733
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   503
                join(unsupported, b", ")
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   504
            ),
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   505
        })
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   506
    }
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46731
diff changeset
   507
}