summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2014-04-17 14:30:05 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2014-04-17 14:40:56 +0200
commit658fe0ac863a4d1c62b3c64d2ed9c92981274bd4 (patch)
treeb9a27d105afa122a13ac57f7bf15142843c502aa
parent1763e2d0347c38aa8f7167f6fcfd4401fd6995dc (diff)
downloadpass-658fe0ac863a4d1c62b3c64d2ed9c92981274bd4.tar.gz
pass-658fe0ac863a4d1c62b3c64d2ed9c92981274bd4.tar.bz2
pass-658fe0ac863a4d1c62b3c64d2ed9c92981274bd4.zip
mv: Add pass mv/rename support
Based-on-work-by: Matthieu Weber <mweber@free.fr> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--man/pass.16
-rw-r--r--src/completion/pass.bash-completion4
-rw-r--r--src/completion/pass.fish-completion4
-rw-r--r--src/completion/pass.zsh-completion7
-rwxr-xr-xsrc/password-store.sh60
5 files changed, 78 insertions, 3 deletions
diff --git a/man/pass.1 b/man/pass.1
index 9890111..3039143 100644
--- a/man/pass.1
+++ b/man/pass.1
@@ -126,6 +126,12 @@ alternatively named \fBremove\fP or \fBdelete\fP. If \fI--recursive\fP or \fI-r\
is specified, delete pass-name recursively if it is a directory. If \fI--force\fP
or \fI-f\fP is specified, do not interactively prompt before removal.
.TP
+\fBmv\fP [ \fI--force\fP, \fI-f\fP ] \fIold-path\fP \fInew-path\fP
+Renames the password or directory named \fIold-path\fP to \fInew-path\fP. This
+command is alternatively named \fBrename\fP. If \fI--force\fP is specified,
+silently overwrite \fInew-path\fP if it exists. If \fInew-path\fP ends in a
+trailing \fI/\fP, it is always treated as a directory.
+.TP
\fBgit\fP \fIgit-command-args\fP...
If the password store is a git repository, pass \fIgit-command-args\fP as arguments to
.BR git (1)
diff --git a/src/completion/pass.bash-completion b/src/completion/pass.bash-completion
index 1f20f51..08378f7 100644
--- a/src/completion/pass.bash-completion
+++ b/src/completion/pass.bash-completion
@@ -84,6 +84,10 @@ _pass()
COMPREPLY+=($(compgen -W "-n --no-symbols -c --clip -f --force" -- ${cur}))
_pass_complete_entries
;;
+ mv|rename)
+ COMPREPLY+=($(compgen -W "-f --force" -- ${cur}))
+ _pass_complete_entries
+ ;;
rm|remove|delete)
COMPREPLY+=($(compgen -W "-r --recursive -f --force" -- ${cur}))
_pass_complete_entries
diff --git a/src/completion/pass.fish-completion b/src/completion/pass.fish-completion
index 10c9488..2498be4 100644
--- a/src/completion/pass.fish-completion
+++ b/src/completion/pass.fish-completion
@@ -81,6 +81,10 @@ complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -s c -l clip -d '
complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -s f -l force -d 'Do not prompt before overwritting'
complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -a "(__fish_pass_print_entry_dirs)"
+complete -c $PROG -f -A -n '__fish_pass_needs_command' -a mv -d 'Command: rename existing password'
+complete -c $PROG -f -A -n '__fish_pass_uses_command mv' -s f -l force -d 'Force rename'
+complete -c $PROG -f -A -n '__fish_pass_uses_command mv' -a "(__fish_pass_print_entries_and_dirs)"
+
complete -c $PROG -f -A -n '__fish_pass_needs_command' -a rm -d 'Command: remove existing password'
complete -c $PROG -f -A -n '__fish_pass_uses_command rm' -s r -l recursive -d 'Remove password groups recursively'
complete -c $PROG -f -A -n '__fish_pass_uses_command rm' -s f -l force -d 'Force removal'
diff --git a/src/completion/pass.zsh-completion b/src/completion/pass.zsh-completion
index 90045f0..b451fbf 100644
--- a/src/completion/pass.zsh-completion
+++ b/src/completion/pass.zsh-completion
@@ -48,6 +48,12 @@ _pass () {
"--clip[copy password to the clipboard]"
_pass_complete_entries_with_subdirs
;;
+ mv|rename)
+ _arguments : \
+ "-f[force rename]" \
+ "--force[force rename]" \
+ _pass_complete_entries_with_subdirs
+ ;;
rm)
_arguments : \
"-f[force deletion]" \
@@ -83,6 +89,7 @@ _pass () {
"insert:Insert a new password"
"generate:Generate a new password using pwgen"
"edit:Edit a password with \$EDITOR"
+ "mv:Rename the password"
"rm:Remove the password"
"git:Call git on the password store"
"version:Output version information"
diff --git a/src/password-store.sh b/src/password-store.sh
index 082501d..5b2293a 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -26,8 +26,13 @@ git_add_file() {
[[ -d $GIT_DIR ]] || return
git add "$1" || return
[[ -n $(git status --porcelain "$1") ]] || return
+ git_commit "$2"
+}
+git_commit() {
+ local sign
+ [[ -d $GIT_DIR ]] || return
[[ $(git config --bool --get pass.signcommits) == "true" ]] && sign="-S" || sign=""
- git commit $sign -m "$2"
+ git commit $sign -m "$1"
}
yesno() {
local response
@@ -185,6 +190,8 @@ cmd_usage() {
Prompt before overwriting existing password unless forced.
$PROGRAM rm [--recursive,-r] [--force,-f] pass-name
Remove existing password or directory, optionally forcefully.
+ $PROGRAM mv [--force,-f] old-path new-path
+ Renames or moves old-path to new-path, optionally forcefully.
$PROGRAM git git-command-args...
If the password store is a git repository, execute a git command
specified by git-command-args.
@@ -482,7 +489,7 @@ cmd_delete() {
if [[ ! -d $passfile ]]; then
passfile="$PREFIX/$path.gpg"
if [[ ! -f $passfile ]]; then
- echo "$path is not in the password store."
+ echo "Error: $path is not in the password store."
exit 1
fi
fi
@@ -492,10 +499,56 @@ cmd_delete() {
rm $recursive -f -v "$passfile"
if [[ -d $GIT_DIR && ! -e $passfile ]]; then
git rm -qr "$passfile"
- git commit -m "Removed $path from store."
+ git_commit "Removed $path from store."
fi
}
+cmd_rename() {
+ local force=0
+
+ local opts
+ opts="$($GETOPT -o f -l force -n "$PROGRAM" -- "$@")"
+ local err=$?
+ eval set -- "$opts"
+ while true; do case $1 in
+ -f|--force) force=1; shift ;;
+ --) shift; break ;;
+ esac done
+ if [[ $# -ne 2 ]]; then
+ echo "Usage: $PROGRAM $COMMAND [--force,-f] old-path new-path"
+ exit 1
+ fi
+ local old_path="$PREFIX/${1%/}"
+ local new_path="$PREFIX/$2"
+ local old_dir="$old_path"
+
+ if [[ ! -d $old_path ]]; then
+ old_dir="${old_path%/*}"
+ old_path="${old_path}.gpg"
+ if [[ ! -f $old_path ]]; then
+ echo "Error: $1 is not in the password store."
+ exit 1
+ fi
+ fi
+
+ mkdir -p -v "${new_path%/*}"
+ [[ -d $old_path || -d $new_path || $new_path =~ /$ ]] || new_path="${new_path}.gpg"
+
+ local interactive="-i"
+ [[ $force -eq 1 ]] && interactive="-f"
+
+ mv $interactive -v "$old_path" "$new_path" || exit 1
+
+ if [[ -d $GIT_DIR && ! -e $old_path ]]; then
+ git rm -qr "$old_path"
+ git_add_file "$new_path" "Renamed ${1} to ${2}."
+ fi
+
+ while rmdir "$old_dir" &>/dev/null; do
+ old_dir="${old_dir%/*}"
+ done
+}
+
cmd_git() {
if [[ $1 == "init" ]]; then
git "$@" || exit 1
@@ -526,6 +579,7 @@ case "$1" in
edit) shift; cmd_edit "$@"; ;;
generate) shift; cmd_generate "$@"; ;;
delete|rm|remove) shift; cmd_delete "$@"; ;;
+ rename|mv) shift; cmd_rename "$@"; ;;
git) shift; cmd_git "$@"; ;;
*) COMMAND="show"; cmd_show "$@"; ;;
esac