簽名腳本2.0

把簡(jiǎn)單的事情艺谆,做得出人意料的精彩。 —《態(tài)度》

寫(xiě)在前面

過(guò)了這么久拜英,2.0終于來(lái)了静汤,對(duì)比1.0還是有不少改動(dòng)的,在1.0的前提下繼續(xù)優(yōu)化居凶,加入了選項(xiàng)虫给,不僅可以打包apk,也可以打包aar侠碧,對(duì)腳本中的錯(cuò)誤做了處理抹估。沒(méi)有看過(guò)1.0的小可愛(ài)趕快去了解下再回來(lái)哦。
送你一直穿云箭弄兜,《簽名腳本》來(lái)相見(jiàn)

搭建環(huán)境

1.修改build目錄

在《簽名腳本1.0》中药蜻,與Project同級(jí)的build目錄名稱修改為script。

script.png
2.修改build.sh

build.sh是一個(gè)可執(zhí)行的腳本文件替饿,它是該環(huán)境的核心语泽。

#!/bin/bash
#
# ----------------------------------
# Build Android Project Script.
# ----------------------------------
#

version=2.0
author=junxiang.zhang

install=false
module=app

main() {
  init_params $@
}

init_params() {
  options=$(getopt -o vha:l: --long version,help,app:,lib:,install: -- $@)
  if [ $? -ne 0 ]; then
    usage
    exit 1
  fi

  eval set -- $options
  while true; do
    case $1 in
    -v | --version)
      version
      ;;
    -h | --help)
      usage
      exit 0
      ;;
    -a | --app)
      format_param $2
      shift 2
      ;;
    -l | --lib)
      module=lib
      format_param $2
      shift 2
      ;;
    --install)
      install=true
      format_param $2
      shift 2
      ;;
    --)
      shift
      break
      ;;
    *)
      usage
      exit 1
      ;;
    esac
  done
}

format_param() {
  param=$1
  if [ -z param ]; then
    usage
    exit 1
  fi
  projectName=${param%/*}
  moduleName=${param#*/}

  verify_name
}

verify_name() {
  if [ -z $projectName ]; then
    failed 'THE PROJECT NAME IS EMPTY'
  fi
  if [ -z $moduleName ]; then
    failed 'THE MODULE NAME IS EMPTY'
  fi

  projectDir=../$projectName
  moduleDir=$projectDir/$moduleName

  if [ ! -d $projectDir ]; then
    failed 'THE PROJECT DOES NOT EXIST'
  fi
  if [ ! -d $moduleDir ]; then
    failed 'THE MODULE DOES NOT EXIST'
  fi

  verify_output_dir
}

verify_output_dir() {
  outputsDir=outputs
  if [ ! -d $outputsDir ]; then
    mkdir outputs
  fi

  cd $outputsDir
  if [ $module == app ]; then
    fileDir=apk
  else
    if [ $module == lib ]; then
      fileDir=lib
    fi
  fi

  if [ ! -d $fileDir ]; then
    mkdir $fileDir
  fi
  cd ../

  build
}

build() {
  cd $projectDir
  if [ $module == app ]; then
    ./gradlew clean &&
      ./gradlew :$moduleName:aDebug || result=$?
  else
    if [ $module == lib ]; then
      ./gradlew :$moduleName:clean &&
        ./gradlew :$moduleName:aRelease || result=$?
    fi
  fi
  cd ../script

  if [ -z $result ]; then
    copy
  fi
}

copy() {
  if [ $module == app ]; then
    inputFile=$moduleDir/build/outputs/apk/debug/$moduleName-debug.apk
  else
    if [ $module == lib ]; then
      inputFile=$moduleDir/build/outputs/aar/$moduleName-release.aar
    fi
  fi

  cp -p $inputFile $outputsDir/$fileDir/ || result=$?
  if [ -z $result ]; then
    signature
  else
    exit 1
  fi
}

