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