2018-07-19 13:58:24 +03:00
|
|
|
// Copyright (c) 2004-present, Facebook, Inc.
|
|
|
|
// All Rights Reserved.
|
|
|
|
//
|
|
|
|
// This software may be used and distributed according to the terms of the
|
|
|
|
// GNU General Public License version 2 or any later version.
|
|
|
|
|
|
|
|
#![deny(warnings)]
|
|
|
|
|
2019-01-30 17:26:26 +03:00
|
|
|
extern crate blobimport_lib;
|
2018-07-19 13:58:24 +03:00
|
|
|
extern crate clap;
|
2019-01-08 22:01:09 +03:00
|
|
|
extern crate cloned;
|
2018-07-19 13:58:24 +03:00
|
|
|
extern crate cmdlib;
|
|
|
|
extern crate failure_ext as failure;
|
|
|
|
extern crate futures;
|
|
|
|
extern crate mercurial_types;
|
|
|
|
#[macro_use]
|
|
|
|
extern crate slog;
|
2019-01-30 17:26:26 +03:00
|
|
|
extern crate phases;
|
2018-07-19 13:58:24 +03:00
|
|
|
extern crate tokio;
|
2019-01-08 22:01:09 +03:00
|
|
|
extern crate tracing;
|
2018-07-19 13:58:24 +03:00
|
|
|
|
|
|
|
use std::str::FromStr;
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
|
|
use clap::{App, Arg};
|
2019-01-08 22:01:09 +03:00
|
|
|
use cloned::cloned;
|
2018-07-19 13:58:24 +03:00
|
|
|
use failure::{Result, SlogKVError};
|
|
|
|
use futures::Future;
|
2019-01-30 17:26:26 +03:00
|
|
|
use phases::SqlPhases;
|
2019-01-08 22:01:09 +03:00
|
|
|
use tracing::{trace_args, Traced};
|
2018-07-19 13:58:24 +03:00
|
|
|
|
2019-01-30 17:26:26 +03:00
|
|
|
use cmdlib::args;
|
2018-07-19 13:58:24 +03:00
|
|
|
use mercurial_types::HgNodeHash;
|
|
|
|
|
|
|
|
fn setup_app<'a, 'b>() -> App<'a, 'b> {
|
|
|
|
let app = args::MononokeApp {
|
|
|
|
safe_writes: true,
|
|
|
|
hide_advanced_args: false,
|
|
|
|
local_instances: true,
|
2018-07-20 21:31:30 +03:00
|
|
|
default_glog: true,
|
2018-07-19 13:58:24 +03:00
|
|
|
};
|
|
|
|
app.build("revlog to blob importer")
|
|
|
|
.version("0.0.0")
|
|
|
|
.about("Import a revlog-backed Mercurial repo into Mononoke blobstore.")
|
|
|
|
.args_from_usage(
|
|
|
|
r#"
|
|
|
|
<INPUT> 'input revlog repo'
|
|
|
|
--changeset [HASH] 'if provided, the only changeset to be imported'
|
|
|
|
--no-bookmark 'if provided won't update bookmarks'
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::from_usage("--skip [SKIP] 'skips commits from the beginning'")
|
|
|
|
.conflicts_with("changeset"),
|
|
|
|
)
|
|
|
|
.arg(
|
|
|
|
Arg::from_usage(
|
|
|
|
"--commits-limit [LIMIT] 'import only LIMIT first commits from revlog repo'",
|
2019-01-14 20:29:33 +03:00
|
|
|
)
|
|
|
|
.conflicts_with("changeset"),
|
2018-07-19 13:58:24 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() -> Result<()> {
|
|
|
|
let matches = setup_app().get_matches();
|
|
|
|
|
2019-01-08 22:01:09 +03:00
|
|
|
let ctx = args::get_core_context(&matches);
|
2018-07-19 13:58:24 +03:00
|
|
|
|
2018-08-07 21:35:20 +03:00
|
|
|
args::init_cachelib(&matches);
|
2018-07-19 13:58:24 +03:00
|
|
|
|
|
|
|
let revlogrepo_path = matches
|
|
|
|
.value_of("INPUT")
|
|
|
|
.expect("input is not specified")
|
|
|
|
.into();
|
|
|
|
|
|
|
|
let changeset = match matches.value_of("changeset") {
|
|
|
|
None => None,
|
|
|
|
Some(hash) => Some(HgNodeHash::from_str(hash)?),
|
|
|
|
};
|
|
|
|
|
|
|
|
let skip = if !matches.is_present("skip") {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(args::get_usize(&matches, "skip", 0))
|
|
|
|
};
|
|
|
|
|
|
|
|
let commits_limit = if !matches.is_present("commits-limit") {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(args::get_usize(&matches, "commits-limit", 0))
|
|
|
|
};
|
|
|
|
|
|
|
|
let no_bookmark = matches.is_present("no-bookmark");
|
|
|
|
|
2019-01-30 17:26:26 +03:00
|
|
|
let phases_store = Arc::new(args::open_sql::<SqlPhases>(&matches, "phases")?);
|
2019-01-21 17:59:47 +03:00
|
|
|
|
2019-01-23 18:58:11 +03:00
|
|
|
let blobimport = args::create_repo(&ctx.logger(), &matches).and_then(move |repo| {
|
|
|
|
let blobrepo = Arc::new(repo.clone());
|
2019-01-30 17:26:26 +03:00
|
|
|
blobimport_lib::Blobimport {
|
2019-01-23 18:58:11 +03:00
|
|
|
ctx: ctx.clone(),
|
|
|
|
logger: ctx.logger().clone(),
|
|
|
|
blobrepo,
|
|
|
|
revlogrepo_path,
|
|
|
|
changeset,
|
|
|
|
skip,
|
|
|
|
commits_limit,
|
|
|
|
no_bookmark,
|
|
|
|
phases_store,
|
|
|
|
}
|
|
|
|
.import()
|
|
|
|
.traced(ctx.trace(), "blobimport", trace_args!())
|
|
|
|
.map_err({
|
|
|
|
cloned!(ctx);
|
|
|
|
move |err| {
|
|
|
|
error!(ctx.logger(), "error while blobimporting"; SlogKVError(err));
|
|
|
|
::std::process::exit(1);
|
2019-01-14 20:29:33 +03:00
|
|
|
}
|
2019-01-23 18:58:11 +03:00
|
|
|
})
|
|
|
|
.then(move |result| args::upload_and_show_trace(ctx).then(move |_| result))
|
|
|
|
});
|
2018-07-19 13:58:24 +03:00
|
|
|
|
|
|
|
let mut runtime = tokio::runtime::Runtime::new()?;
|
|
|
|
let result = runtime.block_on(blobimport);
|
|
|
|
// Let the runtime finish remaining work - uploading logs etc
|
|
|
|
runtime.shutdown_on_idle();
|
|
|
|
result
|
|
|
|
}
|