Skip to content

Instantly share code, notes, and snippets.

@i30817
Last active May 20, 2023 21:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save i30817/8ffcd35f7c16e4dbe474c5fb46a6a61e to your computer and use it in GitHub Desktop.
Save i30817/8ffcd35f7c16e4dbe474c5fb46a6a61e to your computer and use it in GitHub Desktop.
a navi (bash helper for automation) file to build some projects i build often which helps choose the branch to build and automates pulls
#!/bin/bash
ME=$(basename "$0")
function usage(){
cat >&2 <<ENDOFHELP
Usage: $ME [-h] [-c OPT1 -c OPT2...] [-m OPT1 -m OPT2...] [BRANCH_NAME]
$ME optionally updates a local branch from a upstream,
and assuming that there is a configure file and -s
is not passed, calls ./configure with arguments,
and assuming there is a makefile and -s is not
passed, calls make with arguments.
If make fails, before giving up, it calls
make clean and calls make again.
This is intended to run in a git repository directory,
after a fetch of the required branch in the caller.
The fetch is not done in the script because callers
often need to fetch the information about branch to
display to the user anyway.
This will not update from upstream if there is no
upstream for the branch.
Typically, Pull Requests have no upstream, and hacks
to make them have it are unlikely to work with this,
because they tend to fail when you ask for the upstream
in git status or when pulling.
Instead to update a PR, you can delete the PR branch
and fetch it again in the caller with:
git checkout master
git branch -D pr/<pr_number>
git fetch origin "pull/<pr_number>/head:pr/<pr_number>" (for github)
But that's your prerogative, if you find a way that
still works with git status having 'branch.upstream'
it should still work.
-h show this help
-c configure option string (will call configure)
-s skip configure and make if no arguments passed
-m make option string (will call make)
ENDOFHELP
}
CONF=()
MAKE=()
SKIP=0
while getopts "hsc:m:" opt; do
case $opt in
h) usage; exit 0; ;;
s) SKIP=1; ;;
c) CONF+=("${OPTARG}"); ;;
m) MAKE+=("${OPTARG}"); ;;
*) echo >&2 "$ME: unknown option '${OPTARG}'."; usage; exit 1; ;;
esac
done
shift $((OPTIND-1))
#set -x
(( "$#" > 1 )) && { echo >&2 "$ME: requires a single branch or pull name."; exit 1; }
[[ ! -d "$PWD" ]] && { echo >&2 "$ME: could not retrieve current directory."; exit 1; }
if (( "$#" == 1 )); then
git -C "$PWD" rev-parse &>/dev/null || { echo >&2 "$ME: current directory not a git repository."; exit 1; }
git checkout -f "$1" &>/dev/null || { echo >&2 "$ME: failed checking out branch"; exit 1; }
UPSTREAM="$(git status -b --porcelain=v2 | grep -m 1 "^# branch.upstream " | cut -d " " -f 3-)"
if [[ -z "$UPSTREAM" ]]; then
echo "$ME: requested branch upstream does not exist."
else
git pull && git submodule update || { echo >&2 "$ME: failed pulling branch."; }
fi
fi
if [[ ( ${#CONF[@]} -gt 0 && -f ./configure ) || ( $SKIP -eq 0 && -f ./configure ) ]]; then
./configure "${CONF[@]}" || { echo >&2 "$ME: failed configuring project."; exit 1; }
fi
if [[ ( ${#MAKE[@]} -gt 0 && -f ./makefile ) || ( ${#MAKE[@]} -gt 0 && -f ./Makefile ) || ( $SKIP -eq 0 && -f ./makefile ) || ( $SKIP -eq 0 && -f ./Makefile ) ]]; then
make -j"$(nproc)" "${MAKE[@]}" || { echo >&2 "$ME: build failed, retrying with make clean." && make clean && make -j"$(nproc)" "${MAKE[@]}"; } || { echo >&2 "$ME: failed making project."; exit 1; }
fi
% make, build, projects, compile
; variables are initialized by navi per rule BEFORE the commands run so one of these per repository is needed
; this is the reason the fetch origin and ls-remote calls are here, to fetch the new data from the remote and fill correctly the options
; navi is kind of weird in that it will abort the rule if there is a 'variable' with no possibilities, so most of this error handling will not trigger
$ retroarch_config_dir: echo "$HOME/.config/retroarch" --- --prevent-extra
$ retroarch_build_dir: echo "$HOME/Documents/Projects/RetroArch" --- --prevent-extra
$ discord: echo "disable-discord enable-discord" | tr ' ' '\n' --- --prevent-extra
$ qt: echo "disable-qt enable-qt" | tr ' ' '\n' --- --prevent-extra
$ ffmpeg: echo "disable-ffmpeg enable-ffmpeg" | tr ' ' '\n' --- --prevent-extra
$ flac: echo "disable-flac enable-flac" | tr ' ' '\n' --- --prevent-extra
$ cdrom: echo "disable-cdrom enable-cdrom" | tr ' ' '\n' --- --prevent-extra
$ wayland: echo "enable-wayland disable-wayland" | tr ' ' '\n' --- --prevent-extra
$ kms: echo "disable-kms enable-kms" | tr ' ' '\n' --- --prevent-extra
$ sdl2: echo "enable-sdl2 disable-sdl2" | tr ' ' '\n' --- --prevent-extra
$ x11: echo "enable-x11 disable-x11" | tr ' ' '\n' --- --prevent-extra
$ opengl: echo "enable-opengl disable-opengl" | tr ' ' '\n' --- --prevent-extra
$ vulkan: echo "enable-vulkan disable-vulkan" | tr ' ' '\n' --- --prevent-extra
$ use_debug: echo 'false true' | tr ' ' '\n' --- --prevent-extra
$ retroarch_branch: git -C <retroarch_build_dir> fetch origin && { git -C <retroarch_build_dir> branch --no-column --format '%(refname)' -a | sed '/HEAD detached at/d' | sed 's/^refs\/\(heads\|remotes\)\///g' | sort -n ; } || echo "master" --- --prevent-extra
$ retroarch_pr: git -C <retroarch_build_dir> ls-remote -q origin 'pull/*/head' 2>/dev/null | cut -f2 | sed -E 's/[^[:digit:]]*([[:digit:]]+)[^[:digit:]]+/pr\/\1/' | sort -rV --- --prevent-extra
# kill leftover wine processes
( kill -9 $(ps aux |grep -i '\.exe' |awk '{print $2}'|tr '\n' ' ') )
# retroarch
( \
cd "<retroarch_build_dir>"; \
[[ <use_debug> == t* ]] && DBG=--enable-debug || DBG=; \
git-branch-pull -c "$DBG" -c --<cdrom> -c --<discord> -c --<qt> -c --<ffmpeg> -c --<flac> -c --<wayland> -c --<kms> -c --<sdl2> -c --<x11> -c --<opengl> -c --<vulkan> -m TARGET=retroarch "<retroarch_branch>"; printf "\a"; \
)
$ scummvm_build_dir: echo "$HOME/Documents/Projects/scummvm" --- --prevent-extra
$ scummvm_core_build_dir: echo "$HOME/Documents/Projects/scummvm/backends/platform/libretro/build" --- --prevent-extra
$ scummvm_core_dat_dir: echo "$HOME/Documents/Projects/scummvm/backends/platform/libretro/aux-data" --- --prevent-extra
$ scummvm_branch: git -C <scummvm_build_dir> fetch origin && { git -C <scummvm_build_dir> branch --no-column --format '%(refname)' -a | sed '/HEAD detached at/d' | sed 's/^refs\/\(heads\|remotes\)\///g' | sort -n ; } || echo "master" --- --prevent-extra
$ scummvm_core_branch: git -C <scummvm_core_build_dir> fetch origin && { git -C <scummvm_core_build_dir> branch --no-column --format '%(refname)' -a | sed '/HEAD detached at/d' | sed 's/^refs\/\(heads\|remotes\)\///g' | sort -n ; } || echo "main" --- --prevent-extra
# scummvm core
( \
cd "<scummvm_build_dir>"; \
[[ <use_debug> == t* ]] && DBG=1 || DBG=0; \
git-branch-pull -s "<scummvm_branch>"; \
cd "<scummvm_core_build_dir>"; \
make clean; \
git-branch-pull -m DEBUG=$DBG "<scummvm_core_branch>"; \
"<scummvm_core_dat_dir>"/bundle_aux_data.bash && 7z x -y -o"<retroarch_config_dir>"/system/ "<scummvm_core_dat_dir>"/scummvm.zip && cp -v "<scummvm_core_build_dir>"/scummvm_libretro.so "<retroarch_config_dir>"/cores/; printf "\a"; \
)
# scummvm core (no git update)
( \
cd "<scummvm_build_dir>"; \
[[ <use_debug> == t* ]] && DBG=1 || DBG=0; \
git-branch-pull -s; \
cd "<scummvm_core_build_dir>"; \
make clean; \
git-branch-pull -m DEBUG=$DBG; \
"<scummvm_core_dat_dir>"/bundle_aux_data.bash && 7z x -y -o"<retroarch_config_dir>"/system/ "<scummvm_core_dat_dir>"/scummvm.zip && cp -v "<scummvm_core_build_dir>"/scummvm_libretro.so "<retroarch_config_dir>"/cores/; printf "\a"; \
)
$ ppsspp_renderer: echo "enable-opengl31 enable-gles2" | tr ' ' '\n' --- --prevent-extra
$ ppsspp_root_dir: echo "$HOME/Documents/Projects/ppsspp" --- --prevent-extra
$ ppsspp_branch: git -C <ppsspp_root_dir> fetch origin && { git -C <ppsspp_root_dir> branch --no-column --format '%(refname)' -a | sed '/HEAD detached at/d' | sed 's/^refs\/\(heads\|remotes\)\///g' | sort -n ; } || echo "master" --- --prevent-extra
# ppsspp RA core
; to build gles use -DUSING_GLES2 instead of -DHAVE_OPENGL_CORE on DYNAFLAGS (no =1 or =ON at the end)
( \
export CORE="$HOME/.config/retroarch/cores/ppsspp_libretro.so"; \
export CORE_ASSETS="$HOME/.config/retroarch/system/PPSSPP"; \
cd <ppsspp_root_dir>/libretro; \
[[ <ppsspp_renderer> == enable-opengl* ]] && REN="-DHAVE_OPENGL_CORE" || REN="-DUSING_GLES2"; \
[[ <use_debug> == t* ]] && DBG=1 || DBG=0; \
git-branch-pull -m DEBUG=$DBG -m DYNAFLAGS="$REN" "<ppsspp_branch>" && gio trash -f "$CORE" && mv -fT ./ppsspp_libretro.so "$CORE" && chmod -x "$CORE" && rsync -a --delete <ppsspp_root_dir>/assets "$CORE_ASSETS"; \
printf "\a"; \
)
# retroarch pull request
( \
cd "<retroarch_build_dir>"; \
[[ <use_debug> == t* ]] && DBG=--enable-debug || DBG=; \
;fill these first just to push the branch info last like in the non-pr build
echo "<discord><qt><ffmpeg><flac><wayland><kms><sdl2><x11><opengl><vulkan><cdrom>" &>/dev/null; \
;remove prefix
PR="<retroarch_pr>"; \
PR="${PR:3}"; \
;PRs are always deleted locally then downloaded. This is much simpler to update than messing around with git config and fail all the time in unexpected situations
git checkout master &>/dev/null; \
git branch -D "pr/$PR" &>/dev/null; \
git fetch origin "pull/$PR/head:pr/$PR" >/dev/null || { echo "failed fetching branch" >&2; printf "\a"; exit 1; }; \
git-branch-pull -c "$DBG" -c --<cdrom> -c --<discord> -c --<qt> -c --<ffmpeg> -c --<flac> -c --<wayland> -c --<kms> -c --<sdl2> -c --<x11> -c --<opengl> -c --<vulkan> -m TARGET=retroarch "pr/$PR"; \
printf "\a"; \
)
$ ags_build_dir: echo "$HOME/Documents/Projects/ags/Engine" --- --prevent-extra
$ ags_branch: git -C <ags_build_dir> fetch origin && { git -C <ags_build_dir> branch --no-column --format '%(refname)' -a | sed '/HEAD detached at/d' | sed 's/^refs\/\(heads\|remotes\)\///g' | sort -n ; } || echo "master" --- --prevent-extra
$ ags_pr: git -C <ags_build_dir> ls-remote -q origin 'pull/*/head' 2>/dev/null | cut -f2 | sed -E 's/[^[:digit:]]*([[:digit:]]+)[^[:digit:]]+/pr\/\1/' | sort -rV --- --prevent-extra
# ags
( \
cd "<ags_build_dir>"; \
[[ <use_debug> == t* ]] && DBG=debug || DBG=ags; \
; ags uses sdl2_sound which is not packaged by distros, so i built it with checkinstall. It places the headers in this weird directory, which is probably why it's not packaged
git-branch-pull -m $DBG -m CPATH=/usr/local/include/SDL2/ -m USE_BUILT_IN_LIBSRC=0 -m TARGET=ags "<ags_branch>"; printf "\a"; \
)
# ags pull request
( \
cd "<ags_build_dir>"; \
[[ <use_debug> == t* ]] && DBG=debug || DBG=ags; \
PR="<ags_pr>"; \
PR="${PR:3}"; \
git checkout master &>/dev/null; \
git branch -D "pr/$PR" &>/dev/null; \
git fetch origin "pull/$PR/head:pr/$PR" >/dev/null || { echo "failed fetching branch" >&2; printf "\a"; exit 1; }; \
git-branch-pull -m "$DBG" -m CPATH=/usr/local/include/SDL2/ -m USE_BUILT_IN_LIBSRC=1 -m TARGET=ags "pr/$PR"; printf "\a"; \
)
$ pcsx2_build_dir: echo "$HOME/Documents/Projects/pcsx2-git" --- --prevent-extra
$ pcsx2_branch: git -C <pcsx2_build_dir> fetch origin && { git -C <pcsx2_build_dir> branch --no-column --format '%(refname)' -a | sed '/HEAD detached at/d' | sed 's/^refs\/\(heads\|remotes\)\///g' | sort -n ; } || echo "master" --- --prevent-extra
$ pcsx2_pr: git -C <pcsx2_build_dir> ls-remote -q origin 'pull/*/head' 2>/dev/null | cut -f2 | sed -E 's/[^[:digit:]]*([[:digit:]]+)[^[:digit:]]+/pr\/\1/' | sort -rV --- --prevent-extra
# pcsx2 core
( \
cd "<pcsx2_build_dir>"/build; \
export CORE="$HOME/.config/retroarch/cores/pcsx2-aliaspider_libretro.so"; \
export CORE_ASSETS="$HOME/.config/retroarch/system/pcsx2"; \
git-branch-pull "<pcsx2_branch>" && gio trash -f "$CORE" && mv -fT ./bin/pcsx2_libretro.so "$CORE" && chmod -x "$CORE"; \
rsync -a --delete "<pcsx2_build_dir>"/bin/resources "$CORE_ASSETS"; \
printf "\a"; \
)
# pcsx2 core pull request
( \
cd "<pcsx2_build_dir>"/build; \
export CORE="$HOME/.config/retroarch/cores/pcsx2-aliaspider_libretro.so"; \
export CORE_ASSETS="$HOME/.config/retroarch/system/pcsx2"; \
PR="<pcsx2_pr>"; \
PR="${PR:3}"; \
git checkout master &>/dev/null; \
git branch -D "pr/$PR" &>/dev/null; \
git fetch origin "pull/$PR/head:pr/$PR" >/dev/null || { echo "failed fetching branch" >&2; printf "\a"; exit 1; }; \
git-branch-pull "pr/$PR" && gio trash -f "$CORE" && mv -fT ./bin/pcsx2_libretro.so "$CORE" && chmod -x "$CORE"; \
rsync -a --delete "<pcsx2_build_dir>"/bin/resources "$CORE_ASSETS"; \
printf "\a"; \
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment