跳到正文
Pulengba
返回

我给博客写了一个命令行工具

blog-cli 截图占位

今天我给自己的博客写了一个命令行工具 blog-cli,纯玩具,除了能消耗一下我的 token,其实没别的卵用。

为什么要做 blog-cli

我的博客是一个 Astro 静态站点,源码放在 GitHub 私有仓库里,线上通过 Vercel 部署。这个结构很稳定,也足够简单,但它有一个小问题:内容管理还是偏“开发者工作流”。

如果只是在主力电脑上写文章,这不算麻烦。但我不想在公司电脑里 clone 我的整个 blog repo。每次发博客切到博客仓库、创建文件、提交、推送。

我希望能有一个跨设备使用的小工具,可以把单独一个 blog 文件,或者文件夹 push 到我的博客里。

  1. 不需要每台电脑都 clone 博客仓库。
  2. 不需要在每台电脑上配置完整的 Node/Astro 开发环境。
  3. 不需要记住博客项目里的目录结构。
  4. 最好能先 dry-run,看清楚会写入哪些路径,再真正发布。

于是 blog-cli 的目标就变得很明确:它是一个只服务于我这个博客的小工具。

目前支持的功能

现在 blogctl 已经支持这些命令:

blogctl login
blogctl status
blogctl list
blogctl view <slug>
blogctl publish <path>

login 用来配置 GitHub token 和博客仓库信息。

status 用来查看当前配置、认证状态和缓存状态。

list 会读取公开站点的 RSS,列出已经发布的文章。

view 会通过 GitHub API 读取私有仓库里的 Markdown 源文件,并在终端里显示正文。

publish 是最核心的命令,可以发布两种文章:

my-post.md

或者:

my-post/
  index.md
  image.png

单文件文章适合纯文字内容。文件夹文章适合带图片、附件或其他本地资源的内容。

发布前可以先执行:

blogctl publish ./my-post.md --dry-run

确认输出路径、slug、URL 都没问题,再真正发布:

blogctl publish ./my-post.md

如果目标文章已经存在,需要显式加上:

--replace

技术栈

blog-cli 是用 Go 写的。

选择 Go 的原因很直接,AI 推荐的,它说:

  1. 可以编译成单个二进制文件。
  2. 安装后不依赖 Node.js。
  3. 标准库里已经有 HTTP、XML、文件遍历等能力。
  4. 很适合做这种跨设备使用的小工具。

目前它的主要实现思路是:

比较重要的一点是,发布文件夹文章时,它不会一张图一张图单独提交,而是把整篇文章和资源打包成一次 commit。这样历史记录会更干净,也更符合“发布一篇文章”这个动作本身。

做的过程中踩到的小坑

第一个坑是认证。

我一开始当然也希望能像网页登录一样输入 GitHub 账号密码,再输入 2FA 验证码。但 GitHub 现在已经不允许命令行或 API 使用账号密码认证了。最后还是回到了 token。

不过想明白之后,token 也没那么可怕。它更像是每台设备单独配置的一把钥匙,只要权限给得足够小,使用起来反而很清晰。

第二个坑是安装路径。

一开始我把 README 写成把二进制放到 /usr/local/bin。后来发现有些设备上根本没有这个目录。最后改成了更通用的用户级安装:

~/.local/bin

这样不需要 sudo,也不依赖系统目录,更适合个人工具。

第三个坑是发布前校验。

比如文件夹文章里可能会混入 .DS_Store,Markdown 图片路径可能带 query,frontmatter 里的 tags 可能写成 inline list。这些都不是什么大问题,但如果不处理,真正使用时就会很烦。

所以我给它补了一批测试,把这些边界都固定下来。

后面可能会继续做什么

目前 blog-cli 已经有了第一个 release,接下来我可能会继续补这些功能:

  1. delete:删除文章。
  2. edit:拉取文章到本地临时文件,编辑后再发布。
  3. search:搜索已发布文章。
  4. doctor:检查 token、配置、网络和仓库权限。
  5. 更好的安装脚本或 Homebrew 支持。

如果一个工具能对我有一丁点用,那它就已经有价值了。

这篇文章就是用 blog-cli 发布的。



下一篇
介绍一下 Gaphub