# バッチ設計書 7-file_format.py

## 概要

本ドキュメントは、ソースファイルのフォーマット正規化（改行コード、BOM、末尾空白）を行うPythonスクリプトの設計書です。

### 本バッチの処理概要

このバッチは、ソースファイルのフォーマットを統一するスクリプトで、改行コードの正規化、BOM（Byte Order Mark）の追加/削除、行末の空白文字除去を行います。

**業務上の目的・背景**：異なるOS環境（Windows/macOS/Linux）で編集されたファイルは、改行コード（CRLF/LF）やBOMの有無が混在しがちです。また、エディタによっては行末に不要な空白やタブが残ることがあります。このような不統一は、差分表示の読みにくさやマージ競合の原因となります。このバッチは、ファイルタイプに応じた適切なフォーマットに自動的に正規化し、コードベースの一貫性を維持します。

**バッチの実行タイミング**：コミット前のpre-commitフック、CIパイプラインでの検証、または手動でのフォーマット修正時に実行されます。

**主要な処理内容**：
1. 引数で指定されたファイルのリストを処理
2. ファイルタイプに基づいて改行コードを決定（CRLF: .csproj/.sln/.bat/misc/msvs、それ以外: LF）
3. ファイルタイプに基づいてBOM要否を決定（BOM必要: .csproj/.sln）
4. 各行の末尾から空白・タブ・改行を除去
5. ファイル末尾に1つの改行を付与
6. 変更があったファイルのみ書き換え

**前後の処理との関連**：copyright_headers.pyやheader_guards.pyと同様に、ファイル一覧生成スクリプトと組み合わせて使用されることが多いです。

**影響範囲**：指定されたソースファイル全体のフォーマットが更新される可能性があります。

## バッチ種別

品質検証 / コード整形

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時 |
| 実行時刻 | 任意 |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | 手動 / pre-commit |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Python 3環境 | Python 3.xがインストールされていること |
| ファイルアクセス権 | 対象ファイルへの読み書き権限 |

### 実行可否判定

最低1つ以上のファイルパスが引数として指定されていること。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| files | string[] | Yes | なし | 処理対象のファイルパス（複数指定可） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| ソースファイル | テキスト | 任意のテキストファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 入力ファイル（上書き） | テキスト | フォーマットが正規化されたファイル |
| 標準出力 | テキスト | 修正/要手動対応ファイル一覧 |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | 入力と同じ |
| 出力先 | 入力と同じ |
| 文字コード | UTF-8 |
| 改行コード | ファイルタイプ依存（LF/CRLF） |
| BOM | ファイルタイプ依存（.csproj/.slnのみ付与） |

## 処理フロー

### 処理シーケンス

```
1. 引数検証
   └─ ファイルパスが指定されているか確認
2. 各ファイルについてループ処理
   └─ UTF-8で読み込み（デコードエラーはinvalid）
3. 空ファイルチェック
   └─ 空なら次のファイルへ
4. 改行コード決定
   └─ .csproj/.sln/.bat/misc/msvsはCRLF、それ以外はLF
5. BOM要否決定
   └─ .csproj/.slnはBOM必要
6. フォーマット正規化
   └─ 各行末の空白除去、改行コード統一
7. ファイル末尾処理
   └─ 末尾の連続改行を1つに
8. BOM処理
   └─ 必要に応じて追加/削除
9. 差分確認
   └─ 変更がある場合のみ書き込み
10. 結果出力
    └─ FIXED/REQUIRES MANUAL CHANGESを表示
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{引数あり?}
    B -->|No| C[エラー終了]
    B -->|Yes| D[ファイルループ開始]
    D --> E[ファイル読み込み]
    E --> F{デコードエラー?}
    F -->|Yes| G[invalidリスト追加]
    F -->|No| H{空ファイル?}
    H -->|Yes| I[次のファイルへ]
    H -->|No| J[改行コード・BOM決定]
    J --> K[フォーマット正規化]
    K --> L[BOM処理]
    L --> M{変更あり?}
    M -->|Yes| N[ファイル書き込み]
    M -->|No| I
    N --> O[changedリスト追加]
    G --> I
    O --> I
    I --> P{次のファイル?}
    P -->|Yes| D
    P -->|No| Q[結果出力]
    Q --> R{invalid存在?}
    R -->|Yes| S[exit 1]
    R -->|No| T[exit 0]
```

## データベース操作仕様

### 操作別データベース影響一覧

本バッチはデータベース操作を行いません。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 引数エラー | ファイルパスが指定されていない | ファイルパスを引数として指定 |
| 1 | デコードエラー | UTF-8としてデコードできないファイル | エンコーディングを確認して手動修正 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0回（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. 引数なし：使用方法メッセージを確認し、ファイルパスを指定
2. REQUIRES MANUAL CHANGES：該当ファイルのエンコーディングを確認し、UTF-8に変換

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | ファイル単位 |
| コミットタイミング | 各ファイル処理完了時 |
| ロールバック条件 | N/A（ファイル操作） |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 数十〜数百ファイル |
| 目標処理時間 | 1ファイルあたり数ミリ秒 |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

同一ファイルへの同時アクセスは避けること。ファイル単位で排他制御なし。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| エラーログ | 引数不足時 | "Invalid usage of file_format.py, it should be called with a path to one or multiple files." |
| 情報ログ | 修正時 | "FIXED: {file}" |
| 警告ログ | 手動対応時 | "REQUIRES MANUAL CHANGES: {file}" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 1 | 標準エラー出力 |

## 備考

- BOMのバイト列: `\xef\xbb\xbf`（UTF-8 BOM）
- CRLF対象: `.csproj`、`.sln`、`.bat`、`misc/msvs`で始まるパス
- BOM対象: `.csproj`、`.sln`
- 行末の除去対象: `\n`、`\r`、`\t`、半角スペース
- 空ファイルはスキップ（処理しない）
- 差分がない場合は書き込みしない（ファイルの更新日時を保持）
- バイナリモードで読み書きすることで正確なバイト比較を実現
