もう迷わない！コマンドでGit & Python仮想環境構築

# コマンドラインでGitの環境構築

## Git のセットアップ

https://docs.github.com/ja/get-started/getting-started-with-git/set-up-git

https://docs.github.com/ja/get-started/getting-started-with-git/setting-your-username-in-git


### Git Bashを開く

1. Gitのユーザー名を設定する

   ```bash
   git config --global user.name [名前を入れる]
   # 入力例
   git config --global user.name yamadahanako
   ```

2. Gitのメールを設定する

   ```bash
   git config --global user.email [メールアドレスを入れる]
   # 入力例
   git config --global user.email yamadahanako@yamadahanako.com
   ```

3. Gitのユーザー名・メールアドレスが正しく設定されたことを確認

   ```bash
   git config --global user.name
   # 出力: yamadahanako

   git config --global user.email
   # 出力: yamadahanako@yamadahanako.com
   ```

## 新しい SSH キーを生成して ssh-agent に追加する

https://docs.github.com/ja/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent


SSHでGitHubリポジトリをクローンできるようにするために、SSH設定を済ませる。

[1] SSHキーを生成

   ```bash
   ssh-keygen
   ```
:::note warn
Enter passphraseでパスワードを入れる画面になるが、入力しても「***」みたいに
画面に表示されないので気を付ける（自分は最初気づかずEnterを連打）
   ```
   Enter passphrase (empty for no passphrase): [入力しても表示されない]
   Enter same passphrase again: [入力しても表示されない]
   ※でもちゃんと入力されているから安心して
   ```
:::

[2] SSHディレクトリに移動
   └ユーザーのホームディレクトリ内にある`.ssh`ディレクトリに移動する
   ```bash
   cd ~/.ssh
   ```

[3] SSHディレクトリ内容を確認
   └sshディレクトリに移動した後、`ls`コマンドで一覧表示を確認する
　（ls = List Segmentsの略。大文字のiじゃない）
   ```bash
   ls
   # 出力:
   # id_12345  id_12345.pub  known_hosts  known_hosts.old
   ```

   - 公開鍵 (.pub)：安全に他の人やシステムと共有できる
   - 秘密鍵 (.pubが付かないファイル)：むやみに共有せず、厳重に管理する

<details>
<summary>lsコマンドについて</summary>

### `ls` コマンド

`ls` は、コマンドラインで使用されるコマンドで、以下のことを意味します：

- **`ls`**: 現在のディレクトリ内のファイルとディレクトリの一覧を表示するコマンドです。デフォルトでは隠しファイル（ドットで始まるファイル）は表示されません。

`ls` コマンドは、ディレクトリ内にどのようなファイルやディレクトリが存在するかを簡単に確認する際に使用されます。

### `ls -la` コマンド

`ls -la` は、コマンドラインで使用される、より詳細な表示を行うコマンドです。

- **`ls`**: 現在のディレクトリ内のファイルとディレクトリの一覧を表示するコマンドです。
- **`-l`**: "long format" の略で、詳細な情報を表示するオプションです。これにはファイルのパーミッション、リンク数、所有者、グループ、サイズ、最終変更日時が含まれます。
- **`-a`**: "all files" の略で、隠しファイルも含めてすべてのファイルとディレクトリを表示するオプションです。

`ls -la` コマンドは、ディレクトリ内の全ファイルを詳細な情報と共に確認したいときに使用されます。

---

使用例

以下に、`ls` および `ls -la` コマンドの使用例を示します。

```bash
$ ls
directory-1/  directory-2/
```

```bash
$ ls -la  
total 40  
drwxr-xr-x 1 user 1234567  0 Jan 01 12:00 ./  
drwxr-xr-x 1 user 1234567  0 Jan 01 11:50 ../  
drwxr-xr-x 1 user 1234567  0 Jan 01 11:51 .git/  
drwxr-xr-x 1 user 1234567  0 Jan 01 11:52 .github/  
-rw-r--r-- 1 user 1234567 16 Jan 01 11:53 .gitignore
drwxr-xr-x 1 user 1234567  0 Jan 01 11:54 directory-1/  
drwxr-xr-x 1 user 1234567  0 Jan 01 11:55 directory-2/
```

