NO.4 项目无法一键打包?自己写个shell脚本吧

零蚀


目录

🔗 前言
🔗 Android 知识栈
🔗 Android 散装系列
🔗 NO.1 Handler->就这?
🔗 NO.2 Android 垃圾回收机制
🔗 NO.3 Android 测量、排版那点事
🔗 NO.5 EventBus 浅谈


问题出现

  • 矛盾出现
    • 本来是一个愉快的周五,公司里大家都普遍认为,周五要带着愉快的心情来看看今天有没有小bug,缓一缓最近的工作进度,为这一周做个总结,然后考虑一下,这周末的安排,但是,我还没想好端午节该学点啥时,产品突然来让我打个包,打包一般是一个比较死板的活,只要知道对应的命令即可,当然,打渠道包有时也很麻烦(在没有一件打包的情况下)。

    • 公司用的是walle,打包的方式,打包前要先去解注自己要打的渠道,然后,选择自己打包的命令,才能打包,我在网上也搜了很多教程,但是没有一个可以用的一件打包,然后就是因为网上没有一个可用的一键打包,即使可用,也是要很多操作。所以在痛苦的整了1个小时后,没有找到合适的方法,只能手动打包了。具体流程如下所示,我们要现在channel中释放自己的渠道(第一次还打错了)。

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-voOCcyda-1593185533198)(media/15931791016226/15931810800965.jpg)]

    • 但是,问题来了,如果产品哪天突然来说,给我来20个包,想必就不快乐了吧,感觉心里满满的不爽,也许你说,我现在的项目有更先进的库,但是如果你要处理一个老项目,像我这样,只能靠一个一个手动来处理怎么办,所以万事不如写脚本。


构建思路

  • 三步走
    1. step 1: 将build的临时文件全部清理掉,这个主要是删除之前的包,防止打包时候还有些我不要的,还要挑。

    2. step 2: 将channel里面的渠道进行选择性的注释和释放,这个必须有,相比于手动注释、释放渠道来说,这个必须要解放双手,不然,自己弄着弄着都不知道自己做了啥。打包打一半发现注释的和打包命令对不上,多难过啊,还不知道之前有没有遗漏的错。

    3. step 3: 匹配gradle命令,循环进行打包,这个主要通过gradlew来实现

  • 脚本语言的选择
    • 这里我第一个想到的是shell,为什么选择shell脚本,因为mac里一直用的就是shell命令,自来熟,而且这个比较好用,因为设计中是要调用gradlew命令的,对于shell这方面我觉得对于我更简单。当然shell有个非常好的有点,就是mac和window可以通用,只要你有git,你就有bash,你就可以用bash。

    • 然后我第二个想到的是python,python最大的好处是可以做pyqt的界面控制,但是对于如果想调用gradlew这方面就不清楚了。 但是python打包是极为不方便的,window和macos是两种不同的东西,所以我想做一个,大家都方便的脚本,肯定就不能选这玩意了。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-33x2MbPY-1593185533201)(media/15931791016226/15931823398031.jpg)]


