パス管理を効率化するPythonライブラリ「path-chronicle」の紹介

### はじめに

先日携わったプロジェクトにてプロジェクト規模が大きくなるほど、静的パスの管理が複雑化し、開発効率が低下するなと感じることがありました。「path-chronicle」はそんな課題を解決するために開発しました。

この記事では、「path-chronicle」の特徴や使い方について詳しく解説します。

https://github.com/youha6149/path-chronicle

https://pypi.org/project/path-chronicle/

### 環境
- Python ^3.12

### path-chronicleとは？

「path-chronicle」は、Pythonプロジェクト内でディレクトリやファイルのパスを効率的に管理するためのライブラリです。パス情報をCSVファイルに保存し、保存されたパス情報をPythonモジュールとして出力する機能を持ちます。Pythonモジュールとして出力するので、インテリセンスのサポートにより、コーディング時のパス参照が簡単になります。
また、csv他の環境でも簡単に再現できるように設計されています。

#### 主な機能

- **パスの一元管理**: プロジェクト内のすべての静的パスをモジュール化し、効率的に管理。
- **インテリセンスのサポート**: 自動生成されたパス管理モジュールを利用することで、コーディングがスムーズに。
- **移植性の向上**: パス情報をCSVとして保存し、他のプロジェクトや環境へ簡単に移行可能。
- **バリデーション機能**: Pydanticを利用したパス情報のバリデーションで、誤入力を防止。
- **CLIサポート**: `touch`, `mkdir`, `rm`といった基本コマンドに基づいた設計による、直感的で理解しやすいユーザー体験。

### インストール

```bash
pip install path-chronicle
```

### 基本的な使い方

以下に基本的な使い方を紹介します。

#### プロジェクトのルートパスを設定

まず、プロジェクトのルートパスを設定します。
(※インストール後、必ず最初に行ってください)

```bash
pcsetpjroot .
```

#### ディレクトリとファイルの作成

次に、ディレクトリとファイルを作成し、パス情報をCSVに記録します。

```bash
# ディレクトリの作成とパス保存
pcmkdir test_dir

# ファイルの作成とパス保存
pctouch test_dir/test.txt
```

```csv
id,name,path,description
1,test_dir,test_dir,
2,test.txt,test_dir/test.txt,
```

#### パス管理モジュールの生成

最後に、パス管理用モジュールを生成します。

```bash
gpaths
```

```python
from pathlib import Path


class PathArchives:
    """
    This class provides paths for various project directories and files.
    """

    test_dir = Path('/Users/{your dirctory}/Desktop/myprojects/package_test/p_test_1/test_dir')
    test_txt = Path('/Users/{your dirctory}/Desktop/myprojects/package_test/p_test_1/test_dir/test.txt')

    @staticmethod
    def get_path(name: str) -> Path:
        """
        Returns the Path object for the given name.

        Available paths:
        - test_dir: /Users/{your dirctory}/Desktop/myprojects/package_test/p_test_1/test_dir
        - test_txt: /Users/{your dirctory}/Desktop/myprojects/package_test/p_test_1/test_dir/test.txt
        """
        return getattr(PathArchives, name, None) or Path("")

```

これで、プロジェクト内で静的パスを効率的に参照できるようになります。

### 利用例

例えば、以下のように生成されたパス管理モジュールを活用できます。

```python
from path_chronicle.path_archives.path_archives import PathArchives

def main():
    print(PathArchives.get_path("test_dir"))
    print(PathArchives.get_path("test_txt"))

if __name__ == "__main__":
    main()
```

![インテリセンス詳細画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694345/316c90e6-e079-6665-da40-36fd389db7b0.png)

![ターミナルへの出力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694345/200b6e23-ffd1-407e-ec1e-aa93aa88e3d8.png)


### 反省点と改善案

開発を通じて気づいた反省点もあります。当初、サードパーティ製ライブラリの利用を避けたため、コードが冗長化し、エラーが増加する結果となりました。また、柔軟性を持たせようとしすぎたため、管理が複雑化し、開発効率が低下しました。

適材適所で一定基準を満たすライブラリは積極的に活用し、開発期間を短くしたい場合はユーザーに許可する処理はできるだけ制限する方がいいなと思いました。

### 終わりに

初めてのライブラリ開発でしたが、こうした紹介をする中でさらに自分の中で考えが深まったように思います。ライブラリの詳細やソースコードは、[GitHub](https://github.com/youha6149/path-chronicle)で公開しているのでフィードバック頂ければ幸いです！

### 追記
#### 2024年8月16日
共有の際、都度再生成をする設計にしている理由

1. プロジェクト全体からパス管理モジュールをインポートするためには、setup.pyによるパッケージのインストールやsys.path.appendを用いたパスの追加が必要となり、これに伴う設定作業が発生する可能性が考えられた。
2. パス管理モジュールを特定のパスに生成する場合、そのパスを明示的に指定する必要があります。また、指定されたパスに応じて、インポート時にパスの解決が複雑化し、追加の設定が求められる可能性が考えられた。

（インポート処理についてはまだまだ知識不足を感じておりますので、もし誤りや改善点がありましたら、ご指摘いただけると幸いです。）