diff options
author | Freya Murphy <freya@freyacat.org> | 2025-01-16 14:45:14 -0500 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-01-16 14:45:14 -0500 |
commit | 60985236c7070425c28aa0c5ce675306d06ab123 (patch) | |
tree | 7448aef5dadf19d4504151ebc370f9e20757ef10 /src/main.rs | |
download | iris-60985236c7070425c28aa0c5ce675306d06ab123.tar.gz iris-60985236c7070425c28aa0c5ce675306d06ab123.tar.bz2 iris-60985236c7070425c28aa0c5ce675306d06ab123.zip |
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..86cd716 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,193 @@ +//! # Iris +//! A locking plugin manager for vim + +use iris::{Config, Result}; +use log::info; +use std::{env, process::exit}; + +const USAGE: &str = "\ +Usage: iris [OPTION]... COMMAND [FILE}"; + +const HELP: &str = "\ +A locking plugin manager for vim + +Commands: + switch checkout plugins using their current refs and generate autoload + file + lock update plugin refs to point to the latest commit + +Options: + -v, --verbose enable verbose output + -q, --quiet disable output + -h, --help print the help message + -V, --version print the program version +"; + +/// print the program version +fn version() -> ! { + println!("iris {}", env!("CARGO_PKG_VERSION")); + exit(0); +} + +/// print the program's usage +fn usage() -> ! { + eprintln!("{USAGE}"); + exit(1); +} + +/// print the program's help message +fn help() -> ! { + println!("{USAGE}\n{HELP}"); + exit(0); +} + +struct Options { + /// the command to run + command: String, + /// the file to load instead of defaults + file: Option<String>, + /// print verbose output + verbose: bool, + /// silence output + quiet: bool, +} + +// parse options +fn opts() -> Options { + let mut args = env::args().into_iter().peekable(); + let mut quiet = false; + let mut verbose = false; + + // skip program name + _ = args.next(); + + // options + while let Some(arg) = args.peek() { + // arg is not an option + if !arg.starts_with("-") { + break; + }; + // grab next + let arg = args.next().expect("no arg?!"); + + match arg.as_str() { + // stop parsing options + "--" => break, + // quiet + "-q" | "--quiet" => { + quiet = true; + } + // verbose + "-v" | "--verbose" => { + verbose = true; + } + // version + "-V" | "--version" => version(), + // help + "-h" | "--help" => help(), + // invalid + _ => { + eprintln!("invalid options: '{arg}'"); + exit(1); + } + }; + } + + // command + let Some(command) = args.next() else { + usage(); + }; + + // file + let file = args.next(); + + // force end of arguments + if args.next().is_some() { + usage(); + }; + + Options { + command, + file, + quiet, + verbose, + } +} + +fn log(opts: &Options) { + if !opts.quiet { + let level = if opts.verbose { + log::LevelFilter::Trace + } else { + log::LevelFilter::Info + }; + + env_logger::Builder::from_default_env() + .filter_level(level) + .format_timestamp(None) + .format_module_path(false) + .format_source_path(false) + .init(); + } +} + +fn switch(opts: &Options) -> Result<()> { + let cfg = match &opts.file { + Some(path) => Config::read_from_file(path), + None => Config::read_from_lock_file() + .or_else(|_| Config::read_from_plugin_file()), + }?; + + for plugin in &cfg.plugins { + plugin.switch()?; + info!("switched {}", plugin.id); + } + + cfg.write_autoload_file()?; + + Ok(()) +} + +fn lock(opts: &Options) -> Result<()> { + let mut cfg = match &opts.file { + Some(path) => Config::read_from_file(path), + None => Config::read_from_plugin_file(), + }?; + + for plugin in &mut cfg.plugins { + plugin.lock()?; + info!("locked {}", plugin.id); + } + + // save lock file + cfg.write_to_lock_file()?; + + Ok(()) +} + +fn inner() -> Result<()> { + // parse opts + let opts = opts(); + + // initalize logger (if not quiet) + log(&opts); + + // handle command + match opts.command.as_str() { + "switch" => switch(&opts)?, + "lock" => lock(&opts)?, + cmd => { + eprintln!("unknown command: '{cmd}'"); + exit(1); + } + }; + + Ok(()) +} + +fn main() { + if let Err(err) = inner() { + log::error!("{err}"); + exit(1); + } +} |