makem.sh

makem.sh

自动化Emacs Lisp包开发工作流

makem.sh是一款专为Emacs Lisp包开发设计的自动化工具。它无需配置即可使用,能自动发现源文件和测试文件,解析包依赖,并提供字节编译、lint检查和测试等功能。该工具支持在本地Emacs配置或沙盒环境中运行,输出清晰简洁,可轻松与GitHub Actions集成。makem.sh通过简化构建、检查和测试流程,为Emacs Lisp包开发者提供了高效便捷的解决方案。

makem.shEmacs测试lint构建Github开源项目

#+TITLE: makem.sh

#+PROPERTY: LOGGING nil

注意:本自述文件与org-make-toc https://github.com/alphapapa/org-make-toc包配合使用,该包会自动更新目录。

=makem.sh=是一个帮助构建、检查和测试Emacs Lisp包的脚本。它旨在让检查和测试尽可能简单,无需每个包都进行配置。

它的工作方式类似于Makefile,通过调用"规则"来执行诸如字节编译、代码检查、测试等操作。

源文件和测试文件会自动从项目的Git仓库中发现,并自动解析其中的包依赖关系。

输出很简单:默认情况下,除非出现错误,否则不会有输出。随着详细程度的增加,会提供更多积极反馈。默认情况下输出是有颜色的,以方便阅读。

