Convenience script to build a Quicksilver plugin from CLI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
##### | |
# build-plugin.sh | |
# bash 3.2-compatible convenience script to: | |
# - search by partial name for a plugin in the `QSPLUGINS` subdirectory | |
# (default `./QSPlugins`) | |
# - clean plugin directory | |
# - clean QS directory | |
# - `rm -rf /tmp/QS` | |
# - build Quicksilver (loop until it succeeds) | |
# - build plugin | |
# Usage: build-plugin.sh partialpluginname [configuration] | |
# Arguments: | |
# - partialpluginname: case-insensitive, will fail on multiple matches | |
# Options: | |
# - configuration: Debug (default) or Release | |
##### | |
set -Eeuf -o pipefail | |
set -x | |
readonly QS_SOURCE_ROOT="${QS_SOURCE_ROOT:-"${HOME}"/git/quicksilver/Quicksilver}" | |
readonly QSPLUGINS="${QSPLUGINS:-./QSPlugins}" | |
log() { | |
echo "$*" > /dev/stderr | |
} | |
err() { | |
log "error: $*" | |
exit 1 | |
} | |
json() { | |
# Usage: stdin is json content, $1 is python-formatted query | |
# Example: `xcodebuild -list -json | json '["project"]["configurations"][0]'` | |
python3 -c ' | |
import json | |
import sys | |
stdin = sys.stdin.read() | |
content = json.loads(stdin) | |
json_keys = sys.argv[1] | |
output = eval(f"{content}{json_keys}") | |
# Strips quotes if there is a simple result | |
if isinstance(output, str): | |
print(output) | |
# Pretty-print arrays and dicts | |
else: | |
print(json.dumps(output, indent=4)) | |
' "$1" | |
} | |
build_quicksilver() { | |
local configuration | |
configuration=$1 | |
pushd "${QS_SOURCE_ROOT}" | |
open -g Quicksilver.xcodeproj | |
xcodebuild -quiet clean | |
while [[ ! -x "/tmp/QS/build/${configuration}/Quicksilver.app/Contents/MacOS/Quicksilver" ]]; do | |
xcodebuild \ | |
-quiet \ | |
-destination generic/platform=macos \ | |
-configuration "${configuration}" \ | |
-scheme 'Quicksilver Distribution' \ | |
build || true | |
done | |
popd | |
} | |
find_plugin() { | |
local plugin_name target_plugin | |
plugin_name=$1 | |
# Workaround for no mapfile in bash 3, preserving compatibility with /bin/bash | |
target_plugin=() | |
while read -r -d '' target; do | |
target_plugin+=("${target}") | |
done < <( | |
find "${QSPLUGINS}" \ | |
-maxdepth 1 \ | |
-mindepth 1 \ | |
-type d \ | |
-iname "*${plugin_name}*" \ | |
-print0 | |
) | |
if [[ "${#target_plugin[@]}" -ne 1 ]]; then | |
err "possible matches for plugin -- ${plugin_name} -- ${target_plugin[*]}" | |
fi | |
plugindir="${target_plugin[0]}" | |
echo "${plugindir}" | |
} | |
clean_plugin() { | |
local plugindir | |
plugindir=$1 | |
pushd "${plugindir}" | |
xcodebuild -quiet clean | |
} | |
build_plugin() { | |
local plugindir configuration | |
plugindir=$1 | |
configuration=$2 | |
project=$(find . -maxdepth 1 -name '*.xcodeproj' -not -iname "*test.xcodeproj" -print -quit) | |
if [[ -z "${project}" ]]; then | |
scheme_list=$(xcodebuild -list -json || true) | |
else | |
scheme_list=$(xcodebuild -list -json -project "${project}") | |
fi | |
if [[ -z "${scheme_list}" ]]; then | |
err "unable to determine scheme list" | |
fi | |
scheme=$(json '["project"]["targets"][0]' <<< "${scheme_list}") | |
log "Using default scheme: ${scheme}" | |
open -g "${project}" | |
# Absence of a project can still build, but will error if `-project` is specified | |
opts=(-configuration "${configuration}" -scheme "${scheme}") | |
if [[ -n "${project}" ]]; then | |
opts+=(-project "${project}") | |
fi | |
SETTINGS=$(xcodebuild "${opts[@]}" -showBuildSettings -json) | |
xcodebuild build -quiet "${opts[@]}" | |
FULL_PRODUCT_NAME=$(json '[0]["buildSettings"]["FULL_PRODUCT_NAME"]' <<< "${SETTINGS}") | |
log "Built ${FULL_PRODUCT_NAME} successfully" | |
} | |
main() { | |
local plugin configuration | |
plugin=$(find_plugin "$1") | |
configuration=${2-"Debug"} | |
# Sometimes still fails even with `-rf` | |
rm -rf /tmp/QS | |
clean_plugin "${plugin}" | |
build_quicksilver "${configuration}" | |
build_plugin "${plugin}" "${configuration}" | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment