├── README.md ├── config.sh ├── pic ├── pic_1.png ├── pic_2.png └── pic_push.png └── private-pod-push-script.sh /README.md: -------------------------------------------------------------------------------- 1 | # PPPrivatePodPushScript 2 | 3 | ## 预览图 4 | 5 | ![](pic/pic_1.png) 6 | ![](pic/pic_2.png) 7 | 8 | ## 简介 9 | 10 | 私有库的修改, 提交等操作非常没有技术含量并且繁琐. 11 | 12 | 1. 修改私有库代码文件 13 | 2. 修改私有库`.podspec`文件的版本号 14 | 3. 提交所有修改的文件 15 | 4. 添加版本的tag并且push所有的提交. 16 | 5. cd到私有库`.podspec`文件所在目录, 验证并push私有库.(push的时候会执行pod lib lint)操作, 所以这里省略了. 17 | 6. 后续可能还会涉及到修改主工程私有库的版本号, pod install, 运行主工程等操作. 18 | 7. 在以上的基础上, 编写了`private-pod-push-script.sh`脚本. 在终端输入几下命令, 便完成了以上`2~5`的所有操作. 19 | 20 | ## 使用方式 21 | 22 | 1. `git clone` 本仓库, `并cd进入本仓库目录`. (建议加入本仓库到Sourcetree, 这样以后我更新了, 你也可以在 Sourcetree检测到) 23 | 2. 在`config.sh`里面配置工作路径, 填写所有组件的主仓库地址, 组件项目附加的文件路径以及组件名.(配置好你的组件路径, `config.sh`文件可以放在任何地方) 24 | 25 | - `主仓库地址`是`http://host.com/iOS/Specs.git`(这个是你所有组件存放.podspec文件的仓库地址) 26 | - `/Users/pengpeng/Desktop/GithubTest/PPTestComponent/PPTestComponent.podspec` 和 `/Users/pengpeng/Desktop/PPKit.podspec` 是我的组件地址 27 | - `/Users/pengpeng/Desktop/`是工作路径 28 | - `GithubTest/PPTestComponent/`是附加地址(附加地址选填) 29 | - `PPTestComponent.podspec`的`PPTestComponent`是组件名 30 | 3. 在终端输入`sh private-pod-push-script.sh`执行脚本. 31 | 32 | ~~3. 在终端输入`chmod +x private-pod-push-script.sh`, 给`private-pod-push-script.sh`文件增加可执行权限. (此步骤只需要执行一次).~~ 33 | 34 | ~~4. 然后输入`./private-pod-push-script.sh`既可执行脚本.~~ 35 | 36 | - 自动获取你配置的所有组件, 根据编号排序, `输入你想提交的组件编号`. 37 | - 自动获取当前`.podspec`版本号和上一次git所提交的tag号, `输入你想设置的版本号, 再输入注释`. 38 | - `选择你想push到的主仓库名称`, 如果验证成功的情况下, 所有流程已完成. 39 | 40 | ### 做好前期的配置后, 以后只需要cd到脚本所在的文件目录下, 执行第4步中的操作即可. 41 | 42 | ## 目前完成的功能 43 | 44 | 脚本里面我写了`很多注释`, 可以按需修改, 增减自己的需求进去. 45 | 46 | - [x] 脚本可以放在任何文件夹, 可以配置多个组件, 多个组件的路径可以不一致, 1个脚本对应多个组件. 47 | - [x] 根据`config.sh`配置文件的内容, 展示你所有配置的组件仓库. 48 | - [x] 对配置的组件`.podspec`文件是否存在进行判断. 49 | - [x] 根据输入的组件编号配置脚本运行环境. 50 | - [x] 获取组件`.podspec`文件版本号, 并且根据你的输入的版本号修改.(自动获取组件最后一次提交的版本号, 方便你判断最新的版本号). 51 | - [x] 输入注释, `自动提交所有修改的文件`并且push. 52 | - [x] 根据选择的本地specs文件夹进行组件推送. 53 | - [x] 脚本有重要的输出内容时,输出的文本颜色特殊处理. 54 | - [x] 编号类型的输入, 会对内容进行验证, 输入错误(非数字)会有容错处理. 55 | - [x] 组件推送后重要的信息输出. 56 | - [x] 增加推送是否成功的判断, 在终端输出不同的内容提示使用者. 57 | - [x] 可以设置默认推送的仓库名称,必须设置有效的文件夹名称才会生效,获取方式在终端`cd ~/.cocoapods/repos/`目录下获取.(如果你需要推送不同的仓库概率比较高, 建议不要设置这个) 58 | 59 | > 后续还会根据需求增加别的功能, 为了方便使用者更新脚本, 所以把配置文件和脚本拆分了. 只需要更新脚本, 再把最新的脚本和配置文件放到一起既可. 也可以把配置文件放到别处, 配置文件的路径在脚本中可以设置. 60 | 61 | ## 说明 62 | 63 | 为了获取到私有库是否推送成功, 脚本对`pod repo push`的命令输出内容进行重定向到临时文件, 所以`pod repo push`在终端的输出打印会失去原有的特殊彩色. 也就是说预览图中的黄色输出内容会变成普通颜色. 64 | -------------------------------------------------------------------------------- /config.sh: -------------------------------------------------------------------------------- 1 | # 默认推送的仓库名称 必须设置有效的文件夹名称才会生效 获取方式 cd ~/.cocoapods/repos/ 2 | readonly DEFAULT_REPO_DIR_NAME="" 3 | 4 | # 工作路径 5 | readonly WORK_DIR="/Users/pengpeng/Desktop/" 6 | readonly SUFFIX=".podspec" 7 | # 存放你的Specs的地址, 不填写会导致无法repo push 路径之间用逗号分隔 8 | readonly PUSH_REPO_SOURCE=--sources="http://host.com/iOS/Specs.git,https://github.com/CocoaPods/Specs.git" 9 | 10 | # 所有的组件名 11 | MODULES=( 12 | "PPTestComponent" 13 | "PPKit" 14 | ) 15 | 16 | # 附加的文件路径 数量必须和上面的Modules对应 没有附加传 "" 既可 17 | ATTACH_DIR_PATH=( 18 | "GithubTest/PPTestComponent/" 19 | "" 20 | ) 21 | -------------------------------------------------------------------------------- /pic/pic_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zedxpp/PPPrivatePodPushScript/51ff9a483f48caa867a0ff89b256bdc7ced9e1b4/pic/pic_1.png -------------------------------------------------------------------------------- /pic/pic_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zedxpp/PPPrivatePodPushScript/51ff9a483f48caa867a0ff89b256bdc7ced9e1b4/pic/pic_2.png -------------------------------------------------------------------------------- /pic/pic_push.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zedxpp/PPPrivatePodPushScript/51ff9a483f48caa867a0ff89b256bdc7ced9e1b4/pic/pic_push.png -------------------------------------------------------------------------------- /private-pod-push-script.sh: -------------------------------------------------------------------------------- 1 | # 调用配置文件 也可以向前向后配置路径如 . ./..//config.sh 2 | #. ./..//config.sh 3 | . ./config.sh 4 | 5 | #打印时间 6 | function displaysecs() { 7 | local T=$1 8 | local D=$((T/60/60/24)) 9 | local H=$((T/60/60%24)) 10 | local M=$((T/60%60)) 11 | local S=$((T%60)) 12 | (( $D > 0 )) && printf '%d days ' $D 13 | (( $H > 0 )) && printf '%d hours ' $H 14 | (( $M > 0 )) && printf '%d minutes ' $M 15 | (( $D > 0 || $H > 0 || $M > 0 )) && printf 'and ' 16 | printf '%d seconds\n' $S 17 | } 18 | 19 | # 打印红色的文本内容 出现异常时打印 20 | function echo_warning() 21 | { 22 | if [[ ${#1} > 0 ]]; then 23 | echo "\033[31mwarning: ${1}\033[0m" 24 | fi 25 | } 26 | 27 | # 打印绿色的文本内容 正常流程会使用这个打印 28 | function echo_success() 29 | { 30 | if [[ ${#1} > 0 ]]; then 31 | echo "\033[32m${1}\033[0m" 32 | fi 33 | } 34 | 35 | function log_line() 36 | { 37 | echo "========" 38 | } 39 | 40 | # 每次使用后必须置空 防止出错 41 | INPUT_NUMBER= 42 | # 必须输入数字才能继续后面的流程 43 | function circle_input() 44 | { 45 | if [[ ${#1} == 0 ]]; then 46 | echo "circle_input func未传入参数" 47 | exit 48 | fi 49 | 50 | while [[ ! "$INPUT_NUMBER" =~ [0-9] ]];do 51 | read -p "${1}" INPUT_NUMBER 52 | done 53 | } 54 | 55 | # 获取组件所在的文件夹和组件文件的路径 56 | TMP_MODULE_PATH="" 57 | TMP_MODULE_ADDRESS="" 58 | 59 | function get_module_path() 60 | { 61 | TMP_MODULE_PATH="${WORK_DIR}${ATTACH_DIR_PATH[$1]}" 62 | } 63 | 64 | function get_module_address() 65 | { 66 | TMP_MODULE_ADDRESS="${WORK_DIR}${ATTACH_DIR_PATH[$1]}${MODULES[$1]}${SUFFIX}" 67 | } 68 | 69 | 70 | if [[ ${#MODULES[*]} != ${#ATTACH_DIR_PATH[*]} ]]; then 71 | echo_warning "组件名数组和附加路径数组数量不一致!检查配置文件!" 72 | exit 73 | fi 74 | 75 | echo_success "组件总数量: ${#MODULES[*]}" 76 | 77 | # 标识文件是否存在 78 | IS_Exists=false 79 | function file_exists() 80 | { 81 | if [ -e $1 ]; then 82 | IS_Exists=true 83 | else 84 | IS_Exists=false 85 | fi 86 | } 87 | 88 | # 脚本所在目录 89 | SCRIPT_PATH=$(pwd) 90 | 91 | # 遍历所有组件名 判断文件是否存在 并展示 92 | MODULES_COUNT=${#MODULES[*]} 93 | NO=0 94 | for (( i = 0; i < MODULES_COUNT; i++ )); do 95 | # 角标+1获取编号 96 | NO=`expr $i + 1` 97 | # 获取组件路径 98 | get_module_address $i 99 | # 判断文件是否存在 100 | file_exists $TMP_MODULE_ADDRESS 101 | # 打印展示 打印全路径或者只打印module名 102 | # MODULE_PODSPEC="${NO}. ${TMP_MODULE_ADDRESS}" 103 | MODULE_PODSPEC="${NO}. ${MODULES[$i]}" 104 | if [[ $IS_Exists == true ]]; then 105 | echo "${MODULE_PODSPEC}" 106 | else 107 | echo_warning "${MODULE_PODSPEC} (文件未找到)" 108 | fi 109 | done 110 | 111 | log_line 112 | 113 | # 获取输入的组件编号 114 | # read -p "输入组件编号: " READ_INDEX 115 | 116 | circle_input "输入组件编号: " 117 | 118 | # 输入的数值-1转换成数组需要的角标 119 | INDEX=`expr $INPUT_NUMBER - 1` 120 | INPUT_NUMBER= 121 | 122 | log_line 123 | 124 | # 重新获取路径和文件地址 125 | get_module_path INDEX 126 | # echo $TMP_MODULE_PATH 127 | get_module_address INDEX 128 | # echo $TMP_MODULE_ADDRESS 129 | 130 | # 判断文件是否存在 不存在直接退出 131 | file_exists $TMP_MODULE_ADDRESS 132 | # echo $TMP_MODULE_ADDRESS 133 | # echo $IS_Exists 134 | if [[ $IS_Exists == false ]]; then 135 | echo_warning "${TMP_MODULE_ADDRESS} 文件未找到 或 输入的组件编号错误" 136 | exit 137 | fi 138 | 139 | # echo_success "选择的组件: ${MODULES[$INDEX]}" 140 | 141 | PODSPEC_NAME=${MODULES[$INDEX]} 142 | DIR_PATH=$TMP_MODULE_PATH 143 | PODSPEC_PATH=$TMP_MODULE_ADDRESS 144 | 145 | # 进入工作目录 146 | cd $DIR_PATH 147 | BRANCH_NAME=$(git symbolic-ref --short -q HEAD) 148 | # 显示当前工作目录的分支号 149 | echo_success "选择的组件 ${MODULES[$INDEX]} (${BRANCH_NAME}) " 150 | 151 | log_line 152 | 153 | # 1.0.0 这种版本号 154 | OID_VERSION='' 155 | NEW_VERSION='' 156 | # 真正写在文件中的版本号的那一整行文本内容 157 | OID_TMP_STRING='' 158 | NEW_TMP_STRING='' 159 | 160 | # 逐行匹配获取文件中的版本号 161 | while read line 162 | do 163 | # echo $line 164 | if [[ $line == s.version* ]]; then 165 | # echo $line 166 | # 匹配单引号或者双引号 167 | RE="\'([^\']*)\'" 168 | RE_DOUBLE="\"([^\"]*)\"" 169 | if [[ $line =~ $RE || $line =~ $RE_DOUBLE ]]; then 170 | OID_VERSION=${BASH_REMATCH[1]} 171 | echo_success "podspec版本号 $OID_VERSION" 172 | 173 | OID_TMP_STRING=$line 174 | # echo $OID_TMP_STRING 175 | fi 176 | break 177 | fi 178 | done < $PODSPEC_PATH 179 | 180 | log_line 181 | 182 | echo_success "组件仓库最后一次提交的标签版本号是 $(git describe --tags `git rev-list --tags --max-count=1`)" 183 | 184 | log_line 185 | 186 | 187 | read -p "输入需要设置的版本号: " parameter 188 | NEW_VERSION="$parameter" 189 | # echo "输入的版本号是 ${NEW_VERSION} " 190 | 191 | log_line 192 | 193 | if [[ ${#NEW_VERSION} == 0 ]]; then 194 | NEW_VERSION=$OID_VERSION 195 | echo_success "版本号未输入, 保持原样" 196 | else 197 | 198 | NEW_TMP_STRING=${OID_TMP_STRING/$OID_VERSION/$NEW_VERSION} 199 | 200 | # echo $OID_TMP_STRING 201 | # echo $NEW_TMP_STRING 202 | 203 | # pwd 204 | # 将输入的版本号整合成podspec文件中的一行文字 并且整行修改进去 205 | sed -i '' "s/${OID_TMP_STRING}/${NEW_TMP_STRING}/g" $PODSPEC_PATH 206 | echo_success "原版本号${OID_VERSION} 修改后的版本号${NEW_VERSION}" 207 | 208 | fi 209 | 210 | 211 | # echo "====输入提交注释====" 212 | read -p "输入需要提交的注释内容: " parameter 213 | READ_NEW_VERSION="$parameter" 214 | 215 | # 如果没有输入注释 那么默认注释是podspec文件版本号 216 | if [[ ${#READ_NEW_VERSION} == 0 ]]; then 217 | READ_NEW_VERSION=${NEW_VERSION} 218 | echo_success ">>>> 未输入注释, 默认使用push的tag号做为注释内容 <<<<" 219 | else 220 | echo_success ">>>> 输入的提交注释是: <<<<" 221 | echo_success "${READ_NEW_VERSION}" 222 | log_line 223 | fi 224 | 225 | 226 | SECONDS=0 227 | 228 | # 所有修改的文件全量提交 229 | git add . 230 | echo "====正在提交====" 231 | git commit -m "${READ_NEW_VERSION}" 232 | echo "====正在Push====" 233 | git tag -a ${NEW_VERSION} -m "${NEW_VERSION}" 234 | git push --tags 235 | git push 236 | echo "====Push完成====" 237 | log_line 238 | 239 | # 所有仓库目录名的数组 240 | ALL_REPO_DIR_NAME=() 241 | # IS_DIR=false 242 | COCOAPODS_PATH=~/.cocoapods/repos/ 243 | REPO_NAME= 244 | # 是否设置默认推送仓库目录 245 | IS_EXISTS_DEFAULT_REPO=false 246 | 247 | # push 记录写入的文件 判断完成后会删除 248 | TMP_LOG_FILE="${SCRIPT_PATH}/pppsTmpLog.txt" 249 | 250 | # 判断是否设置了默认推送仓库目录名, 并且目录名是真实存在 251 | if [ ${#DEFAULT_REPO_DIR_NAME} != 0 ] && [ -d "${COCOAPODS_PATH}${DEFAULT_REPO_DIR_NAME}" ] ; then 252 | IS_EXISTS_DEFAULT_REPO=true 253 | fi 254 | 255 | if [[ $IS_EXISTS_DEFAULT_REPO == false ]]; then 256 | # 默认忽略cocoapods的公有文件夹 257 | echo_success "检索到以下文件夹, 已忽略"master"文件夹" 258 | REPO_DIR_PATH= 259 | for dir in $(ls $COCOAPODS_PATH) 260 | do 261 | # [ -d $dir ] && echo $dir 262 | REPO_DIR_PATH=${COCOAPODS_PATH}${dir} 263 | if [ -d $REPO_DIR_PATH ] && [ $dir != master ] ; then 264 | # IS_DIR=true 265 | # else 266 | # IS_DIR=false 267 | ALL_REPO_DIR_NAME+=($dir) 268 | echo ${#ALL_REPO_DIR_NAME[*]}. $dir 269 | # echo $dir $IS_DIR 270 | # echo $dir 271 | fi 272 | done 273 | 274 | # read -p "输入需要Push到的文件夹编号: " REPO_INDEX 275 | circle_input "输入需要Push到的目标文件夹编号: " 276 | 277 | REPO_INDEX=`expr $INPUT_NUMBER - 1` 278 | INPUT_NUMBER= 279 | # echo ${ALL_REPO_DIR_NAME[${REPO_INDEX}]} 280 | # echo ${PODSPEC_PATH} 281 | REPO_NAME=${ALL_REPO_DIR_NAME[${REPO_INDEX}]} 282 | else 283 | REPO_NAME=$DEFAULT_REPO_DIR_NAME 284 | echo_success "读取到默认push repo文件夹 (${REPO_NAME})" 285 | 286 | fi 287 | 288 | pod repo push ${REPO_NAME} ${PODSPEC_PATH} ${PUSH_REPO_SOURCE} --allow-warnings --verbose --use-libraries | tee ${TMP_LOG_FILE} 289 | 290 | COUNT=0 291 | TOTAL_COUNT=3 292 | 293 | # 对写入到临时文件的内容进行逐行判断, 满足3个条件表示推送成功 294 | while read TMP_LINE 295 | do 296 | if [[ ${TMP_LINE} == "Adding the spec to the \`${REPO_NAME}' repo" || ${TMP_LINE} == "- [Update] ${PODSPEC_NAME} (${NEW_VERSION})" || ${TMP_LINE} == "Pushing the \`${REPO_NAME}' repo" ]]; then 297 | 298 | COUNT=`expr ${COUNT} + 1` 299 | 300 | fi 301 | done < $TMP_LOG_FILE 302 | 303 | # 移除临时的目录 304 | rm $TMP_LOG_FILE 305 | 306 | # 推送成功和推送失败的提示不一样 307 | if [[ ${COUNT} == ${TOTAL_COUNT} ]]; then 308 | echo_success "推送成功!!!!" 309 | # echo_success "用时: ${SECONDS}s" 310 | echo_success "用时: $(displaysecs ${SECONDS})" 311 | echo_success "${PODSPEC_NAME} (${BRANCH_NAME}) 组件 ${NEW_VERSION} 版本 已提交到 ${REPO_NAME}" 312 | else 313 | echo_warning "推送失败, 请检查!!!!" 314 | fi 315 | 316 | 317 | 318 | # echo_success "${READ_NEW_VERSION}" 319 | 320 | 321 | 322 | 323 | --------------------------------------------------------------------------------