shell编码

  • 遍历用户输入渠道号
    • 首先肯定是要解决渠道号这个问题,因为我们要构建一个一次可以输入很多很多渠道号进行轮循打包的,所以要用户自己输入一连串的渠道号,我们便就好。设计思路如下:

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4wTTdKhQ-1593185533202)(media/15931791016226/15931827996320.jpg)]

      if [[ $1 == "" ]]
      then
          echo "请输入渠道包的渠道号"
          exit
      fi
      #  循环便利用户输入
      for i in $(seq 1 $#)
      do
          # 解码渠道号的函数
          decodeChannelNum $1
          shift
      done
      
    • 这里我先判断第一个参数是不是为空,如果为空,说明用户没有输入,则没有渠道号,就不用打包了,然后开始遍历 $1 $2 $3第一个、第二个、第三个参数,这里的shift是摒弃第一个参数,后面的参数位置都向前移一位。所以我们使用第二个参数时还是$1

  • 打包类型
    • 第二步我们要知道,我们打得是什么包,是Debug?还是Release包,所以啊,我们需要让用户自己选择。

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kgqw7GLI-1593185533204)(media/15931791016226/15931834189436.jpg)]

      echo "请输入参数0->打Debug包,输入1->打Release包:"
      read type_pkg
      while [[ $type_pkg != 0 && $type_pkg != 1 ]]
      do
          echo "你的参数有误,请输入参数0->打Debug包,输入1->打Release包:"
          read type_pkg
      done
      
      echo "--------------------------开始clean掉build内容--------------------------"
      ../gradlew clean
      echo "--------------------------build清理完毕--------------------------"
      
      
    • 我们这里如果用户输入错误,我们需要循环提醒他,输入正确的参数,来确定打包打什么类型的。

  • 注释掉channel 渠道号
    • 我们的channel文件可能是之前用过的,可能有一些不是我们需要的渠道号被被解开了,我们需要的被注释了。而且有些渠道号后面可能还有一些注解。这样的话我们就要对shell文件操作,并多字符串进行一些处理,这在numpy上叫做洗数据😂。我们来好好洗洗数据。

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OR4FaXnM-1593185533205)(media/15931791016226/15931836457504.jpg)]

    • 逻辑很简单,读一行,先把所有没注释的注释掉,然后遍历,将我们需要的打开,这里sed -i '' "$位置行数s/旧数据/新数据/",这代码就是将某一行的就数据,变成新数据。这里重新初始化了数据,将所有的数据注释掉。

      #重新整理渠道号,将没有注释的全注掉
      #这里行数从0开始计数,但是命令从1开始计数
      resetData(){
          index=0
          cat channel | while read line
          do
              let index=index+1
      
              if [[ ${line:0:1} != "#" ]]
              then
                  sed -i '' "${index}s/$line/#$line/" channel
              fi
      
      
          done
          index=0
      }
      
    • 然后我们要开始开放我们的渠道号,方法和上面差不多,然后渠道数据处理完毕,我们就要开始开启打包任务了。

      #将对应的渠道号解封
      decodeChannelNum(){
      
          resetData
          
          index=0
          cat channel | while read content
          do
              let index=index+1
              temp=${content#*#}
              channelNum=${temp%%#*}
              # 去空格
              if [[ $(echo $channelNum | grep "$1") != "" ]]
              then
                  echo ""
                  sed -i '' "${index}s/$content/${content:1}/" channel
                  # 开启打包任务
                  packageTasks $1
              fi
          done
          
          index=0
      
      }
      
    • 我们接下来要过滤命令,这步很关键,我也在这里卡了很久,好几个小时吧,不是说逻辑问题,它里面存在一个不明显的bug,一不小心就容易中招,我们先看代码。

      # 遍历所有的打包任务,找到对应的打包任务的命令
      packageTasks(){
          dealNead=0
          resultCommond=""
          echo $re
          ../gradlew tasks --all | grep -v total > outfile
          while read commond
          do
          
              if [[ $commond == $task_category ]]
              then
                  dealNead=1
              fi
      
              #开始洗数据
              if [[ $dealNead == 1 ]]
              then
                   if [[ $commond == assemble* ]]
                   then
                      originCommod=$(echo ${commond%%-*})
      
      
                      if [[ $originCommod == *Channels ]]
                      then
                          result=$(echo $originCommod | grep "$1")
      
                          if [[ $result != "" ]]
                          then
                              if [[ $(echo $(packageItem $(echo $originCommod) $1)) != "" ]]
                              then
                                  resultCommond=$originCommod
                              fi
                          fi
                      fi
                   fi
              fi
          done < outfile
          rm -f outfile
          echo "resultCommond=$resultCommond"
          ../gradlew $resultCommond
          echo "打包$(echo $resultCommond)完成"
          dealNead=0
      }
      
      
    • 这里是判断是否命令是我们需要的,首先我判断了这里有没有头部匹配的命令,然后判断了有没有尾部匹配的命令,然后判断有没有包含关键字的命令,这样保证命令的唯一性。但是细心的人会发现我这里没有用管道的方式进行循环,而是用的重定义的方式,为什么呢?

    • 首先说一点,我们在遍历所有的task命令时../gradlew tasks --all,当这句代码没有结束的时候,我们是不可以打包,如果我们在遍历中间打包了,那么两个task将会死锁,程序就卡壳了,不要问为什么会发生,没深入研究。

    • 但是我们还要明白一点,管道(../gradlew tasks --all | while read commond)的方式遍历,它内部是将代码放在另一个shell中跑的,不是我们运行的当前的shell,所以里面的所有的变量,不能被拿出来,只能在循环里使用,所以到这一步,gradlew 和 管道 业务逻辑上就发生了死锁,所以我们不能用管道,所以我能用重定义。

    • 重定义是将../gradlew tasks --all所有的内容先写入一个临时文件outfile中,然后我们将outfile的内容通过重定义方式,注入while循环中,这样就可以拿到我们循环里的参数值了,当然,用完记得删除临时文件。

    • 到这里一个简单的脚本就完成了,可以输个命令去喝个茶,等它自己打完。


总结

  • 当然这个脚本还有很多问题,比如说这里的文件位置都是写死的,文件名也是写死的,当然我们的老项目的文件位置,和渠道的命名方式也是一致的,所以没有必要再优化。所以这个脚本的局限性很强。

  • 除了上述问题,我们还有一个问题,就是如果项目很老,但是java版本很新是不能使用gradlew命令的,因为java和gradle版本冲突了,所以我们可以在vi ~/.zshrc中做一个开关,可以选择自己需要的java版本(like this)。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lmZf5ueQ-1593185533206)(media/15931791016226/15931723353408.jpg)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零蚀zero eclipse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值