版本记录
版本号 | 时间 |
---|---|
V1.0 | 2021.11.14 星期日 |
前言
随着App的持续功能迭代和常年的运营,最终包都会越来越大,包太大苹果那边会给限制,不利于用户下载。所以App瘦身也是一项需要持续做的事。正好我这几天就在做瘦身的事,这里记录一下,大家一起学习和交流。感兴趣的可以看下面几篇文章。
1. App包瘦身(一) —— App包瘦身初探(一)
主要内容
主要内容:本文主要做的就是基于
pre-commit
代码提交时,对所提交图片进行自动化压缩,这个过程对于提交代码的人是无感知的。可以实现自动化压缩并提交这个过程。
下面我们开始。
pre-commit简介
pre-commit
是什么?字面的意思就是commit
之前,那这个是用来干什么的呢?这就不得不从git说起。
pre-commit
在commit
之前,是一个hook
,也可以称为钩子,这个东西有什么用呢?就是你可以利用这个hook
在commit
之前做一些提交之前的检测或压缩或者其他的自定义脚本。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
等格式的文件,如果包含的话就会调用imagecompress
的python
脚本进行自动化的压缩。
下面看下压缩脚本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
的图片提交的自动化压缩,感兴趣的给个赞或者关注~~~~