预提交和 Git Hooks:自动化高质量代码

如何使用预提交和 git hooks 提高代码质量

       欢迎来到雲闪世界     什么是预先提交?
Pre-commit是一个 Python 包,它使创建预提交钩子变得更容易。钩子是 git 的原生功能,是在执行特定 git 命令之前运行的脚本。

您可以在 repo.git/hooks目录中找到钩子,该目录由 git 自动填充。如果您查看此目录,您将找到如下所示的文件:

applypatch-msg.sample pre-commit.sample prepare-commit-msg.sample 
commit-msg.sample pre-merge-commit.sample push-to-checkout.sample 
fsmonitor-watchman.sample pre-push.sample update.sample 
post-update.sample pre-rebase.sample 
pre-applypatch.sample pre-receive.sample

扩展阻止了这些钩子的执行。要启用这些钩子,请删除该.sample扩展并编辑文件。

然而,这很繁琐,不太方便用户使用,而且很难通过版本控制进行管理。这就是预提交的作用所在。它为命令创建一个钩子,commit以自动检测代码中的任何问题,并使创建脚本变得无缝。

它会创建一个配置文件,在调用命令时执行git commit。如果配置文件中的任何检查失败,则提交将被中止。这可确保您的代码库始终保持质量和一致性。
为什么要进行数据科学?
您可能想知道,如果您是数据科学家,为什么还需要学习 git hooks。好吧,社区内部发生了变化,精通软件工程变得越来越重要,能够将自己的模型部署到生产中非常有价值。确保机器学习模型的稳健部署并保持良好代码质量的一种技术是使用 git hooks 和预提交。机器学习模型非常复杂,因此,在模型投入生产之前,您可以采取任何措施来自动化工作流程并捕获潜在错误,这是理想的做法。
用法
安装
安装 pre-commit 非常简单,与使用 pip 安装任何其他 Python 库相同。我个人使用Poetry,但它们都可以正常工作。

pip install pre-commit # pip 
poetry add pre-commit # I personally use poetry

您可以通过运行来确认其已安装。

pre-commit --version

配置文件
导航到您的存储库的根目录

touch .pre-commit-config.yaml 

在您的项目中创建一个。您可以通过运行以下命令来执行此操作:

触摸.预提交配置.yaml
此文件将定义您在提交代码之前要运行的内容。示例如下:

repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v2.3.0
    hooks:
    -   id: check-yaml
    -   id: end-of-file-fixer
    -   id: trailing-whitespace

-   repo: https://github.com/psf/black
    rev: 22.10.0
    hooks:
    -   id: black

- repo: https://github.com/PyCQA/flake8
  rev: v6.0.0 
  hooks:
    - id: flake8
      additional_dependencies: [flake8-docstrings, flake8-import-order]
      args: ['--max-line-length=88']

这里发生的事情是,repos指示包含我们想要运行的钩子的存储库列表。第一个是pre-commit-hooks包含钩子的存储库:

id: check-yaml
id: end-of-file-fixer
id: trailing-whitespace
在这种情况下,id是您想要从 repo 运行的精确预提交钩子的特定且唯一的标识符。

black然后,我们对和包执行相同的流程flake8。
执行
定义文件后,您需要运行pre-commit install以让预提交知道您想要使用指定的脚本对此 repo 使用预提交。

然后,更改代码并尝试提交代码。您应该看到预提交钩子正在工作。

您还可以通过运行以下命令查看预提交正在执行的操作pre-commit run --all-files。

如果您想在不运行钩子的情况下提交代码,您可以使用git commit --no-verify它来绕过它。

好啦,现在我们来看一个例子吧!

例子
我已经在我的Medium-Articles仓库中安装了 pre-commit ,我们将用它来展示一个示例。

在我的 repo 中,我有以下 Makefile。

SHELL=/bin/bash

PHONY: install
install:
    poetry install

PHONY: lint
lint:
    poetry run black .
    poetry run isort .

我的两个命令是install和lint设置我的环境并确保我的代码看起来不错。
我.pre-commit-config.yaml看起来像这样,与我之前展示的模板略有不同。

repos:
  - repo: local
    hooks:
      - id: lint
        name: lint
        entry: make lint
        language: python
        types: [python]
        stages: [commit]


在这种情况下,钩子所在的存储库是本地的,即在我的项目中。此钩子将使用该entry命令,并将该命令作为钩子的一部分执行make lint,该命令在 make 文件中定义。我的一个文件如下所示(relu.py):

# Import packages
import numpy as np
import os
import plotly.express as px


# relu function
def relu(x):
    return np.maximum(0, x)


# Generate data
x = np.linspace(-5, 5, 100)
y = relu(x)

# Graph
fig = px.line(x=x, y=y)
fig.update_layout(template="simple_white", font=dict(size=18), title_text="ReLU", width=650, title_x=0.5, height=400,)

if not os.path.exists("../images"):
    os.mkdir("../images")
fig.write_image("../images/relu.png")

fig.show()

现在让我们尝试提交此代码并看看会发生什么。

(medium-articles-py3.11) egorhowell@Egors-MBP Medium-Articles % git add .
(medium-articles-py3.11) egorhowell@Egors-MBP Medium-Articles % git commit -m "testing pre-commit"
[INFO] Initializing environment for local.
[INFO] Installing environment for local.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
lint.....................................................................Failed
- hook id: lint
- files were modified by this hook

poetry run black .
Skipping .ipynb files as Jupyter dependencies are not installed.
You can fix this by running ``pip install "black[jupyter]"``
reformatted /Users/egorhowell/Repos/Medium-Articles/Data Science Basics/relu.py
reformatted /Users/egorhowell/Repos/Medium-Articles/Time Series/Exponential Smoothing/holt_winters.py

All done! ✨ 🍰 ✨
2 files reformatted, 67 files left unchanged.
poetry run isort .
Fixing /Users/egorhowell/Repos/Medium-Articles/Time Series/Exponential Smoothing/holt_winters.py
Skipped 2 files
make: Nothing to be done for `Data Science Basics/relu.py'.

钩子失败,因为它重新格式化了relu.py。现在看起来像这样:

# Import packages
import os

import numpy as np
import plotly.express as px


# relu function
def relu(x):
    return np.maximum(0, x)


# Generate data
x = np.linspace(-5, 5, 100)
y = relu(x)

# Graph
fig = px.line(x=x, y=y)
fig.update_layout(
    template="simple_white",
    font=dict(size=18),
    title_text="ReLU",
    width=650,
    title_x=0.5,
    height=400,
)

if not os.path.exists("../images"):
    os.mkdir("../images")
fig.write_image("../images/relu.png")

fig.show()

因此,我们的预提交钩子成功运行了!
总结与思考
Pre-commit 是一个实用的 Python 包,它可以改善您的 git hook 工作流程并简化您的脚本。它旨在通过自动化代码检查过程来保持软件的高质量并消除错误风险。作为数据科学家,我们越来越多地参与模型部署,使用 git hooks 和 pre-commit 等技术来确保我们的模型安全投入生产。

感谢关注[](雲闪世界)。(Aws解决方案架构师vs开发人员&GCP解决方案架构师vs开发人员)
 订阅频道(https://t.me/awsgoogvps_Host)
 TG交流群(t.me/awsgoogvpsHost)

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值