Nimble入門

# はじめに
今回はNimのパッケージ管理ソフトのnimbleの使い方をご紹介します。  
NimbleはNimのパッケージ管理&ビルドツールとなっています。
今回は、最初の方にある程度使いそうな各種コマンドの説明をしていきます。
  
詳細については以下を確認してください。  
[https://github.com/nim-lang/nimble](https://github.com/nim-lang/nimble)  

## 実行環境

* macOS High Sierra v10.13.3
* Docker 17.12.0-ce
* Nim v0.17.2
* nimble v0.8.8

# インストール
Nimのツールなのでまずはnimをインストールします。
インストールの仕方はいくつかあるのですが、Macでやっているのでbrewにてインストールしちゃいます。

```bash
$ brew install nim
```

[Nim インストール方法|公式](https://nim-lang.org/install.html)  
※Windows Mac両方のインストール方法が記載されています。

環境を汚したくない方はDockerで環境を使ってもいいかもしれません。  
Dockerでのインストールのしかたはこちらを参考にしていただければと思います。  
[https://qiita.com/nemui-fujiu/items/8b541fb9b1f4654938f7](https://qiita.com/nemui-fujiu/items/8b541fb9b1f4654938f7)

# nimbleコマンド

上記の手順でインストールができたら早速コマンドを使ってnimbleを利用して見ましょう。  
※以下に出てくるコマンドの実行は全てDockerで作ったnimの環境で実施しております。

## nimble init 
initコマンドは新規プロジェクト作成時に利用するコマンドです。
プロジェクトディレクトリを作成して、プロジェクトディレクトリ内で

```bash
$ nimble init
```

を入力すると対話形式で必要な情報入力が行えます。   
実際に試してみると以下のようになります。

```bash
$ mkdir sample_nim
$ cd sample_nim/
$ nimble init
      Info: In order to initialise a new Nimble package, I will need to ask you
        ... some questions. Default values are shown in square brackets, press
        ... enter to use them.
    Prompt: Package name? [sample_nim]
    Answer:
    Prompt: Initial version of package? [0.1.0]
    Answer:
    Prompt: Your name? [Anonymous]
    Answer: nemui_fujiu
    Prompt: Package description?
    Answer: sample
    Prompt: Package license? [MIT]
    Answer:
    Prompt: Lowest supported Nim version? [0.17.2]
    Answer:
   Success: Nimble file created successfully
```
入力が完了すると以下のようにファイルができているのがわかると思います。

```bash
drwxr-xr-x 2 root root 4096 Mar 14 05:10 ./
drwx------ 1 root root 4096 Mar 14 05:10 ../
-rw-r--r-- 1 root root  153 Mar 14 05:10 sample_nim.nimble
```
作成したnimbleファイルを見てみると先ほど入力した情報が記載されています。

```nim:sample_nim.nimble
# Package

version       = "0.1.0"
author        = "nemui_fujiu"
description   = "sample"
license       = "MIT"

# Dependencies

requires "nim >= 0.17.2"
```
これでパッケージの準備ができました。  
実際には、後述する各種定義などをしますがinitコマンドの説明としては以上です。

## nimble build
buildコマンドはパッケージのビルドを行うためのコマンドですnimbleファイルにbuildに必要な情報を入力し、ビルド対象のプログラムを作成してから実行してください。

サンプルなので、実際のビルド対象のプログラムは[Nim Tutorial (Part I)](https://nim-lang.org/docs/tut1.html)の「The first program」にあるgreetings.nimの内容で作成して見ました。

buildコマンドを実行して動きを確認するためにnimbleファイルの最後に以下を追記

```nim:sample_nim.nimble
# settings

srcDir = "src"
binDir = "bin"
bin = @["sample_nim"]
```
※詳細については後述の.nimbleの設定をご確認ください。

構成は以下のようにして実行しました。

```bash

|-- sample_nim.nimble
`-- src
    `-- sample_nim.nim
```
buildコマンドの実行

```bash
$ nimble build
  Verifying dependencies for sample_nim@0.1.0
   Building sample_nim/sample_nim using c backend
```
これでビルドが成功して、実行ファイルが作られているはずです。

ビルドするとbinディレクトリとsrc配下にキャッシュディレクトリが生成されていると思います。

```bash
.
|-- bin
|   `-- sample_nim
|-- sample_nim.nimble
`-- src
    |-- nimcache
    |   |-- sample_nim.json
    |   |-- sample_nim_sample_nim.c
    |   |-- sample_nim_sample_nim.o
    |   |-- stdlib_system.c
    |   `-- stdlib_system.o
    `-- sample_nim.nim
```

bin配下のsample_nimが実行ファイルになるので実行してみるとプログラムが動くはずです。
src/nimcacheはbuildで作成されたキャッシュデータです。

## nimble test 
testコマンドはテスト実行のためのコマンドです。
上記のようにソースを作っていれば何も考えずコマンドを打っても実行できます。

```bash
$ nimble test
  Executing task test in /root/sample_nim/sample_nim.nimble
   Success: All tests passed
```

ただし、テストプログラムは書いていないので意味ないですね。
これもしっかりとテストプログラムを書いていればちゃんと意味のあるものになってきます。

## nimble install
installコマンドはリリースビルドをして~/.nimbleへのインストールを行います。

```bash
$ nimble install
  Verifying dependencies for sample_nim@0.1.0
 Installing sample_nim@0.1.0
   Building sample_nim/sample_nim using c backend
   Success: sample_nim installed successfully.
```

これで自分が作成したプログラムがインストールされてコマンド実行できるようになりました。
早速実行して見ます。

```bash
$ sample_nim
What's your name?
> nemui_fujiu
Hi, nemui_fujiu!
```

という感じです。
Docker環境でやっている人は、~/.nimble/binディレクトリ配下に作成したプログラムがあるのがわかると思います。

## nimble uninstall
uninstallコマンドははその名の通りインストールしたパッケージをアンインストールします。

```bash
$ nimble uninstall sample_nim
    Looking for sample_nim (any version)
   Checking reverse dependencies
    Prompt: The following packages will be removed:
        ...   sample_nim (0.1.0)
        ... Do you wish to continue? [y/N]
    Answer: y
    Removed sample_nim (0.1.0)
```

このように最終確認を対話型で確認されてから削除になっています。  
実際に削除されているか確認して見ましょう。

```bash
$ sample_nim
bash: /root/.nimble/bin/sample_nim: No such file or directory
```

この通りコマンドは削除されています。

## nimble refresh
refreshコマンドはNimbleのパッケージを更新するためのコマンドです。   
上記の手順に沿って試している人はコマンドを打っても特に変更はないかと思います。   
実際にはnimbleファイルに各種モジュールを記載するので、記載の仕方にもよりますが
Webから更新されたモジュールを取得することが可能です。

```bash
$ nimble refresh
Downloading Official package list
    Success Package list downloaded.
```

## nimble tasks
tasksコマンドはnimbleファイルに記載されているタスクの一覧を表示してくれます。

tasksコマンドの実行確認をするためにnimbleファイルの最後に以下を追記

```nim:sample_nim.nimble
# tasks

task hello, "This is a hello task":
  echo("Hello World!")
```

実際にtasksコマンドを実行

```bash
$ nimble tasks
hello                This is a hello task
```
このようにタスクの一覧が表示されます。

## nimble list
listコマンドは現在使えるパッケージの一覧を取得します。
--verオプションでバージョンも一覧表示させることができます。

```bash
$ nimble list --ver
awesome_rmdir:
  url:         https://github.com/Araq/awesome_rmdir/ (git)
  tags:        rmdir, awesome, commandline
  description: Command to remove acceptably empty directories.
  license:     MIT
  website:     https://github.com/Araq/awesome_rmdir/
  versions:    v0.2.0, v0.2.1
```
※実際に出てくる内容は多すぎて貼れないので一部のみ記載

## nimble search
searchコマンドは現在使えるパッケージを検索できます。
正直searchコマンドがあるのでlistコマンドを使う機会が思い浮かばない。

```bash
$ nimble search awesome_rmdir --ver
awesome_rmdir:
  url:         https://github.com/Araq/awesome_rmdir/ (git)
  tags:        rmdir, awesome, commandline
  description: Command to remove acceptably empty directories.
  license:     MIT
  website:     https://github.com/Araq/awesome_rmdir/
  versions:    v0.2.0, v0.2.1
```

## nimble path
pathコマンドはインストールされているパッケージの場所を探すコマンドです。
こんな感じになります。

pathコマンドでインストールされているパッケージがちゃんと見えるようにするため、nimbleファイルを一部書き換えて更新する。

```nim:sample_nim.nimble
# Dependencies

requires "nim >= 0.17.2"
requires "jester"
```

pathコマンドを早速実行

```bash
$ nimble path jester
/root/.nimble/pkgs/jester-0.2.0
$ nimble path sample_nim
/root/.nimble/pkgs/sample_nim-0.1.0
```

## nimble publish
publishコマンドは公開用のコマンドです。  
前提としてGitHubのアカウントが登録されていることが前提ですが、自分のNimbleパッケージを公式のNimbleリポジトリに登録できます。

※実行結果は割愛

# nimbleタスク
コマンド側で説明したnimble tasksでちょっと触れましたが、nimbleの機能としてタスクを作ることができます。  
その作成方法についてです。
内容としてはそんな難しいことは何もなく

```nim:sample_nim.nimble
task hello, "This is a hello task":
  echo("Hello World!")
```

nimbleファイルの頭でtaskと宣言してからタスク名続いてカンマの後にコマンドの説明を記載します。  
あとは実際に実行したいコマンドを書くだけです。
コマンドはnimで記述できます。

実行するのは簡単で、nimbleコマンドの後に対象のタスク名を書くだけです。

```bash
$ nimble hello
  Executing task hello in /root/sample_nim/sample_nim.nimble
hello world
```
というような感じです。
一個ハマったことがあるとすると ハイフンをタスク名に含ませるとうまく動作させることができなかった点ですね。

# .nimbleの設定
nimbleファイルの設定項目について

## 必須

|名称|例| 詳細|
|----|---|----|
|name | sample_package | パッケージ名称を記述する(新しいNimScriptの場合は不要) |
|version | 1.0.0 | このパッケージの現在のバージョン。gitタグまたはhgタグを使用している場合は、現在のバージョンにタグを付ける前にインクリメントする必要があります。|
|author | nemui_fujiu |パッケージ作成者の名前 |
|description | サンプル用のパッケージだよ |パッケージの詳細説明 |
|license | MIT |このパッケージにつけるライセンスの名前 (MIT、BSD etc)|

## オプション


|名称| 詳細|
|----|----|
|skipDirs | インストール中に無視したいディレクトリ名を記載します。カンマ[,]区切りで複数のディレクトリを指定できます。|
|skipFiles | インストール中に無視したいファイル名を記載します。カンマ[,]区切りで複数のファイルを指定できます。|
|skipExt | インストール中に無視する必要のあるファイル拡張子を記載する。拡張子は改行なしで指定する必要があります。カンマ[,]区切りで複数のファイルを指定できます。|
|installDirs | インストール対象のディレクトリ名を記載する。カンマ[,]区切りで複数のファイルを指定できます。|
|installFiles | インストール対象のファイル名を記載する。カンマ[,]区切りで複数のファイルを指定できます。|
|installExt | インストール対象の拡張子を記載する。カンマ[,]区切りで複数のファイルを指定できます|
|srcDir | .nimソースファイルを含むディレクトリを指定します。デフォルト：.nimbleファイルが存在するディレクトリ。パッケージのRootディレクトリ|
|binDir | nimbleビルドがバイナリを出力するディレクトリを指定します。デフォルト：.nimbleファイルが存在するディレクトリ。パッケージのRootディレクトリ|
|bin | 実行ファイルの名になります。|
|backend | コンパイル後の形式、バイナリディレクトリに指定した形式でコンパイルしたファイルを出力します。 利用できる種類: c, cc, cpp, objc, js. デフォルト: c|


# 参考
[https://github.com/nim-lang/nimble](https://github.com/nim-lang/nimble)
[https://qiita.com/6in/items/81dd2f7fdf292149874b](https://qiita.com/6in/items/81dd2f7fdf292149874b)