【Nim】Nimbleで1からパッケージを公開してみた＆詰まったところの備忘録

# はじめに
昨日、Nimで制作したゲームを初めてNimbleで公開してみた。
THE 初心者(パッケージを世界に公開するという点においても)でも安心して公開を進められる解説記事があまりない＆詰まったところがあったので備忘録として残す。

# 自分が今回公開したもの

https://nimble.directory/pkg/climinesweeper

https://github.com/KerorinNorthFox/MineSweeper_on_CLI

名前の通り、CLI上で遊べるマインスイーパーを作ったので、Nimbleで楽にインストールして遊べるように公開した。

# Nimbleでパッケージを公開する方法
## Step1.nimble init
まず、プロジェクトディレクトリの先頭でnimble initコマンドを打つ。
このコマンドを打つのはプロジェクトの制作途中からでも問題ない。
```
$ nimble init
      Info: Package initialisation requires info which could not be inferred.
        ... Default values are shown in square brackets, press
        ... enter to use them.
      Using "project_directory_name" for new package name
      Using your_git_name for new package author
      Using "src" for new package source directory
    Prompt: Package type?
        ... Library - provides functionality for other packages.
        ... Binary  - produces an executable for the end-user.
        ... Hybrid  - combination of library and binary
        ... For more information see https://goo.gl/cm2RX5
     Select Cycle with 'Tab', 'Enter' when done
    Answer: binary
    Prompt: Initial version of package? [0.1.0]
    Answer:
    Prompt: Package description? [A new awesome nimble package]
    Answer:
    Prompt: Package License?
        ... This should ideally be a valid SPDX identifier. See https://spdx.org/licenses/.
     Select Cycle with 'Tab', 'Enter' when done
    Answer: MIT
    Prompt: Lowest supported Nim version? [1.6.10]
    Answer:
   Success: Package project_directory_name created successfully
```
project_directory_nameの部分にはプロジェクトディレクトリの名前が入り、これがパッケージの名前となる。(後で変更可能)
your_git_nameにはgitのローカルの自分の名前が入る

7行目の"Prompt: Package type?"では、パッケージの種類を聞かれる。
- Library: 他のパッケージに機能を提供する
- Binary: エンドユーザー向けに実行ファイルを生成する(今回はこれを選択)
- Hybrid: LibraryとBinaryを組み合わせたもの

その後の質問の答えは後で変更できるため空白でEnterを押していく。

18行目の"Prompt: Package License?"では作るプロジェクトに合ったライセンスを選択する。(後で変更できるので特にこだわりがなければMITでOK)

作成が完了するとプロジェクトディレクトリの中は次のような構成になっている
```
$ project_directory_name
  |--src
  |  `--project_directory_name.nim // ビルドすると、このファイルがコンパイルされ実行ファイルになる(Binaryを選択した場合)
  `--project_directory_name.nimble // パッケージについての情報などを記述する重要なファイル
```
制作途中からnimble initをした場合には、上の内容が追加されているような形になるため、元からあるソースコードをsrc/に移したりなど整理をする。

## Step2.プログラムを書く
src/の中のproject_directory_name.nimを起点にし、プログラムを書いていく。

:::note alert
注意！
src/の中にはproject_directory_name.nim以外のnimファイルを置いてはいけない。project_directory_name.nimでインポートするファイルなどを置きたい場合は、src/の中に新しくディレクトリを作成しその中に入れる。
:::
:::note alert
また、project_directory_name.nimのファイル名は基本的に変えないこと。変更した場合は、project_directory_name.nimble内のbin = @[project_directory_name]も変更すること。
:::
:::note alert
プロジェクトディレクトリの名前、project_directory_name.nimbleのどちらかの名前を変更した場合は、それらの名前が一致するようにもう片方も変更する。
:::

