admin: move subcommand definitions into subcommand files

Summary:
This feels like a more natural place to store them. Also, it will make
`main.rs` more readable.

Reviewed By: StanislavGlebik

Differential Revision: D21143850

fbshipit-source-id: 6ab3ec268beea92d7f897860f7688a775d60c4bf
This commit is contained in:
Kostia Balytskyi 2020-04-21 02:27:29 -07:00 committed by Facebook GitHub Bot
parent d3f79980ef
commit 1e95aa7293
20 changed files with 424 additions and 395 deletions

View File

@ -10,7 +10,7 @@ use std::fmt;
use std::sync::Arc;
use anyhow::{format_err, Error, Result};
use clap::ArgMatches;
use clap::{App, Arg, ArgMatches, SubCommand};
use fbinit::FacebookInit;
use futures::compat::Future01CompatExt;
use futures_ext::{try_boxfuture, BoxFuture, FutureExt};
@ -36,9 +36,54 @@ use std::collections::HashMap;
use std::iter::FromIterator;
use std::str::FromStr;
use crate::cmdargs::{BLOBSTORE_FETCH, SCRUB_BLOBSTORE_ACTION_ARG};
use crate::error::SubcommandError;
pub const SCRUB_BLOBSTORE_ACTION_ARG: &'static str = "scrub-blobstore-action";
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(BLOBSTORE_FETCH)
.about("fetches blobs from manifold")
.args_from_usage("[KEY] 'key of the blob to be fetched'")
.arg(
Arg::with_name("decode-as")
.long("decode-as")
.short("d")
.takes_value(true)
.possible_values(&["auto", "changeset", "manifest", "file", "contents", "git-tree"])
.required(false)
.help("if provided decode the value"),
)
.arg(
Arg::with_name("use-memcache")
.long("use-memcache")
.short("m")
.takes_value(true)
.possible_values(&["cache-only", "no-fill", "fill-mc"])
.required(false)
.help("Use memcache to cache access to the blob store"),
)
.arg(
Arg::with_name("no-prefix")
.long("no-prefix")
.short("P")
.takes_value(false)
.required(false)
.help("Don't prepend a prefix based on the repo id to the key"),
)
.arg(
Arg::with_name("inner-blobstore-id")
.long("inner-blobstore-id")
.takes_value(true)
.required(false)
.help("If main blobstore in the storage config is a multiplexed one, use inner blobstore with this id")
)
.arg(
Arg::with_name(SCRUB_BLOBSTORE_ACTION_ARG)
.long(SCRUB_BLOBSTORE_ACTION_ARG)
.takes_value(true)
.required(false)
.help("Enable ScrubBlobstore with the given action. Checks for keys missing from stores. In ReportOnly mode this logs only, otherwise it performs a copy to the missing stores."),
)
}
fn get_blobconfig(
blob_config: BlobConfig,

View File

@ -5,7 +5,7 @@
* GNU General Public License version 2.
*/
use clap::ArgMatches;
use clap::{App, ArgMatches, SubCommand};
use cmdlib::args;
use context::CoreContext;
use fbinit::FacebookInit;
@ -16,9 +16,19 @@ use serde_derive::Serialize;
use slog::Logger;
use std::collections::BTreeMap;
use crate::cmdargs::BONSAI_FETCH;
use crate::common::fetch_bonsai_changeset;
use crate::error::SubcommandError;
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(BONSAI_FETCH)
.about("fetches content of the file or manifest from blobrepo")
.args_from_usage(
r#"<CHANGESET_ID> 'hg/bonsai id or bookmark to fetch file from'
--json 'if provided json will be returned'"#,
)
}
pub async fn subcommand_bonsai_fetch<'a>(
fb: FacebookInit,
logger: Logger,

View File

@ -21,6 +21,7 @@ use slog::{info, Logger};
use blobrepo::BlobRepo;
use bookmarks::{BookmarkName, BookmarkUpdateReason};
use crate::cmdargs::BOOKMARKS;
use crate::common::{fetch_bonsai_changeset, format_bookmark_log_entry};
use crate::error::SubcommandError;
@ -30,7 +31,8 @@ const LOG_CMD: &'static str = "log";
const LIST_CMD: &'static str = "list";
const DEL_CMD: &'static str = "delete";
pub fn prepare_command<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
let parent_subcommand = SubCommand::with_name(BOOKMARKS);
let set = SubCommand::with_name(SET_CMD)
.about(
"sets a bookmark to a specific hg changeset, if the bookmark does not exist it will
@ -102,7 +104,8 @@ pub fn prepare_command<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
"#,
);
app.about("set of commands to manipulate bookmarks")
parent_subcommand
.about("set of commands to manipulate bookmarks")
.subcommand(set)
.subcommand(get)
.subcommand(log)

View File

@ -43,3 +43,4 @@ pub const SKIPLIST: &'static str = "skiplist";
pub const UNODES: &'static str = "unodes";
pub const BLAME: &'static str = "blame";
pub const DELETED_MANIFEST: &'static str = "deleted-manifest";
pub const SCRUB_BLOBSTORE_ACTION_ARG: &'static str = "scrub-blobstore-action";

