Add configuration. See #5 #8.

What's new:
- --config flag to pass a INI config file to parse. See config.ini.
- Updated the modules scripts for configuration. Now needs to unset
  variables passed by CLI or config.
- Fix release directory that was added in love file (maybe).
- Properly escapes sed arguments.
- chmod +x to getopt.sh and read_ini.sh
- Fix #12
This commit is contained in:
Antonin Décimo
2014-08-22 14:07:44 +02:00
parent 83a5f111b7
commit 5bbf17401a
12 changed files with 502 additions and 18 deletions

View File

@@ -98,6 +98,9 @@ with eventual underscores (i.e. [a-zA-Z0-9\_]), otherwise you'll get errors.
#### OTHERS
`--clean` Clean the cache located in `~/.cache/love-release`.
One can replace the Love files there.
`--config` Pass a configuration file as argument.
It describes which build you want to make, with what options.
See `config.ini`.
#### MODULES
The script is modular.

63
config.ini Normal file
View File

@@ -0,0 +1,63 @@
; love-release config file
; Default values will be used if the option is left blank.
; To prevent a build from being executed, comment its section name and options.
[global]
; Directory where the zip archives will be stored
release_dir="releases"
; Love version to use
love_version="0.9.1"
; Project's name
project_name=""
[windows]
; Path to an .ico file to use
icon=""
[macosx]
; Set the maintainer's name. Provide it for CFBundleIdentifier.
; No spaces and no special characters except underscore. Better be lowercase.
maintainer_name=""
; Path to an .icns file to use
icon=""
[debian]
; Version of the package
package_version=""
; Maintainer name (full name)
maintainer_name=""
; Maintainer_email
maintainer_email=""
; Homepage
homepage=""
; Description
description=""
; Package name
; No spaces and no special characters except underscore. Better be lowercase.
package_name=""
[android]
; Android game activity
; No spaces and no special characters except underscore. Better be lowercase.
activity=""
; Package version
package_version=""
; Maintainer name
; No spaces and no special characters except underscore. Better be lowercase.
maintainer_name=""
; Package name
; No spaces and no special characters except underscore. Better be lowercase.
package_name=""

0
include/getopt.sh Normal file → Executable file
View File

280
include/read_ini.sh Executable file
View File

