Skip to content

refactor: rename class from ProgramStorage to ProgramSaver#53

Merged
shimomo merged 5 commits intogh-pagesfrom
refactor/rename-class-name
Aug 29, 2025
Merged

refactor: rename class from ProgramStorage to ProgramSaver#53
shimomo merged 5 commits intogh-pagesfrom
refactor/rename-class-name

Conversation

@shimomo
Copy link
Contributor

@shimomo shimomo commented Aug 29, 2025

JSON ファイルを保存するだけなので直感的な Saver にリネームしました。また、ディレクトリ作成の権限を 0777 から 0755 に変更しました。さらに、一時ディレクトリの衝突耐性を強化しました。

Summary by CodeRabbit

  • Refactor
    • 内部コンポーネント名を ProgramStorage から ProgramSaver に統一し、保存処理周りの命名を整理しました。保存先のディレクトリ作成時のパーミッションを 0777→0755 に引き下げました。ユーザー向けの動作や出力に変更はありません。
  • Tests
    • 自動テストを名称変更とパーミッション変更に合わせて更新し、同等の検証範囲と信頼性を維持しています。

@coderabbitai
Copy link

coderabbitai bot commented Aug 29, 2025

Walkthrough

ProgramStorageProgramSaver にリネームし、参照(スクレイパー)とテストを合わせた。save() のディレクトリ作成パーミッションを 0777 から 0755 に変更し、テストのセットアップでディレクトリ作成チェックを追加した。

Changes

Cohort / File(s) Change Summary
コアクラスのリネーム & パーミッション調整
src/ProgramSaver.php
クラス名を ProgramStorageProgramSaver に変更。save() 内の mkdir パーミッションを 07770755 に変更。その他ロジックは同一。
スクレイパー参照更新
scraper.php
インポートを use BOA\Programs\ProgramStorage;use BOA\Programs\ProgramSaver; に変更。new ProgramStorage()new ProgramSaver()、変数名 \$storage\$saver に更新。save(...) 呼び出しは継続。
テストのリネーム・堅牢化 & パーミッション更新
tests/ProgramSaverTest.php
インポートとテストクラス名を ProgramSaver に変更。テスト内変数を \$saver / new ProgramSaver() に更新。セットアップで一時ディレクトリ名を更新(program_saver_test_...)し、mkdir パーミッションを 07750755 に変更、かつ mkdir 成功チェック(if (!mkdir(...) && !is_dir(...)) { $this->fail(...); })を追加。テスト期待値は不変。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

ぴょん、名を変えたよ、Storage は今日から Saver
小さな足でコードをたどり、インポートもお出迎え
パーミッションはちょっとだけ堅実にしておいたよ 🥕
テストも一緒に跳ねて追いかける、安心して眠れるかな?
ぴょんぴょん、保存の道は同じだよ。


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c225e63 and 7978523.

