美文网首页CodeEase
App包瘦身(二) —— 基于pre-commit的图片提交的自

App包瘦身(二) —— 基于pre-commit的图片提交的自

作者: 刀客传奇 | 来源:发表于2021-11-14 18:59 被阅读0次

版本记录

版本号 时间
V1.0 2021.11.14 星期日

前言

随着App的持续功能迭代和常年的运营,最终包都会越来越大,包太大苹果那边会给限制,不利于用户下载。所以App瘦身也是一项需要持续做的事。正好我这几天就在做瘦身的事,这里记录一下,大家一起学习和交流。感兴趣的可以看下面几篇文章。
1. App包瘦身(一) —— App包瘦身初探(一)

主要内容

主要内容:本文主要做的就是基于pre-commit代码提交时,对所提交图片进行自动化压缩,这个过程对于提交代码的人是无感知的。可以实现自动化压缩并提交这个过程。

下面我们开始。


pre-commit简介

pre-commit是什么?字面的意思就是commit之前,那这个是用来干什么的呢?这就不得不从git说起。

pre-commitcommit之前,是一个hook,也可以称为钩子,这个东西有什么用呢?就是你可以利用这个hookcommit之前做一些提交之前的检测或压缩或者其他的自定义脚本。hooks是一些自定义的脚本,用于控制git工作的流程,分为客户端钩子和服务端钩子。

  • 客户端钩子包括:pre-commit、prepare-commit-msg、commit-msg、post-commit等,主要用于控制客户端git的提交工作流。
  • 服务端钩子:pre-receive、post-receive、update,主要在服务端接收提交对象时、推送到服务器之前调用。

git hooks位置位于每个git项目下的隐藏文件夹.git中的hooks文件夹里,进去后会看到一些hooks的官方示例,他们都是以.sample结尾的文件名。具体如下图所示:

注意:这些以.sample结尾的示例脚本需要重新更改才会实现想要的结果。

下面我们可以简单的看一下pre-commit.sample里默认都是什么。

#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
    against=HEAD
else
    # Initial commit: diff against an empty tree object
    against=$(git hash-object -t tree /dev/null)
fi

# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --bool hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
    # Note that the use of brackets around a tr range is ok here, (it's
    # even required, for portability to Solaris 10's /usr/bin/tr), since
    # the square bracket bytes happen to fall in the designated range.
    test $(git diff --cached --name-only --diff-filter=A -z $against |
      LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
    cat <<\EOF
Error: Attempt to add a non-ASCII file name.

This can cause problems if you want to work with people on other platforms.

To be portable it is advisable to rename the file.

If you know what you are doing you can disable this check using:

  git config hooks.allownonascii true
EOF
    exit 1
fi

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --

上面就是默认的,下面我们就是对这个pre-commit进行定制化,并在其中植入图片压缩的脚本,这样当commit代码的时候会检查,你提交的内容,如果是png、jpg等格式的图片,就会运行python脚本对该图片进行压缩。

下面是修改以后的hook文件夹目录。


pre-commit修改

pre-commit.sample文件进行的修改。主要就是修改为以下内容:

#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
    against=HEAD
else
    # Initial commit: diff against an empty tree object
    against=xxxxxxxx
fi

# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --bool hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

filepath=$(cd "$(dirname "$0")"; pwd)  

branch=$(git symbolic-ref --short HEAD)

git diff --cached --name-only --diff-filter=ACMR -z $against | while read -d $'\0' f; do
if [[ $f == *".png" || $f == *".jpg" || $f == *".jpeg" || $f == *".webp" ]];then
    path="$(cd "$(dirname "$0")";cd ..;cd ..; pwd)/$f"
    python "$filepath/imagecompress.py" $path $branch
    exec git add $f
fi


done

# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
    # Note that the use of brackets around a tr range is ok here, (it's
    # even required, for portability to Solaris 10's /usr/bin/tr), since
    # the square bracket bytes happen to fall in the designated range.
    test $(git diff --cached --name-only --diff-filter=A -z $against |
      LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
    cat <<\EOF
Error: Attempt to add a non-ASCII file name.

This can cause problems if you want to work with people on other platforms.

To be portable it is advisable to rename the file.

If you know what you are doing you can disable this check using:

  git config hooks.allownonascii true
EOF
    exit 1
fi

# If there are whitespace errors, print the offending file names and fail.
# exec git diff-index --check --cached $against --

这里的作用就是首先判断提交的代码,是不是包含.png/.jpeg/.webp等格式的文件,如果包含的话就会调用imagecompresspython脚本进行自动化的压缩。

下面看下压缩脚本imagecompress

# -*- coding: utf-8 -*-
import urllib2
import json
import sys
import os
from base64 import b64encode

class ImageHelper:
    def __init__(self, imagePath, branch):
        self.imagePath = imagePath
        self.branch = branch
    def compress(self):
        file_name = '%s.txt' % self.branch
        file_name = file_name.replace('/', ',');
        path = '%s/%s' % (sys.path[0],file_name)
        print 'path %s' % path
        fp = open(path, 'a')
        print 'compressing %s ...' % self.imagePath
        data = open(self.imagePath, 'rb').read()
        print 'size before compress: %d' % len(data)
        apikey = '自己申请的api key'
        req = urllib2.Request('https://api.tinify.com/shrink', data=data)
        req.add_header('Authorization', 'Basic %s' % b64encode(bytes("api:" + apikey).decode('ascii')))
        try:
            res = urllib2.urlopen(req)
        except urllib2.HTTPError:
            print 'request failed'
            context = 'imagePath: %s ; request failed\n' % (self.imagePath)
            fp.write(context)
            return
        if res.getcode() == 201:
            url = res.headers.get('Location')
            result = json.loads(res.read())
            newlength = result['output']['size']
            print 'compress completed! url: %s length %d' % (url, newlength)
            newdata = urllib2.urlopen(url).read()
            open(self.imagePath, 'wb').write(newdata)
            context = 'imagePath: %s ; oldlength: %d ; newlength: %d\n' % (self.imagePath, len(data), newlength)
            fp.write(context)
        else:
            print 'compress failed, try again'
            context = 'imagePath: %s ; compress failed\n' % (self.imagePath)
            fp.write(context)
            compress()

        fp.close()


def main():
    image_helper = ImageHelper(sys.argv[1],sys.argv[2])
    image_helper.compress()
    print "~~~~~~~~~~~~~~~~~~~~~~"

if __name__=='__main__':
    main()

实践结果

下面我们就对上面的理论进行实践。

1. png图片

我们先看下准备的png图片,大小为4.2MB,如下图所示:

然后我们把图片放到项目里,并打开终端,用git commit命令进行提交。具体提交记录如下:

可以看见,终端输出了compress completed!。然后我们看项目里这个图片文件。

[图片上传失败...(image-dec60-1636887416755)]

可以看见提交的这个图片大小变为了707KB。完美进行了自动化压缩。

2. JPG图片

这个测试过程和上面也是一样的,也是准备图片,然后放入工程里,提交代码这个流程。

测试材料


测试结果

需要说明的是,不仅仅是终端提交git commit命令可以,就是sourceTree提交也可以触发这个自动化的压缩过程,因为都会去触发pre-commit的那个钩子。

到此为止,这个简单的问题应该就说明白了,欢迎大家指正错误。

后记

本篇主要讲述了基于pre-commit的图片提交的自动化压缩,感兴趣的给个赞或者关注~~~~

相关文章

网友评论

    本文标题:App包瘦身(二) —— 基于pre-commit的图片提交的自

    本文链接:https://www.haomeiwen.com/subject/lirxtrtx.html