LoginSignup
9
5

More than 5 years have passed since last update.

Nimbleファイルのバージョン情報をソースに埋め込む

Last updated at Posted at 2018-12-23

概要

追記:2018/12/24
最終的には @flat_leon さんのコメントの方式にしました。
気になる方はコメントへジャンプ!!

以下、読み物としてどうぞ。

Nimbleファイルのバージョン情報をstaticExecを使って、ソースに埋め込みます。

コンパイル時実行

Nimにはコンパイル時に実行するstaticRead/staticExecという機能があるそうで、@2vgさんのこちらの記事(Nimでコンパイルタイム実行を使用してみる)を読んで初めて知りました。

リリース時のミス

ちょうど私のNimで作っているツールのバージョンをアップしようと、Nimbleファイルに記述しているバージョン番号を変更したところ、ツール内で利用しているコマンドラインパーサー(docopt)に渡しているバージョン番号と合っていないという状態になりました。

sample.nimble
srcDir  = "src"         # ソースフォルダ
version = "0.2.0"       # バージョン情報
main.nim
import docopt

let doc = """
application

Usage:
  application (-v | --version)

Options:
  -v --version  Show version. 
"""

# docoptの初期化はバージョンを渡す必要があり、nimbleのversionと合っていない
let args = docopt(doc, version = "application 0.1.0")

コンパイル実行時にnimbleファイルを読んでしまえ

で、冒頭の記事にてstaticExecを使って、コンパイル時に自動でソースにバージョン情報を埋め込んでしまおうというのが今回の内容となります。

ディレクトリ構成は以下を想定します。
utilディレクトリはビルド対象外フォルダとしています。

C:.
|   application.nimble   <= nimbleファイル。バージョンが記述されている
+---src
|   main.nim             <= バージョンを表示したいモジュール
|   version.nim          <= バージョンを埋め込むソース
\---util
    get_version.nim      <= application.nimbleからバージョンを抜き出す
main.nim
import version    # バージョン情報が埋め込まれたソース

# version.nimでexportされたcurrent_versionをバージョン情報として渡す
let args = docopt(doc, version = "application " & version.current_version)
src/version.nim
# staticExecで、util/get_version.nimを実行した結果を埋め込む
const current_version* = staticExec(
  "nim c -r --hints:off --verbosity:0 -o:../bin/test ../util/get_version.nim application")

バージョン埋め込みがリリース時のみで良いなら、以下のようにすれば、ビルドのたびにバージョン読み込みしなくても良いかもしれません。

src/version.nim
when defined(release):
  # staticExecで、util/get_version.nimを実行した結果を埋め込む
  const current_version* = staticExec(
    "nim c -r --hints:off --verbosity:0 -o:../bin/test ../util/get_version.nim application")
else:
  const current_version* = "X.X.X"

nimbleファイルからバージョンを取得

util/get_version.nim
import os
import nre, options, strutils
import strformat

# 引数を取得
let 
  cmdArgs = os.commandLineParams()
  pkgName = cmdArgs[0]

# XXXX.nimbleを読んで、version = X.X.X の X.X.Xを抜き出して、表示する
let f = open(fmt"../{pkgName}.nimble", FileMode.fmRead)
let lines = f.readAll().split("\n")
for line in lines:
  let mOpt = line.match(re"(version)\s*=\s+""(\d+\.\d+\.\d+)""")
  if mOpt.isSome:
    let m = mOpt.get
    echo m.captures[1]
    break
f.close

まとめ

  • staticExecを使って、Nimbleファイルに記述されたバージョン番号をソースに埋め込むことができました。
  • staticReadというメソッドもあり、ファイルの内容を埋め込んでしまうこともできるみたいです。
  • なんでもありなNimが大好きです。
9
5
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5