# Contributing to RDEToolKit

## 機能バグレポートと機能拡張のリクエスト

このツールで、新機能・変更・不具合等が発生した場合、以下の手順で変更をしてください。

- 上記リポジトリのissueで、Issueを作成し新機能、問題や不具合を報告する
- 変更を実際に加える場合、ローカルで新規にブランチを作成し、変更を加える。
- CIテストを実行し、プルリクエストを出す
- CIテストが全てパス、レビューが完了したら、マージする
- Releaseページを作成する

この手順書を参考にして、RDEToolKitの開発・変更を行ってください。共同開発を円滑に進めるためのガイドラインとして利用してください。

## Issueを作成する

問題や不具合が発生した場合、以下のisuueへ起票お願いします。この時、ラベルは`Type:improvement`, `Type: new feature`のどちらかの付与をお願いします。

> <https://github.com/nims-dpfc/rdetoolkit/issues>

## ブランチの作成

新しい機能や修正を行う際は、新しいブランチを作成してください。

- ブランチ名の接頭辞は、`develop-v<x.y.z>`というブランチから、末尾に任意の文字列を追加して作成してください。

```shell
git checkout -b develop-v<x.y.z>-<任意の機能名など> origin/develop-v<x.y.z>
```

## 新機能・修正を加える

### 必要なツール

- `Python` (推奨バージョン: 3.9以上)
- [rye](https://rye-up.com/) or [Poetry](https://python-poetry.org/docs/)(プロジェクト管理ツール)
- `git` (バージョン管理)

## コードのスタイルと要件

### コーディング規約(PEP8)について

一貫したコードスタイルに従うことで、コードをより扱いやすくするため、RDEの構造化プログラムの開発では、PEP8(Python Enhance Proposal #8) に従って開発を行う。

### 基本的に従う規約

> 引用: [PEP 8 – Style Guide for Python Code / Python Enhancement Proposals](https://peps.python.org/pep-0008/)
> 参考: [Python コードのスタイルガイド - pep8-ja](https://pep8-ja.readthedocs.io/ja/latest/)

#### 空白

Pythonは空白が構文上意味を持ちます。Python使う場合、空白の効果とその影響に特に意識してコードを書いた方がいいです。

- インデントには、タブではなく空白を使う
- 構文上意味を持つレベルのインデントには、4個の空白を使う
- 各行の長さが~~79文字かそれ以下とする~~ -> 上限なし。
- 長い式を続けるためにに次の行を使う時、通常のインデントから4個の追加空白を使ってインデントする。
- ファイルでは、関数とクラスは、空白2行で分ける。
- クラスでは、メソッドは、空白行で分ける。
- 辞書では、キーとコロン(`:`)の間には空白をおかずに、同じ行に値を書く場合には値の前に空白を1つ置く。
- 変数代入の前後には、空白を1つ、必ず1つだけおく
- 型ヒント(型アノテーション)では、変数名の直後にコロンをおき、型情報の前に空白を1つおく

#### 名前付け

PEP8は、言語の異なる箇所ごとに他と異なるスタイルを推奨しています。

- 関数、変数、属性は、`lowercase_underscore`のように小文字でアンダースコアを挟む
- プロテクテッド属性は、\_leading_underscoreのようにアンダースコアを先頭につける
- プライベート属性は、\_\_double_underscoreのようにアンダースコアを2つ先頭につける
- クラスと例外は、`CapitalizedWord`のように先頭を大文字にする
- モジュールでの定数は、ALL_CAPSのように全て大文字でアンダースコアで挟む
- クラスのインスタンスメソッドは、(オブジェクトを参照する)第一パラメータの名前に`self`を使う。
- クラスメソッドは、(クラスを参照する)第一パラメータの名前に`cls`を使う。

#### 式と文

- 式の否定(`if not a is b`)ではなく、内側の項の否定(`if a is not b`)を使う
- コンテナやシーケンスの長さ(`if len(somelist) == 0`)を使って、空値(`[]`や`''`など)かどうかをチェックしない。`if not somelist`を使って、空値が暗黙に`False`と評価されることを使う。
- 上と同じことを、非空値(`[1]`や`hi`など)にも使う。非空値について、`if somelist`は、暗黙的に`True`と評価される。
- `if`, `for`, `while`ループ、`except`複合文を1行で書かない。明確になるように複数行にする。
- 式が1行に収まらない場合は、括弧で括って、複数行にして、読みやすいようにインデントする。
- `\`で行わけするよりは、括弧を使って複数の式を囲む方が良い。

#### import

- `import`文は、(`from x import y`も含めて)常にファイルの先頭に置く。
- インポートするときは、常にモジュールの絶対名を使い、現モジュールパスからの相対名を使わない。例えば、モジュール`foo`をパッケージ`bar`からインポートする時は、`import foo`ではなく、`from bar import foo`を使う。
- 相対インポートを使わなければならない時には、明示的な構文`from . import foo` を使う。
- インポートは、1.標準ライブラリモジュール、2.サードパーティモジュール、3.自分の作成したモジュールの順に行う。それぞれの部分では、アルファベット順にインポートする

### RDEToolKitでのフォーマッター・リンターについて

RDEToolKitでは、`Ruff`と`mypy`を使用してフォーマット、リンターを動作させてコード品質を一定に保つことを目標としています。`Ruff`は、isort, black, flake8の機能に変わるツールです。Rustで開発されているため、isort, black, flake8で動作させるより段違いに高速です。また、`mypy`は、静的型チェックツールです。RDEToolKitは型の詳細な定義を強制することで、コードの可読性と保守性の向上を目的としています。

> - Ruff: <https://docs.astral.sh/ruff/>
> - mypy: <https://mypy.readthedocs.io/en/stable/>

### テストの実行

変更を行った後は、テストを実行して正常に動作することを確認してください。

```shell
tox
```

### コミットとプッシュ

変更をコミットし、リモートリポジトリにプッシュします。

```shell
git add .
git commit -m "#[issue番号] [変更内容の簡単な説明]"
git push origin develop-v<x.y.z>-<先ほどつけた名称>
```

もし、pre-commitのチェックでコミットできない場合、全てのエラーを解消した上でコミットをお願いします。

### 変更リクエスト (Pull Request)

:warning: **この時、`main`ブランチにプルリクエストを発行してないでください。**

変更が完了したら、GitHub等のプラットフォームを使用して変更リクエスト (PR) を作成します。
この時、レビューを受け、必ずCIテストが全てパスすることを確認してください。

もし、CI上のテストがパスしない場合、全てのエラーを解消した上で、レビューの依頼を発行してください。

### マージ

レビューが完了し、問題がないと判断されたら、対象ブランチにマージします。

また、全ての開発がfixしたら、mainブランチにマージしてください。mainブランチにマージ後、デプロイが正しく実行できたら、tagの作成とReleaseページを作成してください。

> Releaseページ: <https://github.com/nims-dpfc/rdetoolkit/releases>