signature() {
  if [ $module == app ]; then
    inputApk=$outputsDir/$fileDir/$moduleName-debug.apk
    outputApk=$outputsDir/$fileDir/$projectName-signed.apk
    java -jar signapk/signapk.jar signapk/platform.x509.pem signapk/platform.pk8 $inputApk $outputApk
    rm -f $inputApk
    install
  else
    if [ $module == lib ]; then
      inputAar=$outputsDir/$fileDir/$moduleName-release.aar
      outputAar=$outputsDir/$fileDir/$projectName-release.aar
      mv $inputAar $outputAar
      successful 'BUILD LIBRARY SUCCESSFUL'
    fi
  fi
}

install() {
  if [ $install == true ]; then
    adb install -r -t $outputApk || result=$?
    if [ -z $result ]; then
      successful 'INSTALL APPLICATION SUCCESSFUL'
    fi
  else
    successful 'BUILD APPLICATION SUCCESSFUL'
  fi
}

usage() {
  cat <<!EOF!

USAGE:: ./build.sh [option] [param]

options:
  -v, -version              Print version info.
  -h, --help                Shows this help message.
  -a, --app                 The project you build is the application.
  -l, --lib                 The project you build is the library.
  --install                 Build and install the application.

param:
  project/module

!EOF!
}

version() {
  printf "Version = $version\nAuthor = $author\n"
  exit 0
}

successful() {
  echo -e '\033[32m'$1'\033[0m'
  exit 0
}

failed() {
  echo -e '\033[31m'$1'\033[0m'
  exit 1
}

main $@

腳本講解

這次把相應(yīng)的功能都封裝成了函數(shù),每個(gè)函數(shù)單獨(dú)負(fù)責(zé)自己的部分视卢。

#!/bin/bash
#
# ----------------------------------
# Build Android Project Script.
# ----------------------------------
#

# 版本號(hào)
version=2.0
# 創(chuàng)作者
author=junxiang.zhang

# 該變量只針對(duì)application踱卵,false代表只構(gòu)造不安裝apk,
# true則代表即構(gòu)造又安裝apk据过,默認(rèn)值為false
install=false
# 區(qū)分當(dāng)前構(gòu)造的模塊是application還是library惋砂,默認(rèn)值為application
module=app

# 主函數(shù)
main() {
  init_params $@
}

# 初始化參數(shù)
init_params() {
  # 處理選項(xiàng),-o代表短選項(xiàng)绳锅,--long代表長(zhǎng)選項(xiàng)西饵,$@代表參數(shù)列表
  options=$(getopt -o vha:l: --long version,help,app:,lib:,install: -- $@)

  # $?代表參數(shù)的個(gè)數(shù),如果沒(méi)有參數(shù)榨呆,則調(diào)用usage函數(shù)罗标,退出  
  if [ $? -ne 0 ]; then
    usage
    exit 1
  fi

  # 使用while遍歷參數(shù)
  eval set -- $options
  while true; do
    case $1 in
    -v | --version)
      version
      ;;
    -h | --help)
      usage
      exit 0
      ;;
    -a | --app)
      format_param $2
      shift 2
      ;;
    -l | --lib)
      module=lib
      format_param $2
      shift 2
      ;;
    --install)
      install=true
      format_param $2
      shift 2
      ;;
    --)
      shift
      break
      ;;
    *)
      usage
      exit 1
      ;;
    esac
  done
}

# 格式化參數(shù)
format_param() {
  # $1對(duì)應(yīng)格式為MyApplication/app,
  # 如果參數(shù)是空的积蜻,就打印幫助闯割,退出
  param=$1
  if [ -z param ]; then
    usage
    exit 1
  fi
  # 項(xiàng)目名稱,對(duì)應(yīng)MyApplication竿拆,截取/左邊
  projectName=${param%/*}
  # 工程名稱宙拉,對(duì)應(yīng)app,截取/右邊
  moduleName=${param#*/}

  # 如果項(xiàng)目名稱和工程名稱截取成功丙笋,就要驗(yàn)證名稱的合法性
  verify_name
}