View File

@ -9,7 +9,7 @@ use anyhow::{format_err, Error};
use blobrepo::BlobRepo;
use blobstore::Loadable;
use bytes::BytesMut;
use clap::ArgMatches;
use clap::{App, ArgMatches, SubCommand};
use cloned::cloned;
use cmdlib::{args, helpers};
use context::CoreContext;
@ -23,8 +23,18 @@ use mercurial_types::manifest::Content;
use mercurial_types::{HgManifest, MPath, MPathElement};
use slog::{debug, Logger};
use crate::cmdargs::CONTENT_FETCH;
use crate::error::SubcommandError;
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(CONTENT_FETCH)
.about("fetches content of the file or manifest from blobrepo")
.args_from_usage(
"<CHANGESET_ID> 'hg/bonsai id or bookmark to fetch file from'
<PATH> 'path to fetch'",
)
}
pub async fn subcommand_content_fetch<'a>(
fb: FacebookInit,
logger: Logger,

View File

@ -30,6 +30,7 @@ use movers::{get_large_to_small_mover, get_small_to_large_mover};
use slog::{info, warn, Logger};
use synced_commit_mapping::{SqlSyncedCommitMapping, SyncedCommitMapping};
use crate::cmdargs::CROSSREPO;
use crate::error::SubcommandError;
const MAP_SUBCOMMAND: &str = "map";
@ -339,7 +340,7 @@ async fn update_large_repo_bookmarks(
Ok(())
}
pub fn build_subcommand(name: &str) -> App {
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
let map_subcommand = SubCommand::with_name(MAP_SUBCOMMAND)
.about("Check cross-repo commit mapping")
.arg(
@ -366,7 +367,7 @@ pub fn build_subcommand(name: &str) -> App {
.help("update any inconsistencies between bookmarks (except for the common bookmarks between large and small repo e.g. 'master')"),
);
SubCommand::with_name(name)
SubCommand::with_name(CROSSREPO)
.subcommand(map_subcommand)
.subcommand(verify_wc_subcommand)
.subcommand(verify_bookmarks_subcommand)

View File

@ -17,6 +17,7 @@ use futures::{compat::Future01CompatExt, future::FutureExt as PreviewFutureExt,
use futures_util::future::try_join_all;
use slog::Logger;
use crate::cmdargs::DERIVED_DATA;
use crate::error::SubcommandError;
const SUBCOMMAND_EXISTS: &'static str = "exists";
@ -24,8 +25,8 @@ const SUBCOMMAND_EXISTS: &'static str = "exists";
const ARG_HASH_OR_BOOKMARK: &'static str = "hash-or-bookmark";
const ARG_TYPE: &'static str = "type";
pub fn build_subcommand(name: &str) -> App {
SubCommand::with_name(name)
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(DERIVED_DATA)
.about("request information about derived data")
.subcommand(
SubCommand::with_name(SUBCOMMAND_EXISTS)

View File

@ -25,6 +25,7 @@ use mercurial_types::{HgFileEnvelope, HgFileNodeId, MPath};
use mononoke_types::RepoPath;
use slog::{debug, info, Logger};
use crate::cmdargs::FILENODES;
use crate::common::get_file_nodes;
use crate::error::SubcommandError;
@ -40,8 +41,8 @@ const ARG_PATHS: &str = "paths";
const ARG_ID: &str = "id";
const ARG_PATH: &str = "path";
pub fn build_subcommand(name: &str) -> App {
SubCommand::with_name(name)
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(FILENODES)
.about("fetches hg filenodes information for a commit and one or more paths")
.arg(
Arg::with_name(ARG_ENVELOPE)

View File

@ -26,6 +26,7 @@ use std::io::BufReader;
use std::str::FromStr;
use tokio_old::{codec, fs::File};
use crate::cmdargs::FILESTORE;
use crate::error::SubcommandError;
const COMMAND_METADATA: &str = "metadata";
@ -40,7 +41,7 @@ const ARG_FILE: &str = "file";
// NOTE: Fetching by GitSha1 is not concurrently supported since that needs a size to instantiate.
const VALID_KINDS: [&str; 3] = ["id", "sha1", "sha256"];
pub fn build_subcommand(name: &str) -> App {
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
let kind_arg = Arg::with_name(ARG_KIND)
.possible_values(&VALID_KINDS)
.help("Identifier kind")
@ -52,7 +53,7 @@ pub fn build_subcommand(name: &str) -> App {
.takes_value(true)
.required(true);
SubCommand::with_name(name)
SubCommand::with_name(FILESTORE)
.about("inspect and interact with filestore data")
.subcommand(
SubCommand::with_name(COMMAND_METADATA)

View File

@ -5,7 +5,7 @@
* GNU General Public License version 2.
*/
use clap::ArgMatches;
use clap::{App, Arg, ArgMatches, SubCommand};
use fbinit::FacebookInit;
use futures::compat::Future01CompatExt;
use futures_ext::FutureExt;
@ -18,8 +18,33 @@ use mercurial_types::HgChangesetId;
use mononoke_types::ChangesetId;
use slog::Logger;
use crate::cmdargs::HASH_CONVERT;
use crate::error::SubcommandError;
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(HASH_CONVERT)
.about("convert between bonsai and hg changeset hashes")
.arg(
Arg::with_name("from")
.long("from")
.short("f")
.required(true)
.takes_value(true)
.possible_values(&["hg", "bonsai"])
.help("Source hash type"),
)
.arg(
Arg::with_name("to")
.long("to")
.short("t")
.required(true)
.takes_value(true)
.possible_values(&["hg", "bonsai"])
.help("Target hash type"),
)
.args_from_usage("<HASH> 'source hash'")
}
pub async fn subcommand_hash_convert<'a>(
fb: FacebookInit,
logger: Logger,

View File

@ -8,7 +8,7 @@
use anyhow::{format_err, Error};
use blobrepo::BlobRepo;
use blobstore::Loadable;
use clap::ArgMatches;
use clap::{App, ArgMatches, SubCommand};
use cloned::cloned;
use cmdlib::args;
use context::CoreContext;
@ -26,9 +26,30 @@ use std::collections::BTreeMap;
use std::io;
use std::str::FromStr;
use crate::cmdargs::{HG_CHANGESET_DIFF, HG_CHANGESET_RANGE};
use crate::cmdargs::{HG_CHANGESET, HG_CHANGESET_DIFF, HG_CHANGESET_RANGE};
use crate::error::SubcommandError;
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(HG_CHANGESET)
.about("mercural changeset level queries")
.subcommand(
SubCommand::with_name(HG_CHANGESET_DIFF)
.about("compare two changeset (used by pushrebase replayer)")
.args_from_usage(
"<LEFT_CS> 'left changeset id'
<RIGHT_CS> 'right changeset id'",
),
)
.subcommand(
SubCommand::with_name(HG_CHANGESET_RANGE)
.about("returns `x::y` revset")
.args_from_usage(
"<START_CS> 'start changeset id'
<STOP_CS> 'stop changeset id'",
),
)
}
pub async fn subcommand_hg_changeset<'a>(
fb: FacebookInit,
logger: Logger,

View File

@ -7,7 +7,7 @@
use anyhow::Error;
use bookmarks::{BookmarkUpdateReason, Bookmarks, Freshness};
use clap::ArgMatches;
use clap::{App, Arg, ArgMatches, SubCommand};
use cloned::cloned;
use cmdlib::args;
use context::CoreContext;
@ -25,11 +25,90 @@ use mutable_counters::{MutableCounters, SqlMutableCounters};
use slog::{info, Logger};
use crate::cmdargs::{
HG_SYNC_FETCH_BUNDLE, HG_SYNC_LAST_PROCESSED, HG_SYNC_REMAINS, HG_SYNC_SHOW, HG_SYNC_VERIFY,
HG_SYNC_BUNDLE, HG_SYNC_FETCH_BUNDLE, HG_SYNC_LAST_PROCESSED, HG_SYNC_REMAINS, HG_SYNC_SHOW,
HG_SYNC_VERIFY,
};
use crate::common::{format_bookmark_log_entry, LATEST_REPLAYED_REQUEST_KEY};
use crate::error::SubcommandError;
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(HG_SYNC_BUNDLE)
.about("things related to mononoke-hg-sync counters")
.subcommand(
SubCommand::with_name(HG_SYNC_LAST_PROCESSED)
.about("inspect/change mononoke-hg sync last processed counter")
.arg(
Arg::with_name("set")
.long("set")
.required(false)
.takes_value(true)
.help("set the value of the latest processed mononoke-hg-sync counter"),
)
.arg(
Arg::with_name("skip-blobimport")
.long("skip-blobimport")
.required(false)
.help("skip to the next non-blobimport entry in mononoke-hg-sync counter"),
)
.arg(
Arg::with_name("dry-run")
.long("dry-run")
.required(false)
.help("don't make changes, only show what would have been done (--skip-blobimport only)"),
),
)
.subcommand(
SubCommand::with_name(HG_SYNC_REMAINS)
.about("get the value of the last mononoke-hg-sync counter to be processed")
.arg(
Arg::with_name("quiet")
.long("quiet")
.required(false)
.takes_value(false)
.help("only print the number if present"),
)
.arg(
Arg::with_name("without-blobimport")
.long("without-blobimport")
.required(false)
.takes_value(false)
.help("exclude blobimport entries from the count"),
),
)
.subcommand(
SubCommand::with_name(HG_SYNC_SHOW).about("show hg hashes of yet to be replayed bundles")
.arg(
Arg::with_name("limit")
.long("limit")
.required(false)
.takes_value(true)
.help("how many bundles to show"),
)
)
.subcommand(
SubCommand::with_name(HG_SYNC_FETCH_BUNDLE)
.about("fetches a bundle by id")
.arg(
Arg::with_name("id")
.long("id")
.required(true)
.takes_value(true)
.help("bookmark log id. If it has associated bundle it will be fetched."),
)
.arg(
Arg::with_name("output-file")
.long("output-file")
.required(true)
.takes_value(true)
.help("where a bundle will be saved"),
),
)
.subcommand(
SubCommand::with_name(HG_SYNC_VERIFY)
.about("verify the consistency of yet-to-be-processed bookmark log entries"),
)
}
pub async fn subcommand_process_hg_sync<'a>(
fb: FacebookInit,
sub_m: &'a ArgMatches<'_>,

View File

@ -8,7 +8,7 @@
#![deny(warnings)]
#![feature(process_exitcode_placeholder)]
use clap::{App, Arg, SubCommand};
use clap::App;
use fbinit::FacebookInit;
use futures_ext::FutureExt as Future01Ext;
use std::process::ExitCode;
@ -20,13 +20,9 @@ use slog::error;
use crate::blobstore_fetch::subcommand_blobstore_fetch;
use crate::bonsai_fetch::subcommand_bonsai_fetch;
use crate::cmdargs::{
ADD_PUBLIC_PHASES, BLAME, BLOBSTORE_FETCH, BONSAI_FETCH, BOOKMARKS, CONTENT_FETCH, CROSSREPO,
DELETED_MANIFEST, DERIVED_DATA, FETCH_PHASE, FILENODES, FILESTORE, HASH_CONVERT, HG_CHANGESET,
HG_CHANGESET_DIFF, HG_CHANGESET_RANGE, HG_SYNC_BUNDLE, HG_SYNC_FETCH_BUNDLE,
HG_SYNC_LAST_PROCESSED, HG_SYNC_REMAINS, HG_SYNC_SHOW, HG_SYNC_VERIFY, LIST_PUBLIC,
MUTABLE_COUNTERS, MUTABLE_COUNTERS_GET, MUTABLE_COUNTERS_LIST, MUTABLE_COUNTERS_NAME,
MUTABLE_COUNTERS_SET, MUTABLE_COUNTERS_VALUE, PHASES, REDACTION, REDACTION_ADD, REDACTION_LIST,
REDACTION_REMOVE, SKIPLIST, SKIPLIST_BUILD, SKIPLIST_READ, UNODES,
BLAME, BLOBSTORE_FETCH, BONSAI_FETCH, BOOKMARKS, CONTENT_FETCH, CROSSREPO, DELETED_MANIFEST,
DERIVED_DATA, FILENODES, FILESTORE, HASH_CONVERT, HG_CHANGESET, HG_SYNC_BUNDLE,
MUTABLE_COUNTERS, PHASES, REDACTION, SKIPLIST, UNODES,
};
use crate::content_fetch::subcommand_content_fetch;
use crate::crossrepo::subcommand_crossrepo;
@ -62,365 +58,30 @@ mod subcommand_deleted_manifest;
mod subcommand_unodes;
fn setup_app<'a, 'b>() -> App<'a, 'b> {
let blobstore_fetch = SubCommand::with_name(BLOBSTORE_FETCH)
.about("fetches blobs from manifold")
.args_from_usage("[KEY] 'key of the blob to be fetched'")
.arg(
Arg::with_name("decode-as")
.long("decode-as")
.short("d")
.takes_value(true)
.possible_values(&["auto", "changeset", "manifest", "file", "contents", "git-tree"])
.required(false)
.help("if provided decode the value"),
)
.arg(
Arg::with_name("use-memcache")
.long("use-memcache")
.short("m")
.takes_value(true)
.possible_values(&["cache-only", "no-fill", "fill-mc"])
.required(false)
.help("Use memcache to cache access to the blob store"),
)
.arg(
Arg::with_name("no-prefix")
.long("no-prefix")
.short("P")
.takes_value(false)
.required(false)
.help("Don't prepend a prefix based on the repo id to the key"),
)
.arg(
Arg::with_name("inner-blobstore-id")
.long("inner-blobstore-id")
.takes_value(true)
.required(false)
.help("If main blobstore in the storage config is a multiplexed one, use inner blobstore with this id")
)
.arg(
Arg::with_name(blobstore_fetch::SCRUB_BLOBSTORE_ACTION_ARG)
.long(blobstore_fetch::SCRUB_BLOBSTORE_ACTION_ARG)
.takes_value(true)
.required(false)
.help("Enable ScrubBlobstore with the given action. Checks for keys missing from stores. In ReportOnly mode this logs only, otherwise it performs a copy to the missing stores."),
);
let content_fetch = SubCommand::with_name(CONTENT_FETCH)
.about("fetches content of the file or manifest from blobrepo")
.args_from_usage(
"<CHANGESET_ID> 'hg/bonsai id or bookmark to fetch file from'
<PATH> 'path to fetch'",
);
let bonsai_fetch = SubCommand::with_name(BONSAI_FETCH)
.about("fetches content of the file or manifest from blobrepo")
.args_from_usage(
r#"<CHANGESET_ID> 'hg/bonsai id or bookmark to fetch file from'
--json 'if provided json will be returned'"#,
);
let hg_changeset = SubCommand::with_name(HG_CHANGESET)
.about("mercural changeset level queries")
.subcommand(
SubCommand::with_name(HG_CHANGESET_DIFF)
.about("compare two changeset (used by pushrebase replayer)")
.args_from_usage(
"<LEFT_CS> 'left changeset id'
<RIGHT_CS> 'right changeset id'",
),
)
.subcommand(
SubCommand::with_name(HG_CHANGESET_RANGE)
.about("returns `x::y` revset")
.args_from_usage(
"<START_CS> 'start changeset id'
<STOP_CS> 'stop changeset id'",
),
);
let skiplist = SubCommand::with_name(SKIPLIST)
.about("commands to build or read skiplist indexes")
.subcommand(
SubCommand::with_name(SKIPLIST_BUILD)
.about("build skiplist index")
.args_from_usage(
"<BLOBSTORE_KEY> 'Blobstore key where to store the built skiplist'",
),
)
.subcommand(
SubCommand::with_name(SKIPLIST_READ)
.about("read skiplist index")
.args_from_usage(
"<BLOBSTORE_KEY> 'Blobstore key from where to read the skiplist'",
),
);
let convert = SubCommand::with_name(HASH_CONVERT)
.about("convert between bonsai and hg changeset hashes")
.arg(
Arg::with_name("from")
.long("from")
.short("f")
.required(true)
.takes_value(true)
.possible_values(&["hg", "bonsai"])
.help("Source hash type"),
)
.arg(
Arg::with_name("to")
.long("to")
.short("t")
.required(true)
.takes_value(true)
.possible_values(&["hg", "bonsai"])
.help("Target hash type"),
)
.args_from_usage("<HASH> 'source hash'");
let hg_sync = SubCommand::with_name(HG_SYNC_BUNDLE)
.about("things related to mononoke-hg-sync counters")
.subcommand(
SubCommand::with_name(HG_SYNC_LAST_PROCESSED)
.about("inspect/change mononoke-hg sync last processed counter")
.arg(
Arg::with_name("set")
.long("set")
.required(false)
.takes_value(true)
.help("set the value of the latest processed mononoke-hg-sync counter"),
)
.arg(
Arg::with_name("skip-blobimport")
.long("skip-blobimport")
.required(false)
.help("skip to the next non-blobimport entry in mononoke-hg-sync counter"),
)
.arg(
Arg::with_name("dry-run")
.long("dry-run")
.required(false)
.help("don't make changes, only show what would have been done (--skip-blobimport only)"),
),
)
.subcommand(
SubCommand::with_name(HG_SYNC_REMAINS)
.about("get the value of the last mononoke-hg-sync counter to be processed")
.arg(
Arg::with_name("quiet")
.long("quiet")
.required(false)
.takes_value(false)
.help("only print the number if present"),
)
.arg(
Arg::with_name("without-blobimport")
.long("without-blobimport")
.required(false)
.takes_value(false)
.help("exclude blobimport entries from the count"),
),
)
.subcommand(
SubCommand::with_name(HG_SYNC_SHOW).about("show hg hashes of yet to be replayed bundles")
.arg(
Arg::with_name("limit")
.long("limit")
.required(false)
.takes_value(true)
.help("how many bundles to show"),
)
)
.subcommand(
SubCommand::with_name(HG_SYNC_FETCH_BUNDLE)
.about("fetches a bundle by id")
.arg(
Arg::with_name("id")
.long("id")
.required(true)
.takes_value(true)
.help("bookmark log id. If it has associated bundle it will be fetched."),
)
.arg(
Arg::with_name("output-file")
.long("output-file")
.required(true)
.takes_value(true)
.help("where a bundle will be saved"),
),
)
.subcommand(
SubCommand::with_name(HG_SYNC_VERIFY)
.about("verify the consistency of yet-to-be-processed bookmark log entries"),
);
let phases = SubCommand::with_name(PHASES)
.about("commands to work with phases")
.subcommand(
SubCommand::with_name(ADD_PUBLIC_PHASES)
.about("mark mercurial commits as public from provided new-line separated list")
.arg(
Arg::with_name("input-file")
.help("new-line separated mercurial public commits")
.required(true)
.index(1),
)
.arg(
Arg::with_name("chunk-size")
.help("partition input file to chunks of specified size")
.long("chunk-size")
.takes_value(true),
),
)
.subcommand(
SubCommand::with_name(FETCH_PHASE)
.about("fetch phase of a commit")
.arg(
Arg::with_name("changeset-type")
.long("changeset-type")
.short("c")
.takes_value(true)
.possible_values(&["bonsai", "hg"])
.required(false)
.help(
"What changeset type to return, either bonsai or hg. Defaults to hg.",
),
)
.arg(
Arg::with_name("hash")
.help("changeset hash")
.takes_value(true),
),
)
.subcommand(
SubCommand::with_name(LIST_PUBLIC)
.arg(
Arg::with_name("changeset-type")
.long("changeset-type")
.short("c")
.takes_value(true)
.possible_values(&["bonsai", "hg"])
.required(false)
.help(
"What changeset type to return, either bonsai or hg. Defaults to hg.",
),
)
.about("List all public commits"),
);
let redaction = SubCommand::with_name(REDACTION)
.about("handle file redaction")
.subcommand(
SubCommand::with_name(REDACTION_ADD)
.about("add a new redacted file at a given commit")
.arg(
Arg::with_name("task")
.help("Task tracking the redaction request")
.takes_value(true)
.required(true),
)
.arg(
Arg::with_name("hash")
.help("hg commit hash")
.takes_value(true)
.required(true),
)
.args_from_usage(
r#"
<FILES_LIST>... 'list of files to be be redacted'
"#,
)
)
.subcommand(
SubCommand::with_name(REDACTION_REMOVE)
.about("remove a file from the redaction")
.arg(
Arg::with_name("hash")
.help("hg commit hash")
.takes_value(true)
.required(true),
)
.args_from_usage(
r#"
<FILES_LIST>... 'list of files to be be unredacted'
"#,
)
)
.subcommand(
SubCommand::with_name(REDACTION_LIST)
.about("list all redacted file for a given commit")
.arg(
Arg::with_name("hash")
.help("hg commit hash or a bookmark")
.takes_value(true)
.required(true),
)
);
let mutable_counters = SubCommand::with_name(MUTABLE_COUNTERS)
.about("handle mutable counters")
.subcommand(
SubCommand::with_name(MUTABLE_COUNTERS_LIST)
.about("get all the mutable counters for a repo"),
)
.subcommand(
SubCommand::with_name(MUTABLE_COUNTERS_GET)
.about("get the value of the mutable counter")
.arg(
Arg::with_name(MUTABLE_COUNTERS_NAME)
.help("name of the mutable counter to get")
.takes_value(true)
.required(true)
.index(1),
),
)
.subcommand(
SubCommand::with_name(MUTABLE_COUNTERS_SET)
.about("set the value of the mutable counter")
.arg(
Arg::with_name(MUTABLE_COUNTERS_NAME)
.help("name of the mutable counter to set")
.takes_value(true)
.required(true)
.index(1),
)
.arg(
Arg::with_name(MUTABLE_COUNTERS_VALUE)
.help("value of the mutable counter to set")
.takes_value(true)
.required(true)
.index(2),
),
);
args::MononokeApp::new("Mononoke admin command line tool")
.with_advanced_args_hidden()
.with_source_and_target_repos()
.build()
.version("0.0.0")
.about("Poke at mononoke internals for debugging and investigating data structures.")
.subcommand(blobstore_fetch)
.subcommand(bonsai_fetch)
.subcommand(content_fetch)
.subcommand(bookmarks_manager::prepare_command(SubCommand::with_name(
BOOKMARKS,
)))
.subcommand(hg_changeset)
.subcommand(skiplist)
.subcommand(convert)
.subcommand(hg_sync)
.subcommand(mutable_counters)
.subcommand(redaction)
.subcommand(filenodes::build_subcommand(FILENODES))
.subcommand(phases)
.subcommand(filestore::build_subcommand(FILESTORE))
.subcommand(subcommand_unodes::subcommand_unodes_build(UNODES))
.subcommand(crossrepo::build_subcommand(CROSSREPO))
.subcommand(subcommand_blame::subcommand_blame_build(BLAME))
.subcommand(
subcommand_deleted_manifest::subcommand_deleted_manifest_build(DELETED_MANIFEST),
)
.subcommand(derived_data::build_subcommand(DERIVED_DATA))
.subcommand(blobstore_fetch::build_subcommand())
.subcommand(bonsai_fetch::build_subcommand())
.subcommand(content_fetch::build_subcommand())
.subcommand(bookmarks_manager::build_subcommand())
.subcommand(hg_changeset::build_subcommand())
.subcommand(skiplist_subcommand::build_subcommand())
.subcommand(hash_convert::build_subcommand())
.subcommand(hg_sync::build_subcommand())
.subcommand(mutable_counters::build_subcommand())
.subcommand(redaction::build_subcommand())
.subcommand(filenodes::build_subcommand())
.subcommand(phases::build_subcommand())
.subcommand(filestore::build_subcommand())
.subcommand(subcommand_unodes::build_subcommand())
.subcommand(crossrepo::build_subcommand())
.subcommand(subcommand_blame::build_subcommand())
.subcommand(subcommand_deleted_manifest::build_subcommand())
.subcommand(derived_data::build_subcommand())
}
#[fbinit::main]

View File

@ -6,13 +6,13 @@
*/
use crate::cmdargs::{
MUTABLE_COUNTERS_GET, MUTABLE_COUNTERS_LIST, MUTABLE_COUNTERS_NAME, MUTABLE_COUNTERS_SET,
MUTABLE_COUNTERS_VALUE,
MUTABLE_COUNTERS, MUTABLE_COUNTERS_GET, MUTABLE_COUNTERS_LIST, MUTABLE_COUNTERS_NAME,
MUTABLE_COUNTERS_SET, MUTABLE_COUNTERS_VALUE,
};
use crate::error::SubcommandError;
use anyhow::{format_err, Error};
use clap::ArgMatches;
use clap::{App, Arg, ArgMatches, SubCommand};
use cmdlib::args;
use context::CoreContext;
use failure_ext::FutureFailureErrorExt;
@ -22,6 +22,44 @@ use mononoke_types::RepositoryId;
use mutable_counters::{MutableCounters, SqlMutableCounters};
use slog::{info, Logger};
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(MUTABLE_COUNTERS)
.about("handle mutable counters")
.subcommand(
SubCommand::with_name(MUTABLE_COUNTERS_LIST)
.about("get all the mutable counters for a repo"),
)
.subcommand(
SubCommand::with_name(MUTABLE_COUNTERS_GET)
.about("get the value of the mutable counter")
.arg(
Arg::with_name(MUTABLE_COUNTERS_NAME)
.help("name of the mutable counter to get")
.takes_value(true)
.required(true)
.index(1),
),
)
.subcommand(
SubCommand::with_name(MUTABLE_COUNTERS_SET)
.about("set the value of the mutable counter")
.arg(
Arg::with_name(MUTABLE_COUNTERS_NAME)
.help("name of the mutable counter to set")
.takes_value(true)
.required(true)
.index(1),
)
.arg(
Arg::with_name(MUTABLE_COUNTERS_VALUE)
.help("value of the mutable counter to set")
.takes_value(true)
.required(true)
.index(2),
),
)
}
pub async fn subcommand_mutable_counters<'a>(
fb: FacebookInit,
sub_m: &'a ArgMatches<'_>,

View File

@ -5,9 +5,9 @@
* GNU General Public License version 2.
*/
use crate::cmdargs::{ADD_PUBLIC_PHASES, FETCH_PHASE, LIST_PUBLIC};
use crate::cmdargs::{ADD_PUBLIC_PHASES, FETCH_PHASE, LIST_PUBLIC, PHASES};
use anyhow::{bail, format_err, Error};
use clap::ArgMatches;
use clap::{App, Arg, ArgMatches, SubCommand};
use cloned::cloned;
use fbinit::FacebookInit;
use futures::{
@ -36,6 +36,62 @@ use slog::{info, Logger};
use crate::error::SubcommandError;
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(PHASES)
.about("commands to work with phases")
.subcommand(
SubCommand::with_name(ADD_PUBLIC_PHASES)
.about("mark mercurial commits as public from provided new-line separated list")
.arg(
Arg::with_name("input-file")
.help("new-line separated mercurial public commits")
.required(true)
.index(1),
)
.arg(
Arg::with_name("chunk-size")
.help("partition input file to chunks of specified size")
.long("chunk-size")
.takes_value(true),
),
)
.subcommand(
SubCommand::with_name(FETCH_PHASE)
.about("fetch phase of a commit")
.arg(
Arg::with_name("changeset-type")
.long("changeset-type")
.short("c")
.takes_value(true)
.possible_values(&["bonsai", "hg"])
.required(false)
.help(
"What changeset type to return, either bonsai or hg. Defaults to hg.",
),
)
.arg(
Arg::with_name("hash")
.help("changeset hash")
.takes_value(true),
),
)
.subcommand(
SubCommand::with_name(LIST_PUBLIC)
.arg(
Arg::with_name("changeset-type")
.long("changeset-type")
.short("c")
.takes_value(true)
.possible_values(&["bonsai", "hg"])
.required(false)
.help(
"What changeset type to return, either bonsai or hg. Defaults to hg.",
),
)
.about("List all public commits"),
)
}
pub async fn subcommand_phases<'a>(
fb: FacebookInit,
logger: Logger,

View File

@ -5,12 +5,12 @@
* GNU General Public License version 2.
*/
use crate::cmdargs::{REDACTION_ADD, REDACTION_LIST, REDACTION_REMOVE};
use crate::cmdargs::{REDACTION, REDACTION_ADD, REDACTION_LIST, REDACTION_REMOVE};
use crate::common::get_file_nodes;
use anyhow::{format_err, Error};
use blobrepo::BlobRepo;
use blobstore::Loadable;
use clap::ArgMatches;
use clap::{App, Arg, ArgMatches, SubCommand};
use cloned::cloned;
use cmdlib::{args, helpers};
use context::CoreContext;
@ -32,6 +32,57 @@ use std::sync::Arc;
use crate::error::SubcommandError;
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(REDACTION)
.about("handle file redaction")
.subcommand(
SubCommand::with_name(REDACTION_ADD)
.about("add a new redacted file at a given commit")
.arg(
Arg::with_name("task")
.help("Task tracking the redaction request")
.takes_value(true)
.required(true),
)
.arg(
Arg::with_name("hash")
.help("hg commit hash")
.takes_value(true)
.required(true),
)
.args_from_usage(
r#"
<FILES_LIST>... 'list of files to be be redacted'
"#,
)
)
.subcommand(
SubCommand::with_name(REDACTION_REMOVE)
.about("remove a file from the redaction")
.arg(
Arg::with_name("hash")
.help("hg commit hash")
.takes_value(true)
.required(true),
)
.args_from_usage(
r#"
<FILES_LIST>... 'list of files to be be unredacted'
"#,
)
)
.subcommand(
SubCommand::with_name(REDACTION_LIST)
.about("list all redacted file for a given commit")
.arg(
Arg::with_name("hash")
.help("hg commit hash or a bookmark")
.takes_value(true)
.required(true),
)
)
}
fn find_files_with_given_content_id_blobstore_keys(
logger: Logger,
ctx: CoreContext,

View File

@ -6,7 +6,7 @@
*/
use anyhow::Error;
use clap::ArgMatches;
use clap::{App, ArgMatches, SubCommand};
use cloned::cloned;
use fbinit::FacebookInit;
use fbthrift::compact_protocol;
@ -28,9 +28,28 @@ use mononoke_types::{BlobstoreBytes, ChangesetId, Generation, RepositoryId};
use skiplist::{deserialize_skiplist_index, SkiplistIndex, SkiplistNodeType};
use slog::{debug, info, Logger};
use crate::cmdargs::{SKIPLIST_BUILD, SKIPLIST_READ};
use crate::cmdargs::{SKIPLIST, SKIPLIST_BUILD, SKIPLIST_READ};
use crate::error::SubcommandError;
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(SKIPLIST)
.about("commands to build or read skiplist indexes")
.subcommand(
SubCommand::with_name(SKIPLIST_BUILD)
.about("build skiplist index")
.args_from_usage(
"<BLOBSTORE_KEY> 'Blobstore key where to store the built skiplist'",
),
)
.subcommand(
SubCommand::with_name(SKIPLIST_READ)
.about("read skiplist index")
.args_from_usage(
"<BLOBSTORE_KEY> 'Blobstore key from where to read the skiplist'",
),
)
}
pub async fn subcommand_skiplist<'a>(
fb: FacebookInit,
logger: Logger,

View File

@ -5,7 +5,9 @@
* GNU General Public License version 2.
*/
use crate::cmdargs::BLAME;
use crate::error::SubcommandError;
use anyhow::{format_err, Error};
use blame::{fetch_blame, fetch_file_full_content};
use blobrepo::BlobRepo;
@ -41,7 +43,7 @@ const ARG_CSID: &'static str = "csid";
const ARG_PATH: &'static str = "path";
const ARG_LINE: &'static str = "line";
pub fn subcommand_blame_build(name: &str) -> App {
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
let csid_arg = Arg::with_name(ARG_CSID)
.help("{hg|bonsai} changeset id or bookmark name")
.index(1)
@ -57,7 +59,7 @@ pub fn subcommand_blame_build(name: &str) -> App {
.takes_value(false)
.required(false);
SubCommand::with_name(name)
SubCommand::with_name(BLAME)
.about("fetch/derive blame for specified changeset and path")
.subcommand(
SubCommand::with_name(COMMAND_DERIVE)

View File

@ -5,7 +5,9 @@
* GNU General Public License version 2.
*/
use crate::cmdargs::DELETED_MANIFEST;
use crate::error::SubcommandError;
use anyhow::{format_err, Error};
use blobrepo::BlobRepo;
use blobstore::Loadable;
@ -32,7 +34,7 @@ const ARG_CSID: &'static str = "csid";
const ARG_LIMIT: &'static str = "limit";
const ARG_PATH: &'static str = "path";
pub fn subcommand_deleted_manifest_build(name: &str) -> App {
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
let csid_arg = Arg::with_name(ARG_CSID)
.help("{hg|boinsai} changset id or bookmark name")
.index(1)
@ -43,7 +45,7 @@ pub fn subcommand_deleted_manifest_build(name: &str) -> App {
.index(2)
.default_value("");
SubCommand::with_name(name)
SubCommand::with_name(DELETED_MANIFEST)
.about("derive, inspect and verify deleted files manifest")
.subcommand(
SubCommand::with_name(COMMAND_MANIFEST)

View File

@ -5,7 +5,9 @@
* GNU General Public License version 2.
*/
use crate::cmdargs::UNODES;
use crate::error::SubcommandError;
use anyhow::{bail, Error};
use blobrepo::BlobRepo;
use blobstore::Loadable;
@ -40,7 +42,7 @@ fn path_resolve(path: &str) -> Result<Option<MPath>, Error> {
}
}
pub fn subcommand_unodes_build(name: &str) -> App {
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
let csid_arg = Arg::with_name(ARG_CSID)
.help("{hg|boinsai} changset id or bookmark name")
.index(1)
@ -51,7 +53,7 @@ pub fn subcommand_unodes_build(name: &str) -> App {
.index(2)
.default_value("/");
SubCommand::with_name(name)
SubCommand::with_name(UNODES)
.about("inspect and interact with unodes")
.arg(
Arg::with_name(ARG_TRACE)