Swift の未使用コードを分析する periphery コマンドのオプションメモ

periphery を使用すると Swift プロジェクトの中で未使用なコードを特定できる。
(未使用なクラス・プロパティ、不要な public がわかる)

インストールして、コマンドのオプションを調べたのでメモする。

インストール

brew 経由だと

brew install peripher

ヘルプを実行

periphery scan --help 

実行結果。オプションが羅列される。

% periphery help scan   
OVERVIEW: Scan for unused code

USAGE: periphery scan [<options>] [<build-arguments> ...]

ARGUMENTS:
  <build-arguments>       Arguments following '--' will be passed to the underlying build tool, which is either 'swift build' or
                          'xcodebuild' depending on your project

OPTIONS:
  --setup                 Enable guided setup
  --config <config>       Path to configuration file. By default Periphery will look for .periphery.yml in the current directory
  --workspace <workspace> Path to your project's .xcworkspace. Xcode projects only
  --project <project>     Path to your project's .xcodeproj - supply this option if your project doesn't have an .xcworkspace. Xcode
                          projects only
  --schemes <schemes>     Comma-separated list of schemes that must be built in order to produce the targets passed to the --targets
                          option. Xcode projects only (default: [])
  --targets <targets>     Comma-separated list of target names to scan. Required for Xcode projects. Optional for Swift Package Manager
                          projects, default behavior is to scan all targets defined in Package.swift (default: [])
  --format <format>       Output format (allowed: xcode, csv, json, checkstyle) (default: xcode)
  --index-exclude <index-exclude>
                          Path glob of source files which should be excluded from indexing. Declarations and references within these
                          files will not be considered during analysis. Multiple globs may be delimited by a pipe (default: [])
  --report-exclude <report-exclude>
                          Path glob of source files which should be excluded from the results. Note that this option is purely
                          cosmetic, these files will still be indexed. Multiple globs may be delimited by a pipe (default: [])
  --index-store-path <index-store-path>
                          Path to index store to use. Implies '--skip-build'
  --retain-public         Retain all public declarations - you'll likely want to enable this if you're scanning a framework/library
                          project
  --disable-redundant-public-analysis
                          Disable identification of redundant public accessibility
  --retain-assign-only-properties
                          Retain properties that are assigned, but never used
  --retain-assign-only-property-types <retain-assign-only-property-types>
                          Comma-separated list of property types to retain if the property is assigned, but never read (default: [])
  --external-encodable-protocols <external-encodable-protocols>
                          Comma-separated list of external protocols that inherit Encodable. Properties of types conforming to these
                          protocols will be retained (default: [])
  --retain-objc-accessible
                          Retain declarations that are exposed to Objective-C implicitly by inheriting NSObject classes, or explicitly
                          with the @objc and @objcMembers attributes
  --retain-unused-protocol-func-params
                          Retain unused protocol function parameters, even if the parameter is unused in all conforming functions
  --clean-build           Clean existing build artifacts before building
  --skip-build            Skip the project build step
  --strict                Exit with non-zero status if any unused code is found
  --disable-update-check  Disable checking for updates
  --verbose               Enable verbose logging
  --quiet                 Only output results
  -h, --help              Show help information.

オプションのメモ

--setup

対話形式でセットアップして分析する。
セットアップした結果は .periphery.yml に構成が保存されるので次回以降はセットアップせずに yml から構成を指定して、分析できる。

--config

.periphery.yml のパスを指定する。
デフォルトはカレントディレクトリ。

--workspace

Xcode ワークスペースへのパス。

--project

Xcode プロジェクトへのパス。
ワークスペースがない場合は、こちらを指定する。

--schemes

対象スキーム。
カンマ区切りで複数指定できる。
単体指定も可能。

--targets

対象ターゲット。
カンマ区切りで複数指定できる。
単体指定も可能。

--format

出力フォーマット。以下が指定可能。

デフォルトは xcode
Xcode で Build Phase に追加して、Xcode のエディタ上で結果を表示したい時は xcode 指定にする。
表として、出力したい時は csv が便利。

--index-exclude

インデックス作成から除外するパス。

--report-exclude

出力される結果から除外するパス。
インデックス作成自体はされることに注意。

--index-store-path

インデックスストアのパスを指定する。
この場合、プロジェクトのビルドをスキップする。
--skip-build と同様に)

--retain-public

public された宣言はすべて外部から使用される想定にする。
フレームワークやライブラリのプロジェクトで、実際にそのインターフェースを使用していないプロジェクトの場合にこれを指定する。

--disable-redundant-public-analysis

冗長なパブリックアクセシビリティの識別を無効にする。

--retain-assign-only-propertie

割り当てられているが使用されていないプロパティを保持する。

--retain-assign-only-property-types

プロパティが割り当てられているが、読み取られない場合に保持するプロパティタイプのコンマ区切りリスト。

--external-encodable-protocols

Encodableを継承する外部プロトコルのコンマ区切りリスト。 これらに準拠するタイプのプロパティプロトコルは保持されます。

--retain-objc-accessible

NSObjectクラスを継承することによって暗黙的に、または@objc属性と@objcMembers属性を使用して明示的に、Objective-Cに公開される宣言を保持します。

--retain-unused-protocol-func-params

パラメータがすべての準拠関数で使用されていない場合でも、未使用のプロトコル関数パラメータを保持します。

--clean-build

既存のビルドをクリアしてからビルドする。

誤った結果が出ている時は、インデックスストアが破損したり・ソースファイルと同期しなくなった可能性がある。
たとえば、スキャンを強制的に終了(^C)した場合にこれが発生することがある。
この時は --clean-build すると良い。

--skip-build

ビルドをスキップする。

--strict

未使用コードが見つかった場合は非ゼロのステータスで終了する。

--disable-update-check

更新のチェックを無効にする。

--verbose

冗長なログを出力。

これを指定すると、

[configuration:begin]

から始まる箇所に、分析の構成が表示されるので、それを .periphery.yml に貼り付けると、構成を永続化できる。

--quiet

結果のみを出力。

-h, --help

ヘルプを表示。

CI で使用する場合

https://github.com/peripheryapp/periphery#continuous-integration

たとえばテストを実行した後に periphery を実行する時は

--skip-build でビルドをスキップできる。

インデックスパスが非標準の場所にあるときは

--index-store-path で指定する。

たとえば以下のスキームがあって

  • A
  • B
  • C

それぞれ以下のターゲットがあるとき

  • A
  • B
  • C

これらをそれぞれ分析して、結果を CSV に出力する時は以下のシェルになる。

array=(A B C)
for i in "${array[@]}"
do
    periphery scan --project test.xcodeproj --schemes ${i} --targets ${i} --format csv > ~/Desktop/test/periphery/${i}.csv
done