# 驗(yàn)證名稱
verify_name() {
  # 如果項(xiàng)目名稱是空的谢澈,則失敗煌贴,退出
  if [ -z $projectName ]; then
    failed 'THE PROJECT NAME IS EMPTY'
  fi
  # 如果工程名稱是空的,則失敗锥忿,退出
  if [ -z $moduleName ]; then
    failed 'THE MODULE NAME IS EMPTY'
  fi

  # 項(xiàng)目目錄牛郑,和build目錄同級(jí),所以先../回到同級(jí)目錄
  projectDir=../$projectName
  # 工程目錄敬鬓,對(duì)應(yīng)MyApplication/app
  moduleDir=$projectDir/$moduleName

  # 如果項(xiàng)目目錄不存在淹朋,則失敗,退出
  if [ ! -d $projectDir ]; then
    failed 'THE PROJECT DOES NOT EXIST'
  fi
  # 如果功工程目錄不存在钉答,則失敗础芍,退出
  if [ ! -d $moduleDir ]; then
    failed 'THE MODULE DOES NOT EXIST'
  fi

  # 如果項(xiàng)目目錄和工程目錄都存在,就要去驗(yàn)證文件輸出目錄
  verify_output_dir
}

# 驗(yàn)證文件輸出目錄
verify_output_dir() {
  # 文件輸出目錄的名稱為outputs数尿,如果不存在就創(chuàng)建
  outputsDir=outputs
  if [ ! -d $outputsDir ]; then
    mkdir outputs
  fi

  # 進(jìn)入outputs目錄仑性,判斷module是application還是library,
  # 從而定義不同的目錄名稱
  cd $outputsDir
  if [ $module == app ]; then
    fileDir=apk
  else
    if [ $module == lib ]; then
      fileDir=lib
    fi
  fi

  # 如果fileDir目錄不存在右蹦,就創(chuàng)建
  if [ ! -d $fileDir ]; then
    mkdir $fileDir
  fi
  cd ../

  # 文件輸出目錄沒(méi)問(wèn)題就開(kāi)始編譯了
  build
}

# 構(gòu)造apk/aar
build() {
  # 因?yàn)榫幾g需要用到gradlew诊杆,所以要進(jìn)入項(xiàng)目目錄,
  # result用于接收編譯結(jié)果
  cd $projectDir
  if [ $module == app ]; then
    ./gradlew clean &&
      ./gradlew :$moduleName:aDebug || result=$?
  else
    if [ $module == lib ]; then
      ./gradlew :$moduleName:clean &&
        ./gradlew :$moduleName:aRelease || result=$?
    fi
  fi
  # 編譯結(jié)束嫩实,無(wú)論成功與否刽辙,都要回到script目錄
  cd ../script

  # 如果result不為空,說(shuō)明編譯成功了甲献,接下來(lái)執(zhí)行拷貝
  if [ -z $result ]; then
    copy
  fi
}

# 拷貝
copy() {
  # 根據(jù)module獲取相應(yīng)的文件路徑宰缤,這里的路徑是默認(rèn)的
  if [ $module == app ]; then
    inputFile=$moduleDir/build/outputs/apk/debug/$moduleName-debug.apk
  else
    if [ $module == lib ]; then
      inputFile=$moduleDir/build/outputs/aar/$moduleName-release.aar
    fi
  fi

  # 將構(gòu)造好的文件拷貝到目標(biāo)目錄
  cp -p $inputFile $outputsDir/$fileDir/ || result=$?
  # 如果拷貝成功就執(zhí)行簽名,否則退出
  if [ -z $result ]; then
    signature
  else
    exit 1
  fi
}

