简化语义版本控制脚本



我有一个应用程序组件的语义版本控制,这就是我更新主版本号然后将其存储回版本.txt的方式。对于一个简单的操作来说,这似乎是很多行。有人可以帮我修剪一下吗?不使用bc因为我所在的 docker python 映像似乎没有该命令。

这是从 yml 文件和版本中提取的.txt 仅包含主要和次要编号。 例如 1.3。下面的代码仅更新主编号 (1) 并将次要编号重置为 0。因此,如果我在 1.3 上运行代码,我会得到 2。

- echo $(<version.txt) 1 | awk '{print $1 + $2}' > version.txt
VERSION=$(<version.txt)
VERSION=${VERSION%.*}
echo $VERSION > version.txt
echo "New version = $(<version.txt)"

关于简单

性 ">

简单"和"简短"不是一回事。echo $fooecho "$foo"短,但它实际上做了更多的事情:它将foo的值拆分为IFS中的字符,将该拆分的每个结果评估为 glob 表达式,然后重新组合它们。

同样,使代码更简单- 例如,限制它所经历的过程中的步骤数量 - 与使其更短完全不同。


递增一件,其他不修改

if IFS=. read -r major rest <version.txt || [ -n "$major" ]; then
echo "$((major + 1)).$rest" >"version.txt.$$" && mv "version.txt.$$" version.txt
else
echo "ERROR: Unable to read version number from version.txt" >&2
exit 1
fi

递增主要版本,丢弃其他版本

if IFS=. read -r major rest <version.txt || [ -n "$major" ]; then
echo "$((major + 1))" >"version.txt.$$" && mv "version.txt.$$" "version.txt"
else
echo "ERROR: Unable to read version number from version.txt" >&2
exit 1
fi

理由

以上两者都符合 POSIX 标准,并避免依赖 shell 中未内置的任何功能。

  • IFS=. read -r first second third <input读取输入的第一行,并在.上将其拆分为shell变量firstsecondthird;值得注意的是,这个例子中的third列包括前两行之后的所有内容,所以如果你有a.b.c.d.e.f,你会得到first=a; second=b; third=d.e.f- 因此名称rest清楚这一点。有关详细说明,请参阅 BashFAQ #1。
  • $(( ... ))在所有符合 POSIX 标准的 shell 中创建算术上下文。它只对整数数学有用,但由于我们用read拆分了部分,我们只需要整数数学。请参阅 http://wiki.bash-hackers.org/syntax/arith_expr
  • 写入version.txt.$$并在写入成功时重命名可防止version.txt在打开和写入之间发生故障时留空或损坏。(担心符号链接攻击的版本将使用mktemp,而不是依靠$$来生成唯一的临时文件名)。
  • 仅当read成功或[ -n "$major" ]为 true 时,才继续写入可防止代码在读取失败时将版本重置为1(通过将 1 添加到空字符串,该字符串在算术上下文中的计算结果为 0)。

最新更新