├── LICENSE ├── README.md └── checkPodsUpdate.sh /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 姜沂 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | # 需求原因 8 | 9 | > 做了半年的组件化了,原本的项目由一个集中式的仓库开发被拆分为几十个基础组件,还有各种业务组件。仓库在逻辑上分离也给开发和测试带来了很多好处。当然也有不好的地方。业务方的同事对这方面更为敏感,由于开发的时候壳工程有原来的依赖十几个第三方Pod变成了现在依赖将近上百个Pod,频繁的install 或者 update,偶尔会意外造成某些库更新,这些更新可能是不稳定的,而且QA由于不知道这些修改,会导致突然有些bug出现,有时候会造成不必要的沟(Si)通(Bi)。 10 | > 所以业务方的同学提了一个模糊的需求: 我能不能在每次install 或者update的时候自动检测到第三方Pod的更新,来给我提示,让我重新check这些Pod是否真的需要更新或者是不稳定的版本。`之所以说是模糊的,可能确实由于我们确实也不太知道我们需要怎么做,只是有痛点。` 11 | > 12 | > 不过既然有了痛点,就要去解决。先做出来一般之后在修改。 13 | 14 | # 尝试方案 15 | 16 | > 我收到这个需求的时候,也确实有点懵逼,因为可能最初只是一点抱怨,说的也不明确,我刚开始也没什么思路。不过仔细想了想之后发现,可以把需求整理为2个核心目标。 17 | 18 | 1. 检测更新 19 | 2. 通知开发者有变化 20 | 21 | ## 检测更新 22 | 23 | 作为一个iOS开发者我们要熟悉我们使用的工具,我们知道Pod如何来绑定版本的变化,使用的是当前工作目录的`Podfile.lock`文件,那么我在每次Pod更新前,我用脚本去分析下新旧文件,如果更新了则是有库发送了变化,再去通知开发者。 24 | 说起来简单,不过我这种shell 0基础选手怎么办,当然是学了 25 | 这里找到了[shell30分钟入门教程](http://www.runoob.com/linux/linux-shell.html ) 26 | 说起来30分钟不过我这种笨人学了3个小时才练习完,不过shell脚本确实非常实用,推荐读者去学习下,在平时的开发中确实能帮到自己。 27 | 28 | 学完shell之后,我写了个脚本要求开发者使用我的脚本进行Pod install 或者 update等。不能再直接终端执行这个命令 。 29 | 30 | ![install](http://ompeszjl2.bkt.clouddn.com/%E8%87%AA%E5%8A%A8%E6%A3%80%E6%B5%8B%E7%AC%AC%E4%B8%89%E6%96%B9Pod%E5%B0%8F%E5%B7%A5%E5%85%B7/1.png) 31 | 代码逻辑如下 32 | ```sh 33 | 34 | echo "请输入Pod command 相关参数 " 35 | echo "1 : install" 36 | echo "2 : update" 37 | echo "3 : install --verbose --no-repo-update" 38 | echo "4 : update --verbose --no-repo-update" 39 | echo "5 : 自定义参数" 40 | podcommandParam="install" 41 | while read podCommandInputParam 42 | do 43 | case ${podCommandInputParam} in 44 | 1) 45 | podcommandParam="install" 46 | break 47 | ;; 48 | 2) 49 | podcommandParam="update" 50 | break 51 | ;; 52 | 3) 53 | podcommandParam="install --verbose --no-repo-update" 54 | break 55 | ;; 56 | 4) 57 | podcommandParam="update --verbose --no-repo-update" 58 | break 59 | ;; 60 | 5) 61 | echo "请输入自定义参数" 62 | read podcommandParam 63 | break 64 | ;; 65 | *) 66 | echo "输入有错请重新输入" 67 | ;; 68 | esac 69 | 70 | done 71 | 72 | 73 | echo "您选择的是-------${podcommandParam}" 74 | ``` 75 | 76 | ### 备份逻辑 77 | 78 | 到这一步我们就可以去做备份功能了。 79 | Q: 为什么备份? 80 | A: 每次执行Pod命令 `CocoaPod`都会进行原地修改,涉及到三个东西 `*.xcworkspace` `Podfile.lock` `Pods/` ,回忆一下以往执行命令的时候,你执行pod命令的时候可能还报过错,但是发现整个的几千个文件瞬间都发送变化了,真是非常恶心。有了备份之后我们还可以在pod执行错误的时候恢复这三个东西的原来面目,不用我们每次再用sourcetree去重置文件。 81 | 82 | Pod 命令执行完有两种情况 83 | 1. 执行成功 ----> 检测更新 --> 删除备份 84 | 2. 执行失败------> 恢复文件,删除备份--->并报错 85 | 86 | 下面是基本的代码逻辑 87 | ```sh 88 | function beforePod() { 89 | 90 | #先复制一份原始的lock文件 和 Pods文件夹 91 | echo "正在备份资源" 92 | cp ${oriPodLockName} ${backPodLockName} >> ${logFile} 93 | cp -a ${oriPodsDIR} ${backPodsDIR} >> ${logFile} 94 | cp -a ${currentworkSpace} ${backworkSpaceDIR} >> ${logFile} 95 | } 96 | function afterPod() { 97 | echo "资源后续清理" 98 | rm ${backPodLockName} >> ${logFile} 99 | rm -rf ${backPodsDIR} >> ${logFile} 100 | rm -rf ${backworkSpaceDIR} >> ${logFile} 101 | } 102 | function recoverPod() { 103 | echo "正在恢复原始文件" 104 | mv -f ${backPodLockName} ${oriPodLockName} 105 | 106 | rm -rf ${oriPodsDIR} >> ${logFile} 107 | cp -a ${backPodsDIR} ${oriPodsDIR} >> ${logFile} 108 | rm -rf ${backPodsDIR} >> ${logFile} 109 | # mv -f ${backPodsDIR} ${oriPodsDIR} 110 | rm -rf ${currentworkSpace} >> ${logFile} 111 | cp -a ${backworkSpaceDIR} ${currentworkSpace} >> ${logFile} 112 | rm -rf ${backworkSpaceDIR} >> ${logFile} 113 | 114 | } 115 | ``` 116 | 117 | ### 检测更新 118 | 119 | ```sh 120 | echo "-------------------------------当前发生变更的pod库---------------------------------" >> ${diffchangeFile} 121 | echo "--------------------------------------------------------------------------------" >> ${diffchangeFile} 122 | for (( i = 0; i < 3; i++ )); do 123 | echo "" 124 | done 125 | ### something 126 | diff ${oriPodLockName} ${backPodLockName} -H >> ${diffchangeFile} 127 | echo "-----------------------------当前发生变更的第三方文件统计----------------------------" >> ${diffchangeFile} 128 | echo "--------------------------------------------------------------------------------" >> ${diffchangeFile} 129 | for (( i = 0; i < 3; i++ )); do 130 | echo "" 131 | done 132 | diff ${backPodsDIR} ${oriPodsDIR} -r -B -a | diffstat >> ${diffchangeFile} 133 | 134 | 135 | echo "-------------------------当前发生变更的第三方文件变化详细统计-------------------------" >> ${diffchangeFile} 136 | echo "--------------------------------------------------------------------------------" >> ${diffchangeFile} 137 | for (( i = 0; i < 3; i++ )); do 138 | echo "" 139 | done 140 | diff ${backPodsDIR} ${oriPodsDIR} -r -B -b >> ${diffchangeFile} 141 | ``` 142 | 143 | 144 | ## 通知开发者 145 | 146 | 目前我做的是直接打开文件来给开发者看 147 | 148 | 149 | ```sh 150 | 151 | open -a Atom ${diffchangeFile} 152 | 153 | if [ $? != 0 ] 154 | then 155 | open -a Xcode ${diffchangeFile} 156 | fi 157 | 158 | if [ $? != 0 ] 159 | then 160 | open ${diffchangeFile} 161 | fi 162 | 163 | ``` 164 | 165 | 166 | ## 完整演示 167 | 168 | 这是一个失败的演示: 169 | 170 | ![checkErr](http://ompeszjl2.bkt.clouddn.com/%E8%87%AA%E5%8A%A8%E6%A3%80%E6%B5%8B%E7%AC%AC%E4%B8%89%E6%96%B9Pod%E5%B0%8F%E5%B7%A5%E5%85%B7/checkError.gif) 171 | 172 | 这是一个成功的演示 173 | 174 | ![checkSuccess](http://ompeszjl2.bkt.clouddn.com/%E8%87%AA%E5%8A%A8%E6%A3%80%E6%B5%8B%E7%AC%AC%E4%B8%89%E6%96%B9Pod%E5%B0%8F%E5%B7%A5%E5%85%B7/checkSuccss.gif) 175 | 176 | ## 后记 177 | 178 | > 后面拿着给业务方的同学看了,业务方感叹效率,觉得做的很快,不过还有几点不足(其实就是不满意喽),。 179 | 1. 我们这么大的团队(30iOS 左右)靠开发者主动使用脚本这个约束并不是特别好,如果有新人入职不知道怎么办,有时候着急忘记了怎么办。 180 | 2. 开发者万一没有仔细看log'怎么办,我们需要一个留存的证据 ,比如邮件,这样在出bug的时候就嘿嘿嘿的甩锅给他喽。 181 | 182 | 后面的话和安卓的朋友一起沟通说可以放在server端去做,我们使用的CR平台是gerrit,gerrit能检测到开发者merge代码。可以在这个时候去做,检测 并且可以直接利用邮件系统发给开发组的全组同学,大大降低出现风险的机会。 183 | 不过作为一次学习的记录还是总结一下分享给大家。 184 | [原文地址 ](https://www.valiantcat.cn/index.php/2017/03/13/30.html/) 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /checkPodsUpdate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | oriPodLockName="Podfile.lock" 3 | oriPodsDIR="Pods" 4 | backPodLockName="backPodfile.lock" 5 | backPodsDIR="backPodsDIR" 6 | logFile=`date "+%Y_%m_%d_%H_%M_%S"` 7 | logFile="${logFile}PodErrMsg.txt" 8 | currentDIR=`pwd` 9 | currentworkSpace="" 10 | backworkSpaceDIR="backworkSpaceDIR.xcworkspace" 11 | diffchangeFile=`date "+%Y_%m_%d_%H_%M_%S"` 12 | diffchangeFile="${diffchangeFile}diffChange.txt" 13 | function getcurrentWorkSpace() { 14 | workspacePostFix=".xcworkspace" 15 | for file_a in ${currentDIR}/* 16 | do 17 | result=$(echo $file_a | grep "${workspacePostFix}") 18 | if [[ "$result" != "" ]] 19 | then 20 | currentworkSpace=$result 21 | fi 22 | done 23 | } 24 | getcurrentWorkSpace 25 | 26 | function beforePod() { 27 | 28 | #先复制一份原始的lock文件 和 Pods文件夹 29 | echo "正在备份资源" 30 | cp ${oriPodLockName} ${backPodLockName} >> ${logFile} 31 | cp -a ${oriPodsDIR} ${backPodsDIR} >> ${logFile} 32 | cp -a ${currentworkSpace} ${backworkSpaceDIR} >> ${logFile} 33 | } 34 | function afterPod() { 35 | echo "资源后续清理" 36 | rm ${backPodLockName} >> ${logFile} 37 | rm -rf ${backPodsDIR} >> ${logFile} 38 | rm -rf ${backworkSpaceDIR} >> ${logFile} 39 | } 40 | function recoverPod() { 41 | echo "正在恢复原始文件" 42 | mv -f ${backPodLockName} ${oriPodLockName} 43 | 44 | rm -rf ${oriPodsDIR} >> ${logFile} 45 | cp -a ${backPodsDIR} ${oriPodsDIR} >> ${logFile} 46 | rm -rf ${backPodsDIR} >> ${logFile} 47 | # mv -f ${backPodsDIR} ${oriPodsDIR} 48 | rm -rf ${currentworkSpace} >> ${logFile} 49 | cp -a ${backworkSpaceDIR} ${currentworkSpace} >> ${logFile} 50 | rm -rf ${backworkSpaceDIR} >> ${logFile} 51 | 52 | } 53 | function diffchange() { 54 | echo "-------------------------------当前发生变更的pod库---------------------------------" >> ${diffchangeFile} 55 | echo "--------------------------------------------------------------------------------" >> ${diffchangeFile} 56 | for (( i = 0; i < 3; i++ )); do 57 | echo "" 58 | done 59 | ### something 60 | diff ${oriPodLockName} ${backPodLockName} -H >> ${diffchangeFile} 61 | echo "-----------------------------当前发生变更的第三方文件统计----------------------------" >> ${diffchangeFile} 62 | echo "--------------------------------------------------------------------------------" >> ${diffchangeFile} 63 | for (( i = 0; i < 3; i++ )); do 64 | echo "" 65 | done 66 | diff ${backPodsDIR} ${oriPodsDIR} -r -B -a | diffstat >> ${diffchangeFile} 67 | 68 | 69 | echo "-------------------------当前发生变更的第三方文件变化详细统计-------------------------" >> ${diffchangeFile} 70 | echo "--------------------------------------------------------------------------------" >> ${diffchangeFile} 71 | for (( i = 0; i < 3; i++ )); do 72 | echo "" 73 | done 74 | diff ${backPodsDIR} ${oriPodsDIR} -r -B -b >> ${diffchangeFile} 75 | 76 | open -a Atom ${diffchangeFile} 77 | 78 | if [ $? != 0 ] 79 | then 80 | open -a Xcode ${diffchangeFile} 81 | fi 82 | 83 | if [ $? != 0 ] 84 | then 85 | open ${diffchangeFile} 86 | fi 87 | 88 | } 89 | function install() { 90 | 91 | echo "请输入Pod command 相关参数 " 92 | echo "1 : install" 93 | echo "2 : update" 94 | echo "3 : install --verbose --no-repo-update" 95 | echo "4 : update --verbose --no-repo-update" 96 | echo "5 : 自定义参数" 97 | podcommandParam="install" 98 | while read podCommandInputParam 99 | do 100 | case ${podCommandInputParam} in 101 | 1) 102 | podcommandParam="install" 103 | break 104 | ;; 105 | 2) 106 | podcommandParam="update" 107 | break 108 | ;; 109 | 3) 110 | podcommandParam="install --verbose --no-repo-update" 111 | break 112 | ;; 113 | 4) 114 | podcommandParam="update --verbose --no-repo-update" 115 | break 116 | ;; 117 | 5) 118 | echo "请输入自定义参数" 119 | read podcommandParam 120 | break 121 | ;; 122 | *) 123 | echo "输入有错请重新输入" 124 | ;; 125 | esac 126 | 127 | done 128 | 129 | 130 | echo "您选择的是-------${podcommandParam}" 131 | beforePod 132 | echo "正在使用Pod命令" 133 | 134 | pod ${podcommandParam} 2>> ${logFile} 135 | if [ $? != 0 ] 136 | then 137 | recoverPod 138 | echo "Pod 命令执行失败 请检查是错误信息" 139 | open ${logFile} 140 | exit 1 141 | fi 142 | 143 | diffchange 144 | 145 | afterPod 146 | } 147 | 148 | 149 | install 150 | --------------------------------------------------------------------------------