📒 Files selected for processing (1)
  • tests/ProgramSaverTest.php (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/ProgramSaverTest.php
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/rename-class-name

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/ProgramSaver.php (1)

24-39: today.json の競合や部分書き込みを防ぐため原子的書き込みに変更を。

file_put_contents($path, $contents) は並行実行時に破損の恐れ。テンポラリへ書いて rename() で入れ替える実装へ。

-        if (file_put_contents($path, $contents) === false) {
-            throw new \RuntimeException("Failed to save programs to {$path}");
-        }
+        $tmpPath = $path . '.tmp.' . uniqid('', true);
+        if (file_put_contents($tmpPath, $contents, LOCK_EX) === false) {
+            @unlink($tmpPath);
+            throw new \RuntimeException("Failed to write temp file: {$tmpPath}");
+        }
+        if (!@rename($tmpPath, $path)) {
+            @unlink($tmpPath);
+            throw new \RuntimeException("Failed to move temp file into place: {$path}");
+        }
🧹 Nitpick comments (5)
src/ProgramSaver.php (2)

26-29: JSON エンコードの堅牢化(例外+日本語可読性)。

例外で確実に検知し、文字化け回避のため UNESCAPED_UNICODE を付与するのを推奨。

-        $contents = json_encode(['programs' => $programs]);
-        if ($contents === false) {
-            throw new \RuntimeException("Failed to encode programs to JSON");
-        }
+        try {
+            $contents = json_encode(
+                ['programs' => $programs],
+                JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRESERVE_ZERO_FRACTION | JSON_THROW_ON_ERROR
+            );
+        } catch (\JsonException $e) {
+            throw new \RuntimeException("Failed to encode programs to JSON", 0, $e);
+        }

31-34: 作成ディレクトリのパーミッションを適正化。

0777 は広すぎます。公開用途でなければ 07750755 を推奨。

-        if (!is_dir($dir) && !mkdir($dir, 0777, true) && !is_dir($dir)) {
+        if (!is_dir($dir) && !mkdir($dir, 0775, true) && !is_dir($dir)) {
scraper.php (2)

37-39: 変数名もクラス意図に合わせてリネームすると読みやすいです。

$storage$saver へ。意味の一貫性向上。

-$storage = new ProgramSaver();
-$storage->save($programs, "docs/{$version}/" . $date->format('Y') . '/' . $date->format('Ymd') . '.json');
-$storage->save($programs, "docs/{$version}/today.json");
+$saver = new ProgramSaver();
+$saver->save($programs, "docs/{$version}/" . $date->format('Y') . '/' . $date->format('Ymd') . '.json');
+$saver->save($programs, "docs/{$version}/today.json");

30-33: 終了コードの明示を推奨。

処理不成立時は exit(0)exit(1) を明示。CI での判定が安定します(要件に応じて選択)。

-    exit;
+    exit(0);
tests/ProgramSaverTest.php (1)

30-32: 一時ディレクトリ名のプリフィックスも新名称へ。

整合性のため program_saver_test_ に。

-        $this->tempDir = sys_get_temp_dir() . '/program_storage_test_' . uniqid();
+        $this->tempDir = sys_get_temp_dir() . '/program_saver_test_' . uniqid();
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between df9c0d9 and 07d8ee1.

📒 Files selected for processing (3)
  • scraper.php (2 hunks)
  • src/ProgramSaver.php (1 hunks)
  • tests/ProgramSaverTest.php (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tests/ProgramSaverTest.php (1)
src/ProgramSaver.php (1)
  • ProgramSaver (12-40)
scraper.php (1)
src/ProgramSaver.php (1)
  • ProgramSaver (12-40)
🔇 Additional comments (5)
src/ProgramSaver.php (1)

12-12: 残存参照はありませんでした。マージして構いません。

scraper.php (1)

8-8: use 句のリネーム対応OK。

tests/ProgramSaverTest.php (3)

7-7: インポートのリネーム対応OK。


13-13: テストクラス名のリネーム対応OK。


62-62: インスタンス化のリネーム対応OK。

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
tests/ProgramSaverTest.php (2)

30-31: 一時ディレクトリ生成の堅牢化(uniqid の衝突回避と mkdir 成否確認)

テストのフレーク対策として、uniqid('', true) でエントロピーを増やし、mkdir の戻り値を検証しましょう。

-        $this->tempDir = sys_get_temp_dir() . '/program_saver_test_' . uniqid();
-        mkdir($this->tempDir, 0777, true);
+        $this->tempDir = sys_get_temp_dir() . '/program_saver_test_' . uniqid('', true);
+        if (!mkdir($this->tempDir, 0777, true) && !is_dir($this->tempDir)) {
+            $this->fail('Failed to create temp dir: ' . $this->tempDir);
+        }

105-111: JSON 読み書きテストの堅牢化(read 失敗検知と厳密デコード)

file_get_contents の失敗検知と JSON_THROW_ON_ERROR の利用で、失敗時に原因が即時に分かるようにしましょう。

-        $content = json_decode(file_get_contents($path), true);
+        $raw = file_get_contents($path);
+        $this->assertNotFalse($raw);
+        $content = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
         $this->assertArrayHasKey('programs', $content);
         $this->assertSame($programs, $content['programs']);

追加で、ディレクトリ自動作成の挙動やエラー系も押さえると安心です(任意):

public function testSaveCreatesIntermediateDirectories(): void
{
    $saver = new ProgramSaver();
    $path = $this->tempDir . '/nested/a/b/programs.json';
    $saver->save([['race_date' => '2025-01-01']], $path);
    $this->assertFileExists($path);
}

public function testSaveThrowsOnInvalidJson(): void
{
    $this->expectException(\RuntimeException::class);
    $saver = new ProgramSaver();
    // 不正な UTF-8 を含む文字列でエンコード失敗を誘発
    $invalid = "\xC3\x28";
    $saver->save([['race_title' => $invalid]], $this->tempDir . '/invalid.json');
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bc7cf16 and 730d82e.

📒 Files selected for processing (1)
  • tests/ProgramSaverTest.php (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/ProgramSaverTest.php (1)
src/ProgramSaver.php (2)
  • ProgramSaver (12-40)
  • save (24-39)
🔇 Additional comments (4)
tests/ProgramSaverTest.php (4)

7-7: import のリネーム反映 OK

新しいクラス名 ProgramSaver への置換が適切です。


13-13: テストクラス名のリネーム OK

命名の一貫性が保たれています。


62-62: インスタンス化の置換 OK

ProgramSaver への移行が問題なく行われています。


7-7: リネーム漏れはありません
リポジトリ全体に ProgramStorageprogram_storage_test_ の参照は存在せず、ProgramSaver のクラス宣言と use 構文がすべて整合しています。

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
tests/ProgramSaverTest.php (2)

30-31: 一時ディレクトリの衝突耐性と権限を強化しましょう。

uniqid() は予測可能で衝突耐性が弱めです。乱数ベース+最小権限(0700)にし、mkdir 失敗も検知すると頑健です。

-        $this->tempDir = sys_get_temp_dir() . '/program_saver_test_' . uniqid();
-        mkdir($this->tempDir, 0755, true);
+        $this->tempDir = sys_get_temp_dir() . '/program_saver_test_' . bin2hex(random_bytes(8));
+        if (!mkdir($this->tempDir, 0700, true) && !is_dir($this->tempDir)) {
+            $this->fail('Failed to create temp dir: ' . $this->tempDir);
+        }

105-105: カバレッジ拡充: save() 内のディレクトリ自動作成分岐をテストに追加を。

setUp() で親ディレクトリを先に作っているため、ProgramSaver::save()mkdir(..., 0755, true) 分岐が現状未カバーです。ネストされたパスに保存するテストを1件追加してください。json_decode の結果が配列であることの明示的検証もあると親切です。

例(追加する新規テストメソッド):

public function testSaveCreatesNestedDirectory(): void
{
    $saver = new ProgramSaver();
    $path = $this->tempDir . '/nested/a/b/programs.json';
    $programs = [['race_date' => '2025-01-01']];

    $saver->save($programs, $path);

    $this->assertFileExists($path);
}

既存テストの堅牢化(参考・任意):

$this->assertIsArray($content, 'JSON decode failed: ' . json_last_error_msg());
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 730d82e and c225e63.

📒 Files selected for processing (2)
  • src/ProgramSaver.php (2 hunks)
  • tests/ProgramSaverTest.php (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/ProgramSaver.php
🧰 Additional context used
🧬 Code graph analysis (1)
tests/ProgramSaverTest.php (1)
src/ProgramSaver.php (2)
  • ProgramSaver (12-40)
  • save (24-39)
🔇 Additional comments (3)
tests/ProgramSaverTest.php (3)

13-13: テストクラス名とファイル名の整合性OK。


62-62: 変数名の一貫性($saver)およびクラス名の置換は適切です。


7-7: import 更新と残存参照の検証完了
リネームに伴う import 更新は適切で、旧クラス ProgramStorage の残存参照や mkdir(..., 0777) 呼び出しは検出されませんでした。

@shimomo shimomo merged commit a9a712d into gh-pages Aug 29, 2025
6 checks passed
@shimomo shimomo deleted the refactor/rename-class-name branch August 29, 2025 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant