diff --git a/Cargo.toml b/Cargo.toml index 2432144..d3862c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,14 +19,8 @@ exclude = ["/devtools/*", "/Justfile", "/Vagrantfile", "/screenshots.png"] [[bin]] name = "exa" -path = "src/bin/main.rs" -doc = false -[lib] -name = "exa" -path = "src/exa.rs" - [dependencies] ansi_term = "0.12.0" datetime = "0.5" diff --git a/Justfile b/Justfile index 953e9df..d892165 100644 --- a/Justfile +++ b/Justfile @@ -25,7 +25,7 @@ build-features: # runs unit tests with every combination of feature flags test-features: - cargo hack test --feature-powerset --lib -- --quiet + cargo hack test --feature-powerset -- --quiet # prints versions of the necessary build tools diff --git a/Vagrantfile b/Vagrantfile index 1da3bc8..e9f2334 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -92,7 +92,7 @@ Vagrant.configure(2) do |config| echo -e "#!/bin/sh\ncargo build --manifest-path /vagrant/Cargo.toml \\$@" > /usr/bin/build-exa ln -sf /usr/bin/build-exa /usr/bin/b - echo -e "#!/bin/sh\ncargo test --manifest-path /vagrant/Cargo.toml --lib \\$@ -- --quiet" > /usr/bin/test-exa + echo -e "#!/bin/sh\ncargo test --manifest-path /vagrant/Cargo.toml \\$@ -- --quiet" > /usr/bin/test-exa ln -sf /usr/bin/test-exa /usr/bin/t echo -e "#!/bin/sh\n/vagrant/xtests/run.sh" > /usr/bin/run-xtests diff --git a/src/bin/main.rs b/src/bin/main.rs deleted file mode 100644 index 9b36526..0000000 --- a/src/bin/main.rs +++ /dev/null @@ -1,87 +0,0 @@ -extern crate exa; -use exa::Exa; - -use std::ffi::OsString; -use std::env::{args_os, var_os}; -use std::io::{stdout, stderr, Write, ErrorKind}; -use std::process::exit; - - -fn main() { - configure_logger(); - - let args: Vec = args_os().skip(1).collect(); - match Exa::from_args(args.iter(), &mut stdout()) { - Ok(mut exa) => { - match exa.run() { - Ok(exit_status) => exit(exit_status), - Err(e) => { - match e.kind() { - ErrorKind::BrokenPipe => exit(exits::SUCCESS), - _ => { - eprintln!("{}", e); - exit(exits::RUNTIME_ERROR); - }, - }; - } - }; - }, - - Err(ref e) if e.is_error() => { - let mut stderr = stderr(); - writeln!(stderr, "{}", e).unwrap(); - - if let Some(s) = e.suggestion() { - let _ = writeln!(stderr, "{}", s); - } - - exit(exits::OPTIONS_ERROR); - }, - - Err(ref e) => { - println!("{}", e); - exit(exits::SUCCESS); - }, - }; -} - - -/// Sets up a global logger if one is asked for. -/// The ‘EXA_DEBUG’ environment variable controls whether log messages are -/// displayed or not. Currently there are just two settings (on and off). -/// -/// This can’t be done in exa’s own option parsing because that part of it -/// logs as well, so by the time execution gets there, the logger needs to -/// have already been set up. -pub fn configure_logger() { - extern crate env_logger; - extern crate log; - - let present = match var_os(exa::vars::EXA_DEBUG) { - Some(debug) => debug.len() > 0, - None => false, - }; - - let mut logs = env_logger::Builder::new(); - if present { - logs.filter(None, log::LevelFilter::Debug); - } - else { - logs.filter(None, log::LevelFilter::Off); - } - - logs.init() -} - - -mod exits { - - /// Exit code for when exa runs OK. - pub const SUCCESS: i32 = 0; - - /// Exit code for when there was at least one I/O error during execution. - pub const RUNTIME_ERROR: i32 = 1; - - /// Exit code for when the command-line options are invalid. - pub const OPTIONS_ERROR: i32 = 3; -} diff --git a/src/exa.rs b/src/main.rs similarity index 78% rename from src/exa.rs rename to src/main.rs index c87c200..6806b81 100644 --- a/src/exa.rs +++ b/src/main.rs @@ -1,9 +1,9 @@ #![warn(trivial_casts, trivial_numeric_casts)] #![warn(unused_results)] -use std::env::var_os; +use std::env; use std::ffi::{OsStr, OsString}; -use std::io::{stderr, Write, Result as IOResult}; +use std::io::{stdout, stderr, Write, Result as IOResult, ErrorKind}; use std::path::{Component, PathBuf}; use ansi_term::{ANSIStrings, Style}; @@ -25,6 +25,75 @@ mod output; mod style; +fn main() { + use std::process::exit; + + configure_logger(); + + let args: Vec = env::args_os().skip(1).collect(); + match Exa::from_args(args.iter(), &mut stdout()) { + Ok(mut exa) => { + match exa.run() { + Ok(exit_status) => exit(exit_status), + Err(e) => { + match e.kind() { + ErrorKind::BrokenPipe => exit(exits::SUCCESS), + _ => { + eprintln!("{}", e); + exit(exits::RUNTIME_ERROR); + }, + }; + } + }; + }, + + Err(ref e) if e.is_error() => { + let mut stderr = stderr(); + writeln!(stderr, "{}", e).unwrap(); + + if let Some(s) = e.suggestion() { + let _ = writeln!(stderr, "{}", s); + } + + exit(exits::OPTIONS_ERROR); + }, + + Err(ref e) => { + println!("{}", e); + exit(exits::SUCCESS); + }, + }; +} + + +/// Sets up a global logger if one is asked for. +/// The ‘EXA_DEBUG’ environment variable controls whether log messages are +/// displayed or not. Currently there are just two settings (on and off). +/// +/// This can’t be done in exa’s own option parsing because that part of it +/// logs as well, so by the time execution gets there, the logger needs to +/// have already been set up. +pub fn configure_logger() { + extern crate env_logger; + extern crate log; + + let present = match env::var_os(vars::EXA_DEBUG) { + Some(debug) => debug.len() > 0, + None => false, + }; + + let mut logs = env_logger::Builder::new(); + if present { + logs.filter(None, log::LevelFilter::Debug); + } + else { + logs.filter(None, log::LevelFilter::Off); + } + + logs.init() +} + + /// The main program wrapper. pub struct Exa<'args, 'w, W: Write + 'w> { @@ -52,7 +121,7 @@ pub struct Exa<'args, 'w, W: Write + 'w> { struct LiveVars; impl Vars for LiveVars { fn get(&self, name: &'static str) -> Option { - var_os(name) + env::var_os(name) } } @@ -225,3 +294,16 @@ impl<'args, 'w, W: Write + 'w> Exa<'args, 'w, W> { } } } + + +mod exits { + + /// Exit code for when exa runs OK. + pub const SUCCESS: i32 = 0; + + /// Exit code for when there was at least one I/O error during execution. + pub const RUNTIME_ERROR: i32 = 1; + + /// Exit code for when the command-line options are invalid. + pub const OPTIONS_ERROR: i32 = 3; +}