pub mod commands;
use std::path::PathBuf;
use clap::{ArgAction, Parser, Subcommand, ValueEnum};
#[derive(Parser, Debug)]
#[command(name = "scoop")]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
#[arg(short, long, global = true)]
pub quiet: bool,
#[arg(long, global = true, env = "NO_COLOR")]
pub no_color: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum MigrateSource {
Pyenv,
Virtualenvwrapper,
Conda,
}
impl std::fmt::Display for MigrateSource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Pyenv => write!(f, "pyenv"),
Self::Virtualenvwrapper => write!(f, "virtualenvwrapper"),
Self::Conda => write!(f, "conda"),
}
}
}
#[derive(Subcommand, Debug)]
pub enum MigrateCommand {
List {
#[arg(long)]
json: bool,
#[arg(long, value_enum)]
source: Option<MigrateSource>,
},
All {
#[arg(short = 'n', long)]
dry_run: bool,
#[arg(short, long)]
force: bool,
#[arg(short, long)]
yes: bool,
#[arg(long)]
json: bool,
#[arg(long)]
strict: bool,
#[arg(long)]
delete_source: bool,
#[arg(long, value_enum)]
source: Option<MigrateSource>,
},
#[command(name = "@env")]
Env {
name: String,
#[arg(short = 'n', long)]
dry_run: bool,
#[arg(short, long)]
force: bool,
#[arg(short, long)]
yes: bool,
#[arg(long)]
json: bool,
#[arg(long)]
strict: bool,
#[arg(long, value_name = "NEW_NAME")]
rename: Option<String>,
#[arg(long, conflicts_with = "force")]
auto_rename: bool,
#[arg(long)]
delete_source: bool,
#[arg(long, value_enum)]
source: Option<MigrateSource>,
},
}
#[derive(Subcommand, Debug)]
pub enum SelfCommand {
#[command(disable_version_flag = true)]
Update {
#[arg(long)]
force: bool,
#[arg(long, value_name = "VERSION")]
version: Option<String>,
#[arg(long)]
no_verify: bool,
#[arg(long)]
json: bool,
},
}
#[derive(ValueEnum, Clone, Copy, Debug, PartialEq, Eq)]
#[value(rename_all = "kebab-case")]
pub enum ListSortMode {
Name,
Created,
LastUsed,
}
impl Default for ListSortMode {
fn default() -> Self {
Self::Name
}
}
#[derive(Subcommand, Debug)]
pub enum Commands {
#[command(alias = "ls")]
List {
#[arg(long)]
pythons: bool,
#[arg(long, hide = true)]
bare: bool,
#[arg(long, value_name = "VERSION", conflicts_with = "pythons")]
python_version: Option<String>,
#[arg(long, value_enum, default_value_t = ListSortMode::Name, conflicts_with = "pythons")]
sort: ListSortMode,
#[arg(long)]
json: bool,
},
Use {
name: Option<String>,
#[arg(long)]
unset: bool,
#[arg(long, conflicts_with = "no_link")]
link: bool,
#[arg(short, long)]
global: bool,
#[arg(long, conflicts_with = "link")]
no_link: bool,
#[arg(long)]
json: bool,
},
Create {
name: String,
#[arg(default_value = "3")]
python: String,
#[arg(long = "python-path", value_name = "PATH")]
python_path: Option<PathBuf>,
#[arg(short, long)]
force: bool,
#[arg(long, conflicts_with = "python_path")]
install_python: bool,
#[arg(long)]
json: bool,
},
#[command(alias = "rm", alias = "delete")]
Remove {
name: String,
#[arg(short, long)]
force: bool,
#[arg(long)]
json: bool,
},
Install {
#[arg(name = "VERSION")]
python_version: Option<String>,
#[arg(long)]
latest: bool,
#[arg(long)]
stable: bool,
#[arg(long)]
json: bool,
},
Uninstall {
#[arg(name = "VERSION")]
python_version: String,
#[arg(long)]
cascade: bool,
#[arg(short, long, requires = "cascade")]
force: bool,
#[arg(long)]
json: bool,
},
Doctor {
#[arg(short, long, action = ArgAction::Count)]
verbose: u8,
#[arg(long)]
json: bool,
#[arg(long)]
fix: bool,
},
Info {
name: String,
#[arg(long)]
json: bool,
#[arg(long)]
all_packages: bool,
#[arg(long)]
no_size: bool,
},
Init {
#[arg(value_enum)]
shell: ShellType,
},
Completions {
#[arg(value_enum)]
shell: ShellType,
},
#[command(hide = true)]
Resolve,
#[command(hide = true)]
Activate {
name: String,
#[arg(long, value_enum)]
shell: Option<ShellType>,
},
#[command(hide = true)]
Deactivate {
#[arg(long, value_enum)]
shell: Option<ShellType>,
},
Shell {
name: Option<String>,
#[arg(long)]
unset: bool,
#[arg(long, value_enum)]
shell: Option<ShellType>,
},
Migrate {
#[command(subcommand)]
command: Option<MigrateCommand>,
},
Lang {
lang: Option<String>,
#[arg(long)]
list: bool,
#[arg(long)]
reset: bool,
#[arg(long)]
json: bool,
},
#[command(name = "self")]
Self_ {
#[command(subcommand)]
command: SelfCommand,
},
Status {
#[arg(long)]
json: bool,
},
Clone {
src: String,
dst: String,
#[arg(long)]
no_packages: bool,
#[arg(short, long)]
force: bool,
#[arg(long)]
json: bool,
},
Export {
name: String,
#[arg(short = 'o', long = "output", value_name = "PATH")]
output: Option<PathBuf>,
},
Import {
path: String,
#[arg(long, value_name = "NAME")]
name: Option<String>,
#[arg(short, long)]
force: bool,
#[arg(long)]
json: bool,
},
Sync {
#[arg(long = "with", value_name = "GROUP", action = clap::ArgAction::Append)]
with: Vec<String>,
#[arg(long)]
dry_run: bool,
#[arg(long)]
json: bool,
},
Run {
env: String,
#[arg(trailing_var_arg = true, allow_hyphen_values = true, num_args = 1..)]
command: Vec<String>,
},
Which {
exe: String,
#[arg(long, value_name = "NAME")]
env: Option<String>,
#[arg(long)]
json: bool,
},
Prune {
#[arg(long)]
json: bool,
},
Gc {
#[arg(short, long)]
yes: bool,
#[arg(long)]
aggressive: bool,
#[arg(long, value_name = "DURATION")]
older_than: Option<String>,
#[arg(long)]
json: bool,
},
Man {
#[arg(value_name = "DIR")]
output_dir: Option<PathBuf>,
#[arg(long, requires = "output_dir")]
json: bool,
},
Verify {
#[arg(value_name = "NAME")]
name: Option<String>,
#[arg(long)]
strict: bool,
#[arg(long)]
json: bool,
},
Diff {
env_a: String,
env_b: String,
#[arg(long, conflicts_with = "metadata_only")]
packages_only: bool,
#[arg(long, conflicts_with = "packages_only")]
metadata_only: bool,
#[arg(long)]
strict: bool,
#[arg(long)]
json: bool,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum ShellType {
Bash,
Zsh,
Fish,
#[value(alias = "pwsh")]
Powershell,
}