diff options
author | Justin Wernick <justin@worthe-it.co.za> | 2023-03-25 21:44:51 +0200 |
---|---|---|
committer | Justin Wernick <justin@worthe-it.co.za> | 2023-03-25 21:46:12 +0200 |
commit | 2e8f9e8043594c8e8ce57daabe4a26a8fb7e9826 (patch) | |
tree | 2d4931fa07e31c4a6de023e1c6b47398b05cc823 /src/parser.rs | |
parent | 9761556033c1faaae37f995ba557c47f9f3c357f (diff) |
Insist that git command paths are relative
Diffstat (limited to 'src/parser.rs')
-rw-r--r-- | src/parser.rs | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/src/parser.rs b/src/parser.rs index 6a6459b..55a2be9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,5 +1,8 @@ -use clap::{Parser, Subcommand}; -use std::{path::PathBuf, str::FromStr}; +use clap::Parser; +use std::{ + path::{Path, PathBuf}, + str::FromStr, +}; use thiserror::Error; #[derive(Parser, Clone, Debug, PartialEq, Eq)] @@ -13,11 +16,6 @@ pub enum ShackleCommand { GitReceivePack(GitReceivePackArgs), } -#[derive(Subcommand, Clone, Debug, PartialEq, Eq)] -pub enum GitCommand { - UploadPack(GitUploadPackArgs), -} - #[derive(Parser, Clone, Debug, PartialEq, Eq)] pub struct GitInitArgs { pub repo_name: String, @@ -35,6 +33,7 @@ pub struct GitUploadPackArgs { pub stateless_rpc: bool, #[arg(long)] pub advertise_refs: bool, + #[arg(value_parser = RelativePathParser)] pub directory: PathBuf, } @@ -42,6 +41,7 @@ pub struct GitUploadPackArgs { pub struct GitReceivePackArgs { #[arg(long)] pub http_backend_info_refs: bool, + #[arg(value_parser = RelativePathParser)] pub directory: PathBuf, } @@ -74,6 +74,36 @@ impl FromStr for ShackleCommand { } } +#[derive(Clone)] +struct RelativePathParser; + +impl clap::builder::TypedValueParser for RelativePathParser { + type Value = std::path::PathBuf; + + fn parse_ref( + &self, + cmd: &clap::Command, + arg: Option<&clap::Arg>, + value: &std::ffi::OsStr, + ) -> Result<Self::Value, clap::Error> { + clap::builder::TypedValueParser::parse(self, cmd, arg, value.to_owned()) + } + + fn parse( + &self, + cmd: &clap::Command, + arg: Option<&clap::Arg>, + value: std::ffi::OsString, + ) -> Result<Self::Value, clap::Error> { + let raw = clap::builder::PathBufValueParser::default().parse(cmd, arg, value)?; + Ok(raw + .strip_prefix(Path::new("/~")) + .or_else(|_| raw.strip_prefix(Path::new("~"))) + .map(|m| m.to_owned()) + .unwrap_or(raw)) + } +} + #[cfg(test)] mod test { use super::*; |