Site icon AppTractor

Ищем неиспользуемый код с Periphery

Кодовой базе Muse уже более 5 лет, в ней более 350,000 строк Swift, и я уверен, что в ней есть не мало ископаемого кода. Как и в любом стартапе (честно говоря, как и буквально в каждом кодовом проекте), трудно отсекать старый неиспользуемый код, поддерживая при этом скорость появления новых фич. Чистота кода — это всегда компромисс со скоростью, и часто она отходит на второй план. Вот почему я люблю инструменты, которые помогают автоматизировать эту медленную ручную работу.

Недавно мне рассказали о Periphery, инструменте командной строки для поиска неиспользуемого кода в проектах на Swift. Для чего нужен свободный от работы день, как не для того, чтобы весело поиграть с новым инструментом?

Для начала — установка:

$ brew install periphery

Боже, благослови brew, таки да.

Далее в README предлагается выполнить настройку для первого запуска:

$ periphery scan --setup
Welcome to Periphery!
This guided setup will help you select the appropriate configuration for your project.

* Inspecting project...

Select build targets to analyze:
? Delimit choices with a single space, e.g: 1 2 3, or 'all' to select all options
1 AppKitBridge
2 Muse
3 Muse Integration Tests
4 Muse Tests
5 MuseShare
6 SparklePlugin

...

Очень простая настройка, сплошное удовольствие! Я выбрал нужные мне цели, затем схемы. Далее он спрашивает о коде Objective-C, и я выбрал «Да», чтобы предположить, что используется код obj-c. В Muse его совсем немного, но некоторые взаимодействия с UIKit или AppKit все равно происходят на Objective-C.

Assume Objective-C accessible declarations are in use?
? Declarations exposed to the Objective-C runtime explicitly with @objc, or implicitly by inheriting NSObject will be assumed to be in use. Choose 'No' if your project is pure Swift.
(Y)es/(N)o > y

Далее он предположил, что все public объявления используются — что было бы очень полезно при создании фреймворка или библиотеки, но для приложения вроде Muse я ответил «Нет».

Assume all 'public' declarations are in use?
? You should choose 'Yes' here if your public interfaces are not used by any selected build target, as may be the case for a framework/library project.
(Y)es/(N)o > n

Наконец, я сохранил конфигурацию в .periphery.yml и запустил первое сканирование. К счастью, оно показало, что кодовая база чиста до безобразия! 😉

Я использую Sourcery для автоматической генерации некоторых файлов коннекторов между кастомной кодовой базой синхронизации Muse и кодовой базой приложения Muse. Также в кодовой базе осталось довольно много старого кода CoreData, чтобы очень старые библиотеки Muse можно было перенести в современный мир синхронизации. Для них мне не нужно, чтобы они были включены в вывод Periphery.

Чтобы удалить их, я использовал параметр командной строки --report-exclude, чтобы удалить несколько путей, которые мне не нужны в отчете. Меня также не волнует избыточные public, поэтому я включил опцию
--disable-redundant-public-analysis. Наконец, меня не волнуют неиспользуемые параметры функций, поэтому я использовал --retain-unused-protocol-func-params. Я запустил с параметром --verbose, который показал изменения в конфигурации .yml, которые мне нужно было сделать, чтобы всегда запускаться с этими исключениями.

Наконец, я настроил цель Aggregate в Xcode, чтобы можно было запускать Periphery и видеть неиспользуемый код в навигаторе Issue. Я обновил настройки сборки, чтобы использовать iOS, добавил параметр User Defined для SUPPORTS_MACCATALYST=YES и добавил фазу Run Script со следующими параметрами:

export PATH="$PATH:/opt/homebrew/bin"

if which periphery >/dev/null; then
    periphery scan --config "${SRCROOT}/.periphery.yml"
else
    echo "warning: periphery not installed, install from https://github.com/peripheryapp/periphery"
fi

Теперь при построении агрегированной цели Periphery в Xcode я могу видеть весь неиспользуемый код прямо в Xcode.

Осталось только навести порядок!

Источник

Exit mobile version