23
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

nimのパッケージマネージャnimbleによるプロジェクトテンプレート

Last updated at Posted at 2018-02-07

概要

なんとなくあるんだなーぐらいにしか感じていなかったnimbleについて、ビルドに関する部分を調べてテンプレート化してみました。

(2019/09/28追記)
Nim-1.0.0に対応しました

nimbleのプロジェクト管理機能について

nimbleのタスクはいくつかあるのですが、プロジェクト管理機能は、以下の4つくらいです。

  • nimble init 新規プロジェクト作成
  • nimble build プロジェクトのビルド
  • nimble test テスト実行
  • nimble install リリースビルド&~/.nimbleへのインストール

nimble initによりカレントディレクトリに*.nimbleファイルのみが生成されます。
その後、ソースはsrc/フォルダ配下にするとか、実行モジュールはbin/フォルダに生成するなどの設定は、生成された*.nimbleファイルに記述していくことになります。
nimble initから始まる毎回同じような設定やらフォルダ作成等が面倒だったので、githubにcliツール用のnimbleプロジェクトテンプレートを作成しました。

テンプレート
https://github.com/6in/nimapp_template

テンプレート用README
https://github.com/6in/nimapp_template/blob/master/TEMPLATE-README.md

テンプレートの利用方法について

利用方法は以下のような感じです

# sampleフォルダにclone
$ git clone https://github.com/6in/nimapp_template.git sample

# フォルダに移動
$ cd sample

# プロジェクト名を変更(nimapp_template -> sample)
$ nimble rename

# ビルド
$ nimble build

# 実行
$ bin/sample hoge
{{hello [[hoge]]}}

# ユニットテスト
$ nimble test
or
$ nimble test2

# 実行
$ nimble run

# リリース
$ nimble install

nimbleプロジェクトのパッケージ名は、リポジトリ名と同じnimapp_templateとしており、内包するファイルやフォルダは、nimbleの規約に則った命名規約となっています(たぶん)。

テンプレートから個別のアプリケーションを作るためには、パッケージ名が付与されたファイル・フォルダおよびソース内でimportしているパッケージ名付きフォルダ名の変更等が必要になり、意外と面倒くさい作業が発生します。

本テンプレートは、nimbleの拡張タスクrenameを実行することで、

  • cloneしたフォルダ名を新たなパッケージ名とし、
  • パッケージ名を伴ったファイル・フォルダ・ソースの置換
    を行います。

以下、置換前、置換後のファイル・フォルダ構成となります。

clone直後のファイルフォルダ

$ git clone https://github.com/6in/nimapp_template.git sample
$ cd sample
$ tree .
.
├── nimapp_template.nimble        # nimbleファイル
├── README.md                     # アプリケーション用のREADME.md
├── TEMPLATE-README.md            # テンプレートのREADME.md
├── src                           # ソースフォルダ
│   ├── nimapp_template.nim       # 起動ファイル(docoptによるコマンドラインパース)
│   └── nimapp_templatepkg        # パッケージフォルダ
│       ├── main.nim              # mainソースファイル(メイン処理をここに)
│       └── private
│           └── main_impl.nim     # お好きに利用ください
├── tests                         # ユニットテストフォルダ
│   ├── alltest.nim               # nimble test2タスクが呼び出すソース
│   ├── nim.cfg                   # テスト用コンパイルオプション
│   ├── test1.nim                 # ユニットテストソース(サンプル)
│   └── test2.nim
└── util                          # nimbleから呼び出すツール
    └── rename_app.nim            # nimble renameタスクの実際の処理

nimble rename後のファイルフォルダ

$ nimble rename
$ tree .
.
├── sample.nimble                 # ファイル名・内容が変更
├── README.md                     # 内容が変更
├── TEMPLATE-README.md
├── src
│   ├── sample.nim                # ファイル名・内容が変更
│   └── samplepkg                 # フォルダ名が変更
│       ├── main.nim              
│       └── private
│           └── main_impl.nim
├── tests
│   ├── alltest.nim               # 内容が変更
│   ├── nim.cfg           
│   ├── test1.nim                 # 内容が変更
│   └── test2.nim                 # 内容が変更
└── util
    └── rename_app.nim

テンプレートの内容について

  • {prject_name}.nimbleは、カスタムタスクを含めたプロジェクト設定が記述されています
  • src/はアプリケーションのソースを配置します
  • アプリケーションのエントリポイントは、src/{project_name}.nimです
  • コマンドラインパーサーのdocoptを利用し、コマンドライン解析を行います
  • コマンドラインをパースし、ハッシュオブジェクトを作成します
  • src/{project_name}pkg/main.nimのmain()を呼び出します
  • src/{project_name}pkg/main.nimでは、main関数を定義し、コマンドラインパースされたハッシュオブジェクトを受け取ります
  • tests/はユニットテスト用のフォルダです
  • tで始まるnimファイルを配置することで、nimble testでそれらのファイルが自動実行されます
  • tests/nim.cfgにてsrc/へパスを通すように設定しています
src/{project_name}.nim
# エントリポイント
import {project_name}pkg/main
import docopt

# docopt用のコマンドライン定義
let doc = """
nimapp_template.
Usage:
  nimapp_template <name>
  nimapp_template (-h | --help)
  nimapp_template --version
Options:
  -h --help     Show this screen.
  --version     Show version.
"""

when isMainModule:
  # コマンドライン解析(定義通りでないと、ここでUsageを表示して、アプリケーション終了)
  let args = docopt(doc, version = "nimapp_template 0.1.0")
  echo "args=>",args
  # main関数呼び出し
  let retCode = main(args)
  quit(retCode)
src/{project_name}pkg/main.nim
import private/main_impl
import docopt

proc main*(args:Table[string,Value]) : int =
  ## main関数
  ## 引数は、docoptのパース結果
  result = 0
  let name = $args["<name>"]
  echo say_hello_to(name)

カスタマイズなど

  • nimbleのカスタムタスクのサンプルが*.nimbleに記載されています
  • コンパイラをCからCPPに変えたいとき
    • *.nimblebackendを修正します
  • 実行時(runタスク)の引数を変更したい
    • *.nimbleのrunタスクを修正
  • nimbleのタスクから別のタスクを呼び出したい
    • exec "nimble タスク名"

まとめ?

  • nimbleによるcli系ツール開発用のテンプレートの紹介でした
  • nimを勉強し始めるとちょっとしたツールを作りたくなってきますので、その時の参考になれば幸いです
  • 今回テンプレートの展開処理(rename)ができたので、今後は同じような形式で様々なテンプレートをコツコツ作っていこうかと思います
  • パイプ処理テンプレート
  • DBアクセス処理テンプレート
  • WEBアプリテンプレート
  • GUIアプリテンプレート
  • クロスコンパイラテンプレート

(追記)VSCodeでのデバッグについて

  • nim 0.19.0対応に伴い、Native Debugプラグインをインストールすることにより、VSCodeでのデバッグ(ステップ実行)ができる設定を追加しています。
  • ソースを編集し保存すると、デバッグビルドが自動で実行されます。
    • この機能をOFFにするには、.vscode/setting.jsonの"nim.buildOnSave"をfalseにします
  • ctrl+shift+bでビルド実行します。
  • F5キーでデバッグ実行を開始します。
23
15
3

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
23
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?