---

</details>

<details>
<summary>cd ~/.sshコマンドについて</summary>

### `cd ~/.ssh` コマンド

`cd ~/.ssh` は、コマンドライン環境で使用されるコマンドで、以下のことを意味します：

- **`cd`**: "change directory" の略で、現在の作業ディレクトリを変更するためのコマンドです。  
    
- **`~`**: ユーザーのホームディレクトリを表します。  
  - 例えば、LinuxやmacOSでは通常 `/home/username` や `/Users/username` に対応します。

- **`.ssh`**: ホームディレクトリ内の隠しディレクトリで、SSH（Secure Shell）関連のファイル（鍵ファイルや設定ファイルなど）を格納するのに使われます。ディレクトリの名前が `.` で始まることから、通常は隠しディレクトリとなっています。

したがって、`cd ~/.ssh` コマンドは、「現在の作業ディレクトリをユーザーのホームディレクトリにある `.ssh` ディレクトリに変更する」という意味です。

このディレクトリには通常、SSH の公開鍵や秘密鍵、設定ファイル（`config`）などが保存されています。SSH を利用する際には、このディレクトリ内のファイルを操作することがよくあります。

</details>

[4] 公開鍵を表示する
   └先ほど`ls`コマンドで把握した公開鍵を`cat`の後に入力
   ```bash
   cat [公開鍵]
   # 入力例
   cat id_12345.pub
   ```
<details>
<summary>catコマンドについて</summary>

### `cat ファイル名`

`cat ファイル名` は、コマンドラインで使用されるコマンドで、以下のことを意味しています：

- **`cat`**: "concatenate" の略で、ファイルの内容を標準出力に表示するためのコマンドです。主にファイルの中身を確認するときに使われます。

- **`id_12345.pub`**: 表示したいファイル名です。  
  - このファイルは通常、SSHの公開鍵が保存されているファイルです。

したがって、`cat id_12345.pub` コマンドは、「`id_12345.pub` ファイルの内容をターミナルに表示する」という意味です。

よくある用途としては、このコマンドを使ってSSH公開鍵の内容を確認し、その内容をコピーしてGitHubや他のリモートサーバーの設定に使用することがあります。公開鍵は安全に共有できる情報ですが、このコマンドを秘密鍵（例えば、`id_12345` だけ）に対して実行しないように注意が必要です。秘密鍵は他者と共有せず、厳重に管理する必要があります。

</details>

[5] SSHエージェントを起動し、秘密鍵を追加
   - SSHエージェント*を起動する　*SSHキーの認証情報を管理するためのツール
     ```bash
     eval `ssh-agent`
     ```

 - `ssh-add`コマンドで、SSHエージェントに秘密鍵を追加する
      ```bash
      ssh-add [秘密鍵]
      # 入力例
      ssh-add id_12345
      Enter passphrase for id_12345: [パスワード入れる]
      Identity added: id_12345 (user@example.com)
      ```
<details>
<summary>ssh-addコマンドについて</summary>

### `ssh-add` コマンド

`ssh-add` コマンドは、SSHエージェントに秘密鍵を追加して、SSH接続時にパスフレーズを入力せずに認証できるようにするためのツールです。コマンド `$ ssh-add id_12345` の意味は以下の通りです：

- **`ssh-add`**: SSHエージェントに鍵を追加するためのコマンド。

- **`id_12345`**: 追加したい秘密鍵ファイルの名前。このファイルはSSHキーの秘密鍵ファイルです。

このコマンドを実行すると、`id_12345` の秘密鍵が現在実行中のSSHエージェントに追加され、今後のSSH接続時にこの鍵を自動的に使って認証を行えるようになります。これにより、パスフレーズを毎回手入力せずに済むようになります。

</details>

