From 6302efed97b87adf60148b5bc3c5f2ce01c59fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonin=20D=C3=A9cimo?= Date: Thu, 18 Jun 2015 10:31:08 +0200 Subject: [PATCH] Options & file args support with GNU getopt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Short options are stored in the OPTIONS variable, and longs in LONG_OPTIONS. Modules scripts need to add theses to be able to use options. Theses lines are then parsed by sed at make-time and added to the corresponding variable in the main script. init_module now requires a third argument corresponding to the option that will trigger the execution of the module. Files can also be passed by argument to zip. They are stored in the FILES array. check_deps: - add dependency check for GNU getopt, - echo errors to stderr gen_version now returns 0 on success and 1 on failure. Add short_help function. Shown if -h options is passed, or on parsing options failure. exit_module: - add 'options' exit value if there is an error while parsing the options, - add 'version' exit value if there is an error while generating LÖVE version from user input. dump_var shows files to zip. Script will now exit if it has not been embedded nor installed. Fix bugs with default module. --- Makefile | 21 +++++++-- love-release.sh | 115 ++++++++++++++++++++++++++++++++++++--------- scripts/android.sh | 4 +- scripts/debian.sh | 4 +- scripts/macosx.sh | 4 +- scripts/windows.sh | 4 +- 6 files changed, 121 insertions(+), 31 deletions(-) diff --git a/Makefile b/Makefile index cb79829..45e5406 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,14 @@ SED_INSTALL_DIR=$(shell echo "$(INSTALL_DIR)" | sed -e 's/[\/&]/\\&/g') love-release: clean mkdir -p $(BUILD_DIR) - sed -e 's/INSTALLED=false/INSTALLED=true/' -e 's/SCRIPTS_DIR="scripts"/SCRIPTS_DIR="$(SED_INSTALL_DIR)\/scripts"/' love-release.sh > '$(BUILD_DIR)/love-release' + for file in scripts/*.sh; do \ + short="$${short}$$(grep -E -m 1 "^OPTIONS=['\"]?.*['\"]?" "$$file" | sed -r -e "s/OPTIONS=['\"]?//" -e "s/['\"]?$$//")"; \ + long="$${long}$$(grep -E -m 1 "^LONG_OPTIONS=['\"]?.*['\"]?" "$$file" | sed -r -e "s/LONG_OPTIONS=['\"]?//" -e "s/['\"]?$$//")"; \ + done; \ + if [[ -n $$long && $${long: -1} != ',' ]]; then long="$${long},"; fi; \ + sed -re "s/^OPTIONS=(['\"]?)/OPTIONS=\1$$short/" -e "s/^LONG_OPTIONS=(['\"]?)/LONG_OPTIONS=\1$$long/" \ + -e 's/INSTALLED=false/INSTALLED=true/' \ + -e 's/SCRIPTS_DIR="scripts"/SCRIPTS_DIR="$(SED_INSTALL_DIR)\/scripts"/' love-release.sh > '$(BUILD_DIR)/love-release' cp love-release.1 '$(BUILD_DIR)/love-release.1' gzip '$(BUILD_DIR)/love-release.1' @@ -25,15 +32,19 @@ install: embedded: clean mkdir -p '$(BUILD_DIR)' - sed 's/EMBEDDED=false/EMBEDDED=true/' love-release.sh > '$(BUILD_DIR)/love-release.sh' for file in scripts/*.sh; do \ module="$$(basename -s '.sh' "$$file")"; \ content='(source <(cat <<\EndOfModule'$$'\n'"$$(cat $$file)"$$'\n''EndOfModule'$$'\n''))'$$'\n''default_module'$$'\n\n'; \ echo "$$content" >> "$(BUILD_DIR)/tmp"; \ - done - sed -i.bak -e '/include_scripts_here$$/r $(BUILD_DIR)/tmp' '$(BUILD_DIR)/love-release.sh'; + short="$${short}$$(grep -E -m 1 "^OPTIONS=['\"]?.*['\"]?" "$$file" | sed -r -e "s/OPTIONS=['\"]?//" -e "s/['\"]?$$//")"; \ + long="$${long}$$(grep -E -m 1 "^LONG_OPTIONS=['\"]?.*['\"]?" "$$file" | sed -r -e "s/LONG_OPTIONS=['\"]?//" -e "s/['\"]?$$//")"; \ + done; \ + if [[ -n $$long && $${long: -1} != ',' ]]; then long="$${long},"; fi; \ + sed -re "s/^OPTIONS=(['\"]?)/OPTIONS=\1$$short/" -e "s/^LONG_OPTIONS=(['\"]?)/LONG_OPTIONS=\1$$long/" \ + -e 's/EMBEDDED=false/EMBEDDED=true/' \ + -e '/include_scripts_here$$/r $(BUILD_DIR)/tmp' love-release.sh > '$(BUILD_DIR)/love-release' chmod 0775 '$(BUILD_DIR)/love-release.sh' - rm -rf '$(BUILD_DIR)/love-release.sh.bak' '$(BUILD_DIR)/tmp' + rm -rf '$(BUILD_DIR)/tmp' remove: rm -rf '$(BINARY_DIR)/love-release' diff --git a/love-release.sh b/love-release.sh index 7c9d9cd..2ba5444 100755 --- a/love-release.sh +++ b/love-release.sh @@ -10,17 +10,31 @@ LOVE_DEF_VERSION=0.9.2 # Dependencies check check_deps () { command -v curl > /dev/null 2>&1 || { - echo "curl is not installed. Aborting." + >&2 echo "curl is not installed. Aborting." local EXIT=true } command -v zip > /dev/null 2>&1 || { - echo "zip is not installed. Aborting." + >&2 echo "zip is not installed. Aborting." local EXIT=true } command -v unzip > /dev/null 2>&1 || { - echo "unzip is not installed. Aborting." + >&2 echo "unzip is not installed. Aborting." local EXIT=true } + command -v getopt > /dev/null 2>&1 || { + local opt=false + } && { + unset GETOPT_COMPATIBLE + local out=$(getopt -T) + if [[ $? -eq 4 && -z $out ]]; then + local opt=false + fi + } + if [[ $opt == false ]]; then + >&2 echo "GNU getopt is not installed. Aborting." + local EXIT=true + fi + command -v lua > /dev/null 2>&1 || { echo "lua is not installed. Install it to ease your releases." } && { @@ -58,13 +72,16 @@ get_user_confirmation () { # Generate LÖVE version variables ## $1: LÖVE version string +## return: 0 - string matched, 1 - else gen_version () { if [[ $1 =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then LOVE_VERSION=$1 LOVE_VERSION_MAJOR=${BASH_REMATCH[1]} LOVE_VERSION_MINOR=${BASH_REMATCH[2]} LOVE_VERSION_REVISION=${BASH_REMATCH[3]} + return 0 fi + return 1 } @@ -175,7 +192,7 @@ end if os == "default" then if not t.os then t.os = {} end if not t.os.love then t.os.love = {} end - os = "love" + t.os.default = t.os.love end if t.os[os] then @@ -220,6 +237,18 @@ default_module () { fi } +# Print short help +short_help () { + cat < Set the project's name + -r Set the release directory + -v Set the LÖVE version +EOF +} + dump_var () { echo "LOVE_VERSION=$LOVE_VERSION" echo "LOVE_DEF_VERSION=$LOVE_DEF_VERSION" @@ -237,6 +266,8 @@ dump_var () { echo "EMAIL=$EMAIL" echo "URL=$URL" echo "DESCRIPTION=$DESCRIPTION" + echo + echo "${FILES[@]}" } @@ -245,24 +276,38 @@ dump_var () { # Init module ## $1: Pretty module name ## $2: Configuration module name +## $3: Module option ## return: 0 - if module should be executed, else exit 2 init_module () { + ( + opt="$3" + if (( ${#opt} == 1 )); then opt="-$opt" + elif (( ${#opt} >= 2 )); then opt="--$opt"; fi + eval set -- "$ARGS" + while true; do + case "$1" in + $opt ) exit 0 ;; + -- ) exit 1 ;; + * ) shift ;; + esac + done + ) + local opt=$? local module="$2" read_config "$module" module=${module^^} - if [[ ${!module} == true ]]; then - if compare_version "$LOVE_VERSION" ">" "$VERSION"; then - echo "LÖVE $LOVE_VERSION is out ! Your project uses LÖVE ${VERSION}." - gen_version $VERSION - unset VERSION - fi - MODULE="$1" - mkdir -p "$RELEASE_DIR" "$CACHE_DIR" - echo "Generating $TITLE with LÖVE $LOVE_VERSION for ${MODULE}..." - return 0 - else - exit_module "execute" + if (( $opt == 1 )); then + if [[ ${!module} == false ]]; then exit_module "execute"; fi fi + if compare_version "$LOVE_VERSION" ">" "$VERSION"; then + echo "LÖVE $LOVE_VERSION is out ! Your project uses LÖVE ${VERSION}." + gen_version $VERSION + unset VERSION + fi + MODULE="$1" + mkdir -p "$RELEASE_DIR" "$CACHE_DIR" + echo "Generating $TITLE with LÖVE $LOVE_VERSION for ${MODULE}..." + return 0 } # Create the LÖVE file @@ -272,7 +317,7 @@ create_love_file () { zip -FS -$1 -r "$LOVE_FILE" \ -x "$0" "${RELEASE_DIR#$PWD/}/*" \ $(ls -Ap | grep "^\." | sed -e 's/^/\//g' -e 's/\/$/\/*/g') @ \ - . + "${FILES[@]}" } # Exit module @@ -289,6 +334,11 @@ exit_module () { binary ) >&2 echo "LÖVE $LOVE_VERSION could not be found or downloaded." exit 3 ;; + options ) + exit 4 ;; + version ) + >&2 echo "LÖVE version string is invalid." + exit 5 ;; undef|* ) if [[ -n $2 ]]; then >&2 echo "$2" @@ -316,10 +366,32 @@ DEFAULT_MODULE=true TITLE="$(basename $(pwd))" RELEASE_DIR=releases CACHE_DIR=~/.cache/love-release +FILES=() + +OPTIONS="lhn:r:v:" +LONG_OPTIONS="" +ARGS=$(getopt -o "$OPTIONS" -l "$LONG_OPTIONS" -n 'love-release' -- "$@") +if (( $? != 0 )); then short_help; exit_module "options"; fi +eval set -- "$ARGS" + +while true; do + case "$1" in + -n ) TITLE="$2"; shift 2 ;; + -r ) RELEASE_DIR="$2"; shift 2 ;; + -v ) if ! gen_version "$2"; then exit_module "version"; fi; shift 2 ;; + -h ) short_help; exit 0 ;; + -- ) shift; break ;; + * ) shift ;; + esac +done + +for arg do + FILES+=( "$arg" ) +done +if (( ${#FILES} == 0 )); then FILES+=( "." ); fi if [[ $INSTALLED == false && $EMBEDDED == false ]]; then - >&2 echo "love-release has not been installed, and is not embedded into one script. Consider doing one of the two." - INSTALLED=true + exit_module "undef" "love-release has not been installed, and is not embedded into one script." fi if [[ $EMBEDDED == true ]]; then @@ -334,10 +406,9 @@ fi ( - (init_module "LÖVE" "love") + (init_module "LÖVE" "love" "l") if [[ $? -eq 0 || $DEFAULT_MODULE == true ]]; then - read_config "default" - init_module "LÖVE" + init_module "LÖVE" "default" create_love_file 9 exit_module fi diff --git a/scripts/android.sh b/scripts/android.sh index cb78fa4..4930136 100644 --- a/scripts/android.sh +++ b/scripts/android.sh @@ -1,5 +1,7 @@ # Android debug package -init_module "Android" "android" +init_module "Android" "android" "a" +OPTIONS="a" +LONG_OPTIONS="" PACKAGE_NAME=$(echo $PROJECT_NAME | sed -e 's/[^-a-zA-Z0-9_]/-/g' | tr '[:upper:]' '[:lower:]') diff --git a/scripts/debian.sh b/scripts/debian.sh index 93958df..546a514 100644 --- a/scripts/debian.sh +++ b/scripts/debian.sh @@ -1,5 +1,7 @@ # Debian package -init_module "Debian" "debian" +init_module "Debian" "debian" "d" +OPTIONS="d" +LONG_OPTIONS="" PACKAGE_NAME=$(echo $PROJECT_NAME | sed -e 's/[^-a-zA-Z0-9_]/-/g' | tr '[:upper:]' '[:lower:]') diff --git a/scripts/macosx.sh b/scripts/macosx.sh index 6991eaa..9021b20 100644 --- a/scripts/macosx.sh +++ b/scripts/macosx.sh @@ -1,5 +1,7 @@ # Mac OS X -init_module "Mac OS X" "osx" +init_module "Mac OS X" "osx" "m" +OPTIONS="m" +LONG_OPTIONS="" PACKAGE_NAME=$(echo $PROJECT_NAME | sed -e 's/[^-a-zA-Z0-9_]/-/g' | tr '[:upper:]' '[:lower:]') diff --git a/scripts/windows.sh b/scripts/windows.sh index bfe690b..d6e8426 100644 --- a/scripts/windows.sh +++ b/scripts/windows.sh @@ -1,5 +1,7 @@ # Windows -init_module "Windows" "windows" +init_module "Windows" "windows" "w" +OPTIONS="w" +LONG_OPTIONS="" PACKAGE_NAME=$(echo $PROJECT_NAME | sed -e 's/[^-a-zA-Z0-9_]/-/g' | tr '[:upper:]' '[:lower:]')