mirror of
https://github.com/Llewellynvdm/zoxide.git
synced 2024-11-28 23:46:27 +00:00
Return exit code from main
This commit is contained in:
parent
1d102d4ad2
commit
e4aa0692a4
@ -1,6 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{ArgEnum, Parser, ValueHint};
|
||||
use std::path::PathBuf;
|
||||
|
||||
const ENV_HELP: &str = "ENVIRONMENT VARIABLES:
|
||||
_ZO_DATA_DIR Path for zoxide data files
|
||||
|
@ -1,10 +1,8 @@
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
|
||||
use crate::cmd::{Add, Run};
|
||||
use crate::db::DatabaseFile;
|
||||
use crate::{config, util};
|
||||
use anyhow::{bail, Result};
|
||||
use std::path::Path;
|
||||
|
||||
impl Run for Add {
|
||||
fn run(&self) -> Result<()> {
|
||||
|
@ -1,10 +1,8 @@
|
||||
use std::fs;
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
use crate::cmd::{Import, ImportFrom, Run};
|
||||
use crate::config;
|
||||
use crate::db::{Database, DatabaseFile, Dir};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use std::fs;
|
||||
|
||||
impl Run for Import {
|
||||
fn run(&self) -> Result<()> {
|
||||
@ -120,7 +118,7 @@ mod tests {
|
||||
Dir { path: "/waldo/fred/plugh".into(), rank: 3.0, last_accessed: 300 },
|
||||
Dir { path: "/xyzzy/thud".into(), rank: 8.0, last_accessed: 800 },
|
||||
];
|
||||
println!("exp: {:?}", &exp);
|
||||
println!("exp: {exp:?}");
|
||||
|
||||
for (dir1, dir2) in db.dirs.iter().zip(exp) {
|
||||
assert_eq!(dir1.path, dir2.path);
|
||||
@ -161,7 +159,7 @@ mod tests {
|
||||
Dir { path: "/waldo/fred/plugh".into(), rank: 3.0, last_accessed: 300 },
|
||||
Dir { path: "/xyzzy/thud".into(), rank: 8.0, last_accessed: 800 },
|
||||
];
|
||||
println!("exp: {:?}", &exp);
|
||||
println!("exp: {exp:?}");
|
||||
|
||||
for (dir1, dir2) in db.dirs.iter().zip(exp) {
|
||||
assert_eq!(dir1.path, dir2.path);
|
||||
|
@ -1,12 +1,10 @@
|
||||
use std::io::{self, Write};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use askama::Template;
|
||||
|
||||
use crate::cmd::{Init, InitShell, Run};
|
||||
use crate::config;
|
||||
use crate::error::BrokenPipeHandler;
|
||||
use crate::shell::{self, Opts};
|
||||
use anyhow::{Context, Result};
|
||||
use askama::Template;
|
||||
use std::io::{self, Write};
|
||||
|
||||
impl Run for Init {
|
||||
fn run(&self) -> Result<()> {
|
||||
|
@ -5,10 +5,10 @@ mod init;
|
||||
mod query;
|
||||
mod remove;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
pub use crate::cmd::_cmd::*;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
pub trait Run {
|
||||
fn run(&self) -> Result<()>;
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
use std::io::{self, Write};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use crate::cmd::{Query, Run};
|
||||
use crate::config;
|
||||
use crate::db::{Database, DatabaseFile};
|
||||
use crate::error::BrokenPipeHandler;
|
||||
use crate::util::{self, Fzf};
|
||||
use anyhow::{Context, Result};
|
||||
use std::io::{self, Write};
|
||||
|
||||
impl Run for Query {
|
||||
fn run(&self) -> Result<()> {
|
||||
|
@ -1,11 +1,9 @@
|
||||
use std::io::{self, Write};
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
use crate::cmd::{Remove, Run};
|
||||
use crate::config;
|
||||
use crate::db::DatabaseFile;
|
||||
use crate::util::{self, Fzf};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use std::io::{self, Write};
|
||||
|
||||
impl Run for Remove {
|
||||
fn run(&self) -> Result<()> {
|
||||
|
@ -1,12 +1,10 @@
|
||||
use crate::db::Rank;
|
||||
use anyhow::{Context, Result};
|
||||
use glob::Pattern;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use glob::Pattern;
|
||||
|
||||
use crate::db::Rank;
|
||||
|
||||
pub fn data_dir() -> Result<PathBuf> {
|
||||
let path = match env::var_os("_ZO_DATA_DIR") {
|
||||
Some(path) => PathBuf::from(path),
|
||||
|
@ -1,10 +1,9 @@
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use bincode::Options as _;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct DirList<'a>(#[serde(borrow)] pub Vec<Dir<'a>>);
|
||||
@ -142,10 +141,9 @@ pub type Epoch = u64;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use super::{Dir, DirList};
|
||||
|
||||
#[test]
|
||||
fn zero_copy() {
|
||||
let dirs = DirList(vec![Dir { path: "/".into(), rank: 0.0, last_accessed: 0 }]);
|
||||
|
@ -1,15 +1,14 @@
|
||||
mod dir;
|
||||
mod stream;
|
||||
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
pub use dir::{Dir, DirList, Epoch, Rank};
|
||||
pub use stream::Stream;
|
||||
|
||||
use crate::util;
|
||||
use anyhow::{Context, Result};
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Database<'file> {
|
||||
|
@ -1,10 +1,9 @@
|
||||
use crate::db::{Database, Dir, Epoch};
|
||||
use crate::util;
|
||||
use std::iter::Rev;
|
||||
use std::ops::Range;
|
||||
use std::{fs, path};
|
||||
|
||||
use crate::db::{Database, Dir, Epoch};
|
||||
use crate::util;
|
||||
|
||||
pub struct Stream<'db, 'file> {
|
||||
db: &'db mut Database<'file>,
|
||||
idxs: Rev<Range<usize>>,
|
||||
@ -120,11 +119,9 @@ impl<'db, 'file> Stream<'db, 'file> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::*;
|
||||
use rstest::rstest;
|
||||
|
||||
use super::Database;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[rstest]
|
||||
// Case normalization
|
||||
|
@ -1,12 +1,11 @@
|
||||
use anyhow::{bail, Context, Result};
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::io;
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
/// Custom error type for early exit.
|
||||
#[derive(Debug)]
|
||||
pub struct SilentExit {
|
||||
pub code: i32,
|
||||
pub code: u8,
|
||||
}
|
||||
|
||||
impl Display for SilentExit {
|
||||
|
26
src/main.rs
26
src/main.rs
@ -1,7 +1,7 @@
|
||||
#![allow(clippy::single_component_path_imports)]
|
||||
|
||||
// rstest_reuse must be imported at the top of the crate.
|
||||
#[cfg(test)]
|
||||
#[cfg(all(test, feature = "nix-dev"))]
|
||||
use rstest_reuse;
|
||||
|
||||
mod cmd;
|
||||
@ -11,26 +11,26 @@ mod error;
|
||||
mod shell;
|
||||
mod util;
|
||||
|
||||
use std::io::{self, Write};
|
||||
use std::{env, process};
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use crate::cmd::{Cmd, Run};
|
||||
use crate::error::SilentExit;
|
||||
use clap::Parser;
|
||||
use std::env;
|
||||
use std::io::{self, Write};
|
||||
use std::process::ExitCode;
|
||||
|
||||
pub fn main() {
|
||||
pub fn main() -> ExitCode {
|
||||
// Forcibly disable backtraces.
|
||||
env::remove_var("RUST_LIB_BACKTRACE");
|
||||
env::remove_var("RUST_BACKTRACE");
|
||||
|
||||
if let Err(e) = Cmd::parse().run() {
|
||||
match e.downcast::<SilentExit>() {
|
||||
Ok(SilentExit { code }) => process::exit(code),
|
||||
match Cmd::parse().run() {
|
||||
Ok(()) => ExitCode::SUCCESS,
|
||||
Err(e) => match e.downcast::<SilentExit>() {
|
||||
Ok(SilentExit { code }) => code.into(),
|
||||
Err(e) => {
|
||||
let _ = writeln!(io::stderr(), "zoxide: {:?}", e);
|
||||
process::exit(1);
|
||||
}
|
||||
let _ = writeln!(io::stderr(), "zoxide: {e:?}");
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -35,13 +35,12 @@ make_template!(Zsh, "zsh.txt");
|
||||
#[cfg(feature = "nix-dev")]
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use askama::Template;
|
||||
use assert_cmd::Command;
|
||||
use rstest::rstest;
|
||||
use rstest_reuse::{apply, template};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[template]
|
||||
#[rstest]
|
||||
fn opts(
|
||||
|
16
src/util.rs
16
src/util.rs
@ -1,3 +1,9 @@
|
||||
use crate::config;
|
||||
use crate::db::Epoch;
|
||||
use crate::error::SilentExit;
|
||||
#[cfg(windows)]
|
||||
use anyhow::anyhow;
|
||||
use anyhow::{bail, Context, Result};
|
||||
use std::env;
|
||||
use std::fs::{self, File, OpenOptions};
|
||||
use std::io::{self, Read, Write};
|
||||
@ -7,14 +13,6 @@ use std::process::Command;
|
||||
use std::process::{Child, ChildStdin, Stdio};
|
||||
use std::time::SystemTime;
|
||||
|
||||
#[cfg(windows)]
|
||||
use anyhow::anyhow;
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
use crate::config;
|
||||
use crate::db::Epoch;
|
||||
use crate::error::SilentExit;
|
||||
|
||||
pub struct Fzf {
|
||||
child: Child,
|
||||
}
|
||||
@ -94,7 +92,7 @@ impl Fzf {
|
||||
Some(0) => Ok(output),
|
||||
Some(1) => bail!("no match found"),
|
||||
Some(2) => bail!("fzf returned an error"),
|
||||
Some(code @ 130) => bail!(SilentExit { code }),
|
||||
Some(130) => bail!(SilentExit { code: 130 }),
|
||||
Some(128..=254) | None => bail!("fzf was terminated"),
|
||||
_ => bail!("fzf returned an unknown error"),
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
use anyhow::{bail, Context, Result};
|
||||
use clap::Parser;
|
||||
use ignore::Walk;
|
||||
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::path::PathBuf;
|
||||
@ -44,10 +43,10 @@ trait CommandExt {
|
||||
|
||||
impl CommandExt for &mut Command {
|
||||
fn run(self) -> Result<()> {
|
||||
println!(">>> {:?}", self);
|
||||
let status = self.status().with_context(|| format!("command failed to start: {:?}", self))?;
|
||||
println!(">>> {self:?}");
|
||||
let status = self.status().with_context(|| format!("command failed to start: {self:?}"))?;
|
||||
if !status.success() {
|
||||
bail!("command failed: {:?} with status: {:?}", self, status);
|
||||
bail!("command failed: {self:?} with status: {status:?}");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user