mod audio;
mod commands;
mod diff;
mod ignore;
mod mirror;
mod model;
mod names;
mod paths;
mod prompt;
mod remote;
mod repo;
mod scan;
mod selfcmd;
mod time;
use anyhow::Result;
use clap::{Parser, Subcommand};
use commands::remote::RemoteCmd;
const REMOTES_NOTE: &str = concat!(
"Every remote is one of two shapes:
mirror real, playable folders - a drive or phone you can browse & play
backup deduped content-addressed blobs - S3, or a space-saving archive
Local remotes default to mirror, s3:// to backup; set it with `remote add --format`.
A `.stoweignore` at the repo root keeps paths out of every scan, local and
remote: bare names match anywhere, a trailing `/` means directories only, and a
pattern with a `/` is anchored at the root.
Run `stowe <command> --help` for the full detail of any command.",
"\n\n",
env!("CARGO_PKG_REPOSITORY"),
"\ncontributors: ",
env!("CARGO_PKG_AUTHORS"),
);
const LONG_VERSION: &str = concat!(
env!("CARGO_PKG_VERSION"),
"\n",
env!("CARGO_PKG_LICENSE"),
" ",
env!("CARGO_PKG_REPOSITORY"),
"\ncontributors: ",
env!("CARGO_PKG_AUTHORS"),
);
#[derive(Parser)]
#[command(
name = "stowe",
version,
long_version = LONG_VERSION,
about,
after_help = REMOTES_NOTE,
arg_required_else_help = true
)]
struct Cli {
#[command(subcommand)]
cmd: Cmd,
}
#[derive(Subcommand)]
enum Cmd {
Init,
Status,
#[command(verbatim_doc_comment)]
Add {
paths: Vec<std::path::PathBuf>,
#[arg(short = 'A', long)]
all: bool,
},
Unstage,
#[command(verbatim_doc_comment)]
Commit {
#[arg(short = 'm', long)]
message: String,
},
Log,
#[command(verbatim_doc_comment)]
Remote {
#[arg(short, long)]
verbose: bool,
#[command(subcommand)]
cmd: Option<RemoteCmd>,
},
#[command(verbatim_doc_comment)]
Push {
remotes: Vec<String>,
#[arg(long)]
force: bool,
},
Pull {
#[arg(default_value = "origin")]
remote: String,
},
Adapt {
#[arg(default_value = "origin")]
remote: String,
},
#[command(verbatim_doc_comment)]
Restore {
paths: Vec<std::path::PathBuf>,
#[arg(short = 'A', long)]
all: bool,
#[arg(long)]
from: Option<String>,
#[arg(long, default_value = "origin")]
remote: String,
},
#[command(verbatim_doc_comment)]
Convert {
#[arg(default_value = "origin")]
remote: String,
#[arg(long, value_parser = ["mirror", "backup"])]
to: Option<String>,
},
#[command(name = "self", subcommand, verbatim_doc_comment)]
Selfie(selfcmd::Cmd),
}
fn main() -> Result<()> {
let cli = Cli::parse();
match cli.cmd {
Cmd::Init => commands::init::run(),
Cmd::Status => commands::status::run(),
Cmd::Add { paths, all } => commands::add::run(paths, all),
Cmd::Unstage => commands::unstage::run(),
Cmd::Commit { message } => commands::commit::run(&message),
Cmd::Log => commands::log::run(),
Cmd::Remote { cmd, .. } => commands::remote::run(cmd),
Cmd::Push { remotes, force } => commands::push::run(&remotes, force),
Cmd::Pull { remote } => commands::pull::run(&remote),
Cmd::Restore {
paths,
all,
from,
remote,
} => commands::restore::run(paths, all, from.as_deref(), &remote),
Cmd::Adapt { remote } => commands::adapt::run(&remote),
Cmd::Convert { remote, to } => commands::convert::run(&remote, to.as_deref()),
Cmd::Selfie(cmd) => selfcmd::run(cmd),
}
}