# 簽名
signature() {
  # 如果module是application晃洒,就區(qū)簽名
  if [ $module == app ]; then
    inputApk=$outputsDir/$fileDir/$moduleName-debug.apk
    outputApk=$outputsDir/$fileDir/$projectName-signed.apk
    java -jar signapk/signapk.jar signapk/platform.x509.pem signapk/platform.pk8 $inputApk $outputApk
    rm -f $inputApk
    # 簽名后慨灭,執(zhí)行安裝
    install
  else
    # 如果module是library,就重命名球及,aar打包結(jié)束氧骤,退出
    if [ $module == lib ]; then
      inputAar=$outputsDir/$fileDir/$moduleName-release.aar
      outputAar=$outputsDir/$fileDir/$projectName-release.aar
      mv $inputAar $outputAar
      successful 'BUILD LIBRARY SUCCESSFUL'
    fi
  fi
}

# 安裝
install() {
  # 如果需要安裝,則執(zhí)行adb命令進(jìn)行安裝
  if [ $install == true ]; then
    adb install -r -t $outputApk || result=$?
    if [ -z $result ]; then
      successful 'INSTALL APPLICATION SUCCESSFUL'
    fi
  else
    successful 'BUILD APPLICATION SUCCESSFUL'
  fi
}

# 幫助
usage() {
  cat <<!EOF!

USAGE:: ./build.sh [option] [param]

options:
  -v, -version              Print version info.
  -h, --help                Shows this help message.
  -a, --app                 The project you build is the application.
  -l, --lib                 The project you build is the library.
  --install                 Build and install the application.

param:
  project/module

!EOF!
}

# 版本信息
version() {
  printf "Version = $version\nAuthor = $author\n"
  exit 0
}

# 成功
successful() {
  echo -e '\033[32m'$1'\033[0m'
  exit 0
}

# 失敗
failed() {
  echo -e '\033[31m'$1'\033[0m'
  exit 1
}

# 調(diào)用main函數(shù)
main $@

執(zhí)行腳本

這次使用Ubuntu系統(tǒng)吃引,再也不用在Windows系統(tǒng)上借助Git了筹陵。

1.幫助

help.png
2.版本信息
version.png
3.打包apk
build apk.png
4.打包aar
build aar.png

寫(xiě)在最后

腳本已經(jīng)很簡(jiǎn)單了,其實(shí)有很多重復(fù)的工作都可以通過(guò)腳本封裝起來(lái)镊尺,比如使用repo工具朦佩,用過(guò)的小可愛(ài)肯定都知道到,要先使用Git克隆庐氮,然后repo init语稠,最后在repo sync。針對(duì)這種總使用到的工作就可以封到腳本里,從幾行命令變成一行命令即可仙畦。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末输涕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子慨畸,更是在濱河造成了極大的恐慌莱坎,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寸士,死亡現(xiàn)場(chǎng)離奇詭異型奥,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)碉京,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事跷敬∷诠兀” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵件豌,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)划栓,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任条获,我火速辦了婚禮忠荞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帅掘。我一直安慰自己委煤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布修档。 她就那樣靜靜地躺著碧绞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吱窝。 梳的紋絲不亂的頭發(fā)上讥邻,一...
    開(kāi)封第一講書(shū)人閱讀 51,521評(píng)論 1 304
  • 那天,我揣著相機(jī)與錄音院峡,去河邊找鬼兴使。 笑死,一個(gè)胖子當(dāng)著我的面吹牛撕予,可吹牛的內(nèi)容都是我干的鲫惶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼实抡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼欠母!你這毒婦竟也來(lái)了欢策?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤赏淌,失蹤者是張志新(化名)和其女友劉穎踩寇,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體六水,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俺孙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掷贾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片睛榄。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖想帅,靈堂內(nèi)的尸體忽然破棺而出场靴,到底是詐尸還是另有隱情,我是刑警寧澤港准,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布旨剥,位于F島的核電站,受9級(jí)特大地震影響浅缸,放射性物質(zhì)發(fā)生泄漏轨帜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一衩椒、第九天 我趴在偏房一處隱蔽的房頂上張望蚌父。 院中可真熱鬧,春花似錦烟具、人聲如沸梢什。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)嗡午。三九已至,卻和暖如春冀痕,著一層夾襖步出監(jiān)牢的瞬間荔睹,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工言蛇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留僻他,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓腊尚,卻偏偏與公主長(zhǎng)得像吨拗,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355