summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2023-03-25 21:44:51 +0200
committerJustin Wernick <justin@worthe-it.co.za>2023-03-25 21:46:12 +0200
commit2e8f9e8043594c8e8ce57daabe4a26a8fb7e9826 (patch)
tree2d4931fa07e31c4a6de023e1c6b47398b05cc823 /src
parent9761556033c1faaae37f995ba557c47f9f3c357f (diff)
Insist that git command paths are relative
Diffstat (limited to 'src')
-rw-r--r--src/git.rs5
-rw-r--r--src/parser.rs44
2 files changed, 39 insertions, 10 deletions
diff --git a/src/git.rs b/src/git.rs
index 877e336..f7dbe13 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -19,9 +19,8 @@ fn personal_git_dir() -> Result<PathBuf, ShackleError> {
}
fn is_valid_personal_git_repo(path: &PathBuf) -> Result<bool, ShackleError> {
- let valid_dir = personal_git_dir()?.canonicalize()?;
- let canonical_path = path.canonicalize()?;
- let relative_path = match canonical_path.strip_prefix(&valid_dir) {
+ let valid_dir = personal_git_dir()?;
+ let relative_path = match path.strip_prefix(&valid_dir) {
Ok(relative_path) => relative_path,
Err(_) => {
return Ok(false);
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::*;