#![deny(warnings)]
pub mod common;
mod contract_package;
pub mod dependency;
mod makefile;
mod tests_package;
mod travis_yml;
use std::{
env,
path::{Path, PathBuf},
sync::LazyLock,
};
use clap::{builder::ValueParser, crate_description, crate_name, crate_version, Arg, Command};
const USAGE: &str = r#"cargo casper [FLAGS] <path>
cd <path>
make prepare
make test"#;
const ROOT_PATH_ARG_NAME: &str = "path";
const ROOT_PATH_ARG_VALUE_NAME: &str = "path";
const ROOT_PATH_ARG_HELP: &str = "Path to new folder for contract and tests";
const WORKSPACE_PATH_ARG_NAME: &str = "workspace-path";
const WORKSPACE_PATH_ARG_LONG: &str = "workspace-path";
const GIT_URL_ARG_NAME: &str = "git-url";
const GIT_URL_LONG: &str = "git-url";
const GIT_BRANCH_ARG_NAME: &str = "git-branch";
const GIT_BRANCH_LONG: &str = "git-branch";
const FAILURE_EXIT_CODE: i32 = 101;
static ARGS: LazyLock<Args> = LazyLock::new(Args::new);
#[derive(Debug)]
enum CasperOverrides {
WorkspacePath(PathBuf),
GitRepo { url: String, branch: String },
}
#[derive(Debug)]
struct Args {
root_path: PathBuf,
casper_overrides: Option<CasperOverrides>,
}
impl Args {
fn new() -> Self {
let filtered_args_iter = env::args().enumerate().filter_map(|(index, value)| {
if index == 1 && value.as_str() == "casper" {
None
} else {
Some(value)
}
});
let root_path_arg = Arg::new(ROOT_PATH_ARG_NAME)
.value_parser(ValueParser::path_buf())
.required(true)
.value_name(ROOT_PATH_ARG_VALUE_NAME)
.help(ROOT_PATH_ARG_HELP);
let workspace_path_arg = Arg::new(WORKSPACE_PATH_ARG_NAME)
.long(WORKSPACE_PATH_ARG_LONG)
.hide(true);
let git_url_arg = Arg::new(GIT_URL_ARG_NAME)
.long(GIT_URL_LONG)
.hide(true)
.conflicts_with(WORKSPACE_PATH_ARG_NAME)
.requires(GIT_BRANCH_ARG_NAME);
let git_branch_arg = Arg::new(GIT_BRANCH_ARG_NAME)
.long(GIT_BRANCH_LONG)
.hide(true)
.conflicts_with(WORKSPACE_PATH_ARG_NAME)
.requires(GIT_URL_ARG_NAME);
let arg_matches = Command::new(crate_name!())
.version(crate_version!())
.about(crate_description!())
.override_usage(USAGE)
.arg(root_path_arg)
.arg(workspace_path_arg)
.arg(git_url_arg)
.arg(git_branch_arg)
.get_matches_from(filtered_args_iter);
let root_path = arg_matches
.get_one::<PathBuf>(ROOT_PATH_ARG_NAME)
.expect("expected path")
.clone();
let maybe_workspace_path = arg_matches.get_one::<String>(WORKSPACE_PATH_ARG_NAME);
let maybe_git_url = arg_matches.get_one::<String>(GIT_URL_ARG_NAME);
let maybe_git_branch = arg_matches.get_one::<String>(GIT_BRANCH_ARG_NAME);
let casper_overrides = match (maybe_workspace_path, maybe_git_url, maybe_git_branch) {
(Some(path), None, None) => Some(CasperOverrides::WorkspacePath(path.into())),
(None, Some(url), Some(branch)) => Some(CasperOverrides::GitRepo {
url: url.to_string(),
branch: branch.to_string(),
}),
(None, None, None) => None,
_ => unreachable!("Clap rules enforce either both or neither git args are present"),
};
Args {
root_path,
casper_overrides,
}
}
pub fn root_path(&self) -> &Path {
&self.root_path
}
pub fn casper_overrides(&self) -> Option<&CasperOverrides> {
self.casper_overrides.as_ref()
}
}
fn main() {
if ARGS.root_path().exists() {
common::print_error_and_exit(&format!(
": destination '{}' already exists",
ARGS.root_path().display()
));
}
common::create_dir_all(ARGS.root_path());
contract_package::create();
tests_package::create();
makefile::create();
travis_yml::create();
}