@@ -0,0 +1,280 @@
#
# Copyright (c) 2009 Kevin Porter / Advanced Web Construction Ltd
# (http://coding.tinternet.info, http://webutils.co.uk)
# Copyright (c) 2010-2012 Ruediger Meier <sweet_f_a@gmx.de>
# (https://github.com/rudimeier/)
#
# Simple INI file parser.
#
# See README for usage.
#
#
function read_ini()
{
# Be strict with the prefix, since it's going to be run through eval
function check_prefix()
{
if ! [[ "${VARNAME_PREFIX}" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] ;then
echo "read_ini: invalid prefix '${VARNAME_PREFIX}'" >&2
return 1
fi
}
function check_ini_file()
{
if [ ! -r "$INI_FILE" ] ;then
echo "read_ini: '${INI_FILE}' doesn't exist or not" \
"readable" >&2
return 1
fi
}
# enable some optional shell behavior (shopt)
function pollute_bash()
{
if ! shopt -q extglob ;then
SWITCH_SHOPT="${SWITCH_SHOPT} extglob"
fi
if ! shopt -q nocasematch ;then
SWITCH_SHOPT="${SWITCH_SHOPT} nocasematch"
fi
shopt -q -s ${SWITCH_SHOPT}
}
# unset all local functions and restore shopt settings before returning
# from read_ini()
function cleanup_bash()
{
shopt -q -u ${SWITCH_SHOPT}
unset -f check_prefix check_ini_file pollute_bash cleanup_bash
}
local INI_FILE=""
local INI_SECTION=""
# {{{ START Deal with command line args
# Set defaults
local BOOLEANS=1
local VARNAME_PREFIX=INI
local CLEAN_ENV=0
# {{{ START Options
# Available options:
# --boolean Whether to recognise special boolean values: ie for 'yes', 'true'
# and 'on' return 1; for 'no', 'false' and 'off' return 0. Quoted
# values will be left as strings
# Default: on
#
# --prefix=STRING String to begin all returned variables with (followed by '__').
# Default: INI
#
# First non-option arg is filename, second is section name
while [ $# -gt 0 ]
do
case $1 in
--clean | -c )
CLEAN_ENV=1
;;
--booleans | -b )
shift
BOOLEANS=$1
;;
--prefix | -p )
shift
VARNAME_PREFIX=$1
;;
* )
if [ -z "$INI_FILE" ]
then
INI_FILE=$1
else
if [ -z "$INI_SECTION" ]
then
INI_SECTION=$1
fi
fi
;;
esac
shift
done
if [ -z "$INI_FILE" ] && [ "${CLEAN_ENV}" = 0 ] ;then
echo -e "Usage: read_ini [-c] [-b 0| -b 1]] [-p PREFIX] FILE"\
"[SECTION]\n or read_ini -c [-p PREFIX]" >&2
cleanup_bash
return 1
fi
if ! check_prefix ;then
cleanup_bash
return 1
fi
local INI_ALL_VARNAME="${VARNAME_PREFIX}__ALL_VARS"
local INI_ALL_SECTION="${VARNAME_PREFIX}__ALL_SECTIONS"
local INI_NUMSECTIONS_VARNAME="${VARNAME_PREFIX}__NUMSECTIONS"
if [ "${CLEAN_ENV}" = 1 ] ;then
eval unset "\$${INI_ALL_VARNAME}"
fi
unset ${INI_ALL_VARNAME}
unset ${INI_ALL_SECTION}
unset ${INI_NUMSECTIONS_VARNAME}
if [ -z "$INI_FILE" ] ;then
cleanup_bash
return 0
fi
if ! check_ini_file ;then
cleanup_bash
return 1
fi
# Sanitise BOOLEANS - interpret "0" as 0, anything else as 1
if [ "$BOOLEANS" != "0" ]
then
BOOLEANS=1
fi
# }}} END Options
# }}} END Deal with command line args
local LINE_NUM=0
local SECTIONS_NUM=0
local SECTION=""
# IFS is used in "read" and we want to switch it within the loop
local IFS=$' \t\n'
local IFS_OLD="${IFS}"
# we need some optional shell behavior (shopt) but want to restore
# current settings before returning
local SWITCH_SHOPT=""
pollute_bash
while read -r line || [ -n "$line" ]
do
#echo line = "$line"
((LINE_NUM++))
# Skip blank lines and comments
if [ -z "$line" -o "${line:0:1}" = ";" -o "${line:0:1}" = "#" ]
then
continue
fi
# Section marker?
if [[ "${line}" =~ ^\[[a-zA-Z0-9_]{1,}\]$ ]]
then
# Set SECTION var to name of section (strip [ and ] from section marker)
SECTION="${line#[}"
SECTION="${SECTION%]}"
eval "${INI_ALL_SECTION}=\"\${${INI_ALL_SECTION}# } $SECTION\""
((SECTIONS_NUM++))
continue
fi
# Are we getting only a specific section? And are we currently in it?
if [ ! -z "$INI_SECTION" ]
then
if [ "$SECTION" != "$INI_SECTION" ]
then
continue
fi
fi
# Valid var/value line? (check for variable name and then '=')
if ! [[ "${line}" =~ ^[a-zA-Z0-9._]{1,}[[:space:]]*= ]]
then
echo "Error: Invalid line:" >&2
echo " ${LINE_NUM}: $line" >&2
cleanup_bash
return 1
fi
# split line at "=" sign
IFS="="
read -r VAR VAL <<< "${line}"
IFS="${IFS_OLD}"
# delete spaces around the equal sign (using extglob)
VAR="${VAR%%+([[:space:]])}"
VAL="${VAL##+([[:space:]])}"
VAR=$(echo $VAR)
# Construct variable name:
# ${VARNAME_PREFIX}__$SECTION__$VAR
# Or if not in a section:
# ${VARNAME_PREFIX}__$VAR
# In both cases, full stops ('.') are replaced with underscores ('_')
if [ -z "$SECTION" ]
then
VARNAME=${VARNAME_PREFIX}__${VAR//./_}
else
VARNAME=${VARNAME_PREFIX}__${SECTION}__${VAR//./_}
fi
eval "${INI_ALL_VARNAME}=\"\${${INI_ALL_VARNAME}# } ${VARNAME}\""
if [[ "${VAL}" =~ ^\".*\"$ ]]
then
# remove existing double quotes
VAL="${VAL##\"}"
VAL="${VAL%%\"}"
elif [[ "${VAL}" =~ ^\'.*\'$ ]]
then
# remove existing single quotes
VAL="${VAL##\'}"
VAL="${VAL%%\'}"
elif [ "$BOOLEANS" = 1 ]
then
# Value is not enclosed in quotes
# Booleans processing is switched on, check for special boolean
# values and convert
# here we compare case insensitive because
# "shopt nocasematch"
case "$VAL" in
yes | true | on )
VAL=1
;;
no | false | off )
VAL=0
;;
esac
fi
# enclose the value in single quotes and escape any
# single quotes and backslashes that may be in the value
VAL="${VAL//\\/\\\\}"
VAL="\$'${VAL//\'/\'}'"
eval "$VARNAME=$VAL"
done <"${INI_FILE}"
# return also the number of parsed sections
eval "$INI_NUMSECTIONS_VARNAME=$SECTIONS_NUM"
cleanup_bash
}

View File

@@ -11,20 +11,21 @@ BINARY_DIR=/usr/bin
INSTALL_DIR=/usr/share/love-release
MANPAGE_DIR=/usr/share/man/man1
SED_ARG=$(echo "$INSTALL_DIR" | sed -e 's/[\/&]/\\&/g')
mkdir -p "$BINARY_DIR"
cp ./love-release.sh "$BINARY_DIR"/love-release
SED_ARG=s/INSTALL_DIR=/INSTALL_DIR=${INSTALL_DIR//\//\\\/}/g
sed -i -e "$SED_ARG" "$BINARY_DIR"/love-release
sed -i -e "s/INSTALL_DIR=/INSTALL_DIR=$SED_ARG/g" "$BINARY_DIR"/love-release
mkdir -p "$INSTALL_DIR"
cp ./README.md "$INSTALL_DIR"
cp ./config.ini "$INSTALL_DIR"
cp -r ./scripts "$INSTALL_DIR"
cp -r ./include "$INSTALL_DIR"
mkdir -p "$MANPAGE_DIR"
cp love-release.1 "$MANPAGE_DIR"/love-release.1
sed -i -e "s/scripts/${INSTALL_DIR//\//\\\/}\/scripts/g" "$MANPAGE_DIR"/love-release.1
gzip -9 "$MANPAGE_DIR"/love-release.1
sed -i -e "s/scripts/$SED_ARG\/scripts/g" -e "s/config.ini/$SED_ARG\/config.ini/g" "$MANPAGE_DIR"/love-release.1
gzip -9 -f "$MANPAGE_DIR"/love-release.1
echo "Done !"

View File

@@ -131,6 +131,11 @@ Set the version of your package.
.B \-\-clean
Clean the cache located in \fI~/.cache/love-release\fR.
One can replace the Love files there.
.TP
.B \-\-config \fIfile\fR
Pass a configuration file as argument.
It describes which build you want to make, with what options.
See \fIconfig.ini\fR.
.SH MODULES
The script is modular.
Each different platform is handled by a subscript stored in \fIscripts\fR.

View File

@@ -78,8 +78,10 @@ LOVE_GT_090=$(float_test "$LOVE_VERSION_MAJOR >= 0.9")
# Global variables
ARGS=( "$@" )
SCRIPT_ARGS="$SCRIPT_ARGS h; n: r: v: clean help"
SCRIPT_ARGS="$SCRIPT_ARGS h; n: r: v: config: clean help"
SCRIPT_ARGS=$(printf '%s\n' $SCRIPT_ARGS | sort -u)
CONFIG=false
CONFIG_FILE=config.ini
PROJECT_FILES=
EXCLUDE_FILES=$(/bin/ls -A | grep "^[.]" | tr '\n' ' ')
@@ -106,10 +108,40 @@ Options:
$SHORT_HELP"
# Parsing options
# Read config
missing_operands=true
source "$INCLUDE_DIR"/getopt.sh
while getoptex "$SCRIPT_ARGS" "$@"
do
if [ "$OPTOPT" = "config" ]; then
source "$INCLUDE_DIR"/read_ini.sh
missing_operands=false
CONFIG_FILE=$OPTARG
read_ini "$CONFIG_FILE" || exit 1
CONFIG=true
SED_ARG=$(echo "$PLATFORMS_DIR" | sed -e 's/[\/&]/\\&/g')
PLATFORM_SCRIPTS=$(echo "${INI__ALL_SECTIONS}" | sed -r -e 's/[ ]*global[ ]*//g' -e "s/\<[^ ]+\>/$SED_ARG\/&.sh/g")
IFS=" " read -a PLATFORM_SCRIPTS <<< "$PLATFORM_SCRIPTS"
if [ -n "${INI__global__release_dir}" ]; then
RELEASE_DIR=${INI__global__release_dir}
fi
if [ -n "${INI__global__love_version}" ]; then
LOVE_VERSION=${INI__global__love_version}
LOVE_VERSION_MAJOR=$(echo "$LOVE_VERSION" | grep -Eo '^[0-9]+\.?[0-9]*')
LOVE_GT_080=$(float_test "$LOVE_VERSION_MAJOR >= 0.8")
LOVE_GT_090=$(float_test "$LOVE_VERSION_MAJOR >= 0.9")
fi
if [ -n "${INI__global__project_name}" ]; then
PROJECT_NAME=${INI__global__project_name}
fi
fi
done
unset OPTIND
unset OPTOFS
# Parsing options
while getoptex "$SCRIPT_ARGS" "$@"
do
if [ "$OPTOPT" = "h" ]; then
echo "$SHORT_HELP"
@@ -146,10 +178,15 @@ unset OPTOFS
## $1: Module name
init_module ()
{
GLOBAL_OPTIND=$OPTIND
GLOBAL_OPTOFS=$OPTOFS
unset OPTIND
unset OPTOFS
MAIN_RELEASE_DIR="${RELEASE_DIR##/*/}"
RELEASE_DIR="$RELEASE_DIR"/$LOVE_VERSION
if [ -z "$MAIN_RELEASE_DIR" ]; then
MAIN_RELEASE_DIR=$(cd "$(dirname "$RELEASE_DIR")" && pwd)/$(basename "$RELEASE_DIR")
RELEASE_DIR="$MAIN_RELEASE_DIR"/$LOVE_VERSION
fi
missing_operands=false
CACHE_DIR="$MAIN_CACHE_DIR"/$LOVE_VERSION
mkdir -p "$RELEASE_DIR" "$CACHE_DIR"
rm -rf "$RELEASE_DIR"/"$PROJECT_NAME".love 2> /dev/null
@@ -162,9 +199,9 @@ create_love_file ()
cd "$PROJECT_DIR"
rm -rf "$RELEASE_DIR"/"$PROJECT_NAME".love 2> /dev/null
if [ -z "$PROJECT_FILES" ]; then
zip --filesync -$1 -r "$RELEASE_DIR"/"$PROJECT_NAME".love -x "$0" "$MAIN_RELEASE_DIR"/\* $EXCLUDE_FILES @ *
zip --filesync -$1 -r "$RELEASE_DIR"/"$PROJECT_NAME".love -x "$0" "${MAIN_RELEASE_DIR#$PWD/}/*" "$CONFIG_FILE" $EXCLUDE_FILES @ *
else
zip --filesync -$1 -r "$RELEASE_DIR"/"$PROJECT_NAME".love -x "$0" "$MAIN_RELEASE_DIR"/\* $EXCLUDE_FILES @ $PROJECT_FILES
zip --filesync -$1 -r "$RELEASE_DIR"/"$PROJECT_NAME".love -x "$0" "${MAIN_RELEASE_DIR#$PWD/}/*" "$CONFIG_FILE" $EXCLUDE_FILES @ $PROJECT_FILES
fi
cd "$RELEASE_DIR"
LOVE_FILE="$PROJECT_NAME".love
@@ -175,13 +212,23 @@ create_love_file ()
exit_module ()
{
if [ -z "$1" ] || [ "$1" = "0" ]; then
OPTIND=$GLOBAL_OPTIND
OPTOFS=$GLOBAL_OPTOFS
echo "Done !"
else
echo -e "$2"
exit $1
fi
exit $1
}
if [ "$CONFIG" = true ]; then
for script in "${PLATFORM_SCRIPTS[@]}"
do
source "$script"
done
exit
fi
# Platform-specific scripts registration

View File

@@ -2,6 +2,23 @@
init_module "Android"
# Configuration
if [ "$CONFIG" = true ]; then
if [ -n "${INI__android__activity}" ]; then
ACTIVITY=${INI__android__activity}
fi
if [ -n "${INI__android__package_name}" ]; then
PACKAGE_NAME=${INI__android__package_name}
fi
if [ -n "${INI__android__package_version}" ]; then
PACKAGE_VERSION=${INI__android__package_version}
fi
if [ -n "${INI__android__maintainer_name}" ]; then
MAINTAINER_NAME=${INI__android__maintainer_name}
fi
fi
# Options
activity_defined_argument=false
package_name_defined_argument=false
@@ -104,5 +121,6 @@ else
fi
unset ACTIVITY PACKAGE_NAME PACKAGE_VERSION MAINTAINER_NAME
exit_module

View File

@@ -1,6 +1,28 @@
# Debian package
init_module "Debian"
# Configuration
if [ "$CONFIG" = true ]; then
if [ -n "${INI__debian__package_version}" ]; then
PACKAGE_VERSION=${INI__debian__package_version}
fi
if [ -n "${INI__debian__homepage}" ]; then
PROJECT_HOMEPAGE=${INI__debian__homepage}
fi
if [ -n "${INI__debian__description}" ]; then
PROJECT_DESCRIPTION=${INI__debian__description}
fi
if [ -n "${INI__debian__maintainer_name}" ]; then
MAINTAINER_NAME=${INI__debian__maintainer_name}
fi
if [ -n "${INI__debian__maintainer_email}" ]; then
MAINTAINER_EMAIL=${INI__debian__maintainer_email}
fi
if [ -n "${INI__android__package_name}" ]; then
PACKAGE_NAME=${INI__debian__package_name}
fi
fi
# Options
package_name_defined_argument=false
@@ -111,5 +133,6 @@ cd "$RELEASE_DIR"
rm -rf $TEMP
unset PROJECT_DESCRIPTION PROJECT_HOMEPAGE MAINTAINER_NAME MAINTAINER_EMAIL PACKAGE_NAME PACKAGE_VERSION
exit_module

View File

@@ -12,6 +12,8 @@
# To create a new module, you have to create a file in this directory,
# and to edit the main love-release script.
# If you wish to submit a new module, please also edit README.md and love-release.1
# You could add configuration options in config.ini too,
# but the name of the section must be the same as the name of the script.
# Love-release script
@@ -31,7 +33,7 @@ SHORT_HELP=" -q Create an Example application"
while getoptex "$SCRIPT_ARGS" "$@"
do
if [ "$OPTOPT" = "q" ]; then
source "$PLATFORMS_DIR"/love.sh
source "$PLATFORMS_DIR"/example.sh
fi
done
@@ -52,7 +54,21 @@ done
### $1: Module name
init_module "Example"
## 2. Parse the options
## 2. Read the configuration
# Syntax is ${INI__section__variable}
if [ "$CONFIG" = true ]; then
if [ -n "${INI__q__wer}" ]; then
WER=${INI__q__wer}
fi
if [ -n "${INI__q__ty}" ]; then
TY=${INI_q_ty}
fi
if [ -n "${INI__q__uiop}" ]; then
UIOP=true
fi
fi
## 3. Parse the options
# $OPTOPT holds the option and $OPTARG holds the eventual argument passed to it.
while getoptex "$SCRIPT_ARGS" "$@"
do
@@ -65,13 +81,18 @@ do
fi
done
## 3. Create the love file
## 4. Create the love file
### $1: Compression level 0-9
create_love_file 9
## 4. Write your code
## 5. Exit the module
## 5. Write your code
## 6. Unset every variable passed by configuration or command-line
unset WER TY UIOP
## 7. Exit the module
### $1: exit code. 0 - success, other - failure
### $2: error message
exit_module

View File

@@ -2,6 +2,17 @@
init_module "Mac OS X"
# Configuration
if [ "$CONFIG" = true ]; then
if [ -n "${INI__macosx__maintainer_name}" ]; then
MAINTAINER_NAME=${INI__macosx__maintainer_name}
fi
if [ -n "${INI__macosx__icon}" ]; then
PROJECT_ICNS=${INI__macosx__icon}
fi
fi
# Options
while getoptex "$SCRIPT_ARGS" "$@"
do
@@ -137,5 +148,6 @@ else
fi
unset PROJECT_ICNS
exit_module

View File

@@ -2,6 +2,16 @@
init_module "Windows"
# Configuration
if [ "$CONFIG" = true ]; then
RELEASE_WIN_32=true
RELEASE_WIN_64=true
if [ -n "${INI__windows__icon}" ]; then
PROJECT_ICO=${INI__windows__icon}
fi
fi
# Options
while getoptex "$SCRIPT_ARGS" "$@"
do
@@ -80,10 +90,10 @@ if [ "$RELEASE_WIN_64" = true ] && [ "$LOVE_GT_080" = true ]; then
cp "$CACHE_DIR"/love-$LOVE_VERSION-win-x64.zip ./love-$LOVE_VERSION-win64.zip
fi
fi
unzip -qq love-$LOVE_VERSION-win64.zip
rm -rf "$PROJECT_NAME"-win64.zip 2> /dev/null
if [ "$FOUND_WINE" = true ] && [ -n "$PROJECT_ICO" ]; then
WINEPREFIX="$WINEPREFIX" wine "$RESHACKER" -addoverwrite "love-$LOVE_VERSION-win32/love.exe,love-$LOVE_VERSION-win32/love.exe,"$PROJECT_ICO",ICONGROUP,MAINICON,0" 2> /dev/null
fi
@@ -95,5 +105,6 @@ if [ "$RELEASE_WIN_64" = true ] && [ "$LOVE_GT_080" = true ]; then
fi
unset PROJECT_ICO
exit_module