and another one
[openwrt.git] / scripts / env
1 #!/usr/bin/env bash
2 BASEDIR="$PWD"
3 ENVDIR="$PWD/env"
4
5 usage() {
6 cat <<EOF
7 Usage: $0 [options] <command> [arguments]
8 Commands:
9 help This help text
10 list List environments
11 clear Delete all environment and revert to flat config/files
12 new <name> Create a new environment
13 switch <name> Switch to a different environment
14 delete <name> Delete an environment
15 rename <newname> Rename the current environment
16 diff Show differences between current state and environment
17 save Save your changes to the environment
18 revert Revert your changes since last save
19
20 Options:
21
22 EOF
23 exit ${1:-1}
24 }
25
26 error() {
27 echo "$0: $*"
28 exit 1
29 }
30
31 ask_bool() {
32 local DEFAULT="$1"; shift
33 local def defstr val
34 case "$DEFAULT" in
35 1) def=0; defstr="Y/n";;
36 0) def=1; defstr="y/N";;
37 *) def=; defstr="y/n";;
38 esac
39 while [ -z "$val" ]; do
40 local VAL
41
42 echo -n "$* ($defstr): "
43 read VAL
44 case "$VAL" in
45 y*|Y*) val=0;;
46 n*|N*) val=1;;
47 *) val="$def";;
48 esac
49 done
50 return "$val"
51 }
52
53 env_init() {
54 local CREATE="$1"
55 if [ -z "$CREATE" ]; then
56 [ -d "$ENVDIR" ] || exit 0
57 fi
58 [ -x "$(which git 2>/dev/null)" ] || error "Git is not installed"
59 mkdir -p "$ENVDIR" || error "Failed to create the environment directory"
60 cd "$ENVDIR" || error "Failed to switch to the environment directory"
61 [ -d .git ] || {
62 git init &&
63 touch .config &&
64 mkdir files &&
65 git-add . &&
66 git-commit -q -m "Initial import"
67 } || {
68 rm -rf .git
69 error "Failed to initialize the environment directory"
70 }
71 }
72
73 env_sync_data() {
74 [ \! -L "$BASEDIR/.config" -a -f "$BASEDIR/.config" ] && mv "$BASEDIR/.config" "$ENVDIR"
75 git-add .
76 git-add -u
77 }
78
79 env_sync() {
80 local STR="$1"
81 env_sync_data
82 git-commit -m "${STR:-Update} at $(date)"
83 }
84
85 env_link_config() {
86 rm -f "$BASEDIR/.config"
87 ln -s env/.config "$BASEDIR/.config"
88 mkdir -p "$ENVDIR/files"
89 [ -L "$BASEDIR/files" ] || ln -s env/files "$BASEDIR/files"
90 }
91
92 env_do_reset() {
93 git-reset --hard HEAD
94 git-clean -d -f
95 }
96
97 env_list() {
98 env_init
99 git-branch | grep -vE '^. master$'
100 }
101
102 env_diff() {
103 env_init
104 env_sync_data
105 git-diff --cached
106 }
107
108 env_save() {
109 env_init
110 env_sync
111 env_link_config
112 }
113
114 env_revert() {
115 env_init
116 env_do_reset
117 env_link_config
118 }
119
120 env_ask_sync() {
121 LINES="$(env_diff | wc -l)" # implies env_init
122 [ "$LINES" -gt 0 ] && {
123 if ask_bool 1 "Do you want to save your changes"; then
124 env_sync
125 else
126 env_sync_data
127 env_do_reset
128 fi
129 }
130 }
131
132 env_clear() {
133 env_init
134 [ -L "$BASEDIR/.config" ] && rm -f "$BASEDIR/.config"
135 [ -L "$BASEDIR/files" ] && rm -f "$BASEDIR/files"
136 [ -f "$ENVDIR/.config" ] || ( cd "$ENVDIR/files" && find | grep -vE '^\.$' > /dev/null )
137 env_sync_data
138 if ask_bool 1 "Do you want to keep your current config and files"; then
139 mkdir -p "$BASEDIR/files"
140 cp -a "$ENVDIR/files/*" "$BASEDIR/files" 2>/dev/null >/dev/null
141 cp "$ENVDIR/.config" "$BASEDIR/"
142 else
143 rm -rf "$BASEDIR/files" "$BASEDIR/.config"
144 fi
145 cd "$BASEDIR"
146 rm -rf "$ENVDIR"
147 }
148
149 env_delete() {
150 local name="${1##*/}"
151 [ -z "$name" ] && usage
152 [ -f "$envdir/.git/refs/heads/$name" ] || error "environment '$name' not found"
153 branch="$(git-branch | grep '^\* ' | awk '{print $2}')"
154 [ "$name" = "branch" ] && error "cannot delete the currently selected environment"
155 git-branch -D "$name"
156 }
157
158 env_switch() {
159 local name="${1##*/}"
160 [ -z "$name" ] && usage
161 [ -f "$ENVDIR/.git/refs/heads/$name" ] || error "environment '$name' not found"
162
163 env_init
164 env_ask_sync
165 git-checkout "$name"
166 env_link_config
167 }
168
169 env_rename() {
170 local NAME="${1##*/}"
171 env_init
172 git-branch -m "$NAME"
173 }
174
175 env_new() {
176 local NAME="$1"
177 local branch
178 local from="master"
179
180 [ -z "$NAME" ] && usage
181 env_init 1
182
183 branch="$(git-branch | grep '^\* ' | awk '{print $2}')"
184 if [ -n "$branch" -a "$branch" != "master" ]; then
185 env_ask_sync
186 if ask_bool 0 "Do you want to clone the current environment?"; then
187 from="$branch"
188 fi
189 rm -f "$BASEDIR/.config" "$BASEDIR/files"
190 fi
191 git-checkout -b "$1" "$from"
192 if [ -f "$BASEDIR/.config" -o -d "$BASEDIR/files" ]; then
193 if ask_bool 1 "Do you want to keep your current config and files?"; then
194 [ -d "$BASEDIR/files" -a \! -L "$BASEDIR/files" ] && {
195 mv "$BASEDIR/files/"* "$ENVDIR/" 2>/dev/null
196 rmdir "$BASEDIR/files"
197 }
198 env_sync
199 else
200 rm -rf "$BASEDIR/.config" "$BASEDIR/files"
201 fi
202 fi
203 env_link_config
204 }
205
206 COMMAND="$1"; shift
207 case "$COMMAND" in
208 help) usage 0;;
209 new) env_new "$@";;
210 list) env_list "$@";;
211 clear) env_clear "$@";;
212 switch) env_switch "$@";;
213 delete) env_delete "$@";;
214 rename) env_rename "$@";;
215 diff) env_diff "$@";;
216 save) env_save "$@";;
217 revert) env_revert "$@";;
218 *) usage;;
219 esac
This page took 0.054383 seconds and 5 git commands to generate.