该脚本可以使用开发者本地的Emacs配置运行Emacs,也可以使用一个干净的"沙盒"配置,并可选择在之后删除该配置。当上游依赖可能发布了与开发者个人配置中安装的版本不同的新版本时,这特别有用。

  • 目录 :noexport: :PROPERTIES: :TOC: :include siblings :depth 0 :END: :CONTENTS:
  • [[#installation][安装]]
  • [[#usage][使用]]
  • [[#changelog][变更日志]]
  • [[#comparisons][比较]] :END:
  • 截图 :PROPERTIES: :TOC: :ignore (this) :END:

一些示例输出。第一个显示了以详细程度级别1运行=test=规则的情况,它会显示运行了哪些测试,但除非失败,否则不会显示每个测试的输出:

[[images/make-test-v.png]]

增加详细程度会显示通过测试的绿色输出:

[[images/make-test-vv.png]]

=lint-compile=规则将字节编译器警告视为错误:

[[images/make-lint-compile.png]]

=all=规则运行所有规则并将警告视为错误:

[[images/make-all.png]]

当然,增加详细程度还会显示哪些规则没有发出错误信号:

[[images/make-all-v.png]]

包含的=test.yml= GitHub Actions文件可用于轻松设置CI,输出如下:

[[images/github-action.png]]

  • 安装 :PROPERTIES: :TOC: 0 :END:

将=makem.sh=复制到你的包的根目录中。可选地,也可以复制=Makefile=,以便更容易调用脚本。

  • 使用 :PROPERTIES: :TOC: :include descendants :END: =makem.sh=脚本可以直接调用或通过=Makefile=调用。使用=makem.sh --help=列出可用的规则。Emacs库=makem.el=提供了一个Transient调度器(类似于Magit),可以轻松地在Emacs中运行带有选定选项的脚本。

:CONTENTS:

  • [[#makemsh-script][makem.sh脚本]]
  • [[#transient-menu-makemel][Transient菜单(makem.el)]]
  • [[#makefile][Makefile]]
  • [[#github-action][GitHub Action]]
  • [[#github-linguist-statistics][GitHub Linguist统计]]
  • [[#git-pre-push-hook][git pre-push钩子]]
  • [[#spell-checking][拼写检查]] :END:

** =makem.sh=脚本

可以直接调用脚本来指定其他选项。

#+BEGIN_EXAMPLE makem.sh [选项] 规则...

特定于检查器和测试的规则在找不到相应的检查器或测试时会报错。 使用-vv时,运行多个规则的规则会显示不可用检查器或测试的消息。

规则: all 运行所有检查和测试。 compile 字节编译源文件。

lint           运行所有可用的检查器,忽略不可用的。
lint-checkdoc  运行checkdoc。
lint-compile   字节编译源文件,将警告视为错误。
lint-declare   运行check-declare。
lint-elsa      运行Elsa(不包含在"lint"规则中)。
lint-indent    检查缩进。
lint-package   运行package-lint。
lint-regexps   运行relint。

test, tests           运行所有测试,忽略缺失的测试类型。
test-buttercup        运行Buttercup测试。
test-ert              运行ERT测试。
test-ert-interactive  交互式运行ERT测试。

batch        以批处理模式运行Emacs,自动加载项目源文件和测试文件,
             剩余参数(在"--"之后)传递给Emacs。
interactive  交互式运行Emacs,自动加载项目源文件和测试文件,
             剩余参数(在"--"之后)传递给Emacs。

选项: -d, --debug 打印调试信息。 -h, --help 我需要帮助! -v, --verbose 增加详细程度,最多-vvv。 --no-color 禁用彩色输出。

--debug-load-path  从Emacs内部打印load-path。

-E, --emacs 路径  在指定路径运行Emacs。

-e, --exclude 文件  从检查和测试中排除指定文件。
-f, --file 文件     除了发现的文件外,还检查指定文件。

-c, --compile-batch  批量编译文件(而不是单独编译;更快,但可能隐藏问题)。
-C, --no-compile     不自动编译文件。

沙盒选项: -s[目录], --sandbox[=目录] 在沙盒目录中用空配置运行Emacs。 如果目录不存在,则创建它。如果未指定目录, 使用临时沙盒目录并在之后删除, 隐含--install-deps和--install-linters。 --install-deps 自动安装包依赖。 --install-linters 自动安装检查器。 -i, --install 包 在运行规则之前安装指定的包。

沙盒内部会自动创建一个Emacs版本特定的子目录,允许使用多个Emacs版本进行测试。
指定沙盒目录时,首次运行使用--install-deps和--install-linters选项,
之后省略这些选项以节省时间。

源文件会自动从git中发现,也可以通过选项指定。包依赖从源文件的 "Package-Requires"头、-pkg.el文件和Cask文件中发现。

Checkdoc的拼写检查器可能无法识别某些单词,导致lint-checkdoc规则失败。 可以使用变量ispell-buffer-session-localwords在文件本地或目录本地变量中 添加自定义单词,该变量应设置为字符串列表。 #+END_EXAMPLE

** Transient菜单(=makem.el=)

Elisp文件=makem.el=提供了一个Transient调度器(这个文件应该安装到你的Emacs配置中,而不是项目目录)。使用=M-x makem RET=显示它。

[[images/transient.png]]

** Makefile

提供了一个默认的=Makefile=,它调用=makem.sh=脚本。使用规则名称和可选的详细程度级别调用它,如:

#+BEGIN_SRC sh

运行所有规则

$ make all

运行所有检查

$ make lint

运行所有测试

$ make test

以详细程度级别1运行ERT测试

$ make v=v test-ert

以详细程度级别2运行Buttercup测试

$ make v=vv test-buttercup

在临时沙盒中使用emacs-sandbox.sh运行测试

隐含install-deps=t

$ make sandbox=t test

初始化一个永久沙盒目录DIR(开发者可能选择在必要时手动重新创建它,

否则保留它以节省时间)。然后运行所有检查器和测试。

$ make sandbox=DIR install-deps=t install-linters=t $ make sandbox=DIR all #+END_SRC

** GitHub Action

使用Steve Purcell的[[https://github.com/purcell/setup-emacs][setup-emacs]] Action,可以轻松地为Emacs包在GitHub上设置CI。

  1. 将=makem.sh=放入你的包的仓库中并使其可执行。
  2. 将[[file:test.yml][test.yml]](来自=makem.sh=仓库)添加到你的包的仓库中的=.github/workflows/test.yml=。对于大多数Emacs包,它应该可以直接使用,无需修改。

** GitHub Linguist统计

在你的仓库中包含=makem.sh=会影响GitHub由[[Https://github.com/github/linguist][Linguist]]提供的语言统计,这可能导致它被分类为Shell项目而不是Emacs Lisp项目。[[https://github.com/github/linguist#my-repository-is-detected-as-the-wrong-language][Linguist文档]]解释了如何避免这种情况。可能最合适的方法是使用=.gitattributes=文件将=makem.sh=归类为第三方代码,如: #+BEGIN_EXAMPLE sh makem.sh linguist-vendored #+END_EXAMPLE

** git pre-push 钩子

在使用 git 推送之前自动运行测试通常很有帮助。以下是在 =pre-push= 钩子中使用 =makem.sh= 的示例:

#+BEGIN_SRC sh #!/bin/sh

* 提交参数

目前未使用,但作为未来参考很有用。参见 man 5 githooks。

remote="$1" url="$2"

read local_ref local_sha remote_ref remote_sha

* 运行测试

不使用沙盒和自动安装,因为"git push"不应该

导致下载和执行远程代码(即安装包时会发生的情况)。

需要时可以手动完成。然而,在运行于容器中的 CI 系统中,

如果希望在干净的配置下针对最新可用的依赖版本进行测试,

可以使用:

make sandbox=t install-deps=t test

make test #+END_SRC

** 拼写检查

Checkdoc 的拼写检查器可能无法识别某些单词,导致 lint-checkdoc 规则失败。可以使用文件局部或目录局部变量中的 ispell-buffer-session-localwords 变量添加自定义单词,该变量应设置为字符串列表。

  • 更新日志 :PROPERTIES: :TOC: :ignore children :END:

** 0.8-pre

变更

修复

兼容性

** 0.7.1

修复

  • 不使用过时的 Org ELPA 仓库(防止安装过时的 Org 版本)。

** 0.7

新增

修复

致谢

** 0.6

新增

  • lint-elint 规则(默认未在 lint 规则中启用,因为 Elint 的输出似乎不太有用)。
  • =makem.el= 库,带有 Transient 调度器。
  • 可以在文件或目录局部变量 ispell-buffer-session-localwords 中设置拼写检查的自定义单词。(感谢 [[https://github.com/josephmturner][Joseph Turner]]。)
  • 允许从项目内的子目录以及 Git 子模块中运行 makem.sh。(感谢 [[https://github.com/josephmturner][Joseph Turner]]。)

修复

  • 设置 package-user-dir(Emacs 28 兼容性所需)。
  • Emacs 28 的 lint-indent 规则。
  • 在 CI 中安装 Ispell 用于 checkdoc 检查。

内部

** 0.5

变更

  • 检查时显示所有字节编译警告,而不仅仅是第一个。

** 0.4.2

修复

  • 始终将 load-prefer-newer 设置为 t(而不是仅在初始化包时)。
  • 运行 interactive 时,除非使用 --no-compile,否则自动字节编译源文件,并加载不带扩展名的文件名,以便 Emacs 优先加载字节编译文件。

** 0.4.1

修复

  • 显示所有 checkdoc 警告,而不仅仅是第一个。

** 0.4

新增

  • 详细级别 3(即 -vvv),目前仅用于每个文件的字节编译输出。

修复

  • 冗余的字节编译错误消息。

** 0.3

新增

  • 选项 -c / --compile-batch 以批处理方式在单个 Emacs 进程中编译文件(更快,但可能隐藏问题)。

变更

  • 单独编译文件而不是批处理。(较慢,但不会因编译顺序而隐藏问题。)

** 0.2.1

修复

  • 使用 =grep= 的 =-a= 参数,以防 Elisp 文件包含控制字符(罕见,但有时必要)。

** 0.2

新增

  • 在 =test.yml= 中添加 Emacs 27.1。

** 0.1.1

更新

** 0.1

首个标记版本。

  • 比较 :PROPERTIES: :TOC: ignore-children :END:

有几个类似的工具,每个都略有不同。

注意:

  • 在这些比较中,未包括 =makem.sh= 的 Makefile,因为它只提供了一种替代的、=make= 风格的调用约定;它不提供任何功能。
  • 这些说明是通过阅读这些项目的文档和源代码编写的,但作者并非这些工具的专家。欢迎更正。

** [[https://github.com/cask/cask][Cask]]

Cask 是一个经典的 Emacs 包项目管理工具。它功能强大且文档完善。它比 =makem.sh= 复杂得多。

  • Cask 在使用前需要为每个项目进行配置和初始化。=makem.sh= 设计为无需初始化或配置即可使用。
  • Cask 为构建和测试维护一个项目本地的 Emacs 配置。=makem.sh= 提供类似的可选沙盒,以将依赖项与开发者的 Emacs 配置分开安装。
  • Cask 旨在通过使用 =curl= 下载脚本并通过管道传输给 Python 来安装。这是一种危险、不安全的反模式,加上代码量大,更加复杂。=makem.sh= 旨在由包开发者复制到位,其代码易于检查。
  • Cask 旨在安装在每个开发者的机器上。=makem.sh= 旨在放入包的仓库中,无需本地安装。
  • Cask 的文档在[[https://cask.readthedocs.io/en/latest/][其网站]]上详尽且呈现良好。=makem.sh= 可以通过阅读标准的 =--help= 使用指南来使用。
  • Cask 包含超过 3,000 行 Emacs Lisp 和 Python 代码。=makem.sh= 大约有 600 行非常简单的单文件代码。

** [[https://github.com/doublep/eldev][Eldev]]

Eldev 是一个功能强大、灵活的工具。它有许多功能,可以针对每个项目进行扩展和配置。它的设计比 =makem.sh= 复杂得多。

  • Eldev 在使用前需要对每个项目进行一些初始化和配置。=makem.sh= 设计为无需初始化或配置即可使用。
  • Eldev 将依赖项安装在软件包仓库中特定 Emacs 版本的目录中,这允许使用多个 Emacs 版本进行测试。=makem.sh= 可以使用开发者本地 Emacs 配置中已有的依赖项,或者使用内置的沙盒来单独安装依赖项;它不支持单独的、特定 Emacs 版本的沙盒。
  • Eldev 的安装方式是使用 =curl= 下载脚本并通过管道传输到 shell。这是一种危险且不安全的反模式,加上代码量大更是如此。=makem.sh= 旨在由软件包开发者直接复制到位,其代码易于检查。
  • Eldev 需要在每个开发者的机器上本地安装。=makem.sh= 旨在直接放入软件包的仓库中,无需本地安装。
  • Eldev 的文档全面且编写良好,约有 8,000 字。=makem.sh= 可以通过阅读标准的 =--help= 使用指南来使用。
  • Eldev 在 Emacs 内部运行,与正在运行的操作(如测试)在同一进程中。=makem.sh= 在 Emacs 外部运行,每个操作都在单独的 Emacs 进程中执行。
  • Eldev 有超过 4,000 行密集代码,分布在 8 个源文件中。=makem.sh= 约有 600 行非常简单的代码,集中在一个文件中。

** [[https://github.com/vermiculus/emake.el][emake]]

=emake= 用于持续集成测试。它功能强大、文档完善,并提供了比 =makem.sh= 更具体的灵活性。

  • =emake= 要求在使用前配置多个项目特定和 Emacs 特定的变量。=makem.sh= 设计为无需初始化或配置即可使用。
  • 看起来 =emake= 可以在本地运行,而不仅仅在 Travis CI 或 GitHub Actions 等远程系统上运行,但需要进行大量配置和初始化。=makem.sh= 设计为在本地开发者系统和远程 CI 测试中使用同样简单。
  • =emake= 提供了一些工具,用于在 CI 系统上构建特定的 Emacs 版本。=makem.sh= 本身只使用本地安装的 Emacs 版本;对于 CI 使用,提供了一个 GitHub Actions 配置,使用其他工具安装特定的 Emacs 版本。
  • =emake= 的安装方式是使用 =curl= 下载脚本并通过管道传输到 shell,而且似乎在运行时还会进一步下载远程 shell 脚本,至少在初始化时是这样。这是一种危险且不安全的反模式。=makem.sh= 旨在由软件包开发者直接复制到位,其代码易于检查。除了根据要求安装 Emacs 软件包依赖项外,不会下载任何远程代码。
  • =emake= 的文档全面且编写良好,约有 2,000 字。=makem.sh= 可以通过阅读标准的 =--help= 使用指南来使用。
  • =emake= 是一个 700 行的 Emacs Lisp 文件,还有一个可选的 100 行 Makefile 提供一些默认配置。=makem.sh= 约有 600 行 Bash 代码,集中在一个文件中。

** [[https://gitlab.petton.fr/DamienCassou/makel/][makel]]

在这些替代方案中,=makel= 最像 =makem.sh=。它简单且几乎不需要配置。

  • =makel= 在使用前需要配置几个变量。=makem.sh= 设计为无需初始化或配置即可使用。
  • =makel= 可以安装手动指定的软件包依赖项,并且似乎将它们下载到本地软件包仓库目录中。=makem.sh= 只将依赖项安装到沙盒目录中,默认情况下,这是一个自动删除的临时目录。
  • =makel= 可以在远程 CI 系统上使用,但没有提供特定的集成工具。=makem.sh= 提供了一个可以直接使用的 GitHub Actions 文件。
  • =makel= 的使用方式是将两个 Make 文件复制到项目仓库目录中。它建议在其中一个文件不存在时允许自动从互联网下载。=makem.sh= 旨在由软件包开发者直接复制到位。除了根据要求安装 Emacs 软件包依赖项外,不会下载任何远程代码。
  • =makel= 没有内置文档,但使用非常简单。=makem.sh= 可以通过阅读标准的 =--help= 使用指南来使用。
  • =makel= 是一个文件中约 150 行的 Make 代码。=makem.sh= 约有 600 行 Bash 代码,集中在一个文件中。
  • 鸣谢

灵感来自 Damien Cassou 的优秀项目 [[https://gitlab.petton.fr/DamienCassou/makel][makel]]。

  • 开发

Bug 报告、功能请求、建议 — 欢迎提出!

  • 许可证

GPLv3

编辑推荐精选

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

Trae

Trae

字节跳动发布的AI编程神器IDE

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

热门AI辅助写作AI工具讯飞绘文内容运营AI创作个性化文章多平台分发AI助手
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

openai-agents-python

openai-agents-python

OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。

openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。

Hunyuan3D-2

Hunyuan3D-2

高分辨率纹理 3D 资产生成

Hunyuan3D-2 是腾讯开发的用于 3D 资产生成的强大工具,支持从文本描述、单张图片或多视角图片生成 3D 模型,具备快速形状生成能力,可生成带纹理的高质量 3D 模型,适用于多个领域,为 3D 创作提供了高效解决方案。

3FS

3FS

一个具备存储、管理和客户端操作等多种功能的分布式文件系统相关项目。

3FS 是一个功能强大的分布式文件系统项目,涵盖了存储引擎、元数据管理、客户端工具等多个模块。它支持多种文件操作,如创建文件和目录、设置布局等,同时具备高效的事件循环、节点选择和协程池管理等特性。适用于需要大规模数据存储和管理的场景,能够提高系统的性能和可靠性,是分布式存储领域的优质解决方案。

下拉加载更多