add script for managing 'build environments' (.config+files/), including documentation
SVN-Revision: 12212
This commit is contained in:
parent
3a321fb110
commit
131ba6fed7
2 changed files with 276 additions and 0 deletions
|
@ -483,3 +483,60 @@ Other useful targets include:
|
||||||
\item \texttt{make package/\textit{<name>}/configure V=99}
|
\item \texttt{make package/\textit{<name>}/configure V=99}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
|
\subsection{Using build environments}
|
||||||
|
OpenWrt provides a means of building images for multiple configurations
|
||||||
|
which can use multiple targets in one single checkout. These \emph{environments}
|
||||||
|
store a copy of the .config file generated by \texttt{make menuconfig} and the contents
|
||||||
|
of the \texttt{./files} folder.
|
||||||
|
The script \texttt{./scripts/env} is used to manage these environments, it uses
|
||||||
|
\texttt{git} (which needs to be installed on your system) as backend for version control.
|
||||||
|
|
||||||
|
The command
|
||||||
|
\begin{Verbatim}
|
||||||
|
\texttt{./scripts/env help}
|
||||||
|
\end{Verbatim}
|
||||||
|
produces a short help text with a list of commands.
|
||||||
|
|
||||||
|
To create a new environment named \texttt{current}, run the following command
|
||||||
|
\begin{Verbatim}
|
||||||
|
./scripts/env new current
|
||||||
|
\end{Verbatim}
|
||||||
|
This will move your \texttt{.config} file and \texttt{./files} (if it exists) to
|
||||||
|
the \texttt{env/} subdirectory and create symlinks in the base folder.
|
||||||
|
|
||||||
|
After running make menuconfig or changing things in files/, your current state will
|
||||||
|
differ from what has been saved before. To show these changes, use:
|
||||||
|
\begin{Verbatim}
|
||||||
|
./scripts/env diff
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
If you want to save these changes, run:
|
||||||
|
\begin{Verbatim}
|
||||||
|
./scripts/env save
|
||||||
|
\end{Verbatim}
|
||||||
|
If you want to revert your changes to the previously saved copy, run:
|
||||||
|
\begin{Verbatim}
|
||||||
|
./scripts/env revert
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
If you want, you can now create a second environment using the \texttt{new} command.
|
||||||
|
It will ask you whether you want to make it a clone of the current environment (e.g.
|
||||||
|
for minor changes) or if you want to start with a clean version (e.g. for selecting
|
||||||
|
a new target).
|
||||||
|
|
||||||
|
To switch to a different environment (e.g. \texttt{test1}), use:
|
||||||
|
\begin{Verbatim}
|
||||||
|
./scripts/env switch test1
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
To rename the current branch to a new name (e.g. \texttt{test2}), use:
|
||||||
|
\begin{Verbatim}
|
||||||
|
./scripts/env rename test2
|
||||||
|
\end{Verbatim}
|
||||||
|
|
||||||
|
If you want to get rid of environment switching and keep everything in the base directory
|
||||||
|
again, use:
|
||||||
|
\begin{Verbatim}
|
||||||
|
./scripts/env clear
|
||||||
|
\end{Verbatim}
|
||||||
|
|
219
scripts/env
Executable file
219
scripts/env
Executable file
|
@ -0,0 +1,219 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
BASEDIR="$PWD"
|
||||||
|
ENVDIR="$PWD/env"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $0 [options] <command> [arguments]
|
||||||
|
Commands:
|
||||||
|
help This help text
|
||||||
|
list List environments
|
||||||
|
clear Delete all environment and revert to flat config/files
|
||||||
|
new <name> Create a new environment
|
||||||
|
switch <name> Switch to a different environment
|
||||||
|
delete <name> Delete an environment
|
||||||
|
rename <newname> Rename the current environment
|
||||||
|
diff Show differences between current state and environment
|
||||||
|
save Save your changes to the environment
|
||||||
|
revert Revert your changes since last save
|
||||||
|
|
||||||
|
Options:
|
||||||
|
|
||||||
|
EOF
|
||||||
|
exit ${1:-1}
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo "$0: $*"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ask_bool() {
|
||||||
|
local DEFAULT="$1"; shift
|
||||||
|
local def defstr val
|
||||||
|
case "$DEFAULT" in
|
||||||
|
1) def=0; defstr="Y/n";;
|
||||||
|
0) def=1; defstr="y/N";;
|
||||||
|
*) def=; defstr="y/n";;
|
||||||
|
esac
|
||||||
|
while [ -z "$val" ]; do
|
||||||
|
local VAL
|
||||||
|
|
||||||
|
echo -n "$* ($defstr): "
|
||||||
|
read VAL
|
||||||
|
case "$VAL" in
|
||||||
|
y*|Y*) val=0;;
|
||||||
|
n*|N*) val=1;;
|
||||||
|
*) val="$def";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
return "$val"
|
||||||
|
}
|
||||||
|
|
||||||
|
env_init() {
|
||||||
|
local CREATE="$1"
|
||||||
|
if [ -z "$CREATE" ]; then
|
||||||
|
[ -d "$ENVDIR" ] || exit 0
|
||||||
|
fi
|
||||||
|
[ -x "$(which git 2>/dev/null)" ] || error "Git is not installed"
|
||||||
|
mkdir -p "$ENVDIR" || error "Failed to create the environment directory"
|
||||||
|
cd "$ENVDIR" || error "Failed to switch to the environment directory"
|
||||||
|
[ -d .git ] || {
|
||||||
|
git init &&
|
||||||
|
touch .config &&
|
||||||
|
mkdir files &&
|
||||||
|
git-add . &&
|
||||||
|
git-commit -q -m "Initial import"
|
||||||
|
} || {
|
||||||
|
rm -rf .git
|
||||||
|
error "Failed to initialize the environment directory"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
env_sync_data() {
|
||||||
|
[ \! -L "$BASEDIR/.config" -a -f "$BASEDIR/.config" ] && mv "$BASEDIR/.config" "$ENVDIR"
|
||||||
|
git-add .
|
||||||
|
git-add -u
|
||||||
|
}
|
||||||
|
|
||||||
|
env_sync() {
|
||||||
|
local STR="$1"
|
||||||
|
env_sync_data
|
||||||
|
git-commit -m "${STR:-Update} at $(date)"
|
||||||
|
}
|
||||||
|
|
||||||
|
env_link_config() {
|
||||||
|
rm -f "$BASEDIR/.config"
|
||||||
|
ln -s env/.config "$BASEDIR/.config"
|
||||||
|
mkdir -p "$ENVDIR/files"
|
||||||
|
[ -L "$BASEDIR/files" ] || ln -s env/files "$BASEDIR/files"
|
||||||
|
}
|
||||||
|
|
||||||
|
env_do_reset() {
|
||||||
|
git-reset --hard HEAD
|
||||||
|
git-clean -d -f
|
||||||
|
}
|
||||||
|
|
||||||
|
env_list() {
|
||||||
|
env_init
|
||||||
|
git-branch | grep -vE '^. master$'
|
||||||
|
}
|
||||||
|
|
||||||
|
env_diff() {
|
||||||
|
env_init
|
||||||
|
env_sync_data
|
||||||
|
git-diff --cached
|
||||||
|
}
|
||||||
|
|
||||||
|
env_save() {
|
||||||
|
env_init
|
||||||
|
env_sync
|
||||||
|
env_link_config
|
||||||
|
}
|
||||||
|
|
||||||
|
env_revert() {
|
||||||
|
env_init
|
||||||
|
env_do_reset
|
||||||
|
env_link_config
|
||||||
|
}
|
||||||
|
|
||||||
|
env_ask_sync() {
|
||||||
|
LINES="$(env_diff | wc -l)" # implies env_init
|
||||||
|
[ "$LINES" -gt 0 ] && {
|
||||||
|
if ask_bool 1 "Do you want to save your changes"; then
|
||||||
|
env_sync
|
||||||
|
else
|
||||||
|
env_sync_data
|
||||||
|
env_do_reset
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
env_clear() {
|
||||||
|
env_init
|
||||||
|
[ -L "$BASEDIR/.config" ] && rm -f "$BASEDIR/.config"
|
||||||
|
[ -L "$BASEDIR/files" ] && rm -f "$BASEDIR/files"
|
||||||
|
[ -f "$ENVDIR/.config" ] || ( cd "$ENVDIR/files" && find | grep -vE '^\.$' > /dev/null )
|
||||||
|
env_sync_data
|
||||||
|
if ask_bool 1 "Do you want to keep your current config and files"; then
|
||||||
|
mkdir -p "$BASEDIR/files"
|
||||||
|
cp -a "$ENVDIR/files/*" "$BASEDIR/files" 2>/dev/null >/dev/null
|
||||||
|
cp "$ENVDIR/.config" "$BASEDIR/"
|
||||||
|
else
|
||||||
|
rm -rf "$BASEDIR/files" "$BASEDIR/.config"
|
||||||
|
fi
|
||||||
|
cd "$BASEDIR"
|
||||||
|
rm -rf "$ENVDIR"
|
||||||
|
}
|
||||||
|
|
||||||
|
env_delete() {
|
||||||
|
local name="${1##*/}"
|
||||||
|
[ -z "$name" ] && usage
|
||||||
|
[ -f "$envdir/.git/refs/heads/$name" ] || error "environment '$name' not found"
|
||||||
|
branch="$(git-branch | grep '^\* ' | awk '{print $2}')"
|
||||||
|
[ "$name" = "branch" ] && error "cannot delete the currently selected environment"
|
||||||
|
git-branch -D "$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
env_switch() {
|
||||||
|
local name="${1##*/}"
|
||||||
|
[ -z "$name" ] && usage
|
||||||
|
[ -f "$envdir/.git/refs/heads/$name" ] || error "environment '$name' not found"
|
||||||
|
|
||||||
|
env_init
|
||||||
|
env_ask_sync
|
||||||
|
git-checkout "$NAME"
|
||||||
|
env_link_config
|
||||||
|
}
|
||||||
|
|
||||||
|
env_rename() {
|
||||||
|
local NAME="${1##*/}"
|
||||||
|
env_init
|
||||||
|
git-branch -m "$NAME"
|
||||||
|
}
|
||||||
|
|
||||||
|
env_new() {
|
||||||
|
local NAME="$1"
|
||||||
|
local branch
|
||||||
|
local from="master"
|
||||||
|
|
||||||
|
[ -z "$NAME" ] && usage
|
||||||
|
env_init 1
|
||||||
|
|
||||||
|
branch="$(git-branch | grep '^\* ' | awk '{print $2}')"
|
||||||
|
if [ -n "$branch" -a "$branch" != "master" ]; then
|
||||||
|
env_ask_sync
|
||||||
|
if ask_bool 0 "Do you want to clone the current environment?"; then
|
||||||
|
from="$branch"
|
||||||
|
fi
|
||||||
|
rm -f "$BASEDIR/.config" "$BASEDIR/files"
|
||||||
|
fi
|
||||||
|
git-checkout -b "$1" "$from"
|
||||||
|
if [ -f "$BASEDIR/.config" -o -d "$BASEDIR/files" ]; then
|
||||||
|
if ask_bool 1 "Do you want to keep your current config and files?"; then
|
||||||
|
[ -d "$BASEDIR/files" -a \! -L "$BASEDIR/files" ] && {
|
||||||
|
mv "$BASEDIR/files/"* "$ENVDIR/" 2>/dev/null
|
||||||
|
rmdir "$BASEDIR/files"
|
||||||
|
}
|
||||||
|
env_sync
|
||||||
|
else
|
||||||
|
rm -rf "$BASEDIR/.config" "$BASEDIR/files"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
env_link_config
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMAND="$1"; shift
|
||||||
|
case "$COMMAND" in
|
||||||
|
help) usage 0;;
|
||||||
|
new) env_new "$@";;
|
||||||
|
list) env_list "$@";;
|
||||||
|
clear) env_clear "$@";;
|
||||||
|
switch) env_switch "$@";;
|
||||||
|
delete) env_delete "$@";;
|
||||||
|
rename) env_rename "$@";;
|
||||||
|
diff) env_diff "$@";;
|
||||||
|
save) env_save "$@";;
|
||||||
|
revert) env_revert "$@";;
|
||||||
|
*) usage;;
|
||||||
|
esac
|
Loading…
Reference in a new issue