工作快一年了, 积累了很多的 代码片段(code snippet), 所以需要一个小工具来实现公司\家庭\开发\私人服务器等地方的代码片段的同步.

同步的方法有很多, 我试过onedriver \ codemass \ gist 等手段, 但是各有各的缺点(后文补充), 所以最后还是选择了一个相对折中的方案, GitHub.

本文主要介绍的就是如何通过自动化脚本实现GitHub代码片段的同步.

代码环境:

  • macos
  • ubuntu
  • centos

常见方案

mass code

mass code是一款开源的代码片段同步工具, 但是其本身不具备代码片段同步的功能, 官方给出的一个方案是使用第三方网盘来实现同步的功能.

笔者惯用的是Onedrive, 但是在Ubuntu上, 并没有官方的Onedrive程序, 而第三方的onedrive同步工具在使用过程中总有各种奇怪的问题, 导致代码片段在同步的过程中出现丢失的现象. 这是笔者选择放弃 masscode 的主要原因.

gist

在尝试了masscode之后, 再使用gist总是有很多的不习惯, 最主要的是, masscode能够根据代码的 种类 \ 用途 进行分类管理, 而gist则不能这么做.

使用git仓库

在GitHub中有不少代码片段的仓库, 其中不乏一些高星的仓库. 不过我们的代码片段是私人性质的, 因为其中还有 token \ smtp 等敏感信息.

使用git来管理代码片段, 本身并没有什么难度, 按照正常的git使用流程来即可.

接下来主要的内容是, 如何实现自动化的代码片段同步功能, 以及一些让使用更加人性化的技巧.

核心的思路是: 一个自动同步代码仓库的脚本 + 定时任务, 由于代码片段的使用是个人性质的, 所以使用的流程基本上是线性流程, 在设计过程中不需要考虑代码冲突的问题.

crontab定时任务

crontab 是Linux系统的定时任务程序, 在Ubuntu \ Centos\ MacOS上都可以直接使用. 这里给出一个生成网站, 用来快速生成一个crontab配置.

# 每隔10分钟执行一次同步脚本
*/10 * * * * [path-to-your-script]

notification同步成功通知

os_type=$(uname -s)
# validate os is ubuntu or mac
if [ "${os_type}" = "Darwin" ]; then
    # mac os
    notification="display notification \"${now_date} code snippet git sync done\""
    osascript -e "$notification"
elif [ "${os_type}" = "Linux" ]; then
    # ubuntu os
    notify-send CrontabTask "${now_date} code snippet git sync done"
else
    echo "unknown os ${os_type}"
fi

问题

检查是否是git目录

crontab 执行时, 通过文件路径的方式执行的话, 启动的路径并不是在我们的代码片段仓库的根目录下, 所以需要检查一下是否是 git 目录.

笔者的同步脚本存放在仓库的 shell/ 目录下, 所以就有了如下的检查代码.

dir_of_path=$(dirname "$0")   # 得到脚本所在目录 /shell/
dir_of_path=$(dirname "$dir_of_path")  # 得到脚本所在根目录 /
cd $dir_of_path
echo $(pwd)

# 检查是否是git目录
if [ !$(git status) ]; then
    echo "$(pwd) is not a git repository"
    exit 1
fi

附录

这里给出完整的脚本代码

#!/bin/bash
# */10 * * * * [script-path]

dir_of_path=$(dirname "$0")
dir_of_path=$(dirname "$dir_of_path")
now_date=$(date +%Y-%m-%d)

cd $dir_of_path
echo $(pwd)

if [ !$(git status) ]; then
    echo "$(pwd) is not a git repository"
    exit 1
fi

git add .
git commit -m "auto-commit: $now_date"

git pull
git push

echo "$(date) git sync done" >>/tmp/git-auto-pull.log

os_type=$(uname -s)
# validate os is ubuntu or mac
if [ "${os_type}" = "Darwin" ]; then
    # mac os
    notification="display notification \"${now_date} code snippet git sync done\""
    osascript -e "$notification"
elif [ "${os_type}" = "Linux" ]; then
    # linux os
    notify-send CrontabTask "${now_date} code snippet git sync done"
else
    echo "unknown os ${os_type}"
fi

Reference

Bash脚本
Crontab生成网站