[6] ホームディレクトリに戻る

   ```bash
   cd -
   # 出力:
   # /c/Users/your_username  
   ```

<details>
<summary>cdコマンドについて（cd - / cd .. 等）</summary>

### `cd` コマンド

`cd` コマンドはディレクトリ間を移動するために使われるコマンドで、特定のパスを指定することで、そのディレクトリに移動します。以下に、`cd` コマンドのいくつかの一般的な用法を示します：

- **`cd directory_path`**: 指定されたディレクトリパスに移動します。  
  - 例: `cd /home/user/documents` は `/home/user/documents` に移動します。

- **`cd ..`**: 現在のディレクトリの親ディレクトリに移動します。  
  - 例: `/home/user/documents` にいるときに `cd ..` とすると、`/home/user` に移動します。

- **`cd -`**: 直前にいたディレクトリに戻ります。  
  - 例: `/home/user` から `/etc` に移動後、`cd -` とすると、元の `/home/user` に戻ります。

- **`cd ~` または `cd`（引数なし）**: ユーザーのホームディレクトリに移動します。  
  - 例: どこにいても `cd` または `cd ~` を実行すれば、`/home/username` のようなホームディレクトリに移動します（`username` は実際のユーザー名）。

`cd` コマンドのこれらの使用方法を覚えておくと、ファイルシステム内の移動がよりスムーズに行えます。

</details>

## リポジトリをクローンする

https://docs.github.com/ja/repositories/creating-and-managing-repositories/cloning-a-repository

1. リポジトリをクローンする

   ```bash
   git clone [Githubの該当ページからSSHのURLをコピー]
   # 入力例
   git clone git@github.com:user/repository-name.git
   # yesを入力すると、リポジトリの内容がローカルにダウンロードされる
   ```

2. 新しいブランチを作成する

   ```bash
   # 先ほどダウンロードしたディレクトリに移動する
   cd project-directory
   
   # 現在のリポジトリ内で使用可能なブランチを一覧表示する
   git branch
   # 出力例: * mainは、現在の作業ブランチがmainであることを示している

   # 現在のブランチを確認する
   git checkout
   
   # 新しいブランチを作成する
   git checkout -b new-feature
   # 出力例: Switched to a new branch 'new-feature'
   # 新しいブランチ `new-feature` が作成され、それに切り替えている
   ```

# コマンドラインでPythonの仮想環境の構築
以下は、Pythonの仮想環境をコマンドラインで構築する方法です。

## Pythonのインストール

Pythonのバージョン確認は以下のリンクから可能です。必要なバージョンをダウンロードするよう事前に確認されることをお勧めします。 

https://www.python.org/downloads/

> **注:** 自分は3.12をダウンロードしていたが、必要だった3.11を新たに追加しました。

### 仮想環境の構築

Windowsの場合：

```bash
py -3.11 -m venv .venv
```

一般的な場合：

```bash
python -m venv .venv
```

作成後、以下でバージョンを確認してください。

```bash
python --version
Python 3.11.9
```

<details>
<summary>-m venvコマンドについて</summary>

### `py -3.11 -m venv .venv` コマンド

このコマンドは、Pythonの仮想環境を作成するために使用されます。このコマンドが行うことを分解して説明します：

- **`py`**: WindowsのPythonランチャーを呼び出すコマンドです。特定のバージョンのPythonを簡単に呼び出すことができます。

- **`-3.11`**: 使用するPythonのバージョンを指定します。このオプションにより、Python 3.11を使用して仮想環境を作成することを指示しています。

- **`-m venv`**: Pythonの標準モジュールである `venv` を実行します。このモジュールは、仮想環境を作成するために使われます。

- **`.venv`**: 仮想環境を作成するディレクトリの名前です。この場合、現在のディレクトリに `.venv` という名前のディレクトリを作成し、その中に仮想環境をセットアップします。

