Created
February 28, 2017 05:48
-
-
Save Limon-O-O/390b06f1354e2003cb20e6ff98ff6905 to your computer and use it in GitHub Desktop.
Release Pod script.
This file contains hidden or 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 | |
BGreen='\033[1;32m' | |
Default='\033[0;m' | |
podName="" | |
version="" | |
podspecFilePath="" | |
homepage="" | |
httpsRepo="" | |
oldVersion="" | |
confirmed="n" | |
getPodInfo() { | |
for file in ./* | |
do | |
if test -f $file | |
then | |
if [[ $file == *".podspec"* ]]; then | |
filename=`basename $file` | |
podName=${filename%.podspec*} | |
podspecFilePath="./${podName}.podspec" | |
fi | |
fi | |
done | |
while read line; do | |
line=${line//[[:blank:]]/} | |
if [[ $line == *".homepage="* ]]; then | |
homepage=${line##*='"'} | |
homepage=${homepage%'"'} | |
fi | |
if [[ $line == *".source="* ]]; then | |
httpsRepo=${line##*git=>'"'} | |
httpsRepo=${httpsRepo%'"'*} | |
fi | |
# 截取旧版本号 | |
if [[ $line == *"s.version"*"="* ]]; then | |
oldVersion=${line##*=} | |
oldVersion=${oldVersion#*\"} | |
oldVersion=${oldVersion%\"} | |
oldVersion=${oldVersion#*\'} | |
oldVersion=${oldVersion%\'} | |
fi | |
done < $podspecFilePath | |
} | |
getVersion() { | |
read -p "Enter New Version: " version | |
if test -z "$version"; then | |
getVersion | |
fi | |
} | |
updateVersion() { | |
# update .podspec file | |
while read line; do | |
if [[ $line == *"s.version"*"="* ]]; then | |
newLine=${line/$oldVersion/$version} | |
sed -i '' "s#$line#$newLine#" "$podspecFilePath" | |
fi | |
done < $podspecFilePath | |
# update README.md file | |
while read line; do | |
if [[ $line == *"pod"*"${oldVersion}"* ]]; then | |
newLine=${line/$oldVersion/$version} | |
sed -i '' "s#$line#$newLine#" "./README.md" | |
fi | |
if [[ $line == *"github"*"${podName}"*"${oldVersion}"* ]]; then | |
newLine=${line/$oldVersion/$version} | |
sed -i '' "s#${line}#${newLine}#" "./README.md" | |
fi | |
done < "./README.md" | |
# update Xcode project | |
updateProjectVersion --version=$version --target=$podName | |
# ./update_version.sh --version=$version --target=$podName | |
} | |
getInfomation() { | |
getVersion | |
echo -e "\n${Default}================================================" | |
echo -e " Pod Name : ${BGreen}${podName}${Default}" | |
echo -e " Version : ${BGreen}${version}${Default}" | |
echo -e " HTTPS Repo : ${BGreen}${httpsRepo}${Default}" | |
echo -e " Home Page URL : ${BGreen}${homepage}${Default}" | |
echo -e "================================================\n" | |
} | |
########### Compare newVersion and oldVersion ############### | |
compareVersion() { | |
## @file version_compare | |
## Compare [semantic] versions in Bash, comparable to PHP's version_compare function. | |
# ------------------------------------------------------------------ | |
## @author Mark Carver <[email protected]> | |
## @copyright MIT | |
## @version 1.0.0 | |
## @see http://php.net/manual/en/function.version-compare.php | |
APP_NAME=$(basename ${0}) | |
APP_VERSION="1.0.0" | |
# Version compare | |
function version_compare () { | |
# Default to a failed comparison result. | |
local -i result=1; | |
# Ensure there are two versions to compare. | |
[ $# -lt 2 ] || [ -z "${1}" ] || [ -z "${2}" ] && echo "${FUNCNAME[0]} requires a minimum of two arguments to compare versions." &>/dev/stderr && return ${result} | |
# Determine the operation to perform, if any. | |
local op="${3}" | |
# Convert passed versions into values for comparison. | |
local v1=$(version_compare_convert ${1}) | |
local v2=$(version_compare_convert ${2}) | |
# Immediately return when comparing version equality (which doesn't require sorting). | |
if [ -z "${op}" ]; then | |
[ "${v1}" == "${v2}" ] && echo 0 && return; | |
else | |
if [ "${op}" == "!=" ] || [ "${op}" == "<>" ] || [ "${op}" == "ne" ]; then | |
if [ "${v1}" != "${v2}" ]; then let result=0; fi; | |
return ${result}; | |
elif [ "${op}" == "=" ] || [ "${op}" == "==" ] || [ "${op}" == "eq" ]; then | |
if [ "${v1}" == "${v2}" ]; then let result=0; fi; | |
return ${result}; | |
elif [ "${op}" == "le" ] || [ "${op}" == "<=" ] || [ "${op}" == "ge" ] || [ "${op}" == ">=" ] && [ "${v1}" == "${v2}" ]; then | |
if [ "${v1}" == "${v2}" ]; then let result=0; fi; | |
return ${result}; | |
fi | |
fi | |
# If we get to this point, the versions should be different. | |
# Immediately return if they're the same. | |
[ "${v1}" == "${v2}" ] && return ${result} | |
local sort='sort' | |
# If only one version has a pre-release label, reverse sorting so | |
# the version without one can take precedence. | |
[[ "${v1}" == *"-"* ]] && [[ "${v2}" != *"-"* ]] || [[ "${v2}" == *"-"* ]] && [[ "${v1}" != *"-"* ]] && sort="${sort} -r" | |
# Sort the versions. | |
local -a sorted=($(printf "%s\n%s" "${v1}" "${v2}" | ${sort})) | |
# No operator passed, indicate which direction the comparison leans. | |
if [ -z "${op}" ]; then | |
if [ "${v1}" == "${sorted[0]}" ]; then echo -1; else echo 1; fi | |
return | |
fi | |
case "${op}" in | |
"<" | "lt" | "<=" | "le") if [ "${v1}" == "${sorted[0]}" ]; then let result=0; fi;; | |
">" | "gt" | ">=" | "ge") if [ "${v1}" == "${sorted[1]}" ]; then let result=0; fi;; | |
esac | |
return ${result} | |
} | |
# Converts a version string to an integer that is used for comparison purposes. | |
function version_compare_convert () { | |
local version="${@}" | |
# Remove any build meta information as it should not be used per semver spec. | |
version="${version%+*}" | |
# Extract any pre-release label. | |
local prerelease | |
[[ "${version}" = *"-"* ]] && prerelease=${version##*-} | |
[ -n "${prerelease}" ] && prerelease="-${prerelease}" | |
version="${version%%-*}" | |
# Separate version (minus pre-release label) into an array using periods as the separator. | |
local OLDIFS=${IFS} && local IFS=. && version=(${version%-*}) && IFS=${OLDIFS} | |
# Unfortunately, we must use sed to strip of leading zeros here. | |
local major=$(echo ${version[0]:=0} | sed 's/^0*//') | |
local minor=$(echo ${version[1]:=0} | sed 's/^0*//') | |
local patch=$(echo ${version[2]:=0} | sed 's/^0*//') | |
local build=$(echo ${version[3]:=0} | sed 's/^0*//') | |
# Combine the version parts and pad everything with zeros, except major. | |
printf "%s%04d%04d%04d%s\n" "${major}" "${minor}" "${patch}" "${build}" "${prerelease}" | |
} | |
# Color Support | |
# See: http://unix.stackexchange.com/a/10065 | |
if test -t 1; then | |
ncolors=$(tput colors) | |
if test -n "$ncolors" && test $ncolors -ge 8; then | |
bold="$(tput bold)" && underline="$(tput smul)" && standout="$(tput smso)" && normal="$(tput sgr0)" | |
black="$(tput setaf 0)" && red="$(tput setaf 1)" && green="$(tput setaf 2)" && yellow="$(tput setaf 3)" | |
blue="$(tput setaf 4)" && magenta="$(tput setaf 5)" && cyan="$(tput setaf 6)" && white="$(tput setaf 7)" | |
fi | |
fi | |
function version_compare_usage { | |
echo "${bold}${APP_NAME} (${APP_VERSION})${normal}" | |
echo "Compare [semantic] versions in Bash, comparable to PHP's version_compare function." | |
echo | |
echo "${bold}Usage:${normal}" | |
echo " ${APP_NAME} [-hV] ${cyan}<version1> <version2>${normal} [${cyan}<operator>${normal}]" | |
echo | |
echo "${bold}Required arguments:${normal}" | |
echo " - ${cyan}<version1>${normal}: First version number to compare." | |
echo " - ${cyan}<version2>${normal}: Second version number to compare." | |
echo | |
echo "${bold}Optional arguments:${normal}" | |
echo " - ${cyan}<operator>${normal}: When this argument is provided, it will test for a particular" | |
echo " relationship. This argument is case-sensitive, values should be lowercase." | |
echo " Possible operators are:" | |
echo " ${bold}=, ==, eq${normal} (equal)" | |
echo " ${bold}>, gt${normal} (greater than)" | |
echo " ${bold}>=, ge${normal} (greater than or equal)" | |
echo " ${bold}<, lt${normal} (less than)" | |
echo " ${bold}<=, le${normal} (less than or equal)" | |
echo " ${bold}!=, <>, ne${normal} (not equal)" | |
echo | |
echo "${bold}Return Value:${normal}" | |
echo " There are two distinct operation modes for ${APP_NAME}. It's solely based" | |
echo " on whether or not the ${cyan}<operator>${normal} argument was provided:" | |
echo | |
echo " - When ${cyan}<operator>${normal} IS provided, ${APP_NAME} will return either a 0 or 1" | |
echo " exit code (no output printed to /dev/stdout) based on the result of the ${cyan}<operator>${normal}" | |
echo " relationship between the versions. This is particularly useful in cases where" | |
echo " testing versions can, historically, be quite cumbersome:" | |
echo | |
echo " ${magenta}! ${APP_NAME} \${version1} \${version2} \">\" && echo \"You have not met the minimum version requirements.\" && exit 1${normal}" | |
echo | |
echo " You can, of course, opt for the more traditional/verbose conditional" | |
echo " block in that suites your fancy:" | |
echo | |
echo " ${magenta}${APP_NAME} \${version1} \${version2}" | |
echo " if [ \$? -gt 0 ]; then" | |
echo " echo \"You have not met the minimum version requirements.\"" | |
echo " exit 1" | |
echo " fi${normal}" | |
echo | |
echo " - When ${cyan}<operator>${normal} is NOT provided, ${APP_NAME} will output (print to /dev/stdout):" | |
echo " -1: ${cyan}<version1>${normal} is lower than ${cyan}<version2>${normal}" | |
echo " 0: ${cyan}<version1>${normal} and ${cyan}<version2>${normal} are equal" | |
echo " 1: ${cyan}<version2>${normal} is lower than ${cyan}<version1>${normal}" | |
echo | |
echo " This mode is primarily only ever helpful when there is a need to determine the" | |
echo " relationship between two versions and provide logic for all three states:" | |
echo | |
echo " ${magenta}ret=\$(${APP_NAME} \${version1} \${version2})" | |
echo " if [ \"\${ret}\" == \"-1\" ]; then" | |
echo " # Do some logic here." | |
echo " elif [ \"\${ret}\" == \"0\" ]; then" | |
echo " # Do some logic here." | |
echo " else" | |
echo " # Do some logic here." | |
echo " fi${normal}" | |
echo | |
echo " While there are use cases for both modes, it's recommended that you provide an" | |
echo " ${cyan}<operator>${normal} argument to reduce any logic whenever possible." | |
echo | |
echo "${bold}Options:${normal}" | |
echo " ${bold}-h${normal} Display this help and exit." | |
echo " ${bold}-V${normal} Display version information and exit." | |
} | |
# Do not continue if sourced. | |
[[ ${0} != "$BASH_SOURCE" ]] && return | |
# Process options. | |
while getopts ":hV" opt; do | |
case $opt in | |
h) version_compare_usage && exit;; | |
V) echo "${APP_VERSION}" && exit;; | |
\?|*) echo "${red}${APP_NAME}: illegal option: -- ${OPTARG}${normal}" >&2 && echo && version_compare_usage && exit 64;; | |
esac | |
done | |
shift $((OPTIND-1)) # Remove parsed options. | |
# Allow script to be invoked as a CLI "command" by proxying arguments to the internal function. | |
[ $# -gt 0 ] && version_compare ${@} | |
} | |
########### Update Xocde Info.plist ############### | |
updateProjectVersion() { | |
# Link: <https://gist.github.com/jellybeansoup/db7b24fb4c7ed44030f4> | |
# ./update-version.sh --version=1.2.9 --build=95 --target=MonkeyKing | |
# We use PlistBuddy to handle the Info.plist values. Here we define where it lives. | |
plistBuddy="/usr/libexec/PlistBuddy" | |
BGreen='\033[1;32m' | |
# Parse input variables and update settings. | |
for i in "$@"; do | |
case $i in | |
-h|--help) | |
echo "usage: sh version-update.sh [options...]\n" | |
echo "Options: (when provided via the CLI, these will override options set within the script itself)" | |
echo " --build=<number> Apply the given value to the build number (CFBundleVersion) for the project." | |
echo "-p, --plist=<path> Use the specified plist file as the source of truth for version details." | |
echo " --version=<number> Apply the given value to the marketing version (CFBundleShortVersionString) for the project." | |
echo "-x, --xcodeproj=<path> Use the specified Xcode project file to gather plist names." | |
echo "-x, --target=<name> Use the specified Xcode project target to gather plist names." | |
echo "\nFor more detailed information on the use of these variables, see the script source." | |
exit 1 | |
;; | |
-x=*|--xcodeproj=*) | |
xcodeproj="${i#*=}" | |
shift | |
;; | |
-p=*|--plist=*) | |
plist="${i#*=}" | |
shift | |
;; | |
--target=*) | |
specified_target="${i#*=}" | |
shift | |
;; | |
--build=*) | |
specified_build="${i#*=}" | |
shift | |
;; | |
--version=*) | |
specified_version="${i#*=}" | |
shift | |
;; | |
*) | |
;; | |
esac | |
done | |
# Locate the xcodeproj. | |
# If we've specified a xcodeproj above, we'll simply use that instead. | |
if [[ -z ${xcodeproj} ]]; then | |
xcodeproj=$(find . -depth 1 -name "*.xcodeproj" | sed -e 's/^\.\///g') | |
fi | |
# Check that the xcodeproj file we've located is valid, and warn if it isn't. | |
# This could also indicate an issue with the code used to automatically locate the xcodeproj file. | |
# If you're encountering this and the file exists, ensure that ${xcodeproj} contains the correct | |
# path, or use the "--xcodeproj" variable to provide an accurate location. | |
if [[ ! -f "${xcodeproj}/project.pbxproj" ]]; then | |
echo "${BASH_SOURCE}:${LINENO}: error: Could not locate the xcodeproj file \"${xcodeproj}\"." | |
exit 1 | |
else | |
echo "Xcode Project: \"${xcodeproj}\"" | |
fi | |
# Find unique references to Info.plist files in the project | |
projectFile="${xcodeproj}/project.pbxproj" | |
plists=$(grep "^\s*INFOPLIST_FILE.*$" "${projectFile}" | sed -Ee 's/^[[:space:]]+INFOPLIST_FILE[[:space:]*=[[:space:]]*["]?([^"]+)["]?;$/\1/g' | sort | uniq) | |
# Attempt to guess the plist based on the list we have. | |
# If we've specified a plist above, we'll simply use that instead. | |
if [[ -z ${plist} ]]; then | |
while read -r thisPlist; do | |
if [[ $thisPlist == *"${specified_target}"* ]]; then | |
plist=$thisPlist | |
fi | |
done <<< "${plists}" | |
fi | |
# Check that the plist file we've located is valid, and warn if it isn't. | |
# This could also indicate an issue with the code used to match plist files in the xcodeproj file. | |
# If you're encountering this and the file exists, ensure that ${plists} contains _ONLY_ filenames. | |
if [[ ! -f ${plist} ]]; then | |
echo "${BASH_SOURCE}:${LINENO}: error: Could not locate the plist file \"${plist}\"." | |
exit 1 | |
else | |
echo "Source Info.plist: \"${plist}\"" | |
fi | |
# Find the current build number in the main Info.plist | |
mainBundleVersion=$("${plistBuddy}" -c "Print CFBundleVersion" "${plist}") | |
mainBundleShortVersionString=$("${plistBuddy}" -c "Print CFBundleShortVersionString" "${plist}") | |
echo "Current project version is ${mainBundleShortVersionString} (${mainBundleVersion})." | |
# If the user specified a marketing version (via "--version"), we overwrite the version from the source of truth. | |
if [[ ! -z ${specified_version} ]]; then | |
mainBundleShortVersionString=${specified_version} | |
echo "Applying specified marketing version (${specified_version})..." | |
fi | |
if [[ ! -z ${specified_build} ]]; then | |
mainBundleVersion=${specified_build} | |
echo "Applying specified build number (${specified_build})..." | |
fi | |
# Update all of the Info.plist files we discovered | |
while read -r thisPlist; do | |
# Find out the current version | |
thisBundleVersion=$("${plistBuddy}" -c "Print CFBundleVersion" "${thisPlist}") | |
thisBundleShortVersionString=$("${plistBuddy}" -c "Print CFBundleShortVersionString" "${thisPlist}") | |
# Update the CFBundleVersion if needed | |
if [[ ${thisBundleVersion} != ${mainBundleVersion} ]]; then | |
echo -e "${BGreen}Updating \"${thisPlist}\" with build ${mainBundleVersion}..." | |
"${plistBuddy}" -c "Set :CFBundleVersion ${mainBundleVersion}" "${thisPlist}" | |
fi | |
# Update the CFBundleShortVersionString if needed | |
if [[ ${thisBundleShortVersionString} != ${mainBundleShortVersionString} ]]; then | |
echo -e "${BGreen}Updating \"${thisPlist}\" with marketing version ${mainBundleShortVersionString}..." | |
"${plistBuddy}" -c "Set :CFBundleShortVersionString ${mainBundleShortVersionString}" "${thisPlist}" | |
git add "${thisPlist}" | |
fi | |
echo -e "${BGreen}Current \"${thisPlist}\" version is ${mainBundleShortVersionString} (${mainBundleVersion})." | |
done <<< "${plist}" | |
} | |
########### 开始 ############### | |
getPodInfo | |
echo -e "\n" | |
echo "Current Version: ${oldVersion}" | |
while [ "$confirmed" != "y" -a "$confirmed" != "Y" ] | |
do | |
if [ "$confirmed" == "n" -o "$confirmed" == "N" ]; then | |
getInfomation | |
fi | |
read -p "confirm? (y/n):" confirmed | |
done | |
! compareVersion $version $oldVersion ">" && echo "Invalid version. $version <= $oldVersion" && exit 1 | |
updateVersion | |
echo "" | |
echo "--------------------------------------------------------------------------------" | |
echo "" | |
git add "${podspecFilePath}" | |
git add "./README.md" | |
git commit -m "[$podName] update version $version" | |
git push | |
git tag "${version}" | |
git push --tags | |
echo "" | |
echo "--------------------------------------------------------------------------------" | |
echo "Start pod trunk push \"${podName}.podspec\" --allow-warnings" | |
pod trunk push "${podName}.podspec" --allow-warnings | |
echo -e "\n" | |
say "finished" | |
echo "finished" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment