git-repo-manager 0.10.0

Manage multiple git repositories. You configure the git repositories in a file, the program does the rest!
Documentation
use std::process;

use thiserror::Error;

#[derive(Clone)]
pub struct AuthToken(String);

#[derive(Error, Debug)]
pub enum Error {
    #[error("Token command failed: {0}")]
    TokenCommandInvocationFailed(#[from] std::io::Error),

    #[error("Token command produced non-utf8 output: {0}")]
    TokenCommandInvocationInvalidUtf8(#[from] std::string::FromUtf8Error),

    #[error("Token command failed, stderr: {0}")]
    TokenCommandFailed(String),

    #[error("Token command produced stderr: {0}")]
    TokenCommandStderr(String),

    #[error("Token command output empty")]
    TokenCommandEmptyOutput,

    #[error("Token command output did not contain any newline")]
    TokenCommandNoNewlineInOutput,
}

impl AuthToken {
    pub fn access(&self) -> &str {
        &self.0
    }
}

pub fn get_token_from_command(command: &str) -> Result<AuthToken, Error> {
    let output = process::Command::new("/usr/bin/env")
        .arg("sh")
        .arg("-c")
        .arg(command)
        .output()?;

    let stderr = String::from_utf8(output.stderr)?;
    let stdout = String::from_utf8(output.stdout)?;

    if !output.status.success() {
        return Err(Error::TokenCommandFailed(stderr));
    }

    if !stderr.is_empty() {
        return Err(Error::TokenCommandStderr(stderr));
    }

    if stdout.is_empty() {
        return Err(Error::TokenCommandEmptyOutput);
    }

    let token = stdout
        .split('\n')
        .next()
        .ok_or(Error::TokenCommandNoNewlineInOutput)?;

    Ok(AuthToken(token.to_owned()))
}