したがって、このコマンドは「Python 3.11を使って、現在のディレクトリに `.venv` という名前の仮想環境を作成する」ことを意味しています。作成された仮想環境は、プロジェクトの依存関係を隔離して管理するのに役立ちます。※ `venv` は Virtual ENVironment の略です。

</details>

## 仮想環境のアクティブ化

Git Bashを使用する場合：

```bash
source .venv/Scripts/activate
```

それ以外の場合：

```bash
source .venv/bin/activate
```

> 仮想環境がアクティブになると、プロンプトに `(.venv)` という表示が追加されます。

## 必要なパッケージのインストール

```bash
pip install poetry
```

私の場合、以下のエラーが発生したのですが、NetskopeによるSSL認証のエラーでした。

```plaintext
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED]...
ERROR: Operation cancelled by user
```

### NetskopeのSSH認証エラーの対策

https://docs.netskope.com/en/configuring-cli-based-tools-and-development-frameworks-to-work-with-netskope-ssl-interception/

- Netskopeがインストールされたフォルダ内に保管されているNetskope証明書を利用すると解消
- `nscacert.pem` をダウンロードしてユーザー配下に保存

対象のフォルダに移動し、`poetry` を使用して依存関係をインストールします。

```bash
poetry install
```

> **注:** Pythonのバージョンが高すぎる場合、エラーが発生する可能性があります。

:::note warn
### 仮想環境の削除
Poetryで依存関係をインストールした後、Pythonのバージョンが高すぎるためエラーが発生し、ダウングレードが必要でした。

```
Current Python version (3.12.7) is not allowed by the project (^3.9, <3.12).
Please change python executable via the "env use" command.
```

```bash
username@hostname MINGW64 ~/dummy-project (branch-name)
$ rm -rf .venv
(.venv)
username@hostname MINGW64 ~/dummy-project (branch-name)
$ deactivate
```

そのため、既存の仮想環境を削除し、仮想環境から抜け出しました。

- **`rm -rf .venv`**: `.venv`という名前のディレクトリを削除するコマンドです。このディレクトリは通常、Pythonの仮想環境を保持するために使われます。`-rf`オプションは、ディレクトリとその中身を再帰的に強制削除することを示します。

- **`deactivate`**: 現在アクティブなPythonの仮想環境を終了するコマンドです。仮想環境を終了することで、システムのPython環境に戻ります。
:::

## コードの品質テスト

### 単体テスト

以下のコマンドを使用し、設定が正しく行われているか確認します。

```bash
poetry run pytest -s -v tests
```

- `pytest`: Python用のテストフレームワークで、単体テストを実行するもの
- `-s`: テスト中の標準出力や標準エラーの出力を抑制せずに表示する
- `-v`: 冗長モードで実行し、テストごとの詳細情報を表示する
- `tests`: テストファイルやディレクトリを指定しており、ここに含まれるテストを実行する
- `poetry run`: 仮想環境上で直接ツールを実行する

これにより、その仮想環境にインストールされたバージョンを使ってコマンドが実行されます。

<details>
<summary>単体テスト（ユニットテスト）について</summary>

### 単体テスト（ユニットテスト）

単体テストは、ソフトウェア開発の一環として、個々の部品、すなわち最小のテスト可能な部分（通常は関数やメソッド）に対して行われるテストです。

目的とメリット：

- **動作の確認**: 各部品が設計どおりに機能しているかを確認します。

- **バグの早期発見**: 小さな単位のテストを徹底することで、エラーやバグを早期に発見し、修正することができます。

- **リファクタリングの安全性**: コードのリファクタリング（内部の改善）を行う際に、機能に影響を与えないことを確認できます。既存のテストを実行してすべてが合格することを確認することで、信頼性を保持したままコードを改善できます。

- **コードの理解**: 単体テストを作成することは、コードの設計を見直し、関数やメソッドの目的とその利用方法を理解するのにも役立ちます。

単体テストの内容：

1. **前提条件の設定**: テストすべき対象がどのような入力を受け取るかを設定します。

2. **実行**: 対象のコンポーネントや関数を呼び出し、その動作を確認します。

