|
@@ -22,7 +22,7 @@
|
|
|
set -u
|
|
|
|
|
|
PROGRAM="factorio_development.sh"
|
|
|
VERSION="0.0.3"
|
|
|
VERSION="0.0.4"
|
|
|
|
|
|
function usage() {
|
|
|
cat <<EOF
|
|
@@ -33,6 +33,7 @@ Usage:
|
|
|
$PROGRAM [OPTIONS] init MOD_DIRECTORY_PATH
|
|
|
$PROGRAM [OPTIONS] build [MOD_DIRECTORY_PATH]
|
|
|
$PROGRAM [OPTIONS] release [MOD_DIRECTORY_PATH]
|
|
|
$PROGRAM [OPTIONS] abort-release [MOD_DIRECTORY_PATH]
|
|
|
|
|
|
EOF
|
|
|
}
|
|
@@ -154,6 +155,26 @@ release MOD_VERSION [MOD_DIRECTORY_PATH]
|
|
|
default "1.0.0".
|
|
|
|
|
|
|
|
|
abort-release [MOD_DIRECTORY_PATH]
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
MOD_DIRECTORY_PATH (path to base directory)
|
|
|
|
|
|
Aborts release process (started with the release command) for a
|
|
|
mod. Expects (optional) path to mod base directory. Default is to
|
|
|
use working directory as mod directory path.
|
|
|
|
|
|
Must be run from a release branch.
|
|
|
|
|
|
Aborting the release will:
|
|
|
|
|
|
- Undo all current changes to git-managed files.
|
|
|
- Drop version tag associated with the release branch.
|
|
|
- Switch back to main branch.
|
|
|
- Drop the release branch.
|
|
|
|
|
|
|
|
|
$PROGRAM accepts the following options:
|
|
|
|
|
|
-q
|
|
@@ -194,6 +215,220 @@ EOF
|
|
|
}
|
|
|
|
|
|
|
|
|
# Utilities
|
|
|
# =========
|
|
|
|
|
|
#
|
|
|
# Finds the source directory under the passed-in base directory.
|
|
|
#
|
|
|
# Arguments:
|
|
|
#
|
|
|
# $1 (base_dir)
|
|
|
# Base mod directory.
|
|
|
#
|
|
|
# Outputs:
|
|
|
#
|
|
|
# Path to mod sources directory.
|
|
|
#
|
|
|
# Returns:
|
|
|
#
|
|
|
# 0 on success, 1 otherwise.
|
|
|
#
|
|
|
function get_source_directory() {
|
|
|
local base_dir="$1"
|
|
|
|
|
|
local source_dir
|
|
|
|
|
|
if [[ -d $base_dir/src ]]; then
|
|
|
source_dir="src"
|
|
|
else
|
|
|
source_dir="."
|
|
|
fi
|
|
|
|
|
|
if [[ ! -d $source_dir ]]; then
|
|
|
error "Could not locate source directory."
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
echo "$source_dir"
|
|
|
return 0
|
|
|
}
|
|
|
|
|
|
|
|
|
#
|
|
|
# Finds the info file under the passed-in base directory.
|
|
|
#
|
|
|
# Arguments:
|
|
|
#
|
|
|
# $1 (base_dir)
|
|
|
# Base mod directory.
|
|
|
#
|
|
|
# Outputs:
|
|
|
#
|
|
|
# Path to info file.
|
|
|
#
|
|
|
# Returns:
|
|
|
#
|
|
|
# 0 on success, 1 otherwise.
|
|
|
#
|
|
|
function get_info_file() {
|
|
|
local base_dir="$1"
|
|
|
|
|
|
local info_file
|
|
|
|
|
|
if [[ -d $base_dir/src ]]; then
|
|
|
info_file="$base_dir/src/info.json"
|
|
|
else
|
|
|
info_file="$base_dir/info.json"
|
|
|
fi
|
|
|
|
|
|
if [[ ! -f $info_file ]]; then
|
|
|
error "Could not locate info file under: $info_file"
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
echo "$info_file"
|
|
|
return 0
|
|
|
}
|
|
|
|
|
|
|
|
|
#
|
|
|
# Finds the changelog file under the passed-in base directory.
|
|
|
#
|
|
|
# Arguments:
|
|
|
#
|
|
|
# $1 (base_dir)
|
|
|
# Base mod directory.
|
|
|
#
|
|
|
# Outputs:
|
|
|
#
|
|
|
# Path to changelog file.
|
|
|
#
|
|
|
# Returns:
|
|
|
#
|
|
|
# 0 on success, 1 otherwise.
|
|
|
#
|
|
|
function get_changelog_file() {
|
|
|
local base_dir="$1"
|
|
|
|
|
|
local changelog_file
|
|
|
|
|
|
if [[ -d $base_dir/src ]]; then
|
|
|
changelog_file="$base_dir/src/changelog.txt"
|
|
|
else
|
|
|
changelog_file="$base_dir/changelog.txt"
|
|
|
fi
|
|
|
|
|
|
if [[ ! -f $changelog_file ]]; then
|
|
|
error "Could not locate changelog file under: $changelog_file"
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
echo "$changelog_file"
|
|
|
return 0
|
|
|
}
|
|
|
|
|
|
|
|
|
#
|
|
|
# Loads build configuration from the passed-in base directory.
|
|
|
#
|
|
|
# Arguments:
|
|
|
#
|
|
|
# $1 (base_dir)
|
|
|
# Base mod directory.
|
|
|
#
|
|
|
# Returns:
|
|
|
#
|
|
|
# 0 on success, 1 otherwise.
|
|
|
#
|
|
|
function load_build_configuration() {
|
|
|
build_config="$base_dir/build.cfg"
|
|
|
|
|
|
# Set default values to ensure they are set.
|
|
|
declare -g IGNORE_PATHS=()
|
|
|
declare -g GIT_VERSION_TAG_PREFIX=""
|
|
|
|
|
|
# Read build configuration.
|
|
|
# shellcheck disable=SC1090 # build configuration file is create per-mod directory
|
|
|
if [[ -f $build_config ]] && ! source "$build_config"; then
|
|
|
error "Failed to load build configuration from: $build_config"
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
return 0
|
|
|
}
|
|
|
|
|
|
|
|
|
#
|
|
|
# Determines the main branch name (should be master/main/devel).
|
|
|
#
|
|
|
#
|
|
|
# Arguments:
|
|
|
#
|
|
|
# $1 (base_dir)
|
|
|
# Mod base directory.
|
|
|
#
|
|
|
# Outputs:
|
|
|
#
|
|
|
# Branch name.
|
|
|
#
|
|
|
# Returns:
|
|
|
#
|
|
|
# 0 on success, 1 otherwise.
|
|
|
#
|
|
|
function get_main_branch() {
|
|
|
local base_dir="$1"
|
|
|
|
|
|
local candidates=(
|
|
|
"master"
|
|
|
"main"
|
|
|
"devel"
|
|
|
)
|
|
|
|
|
|
local candidate
|
|
|
|
|
|
for candidate in "${candidates[@]}"; do
|
|
|
if git -C "$base_dir" rev-parse --abbrev-ref "$candidate" >/dev/null 2>&1; then
|
|
|
echo "$candidate"
|
|
|
return 0
|
|
|
fi
|
|
|
done
|
|
|
|
|
|
error "Could not determine main branch."
|
|
|
|
|
|
return 1
|
|
|
}
|
|
|
|
|
|
|
|
|
#
|
|
|
# Determines the current branch name.
|
|
|
#
|
|
|
#
|
|
|
# Arguments:
|
|
|
#
|
|
|
# $1 (base_dir)
|
|
|
# Mod base directory.
|
|
|
#
|
|
|
# Outputs:
|
|
|
#
|
|
|
# Branch name.
|
|
|
#
|
|
|
# Returns:
|
|
|
#
|
|
|
# 0 on success, 1 otherwise.
|
|
|
#
|
|
|
function get_current_branch() {
|
|
|
local base_dir="$1"
|
|
|
|
|
|
if ! git -C "$base_dir" rev-parse --abbrev-ref "HEAD"; then
|
|
|
error "Could not determine current branch name."
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
return 0
|
|
|
}
|
|
|
|
|
|
|
|
|
# Commands
|
|
|
# ========
|
|
|
|
|
@@ -307,7 +542,7 @@ EOF
|
|
|
# -*- mode: sh-mode; sh-shell: bash -*-
|
|
|
|
|
|
# Specify list of paths to exclude from the built release archives.
|
|
|
ignore_paths=(
|
|
|
IGNORE_PATHS=(
|
|
|
".gitignore"
|
|
|
"build.cfg"
|
|
|
)
|
|
@@ -315,7 +550,7 @@ ignore_paths=(
|
|
|
# Specify prefix to use in front of versions when tagging releases
|
|
|
# (for example if tags should be of format vX.Y.Z as opposed to
|
|
|
# X.Y.Z).
|
|
|
git_version_tag_prefix=""
|
|
|
GIT_VERSION_TAG_PREFIX=""
|
|
|
EOF
|
|
|
|
|
|
cat <<EOF > "$base_dir/.gitignore"
|
|
@@ -380,7 +615,6 @@ function command_build() {
|
|
|
|
|
|
local error_count=0
|
|
|
|
|
|
declare -a ignore_paths
|
|
|
declare -a mod_files
|
|
|
|
|
|
local source_dir dist_dir build_dir info_file target_dir archive_file build_config
|
|
@@ -391,27 +625,11 @@ function command_build() {
|
|
|
base_dir=$(readlink -f "$base_dir")
|
|
|
build_dir="$base_dir/build"
|
|
|
dist_dir="$base_dir/dist"
|
|
|
build_config="$base_dir/build.cfg"
|
|
|
|
|
|
# Read build configuration.
|
|
|
# shellcheck disable=SC1090 # build configuration file is create per-mod directory
|
|
|
if [[ -f $build_config ]] && ! source "$build_config"; then
|
|
|
error "Failed to load build configuration from: $build_config"
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
if [[ -d $base_dir/src ]]; then
|
|
|
source_dir="src"
|
|
|
info_file="$base_dir/src/info.json"
|
|
|
else
|
|
|
source_dir="."
|
|
|
info_file="$base_dir/info.json"
|
|
|
fi
|
|
|
load_build_configuration "$base_dir" || return 1
|
|
|
|
|
|
if [[ ! -f $info_file ]]; then
|
|
|
error "Could not locate info file under: $info_file"
|
|
|
return 1
|
|
|
fi
|
|
|
source_dir=$(get_source_directory "$base_dir") || return 1
|
|
|
info_file=$(get_info_file "$base_dir") || return 1
|
|
|
|
|
|
# Extract modpack name and version
|
|
|
if ! jq . "$info_file" > /dev/null; then
|
|
@@ -434,7 +652,8 @@ function command_build() {
|
|
|
# build.
|
|
|
readarray -t mod_files < <(git -C "$base_dir" ls-files)
|
|
|
|
|
|
for path in "${ignore_paths[@]}"; do
|
|
|
# IGNORE_PATHS comes from build configuration.
|
|
|
for path in "${IGNORE_PATHS[@]}"; do
|
|
|
for i in "${!mod_files[@]}"; do
|
|
|
if [[ -d $path && ${mod_files[i]} == $path/* ]] || [[ ${mod_files[i]} == "$path" ]]; then
|
|
|
unset "mod_files[i]"
|
|
@@ -530,11 +749,8 @@ function command_release() {
|
|
|
local version="$1"
|
|
|
local base_dir="$2"
|
|
|
|
|
|
# Prefix can be overridden via build configuration file.
|
|
|
local git_version_tag_prefix=""
|
|
|
|
|
|
local info_file changelog_file build_config
|
|
|
local current_branch release_branch
|
|
|
local main_branch current_branch release_branch
|
|
|
|
|
|
build_config="$base_dir/build.cfg"
|
|
|
|
|
@@ -548,26 +764,14 @@ function command_release() {
|
|
|
current_branch=$(git -C "$base_dir" rev-parse --abbrev-ref HEAD)
|
|
|
release_branch="release-${version}"
|
|
|
|
|
|
if [[ -d $base_dir/src ]]; then
|
|
|
info_file="$base_dir/src/info.json"
|
|
|
changelog_file="$base_dir/src/changelog.txt"
|
|
|
else
|
|
|
info_file="$base_dir/info.json"
|
|
|
changelog_file="$base_dir/changelog.txt"
|
|
|
fi
|
|
|
|
|
|
if [[ ! -f $info_file ]]; then
|
|
|
error "Could not locate info file under: $info_file"
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
if [[ ! -f $changelog_file ]]; then
|
|
|
error "Could not locate changelog file under: $changelog_file"
|
|
|
return 1
|
|
|
fi
|
|
|
source_dir=$(get_source_directory "$base_dir") || return 1
|
|
|
info_file=$(get_info_file "$base_dir") || return 1
|
|
|
changelog_file=$(get_changelog_file "$base_dir") || return 1
|
|
|
current_branch=$(get_current_branch "$base_dir") || return 1
|
|
|
main_branch=$(get_main_branch "$base_dir") || return 1
|
|
|
|
|
|
if [[ $current_branch != master && $current_branch != main && $current_branch != devel ]]; then
|
|
|
error "Releases must be based off of the master/main/devel branch."
|
|
|
if [[ $current_branch != "$main_branch" ]]; then
|
|
|
error "Releases must be based off of the main branch."
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
@@ -613,10 +817,11 @@ function command_release() {
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
# Commit the changes and create a tag.
|
|
|
# Commit the changes and create a tag. GIT_VERSION_TAG_PREFIX
|
|
|
# comes from build configuration.
|
|
|
if ! git -C "$base_dir" add "$changelog_file" "$info_file" || \
|
|
|
! git -C "$base_dir" commit --edit -m "Prepared release $version." || \
|
|
|
! git -C "$base_dir" tag -a -m "Release $version." "${git_version_tag_prefix}${version}"; then
|
|
|
! git -C "$base_dir" tag -a -m "Release $version." "${GIT_VERSION_TAG_PREFIX}${version}"; then
|
|
|
|
|
|
error "Failed to create release commit and tag."
|
|
|
return 1
|
|
@@ -641,6 +846,64 @@ $(< "$changelog_file")
|
|
|
}
|
|
|
|
|
|
|
|
|
#
|
|
|
# Aborts the current release process.
|
|
|
#
|
|
|
# Arguments:
|
|
|
#
|
|
|
# $1 (base_dir)
|
|
|
# Base (top-level) directory with the mod files.
|
|
|
#
|
|
|
# Returns:
|
|
|
#
|
|
|
# 0 on success, 1 otherwise.
|
|
|
#
|
|
|
function command_abort_release() {
|
|
|
local base_dir="$1"
|
|
|
|
|
|
local info_file changelog_file build_config
|
|
|
local current_branch release_branch version
|
|
|
|
|
|
load_build_configuration "$base_dir" || return 1
|
|
|
main_branch=$(get_main_branch "$base_dir") || return 1
|
|
|
release_branch=$(get_current_branch "$base_dir") || return 1
|
|
|
version="${release_branch##release-}"
|
|
|
|
|
|
if [[ ! $release_branch =~ ^release-[[:digit:]]+\.[[:digit:]]+\.[[:digit:]] ]]; then
|
|
|
error "Current branch is not a release branch."
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
# Drop the tag.
|
|
|
if [[ -n $(git -C "$base_dir" tag --list "${GIT_VERSION_TAG_PREFIX}${version}") ]] &&
|
|
|
! git tag --delete "${GIT_VERSION_TAG_PREFIX}${version}"; then
|
|
|
|
|
|
error "Failed to drop the git tag: ${GIT_VERSION_TAG_PREFIX}${version}"
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
# Reset working directory, dropping eventual local changes.
|
|
|
if ! git -C "$base_dir" reset --hard HEAD; then
|
|
|
error "Failed to reset working directory."
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
# Switch back to main branch.
|
|
|
if ! git -C "$base_dir" checkout "$main_branch"; then
|
|
|
error "Failed to switch to main branch."
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
# Drop the release branch.
|
|
|
if ! git -C "$base_dir" branch --delete --force "$release_branch"; then
|
|
|
error "Failed to remove the release branch."
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
return 0
|
|
|
}
|
|
|
|
|
|
|
|
|
# Set-up colours for message printing if we're not piping and terminal is
|
|
|
# capable of outputting the colors.
|
|
|
_COLOR_TERMINAL=$(tput colors 2>&1)
|
|
@@ -782,6 +1045,21 @@ elif [[ $COMMAND == release ]]; then
|
|
|
exit "$ERROR_GENERAL"
|
|
|
fi
|
|
|
|
|
|
elif [[ $COMMAND == abort-release ]]; then
|
|
|
|
|
|
MOD_DIRECTORY_PATH="${1:-.}"
|
|
|
shift
|
|
|
|
|
|
# Ensure that passed-in base directory is the repository root.
|
|
|
if [[ ! -d $MOD_DIRECTORY_PATH/.git ]]; then
|
|
|
error "Passed-in path does not point to base directory of the mod (must contain the .git sub-directory)."
|
|
|
exit "$ERROR_ARGUMENTS"
|
|
|
fi
|
|
|
|
|
|
if ! command_abort_release "$MOD_DIRECTORY_PATH"; then
|
|
|
exit "$ERROR_GENERAL"
|
|
|
fi
|
|
|
|
|
|
else
|
|
|
|
|
|
error "Unsupported command: $COMMAND"
|