## Step3.project_directory_name.nimbleの中身を変更する
.nimbleファイルの中に書くことができるものは次の記事で解説されている。
(確認はできていないが、おそらく.nimbleファイルの名前がパッケージの名前となって登録されるため、しっかりと確認すること)
descriptionは[Nim package directory](https://nimble.directory)のサイトでパッケージについての説明に使われるのでしっかりと記述する。
また、binのところもproject_directory_name.nimと名前があっていないとnimble install時にエラーがでるため気を付ける。***(大文字小文字も一致させること)***

https://qiita.com/nemui-fujiu/items/2a959bd6cbfe7ff35528#nimble%E3%81%AE%E8%A8%AD%E5%AE%9A

:::note alert
project_directory_name.nimbleファイルには必要なことだけを書くこと。不必要なことを書く必要はないし、nimble install時にエラーが出る原因にもなる。
:::

## Step4.READMEをしっかり書く
最後にREADMEをしっかりと書く。
この内容は[Nim package directory](https://nimble.directory)のサイトでも表示されるため、他の人に使ってもらうならインストール方法や使い方などをしっかりと書く。

## Step5.nimble publish
最後にnimble publishコマンドを打つと、Githubの[nim-lang/packages](https://github.com/nim-lang/packages)リポジトリにプルリクエストが出され、そこでマージされると無事パッケージの公開が完了する。
```
$ nimble publish
      Info: Please create a new personal access token on Github in order to allow Nimble to fork the packages repository.
      Hint: Make sure to give the access token access to public repos (public_repo scope)!
      Info: Your default browser should open with the following URL: https://github.com/settings/tokens/new
sh: 1: xdg-open: not found
    Prompt: Personal access token?
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
    Answer:       Info: Writing access token to file:/home/kerorinnf/.nimble/github_api_token
   Success: Verified as your_github_name
      Info: Waiting 10s to let Github create a fork
    Copying packages fork into: /tmp/nimble-packages-fork
   Updating the fork
    Prompt: Whitespace separated list of tags? (For example: web library wrapper)
tags
    Answer:     Pushing to remote of fork.
       Info Creating PR
   Success: Pull request successful, check at https://github.com/nim-lang/packages/pull/2544
```
五行目の"Prompt: Personal access token?"はGitHubのアクセストークンを要求されているためトークンを発行して入力する。
ちょっと古いがトークンの発行の仕方は今と変わらないため次の記事が参考になる。

https://qiita.com/kz800/items/497ec70bff3e555dacd0

12行目ではパッケージを探しやすくするための任意のタグが設定できる。
タグの間にはスペースを1つ開けて記述する。

:::note alert
nimble publishには時間制限があり、特にアクセストークンの発行などに手間取ると制限時間が来て公開作業が中断される。その時はもう一度nimble publishを試す必要がある。
:::

## Step6.マージしてもらうのを待つ
[nim-lang/packages](https://github.com/nim-lang/packages)リポジトリを見てみると、自分のプルリクエストが出されているのがわかる。特に異常がなければ数分のうちにマージされ、無事パッケージが世界に公開されることになる。

## Step7.nimble install
少し待つと、nimble installで自分の公開したパッケージをインストールすることができる。ここでエラーがでる可能性があるため、自分で一度nimble installしてみると良い。
もしエラーが出た場合はエラーを読み、該当の個所を修正する。修正したら、新しいバージョンのタグをつけてGitHubでリリースする。するとnimbleで公開したパッケージもバージョンが更新され、変更が適応される。

## Step8.パッケージのアップデートの反映
「もしパッケージの公開後にミスを見つけてアップデートすることになったらどうやるんだろう？」と、パッケージを公開する前に調べまくったが全く出てこなかった。というのも、パッケージのGitHubリポジトリを更新し***タグをつけてリリースを作ると更新される(重要)*** …という手軽さになっている。

### 注意！！！
今回詰まったことの[アップデートが反映されない！](#3アップデートが反映されない)参照。

# 自分が今回詰まったこと
## 1.登録方法の全体像がわからない！
情報が少なく、ここで尻込みしていた。
登録の全体の流れは次の通り:
1. プロジェクトディレクトリを作成し、nimble init(ライセンスを決めておくこと)
1. src/内に作成された.nimファイルからプログラムを書き始める(ファイルの配置に注意)
1. .nimbleファイルに情報を書き足す(.nimbleのファイル名と中身の内容に注意)
1. nimble publishでプルリクを出す(アクセストークンを準備し、何のタグをつけるか考えておくこと)
1. マージされたらnimble installしてみて、挙動を確認
1. アップデートしたい場合は、GitHubのリポジトリに変更を反映させそのタグをつけてリリースを作る


## 2.ビルドできない！
いざパッケージを公開しnimble installをしたものの、エラーが出てビルドできないということがあった。
これは自分の場合パッケージのファイル構成が間違っていることが原因で、正しいファイル構成([Step1.nimble initのプロジェクトディレクトリのファイル構成参照](#step1nimble-init))にしてやると無事ビルドしてインストールすることができた。
また、.nimbleファイルの中に余計なことを書くとビルドできないこともあるため確認する。
nimble installするときにエラーメッセージが出るためそれを読み解決すること。

## 3.アップデートが反映されない！
GitHubでmainブランチを更新したのに、nimbleの方は古いままになっている...ということがあった。
これの解決方法としては、新しいバージョンのタグをつけて最新版のリリースを作ることで解決することができる。
ただ、README.mdだけはリアルタイムで反映されるため気軽に変更ができる。

# さいごに
Nimやそのライブラリの日本語の公式ドキュメントや記事がもっと増えてほしい。(切実な願い)