🐷

[PHP]特定のクラスやnamespaceに依存するクラスを一覧表示する静的解析ツールを作成しました

2022/06/18に公開

概要

特定のクラスやnamespaceへ依存するクラスを分析する静的解析ツールを作ってみました。

https://github.com/tasuku43/dependency-analyzer

車輪の再発明感が半端ないのですが、静的解析ツールってどういうふうに作るのかな、というところに興味があったので良しとしています。

想定ユースケースとしては、依存するライブラリのメジャーバージョンアップの際などに役立つことを考えてます。
例えば、特定のクラスに破壊的な変更があることが分かれば、プロジェクト内のどのクラスが影響を受けるかを即座に確認することができます。
dependebot のようなライブラリアップグレードツールと組み合わせることで、生成されるPRに影響を受けるクラスをコメントすることも可能です。

Install

packagistに公開しているので、composer経由でinstallが可能です。

composer require --dev tasuku43/dependency-analyzer

使用方法

サンプルプロジェクトとしてlaravel/laravelを使用して、動作確認を行います。

$ composer create-project laravel/laravel example-app
$ cd example-app
$ composer require --dev tasuku43/dependency-analyzer
$ tree -L 1
.
├── README.md
├── app
├── artisan
├── bootstrap
├── composer.json
├── composer.lock
├── config
├── database
├── lang
├── package.json
├── phpunit.xml
├── public
├── resources
├── routes
├── storage
├── tests
├── vendor
└── webpack.mix.js

11 directories, 7 files

指定した名前空間に依存するクラスの一覧を確認する

バージョンアップ対象のライブラリのnamespaceを対象に解析をかける、などの場面を想定しています。

$ ./vendor/bin/dependency-analyzer analyse --path app --pattern "Illuminate\Support"
 [============================] 100%
 ---------------- ------------------------------------
  Depender         App\Providers\AppServiceProvider
 ---------------- ------------------------------------
  Dependent List   Illuminate\Support\ServiceProvider
 ---------------- ------------------------------------

 ---------------- -----------------------------------
  Depender         App\Providers\AuthServiceProvider
 ---------------- -----------------------------------
  Dependent List   Illuminate\Support\Facades\Gate
 ---------------- -----------------------------------

 ---------------- ----------------------------------------
  Depender         App\Providers\RouteServiceProvider
 ---------------- ----------------------------------------
  Dependent List   Illuminate\Support\Facades\RateLimiter
                   Illuminate\Support\Facades\Route
 ---------------- ----------------------------------------

 ---------------- ----------------------------------------
  Depender         App\Providers\BroadcastServiceProvider
 ---------------- ----------------------------------------
  Dependent List   Illuminate\Support\Facades\Broadcast
                   Illuminate\Support\ServiceProvider
 ---------------- ----------------------------------------

 ---------------- ------------------------------------
  Depender         App\Providers\EventServiceProvider
 ---------------- ------------------------------------
  Dependent List   Illuminate\Support\Facades\Event
 ---------------- ------------------------------------

 ---------------- ---------------------------------------------
  Depender         App\Http\Middleware\RedirectIfAuthenticated
 ---------------- ---------------------------------------------
  Dependent List   Illuminate\Support\Facades\Auth
 ---------------- ---------------------------------------------


 [OK] Found 6 dependers

指定されたクラスに依存しているクラスのリストを確認する

バージョンアップ時に破壊的変更のあるクラスを対象に依存クラスを探す、などの場面を想定しています。

$ ./vendor/bin/dependency-analyzer analyse --path app --pattern "Illuminate\Support\ServiceProvider"
 [============================] 100%
 ---------------- ------------------------------------
  Depender         App\Providers\AppServiceProvider
 ---------------- ------------------------------------
  Dependent List   Illuminate\Support\ServiceProvider
 ---------------- ------------------------------------

 ---------------- ----------------------------------------
  Depender         App\Providers\BroadcastServiceProvider
 ---------------- ----------------------------------------
  Dependent List   Illuminate\Support\ServiceProvider
 ---------------- ----------------------------------------


 [OK] Found 2 dependers

指定されたクラスに依存しているクラスのリストを「依存されるクラス」でグループ化して確認する

group-byオプションをつけることで、表示形式を変更する事ができます。
デフォルトは「依存するクラス」に対して「依存されるクラス」を一覧表示していますが、--group-by dependentを指定する事で、「依存されるクラス」に対して「依存するクラス」を一覧表示する事が可能です。

$ ./vendor/bin/dependency-analyzer analyse --path app --pattern "Illuminate\Support\ServiceProvider" --group-by dependent
 [============================] 100%
 --------------- ----------------------------------------
  Dependent       Illuminate\Support\ServiceProvider
 --------------- ----------------------------------------
  Depender List   App\Providers\AppServiceProvider
                  App\Providers\BroadcastServiceProvider
 --------------- ----------------------------------------


 [OK] Found 1 dependents

終わりに

試していただけると嬉しいです。

Discussion