作为一个前端开发人员,让写自动化脚本,最开始还是一脸懵逼的,但是没办法啊,还是得硬着脸皮上啊,于是到网上找各种资料,学习了一下shell常用命令,然后便开始研究了,因为平时mac打包用的是package工具,所以得整理一下使用工具打包的过程是怎样的,然后再思考如何用脚本来替代工具所做的步骤。客户端开发的框架是用的nw.js+angular,所以得在nw.js的打包原理上入手。终于在github找到了开源项目nwjs-shell-builder。研究了一天脚本,然后就尝试着开始自己打包了。
首先需要做的就是配置文件config.json,该文件是配置打包时需要进行替换的相关信息
其中name字段是用来定义安装包的名称,applicationName是用来配置应用名称,version是用来配置应用版本,src表示的是源代码的路径,nwjsVersion表示的是nwjs的版本,osxIconPath表示的是应用图标,faviconIconPath表示的是任务栏图标,license表示的是用户许可协议,CFBundleIdentifier表示的bundleID,后面的则表示在应用中需要替换的样式,应用logo等。
接下来就是开始打包了,首先获取配置文件的路径,并根据配置文件中的key获取对应的value,定义临时打包文件夹,安装包存放位置,以下就是打包的脚本,给该脚本命名为package.sh
#!/usr/bin/env bash
# Exit on error
set -e
BUILD_DIR=`pwd`
WORKING_DIR="${BUILD_DIR}/TMP"
RELEASE_DIR="${BUILD_DIR}/releases"
DIST_DIR="${RELEASE_DIR}/build"
# 配置文件config.json的路径
CONFIG_FILE="${BUILD_DIR}/config.json"
# 根据key获取value方法封装
get_value_by_key() {
JSON_FILE=${CONFIG_FILE}
KEY=${1}
# REGEX="\"([^\"]*)\""
JSON_VALUE=$(cat ${JSON_FILE} | jq .${KEY} | sed 's/\"//g')
echo "${JSON_VALUE}"
}
# Name of your package
architechture="x64"
# architechture="ia32"
pack_osx () {
for arch in ${architechture[@]}; do
# 进入到TMP文件夹
cd ${WORKING_DIR}
mkdir -p ${WORKING_DIR}/build_osx/root/Applications
# 把app文件复制到applications中去/
cp -R "${WORKING_DIR}/osx-${arch}/latest-git/$(get_value_by_key applicationName).app" ${WORKING_DIR}/build_osx/root/Applications/
# 修改distribution.xml和componts.plist中的内容
cp ${BUILD_DIR}/resources/osx/components.plist ${RELEASE_DIR}
cp ${BUILD_DIR}/resources/osx/distribution.xml ${RELEASE_DIR}
#替换license中的应用名称
# cp ${BUILD_DIR}/resources/osx/License.rtf ${RELEASE_DIR}
cp ${BUILD_DIR}/resources/osx/index.html ${RELEASE_DIR}
sed -i.bak "s/PengCloud.app/$(get_value_by_key applicationName).app/g" ${RELEASE_DIR}/components.plist
sed -i.bak "s/com.PengCloud.app/$(get_value_by_key CFBundleIdentifier)/g" ${RELEASE_DIR}/distribution.xml
sed -i.bak "s/PengCloud.pkg/$(get_value_by_key name).pkg/g" ${RELEASE_DIR}/distribution.xml
( cd ${WORKING_DIR}/build_osx/root/Applications && chmod -R a+xr $(get_value_by_key applicationName).app )
local COUNT_FILES=$(find ${WORKING_DIR}/build_osx/root | wc -l)
local INSTALL_KB_SIZE=$(du -k -s ${WORKING_DIR}/build_osx/root | awk '{print $1}')
codesign -f --verbose=4 -s "Developer ID Application: Beijing Xiaopeng Education Technology Development Co. Ltd. (3QN2QHQC4Q)" ${WORKING_DIR}/build_osx/root/Applications/$(get_value_by_key applicationName).app --deep --timestamp=none
pkgbuild --root ${WORKING_DIR}/build_osx/root/Applications/ --component-plist ${RELEASE_DIR}/components.plist --identifier $(get_value_by_key CFBundleIdentifier) --install-location /Applications ${RELEASE_DIR}/$(get_value_by_key name).pkg
productbuild --distribution ${RELEASE_DIR}/distribution.xml --resources ${RELEASE_DIR} --package-path ${RELEASE_DIR}/ ${DIST_DIR}/$(get_value_by_key name)-$(get_value_by_key version).pkg
productsign --sign "Developer ID Installer: Beijing Xiaopeng Education Technology Development Co. Ltd. (3QN2QHQC4Q)" ${DIST_DIR}/$(get_value_by_key name)-$(get_value_by_key version).pkg ${DIST_DIR}/$(get_value_by_key name)-$(get_value_by_key version)-sign.pkg --timestamp=none
done;
}
build() {
# if [[ `check_dependencies` = "NO" ]]; then
# printf "\nNOTE! NSIS or ImageMagick is missing in the system\n\n";
# exit 1;
# fi
if [[ ! -f "${WORKING_DIR}" ]]; then
mkdir -p TMP
fi
if [[ ! -d "${RELEASE_DIR}" ]]; then
mkdir ${RELEASE_DIR}
fi
if [[ ! -d "${DIST_DIR}" ]]; then
mkdir ${DIST_DIR}
fi
# 判断是否存在资源文件,如果不存在则下载
if [[ ! -d "$(get_value_by_key src)" ]]; then
echo "=========bucunzai"
git clone -b customized gitv:desktop $(get_value_by_key src)
rm -rf ./resources/.git
fi
# 然后对资源文件中需要定制化的文件进行替换
# 替换应用图标
cp -rf $(get_value_by_key indexBackground) $(get_value_by_key src)/img/images/pengBG.png
# 替换任务栏图标
cp -rf $(get_value_by_key faviconIconPath) $(get_value_by_key src)/configuration/favicon.png
# 替换首页背景
cp -rf $(get_value_by_key indexBackground) $(get_value_by_key src)/img/images/pengBg.png
# 替换首页logo
cp -rf $(get_value_by_key indexLogo) $(get_value_by_key src)/img/images/pengLogo.png
# 替换会议室背景
cp -rf $(get_value_by_key conferenceBackground) $(get_value_by_key src)/configuration/themes/default/background1.png
# 替换package.json文件中的name和productName属性
sed -i "" 's/\("name": "\).*/\1'"$(get_value_by_key name)"'",/g' $(get_value_by_key src)/package.json
# sed -i "" 's/\("productName": "\).*/\1'"$(get_value_by_key applicationName)"'",/g' $(get_value_by_key src)/package.json
#替换中英文语言包中的应用名称
sed -i "" 's/\("IDS_PRODUCT_NAME": "\).*/\1'"$(get_value_by_key applicationName)"'",/g' $(get_value_by_key src)/configuration/languages/cn-cn.json
sed -i "" 's/\("IDS_PRODUCT_NAME": "\).*/\1'"$(get_value_by_key name)"'",/g' $(get_value_by_key src)/configuration/languages/en-us.json
${BUILD_DIR}/nwjs-build.sh \
--name=$(get_value_by_key name) \
--application=$(get_value_by_key applicationName) \
--version=$(get_value_by_key version) \
--src=$(get_value_by_key src) \
--nw=$(get_value_by_key nwjsVersion) \
--osx-icon=$(get_value_by_key osxIconPath) \
--favicon-icon=$(get_value_by_key faviconIconPath) \
--CFBundleIdentifier=$(get_value_by_key CFBundleIdentifier) \
--indexBackground=$(get_value_by_key indexBackground) \
--indexLogo=$(get_value_by_key indexLogo) \
--conferenceBackground=$(get_value_by_key conferenceBackground) \
--target="${1}" \
--libudev \
--build
cd ${BUILD_DIR}
}
clean() {
if [[ ${1} = "all" ]];then
rm -rf ${RELEASE_DIR}; printf "\nCleaned ${RELEASE_DIR}\n\n";
fi
rm -rf ${WORKING_DIR}; printf "\nCleaned ${WORKING_DIR}\n\n";
}
# TODO maybe deal with cmd switches or leave it all in the config.json file
if [[ ${1} = "--osx" ]]; then
clean "all";
build "5";
pack_osx;
fi
我将生成.app文件的脚本分离出来了,命名为nwjs-build.sh,内容如下:
#!/usr/bin/env bash
WORKING_DIR="$(cd -P -- "$(dirname -- "$0")" && pwd -P)"
# default is "FALSE"
LOCAL_NW_ARCHIVES_MODE=true
LOCAL_NW_ARCHIVES_PATH="${WORKING_DIR}/nwjs_download_cache"
# Default nwjs version
NW_VERSION="0.23.7"
# Base domain for nwjs download server
DL_URL="http://dl.nwjs.io"
# This directory will be auto created
TMP="TMP"
# Build target(s)
# 0 - linux-ia32
# 1 - linux-x64
# 2 - win-ia32
# 3 - win-
# 4 - osx-ia32
# 5 - osx-x64
TARGET="0 1 2 3 4 5"
# Final output directory (relative to current directory where this script running from)
RELEASE_DIR="${WORKING_DIR}/${TMP}/output"
# Date on the package archive as PkgName-YYYYMMDD-OS-architecture.zip
DATE=$(date +"%Y%m%d")
# Name of your package
# Package version
# Handle libudev on linux
LIBUDEV_HANDLER=false
ARR_OS[0]="linux-ia32"
ARR_OS[1]="linux-x64"
ARR_OS[2]="win-ia32"
ARR_OS[3]="win-x64"
ARR_OS[4]="osx-ia32"
ARR_OS[5]="osx-x64"
ARR_DL_EXT[0]="tar.gz"
ARR_DL_EXT[1]="tar.gz"
ARR_DL_EXT[2]="zip"
ARR_DL_EXT[3]="zip"
ARR_DL_EXT[4]="zip"
ARR_DL_EXT[5]="zip"
ARR_EXTRACT_COMMAND[0]="tar"
ARR_EXTRACT_COMMAND[1]="tar"
ARR_EXTRACT_COMMAND[2]="zip"
ARR_EXTRACT_COMMAND[3]="zip"
ARR_EXTRACT_COMMAND[4]="zip"
ARR_EXTRACT_COMMAND[5]="zip"
TXT_BOLD="\e[1m"
TXT_NORMAL="\e[1m"
TXT_RED="\e[31m"
TXT_BLUE="\e[34m"
TXT_GREEN="\e[32m"
TXT_YELLO="\e[93m"
TXT_RESET="\e[0m"
TXT_NOTE="\e[30;48;5;82m"
usage() {
cat < /dev/null;
usage | less;
exit 0
;;
--nw=* )
NW_VERSION="${1#*=}";
shift
;;
--name=* )
PKG_NAME="${1#*=}";
shift
;;
--application=* )
APPLICATION_NAME="${1#*=}";
shift
;;
--version=* )
PKG_VERSION="${1#*=}";
shift
;;
--output-dir=* )
RELEASE_DIR="${1#*=}";
shift
;;
--src=* )
PKG_SRC="${1#*=}"
shift
;;
--target=* )
TARGET="${1#*=}"
shift
;;
--osx-icon=* )
OSX_RESOURCE_ICNS="${1#*=}"
shift
;;
--favicon-icon=* )
OSX_FAVICON="${1#*=}"
shift
;;
--CFBundleIdentifier=* )
CFBundleIdentifier="${1#*=}"
shift
;;
--indexBackground=* )
indexBackground="${1#*=}"
shift
;;
--indexLogo=* )
indexLogo="${1#*=}"
shift
;;
--conferenceBackground=* )
conferenceBackground="${1#*=}"
shift
;;
--clean )
clean;
exit 0
;;
--local )
LOCAL_NW_ARCHIVES_MODE=true
shift
;;
--libudev )
LIBUDEV_HANDLER=true
shift
;;
--build )
build;
exit 0
;;
-- )
shift;
break
;;
-* )
printf 'Hmmm, unknown option: "%s".\n' "${1}";
exit 0
;;
* )
usage;
break
;;
esac
done
到这里为止,一个完整的打包脚本就出炉了,接下来就是执行脚本进行自动化打包了。其中具体的路径就需要我们根据自己的需要来进行配置了。进入到package.sh所在的文件目录,打开终端,执行命令./pack.sh --osx,接下来就坐等生成的pkg安装包了。第一次执行的时候会报错,直接加上chomd +x package.sh,然后再执行就可以了。当然,能一下子把脚本贴出来肯定是在完全实现之后了,在研究过程中也是遇到很多很多各种各样的问题,毕竟是第一次接触shell,有时候甚至能在问题上卡住好久好久,不过好在结果是美好的。不过脚本肯定还有很多需要优化的地方,有什么建议或者问题也欢迎指正。