forked from wulfgarpro/history-sync
-
Notifications
You must be signed in to change notification settings - Fork 0
/
history-sync.plugin.zsh
172 lines (151 loc) · 4.77 KB
/
history-sync.plugin.zsh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# ----------------------------------------------------------------
# Description
# -----------
# An Oh My Zsh plugin for GPG encrypted, Internet synchronized Zsh
# history using Git.
#
# ----------------------------------------------------------------
# Authors
# -------
#
# * James Fraser <[email protected]>
# https://www.wulfgar.pro
# ----------------------------------------------------------------
#
autoload -U colors && colors
alias zhpl=history_sync_pull
alias zhps=history_sync_push
alias zhsync="history_sync_pull && history_sync_push"
GIT=$(which git)
GPG=$(which gpg)
ZSH_HISTORY_PROJ="${HOME}/.zsh_history_proj"
ZSH_HISTORY_FILE_NAME=".zsh_history"
ZSH_HISTORY_FILE="${HOME}/${ZSH_HISTORY_FILE_NAME}"
ZSH_HISTORY_FILE_ENC_NAME="zsh_history"
ZSH_HISTORY_FILE_ENC="${ZSH_HISTORY_PROJ}/${ZSH_HISTORY_FILE_ENC_NAME}"
ZSH_HISTORY_FILE_DECRYPT_NAME="zsh_history_decrypted"
GIT_COMMIT_MSG="latest $(date)"
function _print_git_error_msg() {
echo "$bold_color${fg[red]}There's a problem with git repository: ${ZSH_HISTORY_PROJ}.$reset_color"
return
}
function _print_gpg_encrypt_error_msg() {
echo "$bold_color${fg[red]}GPG failed to encrypt history file.$reset_color"
return
}
function _print_gpg_decrypt_error_msg() {
echo "$bold_color${fg[red]}GPG failed to decrypt history file.$reset_color"
return
}
function _usage() {
echo "Usage: [ [-r <string> ...] [-y] ]" 1>&2
echo
echo "Optional args:"
echo
echo " -r receipients"
echo " -y force"
return
}
# Pull current master, decrypt, and merge with .zsh_history
function history_sync_pull() {
DIR=$(pwd)
# Backup
cp -av "$ZSH_HISTORY_FILE" "$ZSH_HISTORY_FILE.backup" 1>&2
# Pull
cd "$ZSH_HISTORY_PROJ" && "$GIT" pull
if [[ "$?" != 0 ]]; then
_print_git_error_msg
cd "$DIR"
return
fi
# Decrypt
"$GPG" --output "$ZSH_HISTORY_FILE_DECRYPT_NAME" --decrypt "$ZSH_HISTORY_FILE_ENC"
if [[ "$?" != 0 ]]; then
_print_gpg_decrypt_error_msg
cd "$DIR"
return
fi
# Merge
cat "$ZSH_HISTORY_FILE" "$ZSH_HISTORY_FILE_DECRYPT_NAME" | awk '/:[0-9]/ { if(s) { print s } s=$0 } !/:[0-9]/ { s=s"\n"$0 } END { print s }' | LC_ALL=C sort -u > "$ZSH_HISTORY_FILE"
rm "$ZSH_HISTORY_FILE_DECRYPT_NAME"
cd "$DIR"
}
# Encrypt and push current history to master
function history_sync_push() {
# Get options recipients, force
local recipients=()
local force=false
while getopts r:y opt; do
case "$opt" in
r)
recipients+="$OPTARG"
;;
y)
force=true
;;
*)
_usage
return
;;
esac
done
# Encrypt
if ! [[ "${#recipients[@]}" > 0 ]]; then
echo -n "Please enter GPG recipient name: "
read name
recipients+="$name"
fi
ENCRYPT_CMD="$GPG --yes -v "
for r in "${recipients[@]}"; do
ENCRYPT_CMD+="-r \"$r\" "
done
if [[ "$ENCRYPT_CMD" =~ '.(-r).+.' ]]; then
ENCRYPT_CMD+="--encrypt --sign --armor --output $ZSH_HISTORY_FILE_ENC $ZSH_HISTORY_FILE"
eval "$ENCRYPT_CMD"
if [[ "$?" != 0 ]]; then
_print_gpg_encrypt_error_msg
return
fi
# Commit
if [[ $force = false ]]; then
echo -n "$bold_color${fg[yellow]}Do you want to commit current local history file (y/N)?$reset_color "
read commit
else
commit='y'
fi
if [[ -n "$commit" ]]; then
case "$commit" in
[Yy]* )
DIR=$(pwd)
cd "$ZSH_HISTORY_PROJ" && "$GIT" add * && "$GIT" commit -m "$GIT_COMMIT_MSG"
if [[ $force = false ]]; then
echo -n "$bold_color${fg[yellow]}Do you want to push to remote (y/N)?$reset_color "
read push
else
push='y'
fi
if [[ -n "$push" ]]; then
case "$push" in
[Yy]* )
"$GIT" push
if [[ "$?" != 0 ]]; then
_print_git_error_msg
cd "$DIR"
return
fi
cd "$DIR"
;;
esac
fi
if [[ "$?" != 0 ]]; then
_print_git_error_msg
cd "$DIR"
return
fi
;;
* )
;;
esac
fi
fi
}