3. **結果の確認**: 予期される出力や状態が実際と一致しているかを検証します。

例：

単体テストの簡単な例を考えてみましょう。例えば、次のようなPython関数をテストする場合です。

```python
def add(a, b):
    return a + b
```

この関数に対する単体テストは、次のようになります。

```python
def test_add():
    assert add(1, 2) == 3
    assert add(-1, 1) == 0
    assert add(0, 0) == 0
```

これは、`add` 関数が期待した通り動作するかを検証するテストケースです。このようにして、個々の機能が正しく動作することを確認するのが単体テストの目的です。

</details>

### コードフォーマット

`black`を使ってコードをフォーマットします。

```bash
poetry run black .
```

`isort`を使ってインポートを整列します。

```bash
poetry run isort .
```

- `black` はPythonコードを自動整形するツールです(一貫性のあるスタイルに成形)。
- `isort` はPythonのインポート文を整形します(アルファベット順に並べ替えたり)。
- `. `は、カレントディレクトリ以下のすべてのPythonファイルを対象にフォーマットを実行することを意味します

# コマンドラインでGitを実行

`git branch`

現在のブランチ状況を表示しています。

- 使用中のブランチは `feature-x`
- もう一つのブランチが `development`

`git status`（1回目）

ワークツリーの状況を表示しています。

- 現在のブランチは `feature-x`
- `./dummy-folder/` が未追跡ファイルとして表示されています。

`git add .`

カレントディレクトリ以下のすべての変更をステージングエリアに追加しています。

- 警告メッセージは、ファイル内の行末コードが LF から CRLF に変わる可能性があることを示しています。

`git status`（2回目）

変更がステージングエリアに追加されたことを確認できます。

- `project-folder/src/example.py` が変更として追加
- `./dummy-folder/` はまだ未追跡です。

`git commit -m "fix: リファクタリングしました"`

- ステージングされた変更をコミットし、メッセージを `"fix: リファクタリングしました"` としています。
- `-m` は、messageの略称。

`git push origin feature-x`

- リモートリポジトリの `feature-x` ブランチにローカルのコミットを反映させています。
- プッシュが成功し、リモートリポジトリに変更が適用されました。

<details>
<summary>ローカルブランチとリモートブランチの概念を理解する</summary>

Gitのブランチ管理

ローカルとリモート（例えばGitHub）の間でどのようにブランチ管理が行われるかについて整理しました。

ローカルブランチとリモートブランチは、それぞれ独立して存在し、どちらも手動で同期を行う必要があります。

▼ローカルブランチの作成と同期

1) **ローカルで新しいブランチを作成**  
   - 例：`git checkout -b ブランチ名`  
   - このコマンドで作成されたブランチは、ローカルのみに存在します。  
   - この段階ではリモート（GitHub）には反映されていません。

2) **リモートにブランチをプッシュ**  
   - 例: `git push origin ブランチ名`  
   - ローカルのブランチをリモートリポジトリにも作成できます。  
   - この操作を行わないと、リモートにそのブランチは存在しません。

▼リモートブランチの取得と同期

1) **リモートで新しいブランチが作成されている**  
   - 例: `branch-2`, `branch-3` がリモートに存在しているが、ローカルでまだチェックアウトしていない場合。

2) **リモートブランチをローカルに取得**  
   - 例：`git fetch origin`  
   - リモートリポジトリから新しい変更やブランチ情報をローカルのリポジトリに取得しますが、ローカルにブランチを作成することは自動的に行われません。

3) **リモートブランチのチェックアウト**  
   - 例: `git checkout branch-2`  
   - 上記の `fetch` をした後にこのコマンドを行うことで、リモートの `branch-2` をローカルで作成し、そのブランチに移動します。

まとめ

- ローカルブランチは手動でリモートにプッシュする必要があります。  
- リモートブランチは `fetch` コマンドを使用してローカルに情報を取得し、必要に応じて `checkout` で作業できるようにする必要があります。

</details>