Как найти / удалить неиспользуемые зависимости в Gradle

128

Я хотел найти в своем проекте неиспользуемые зависимости. Есть ли в Gradle такая функция, как в Maven?

Александр Безродный
источник

Ответы:

72

ОБНОВЛЕНИЕ: 28-06-2016: Android поддерживает неиспользуемую зависимость

В июне 2017 года они выпустили 4.0.0 version и переименовали корневой проект "gradle-lint-plugin"в "nebula-lint-plugin". Они также добавили поддержку Android в неиспользуемые зависимости .


В мае 2016 года Gradle реализовал плагин Gradle lint для поиска и удаления нежелательной зависимости.

Плагин Gradle Lint: полная документация

Плагин Gradle Lint - это подключаемый и настраиваемый инструмент линтера для выявления и составления отчетов о шаблонах неправильного использования или устаревания в скриптах Gradle и связанных файлах.

У этого плагина разные правила. Неиспользуемое правило зависимости - одно из них. У него есть три характерные особенности.

  1. Удаляет неиспользуемые зависимости.
  2. Продвигает транзитивные зависимости, которые используются непосредственно вашим кодом, до явных зависимостей первого порядка.
  3. Перемещает зависимости в «правильную» конфигурацию.

Чтобы применить правило, добавьте:

gradleLint.rules += 'unused-dependency'

Подробная информация о неиспользованном правиле зависимости приведена в последней части.

Чтобы применить плагин Gradle lint:

buildscript { repositories { jcenter() } }
plugins {
  id 'nebula.lint' version '0.30.2'
}

В качестве альтернативы:

buildscript {
  repositories { jcenter() }
  dependencies {
    classpath 'com.netflix.nebula:gradle-lint-plugin:latest.release'
  }
}

apply plugin: 'nebula.lint'

Определите, против каких правил вы хотите действовать:

gradleLint.rules = ['all-dependency'] // Add as many rules here as you'd like

Для корпоративной сборки мы рекомендуем определять правила lint в скрипте init.gradle или в скрипте Gradle, который включается через механизм Gradle apply from.

Для многомодульных проектов мы рекомендуем применять плагин в allprojectsблоке:

allprojects {
  apply plugin: 'nebula.lint'
  gradleLint.rules = ['all-dependency'] // Add as many rules here as you'd like
}


Подробная информация о неиспользованном правиле зависимости приведена в этой части.

Чтобы применить правило, добавьте:

gradleLint.rules += 'unused-dependency'

Правило проверяет скомпилированные двоичные файлы, исходящие из исходных наборов вашего проекта, в поисках ссылок на классы и сопоставляет эти ссылки с зависимостями, которые вы объявили в своем блоке зависимостей .

В частности, правило вносит следующие изменения в зависимости:

1. Удаляет неиспользуемые зависимости

  • Банки в семейном стиле, такие как com.amazonaws: aws-java-sdk, удаляются, так как они не содержат кода.

2. Продвигает транзитивные зависимости, которые используются непосредственно вашим кодом, до явных зависимостей первого порядка.

  • Это имеет побочный эффект разбиения файлов JAR семейного стиля, таких как com.amazonaws: aws-java-sdk, на части, которые вы фактически используете, и добавления их в качестве зависимостей первого порядка.

3. Перемещает зависимости в "правильную" конфигурацию.

  • Веб-журналы перемещены в конфигурацию среды выполнения
  • Файлы JAR, не содержащие классов и содержимого вне META-INF, перемещаются во время выполнения.
  • 'xerces', 'xercesImpl', 'xml-apis' всегда должны иметь область выполнения
  • Поставщики услуг (файлы JAR, содержащие META-INF / services), такие как mysql-connector-java, перемещаются во время выполнения, если нет какой-либо доказуемой ссылки во время компиляции
  • Зависимости перемещаются в максимально возможную конфигурацию исходного набора. Например, junit перемещается в testCompile, если нет явной зависимости от него в основном исходном наборе (редко).


ОБНОВЛЕНИЕ: предыдущие плагины

Для вашего удовольствия, я хочу рассказать о предыдущих плагинах

  1. Плагин Gradle, который находит неиспользуемые зависимости, объявленные и транзитивные, называется com.github.nullstress.dependency-analysis.

Но его последняя версия 1.0.3 создана 23 декабря 2014 года . После этого обновлений нет.

NB: Многие наши инженеры сбиты с толку этим плагином, поскольку они обновили только номер версии, ничего больше.

Ходящий по небу
источник
Совместим ли gradle-lint-plugin с Android?
Jaythaking
@Jaythaking да. Вы можете перейти по этой ссылке: tools.android.com/tech-docs/new-build-system/… . Надеюсь, это прояснит вас.
SkyWalker
@Jaythaking - только что добавлена ​​экспериментальная поддержка неиспользуемых зависимостей Android сегодня с версией 4.0.0
jkschneider
4
К сожалению, этот плагин не работает с kotlin dsl. У них нет планов поддерживать это.
Сноу
3
Он также не работает с новыми Gradle конфигурациями (например: implementationа api), и даже хуже, рекомендует изменить от новых к старым устаревших единиц (например: compile, testCompileи т.д.).
Лоуренс Гонсалвес
8

Проект, упомянутый в предыдущих ответах, кажется мертвым. Я использую gradle-dependency-analysis . Настройка проста:

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath 'ca.cutterslade.gradle:gradle-dependency-analyze:1.0.3'
  }
}

apply plugin: 'ca.cutterslade.analyze'

Затем сделайте:

$ gradle analyzeDependencies
Субхаш Чандран
источник
4
Я столкнулся с этой ошибкой: «Ошибка синхронизации Gradle: задача с именем« классы »не найдена в проекте»
Паван
Я получаю от этого stackOverflowException. Однако нет точной информации, что является причиной этого. Я думаю, что здесь может быть проблема с циклической зависимостью, но это было бы отличной идеей, я инструмент сказал мне, где.
SGal
1
@Pawan этот плагин не работает с проектами Android, и в ближайшее время это не изменится. Доказательство: github.com/wfhartford/gradle-dependency-analyze/issues/18
diesersamat
8

Мне очень повезло с использованием подключаемого модуля Gradle Dependency Analysis . Чтобы начать работу с ним, добавьте следующие две вещи в свой сценарий сборки Gradle.

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "com.github.nullstress:DependencyAnalysisPlugin:1.0.3"
    }
}

и

apply plugin: "dependencyAnalysis"

Как только они будут на месте, бегите gradle analyze. Если есть неиспользуемые зависимости, вы получите сбой сборки, в котором будут отображаться выходные данные, аналогичные приведенному ниже, плюс список неиспользуемых зависимостей (как объявленных, так и транзитивных). Сбой сборки действительно удобен, если вы хотите принудительно исключить неиспользуемые зависимости через сборку CI.

:foo:analyze FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':foo:analyze'.
> The project has unused declared artifacts
jstricker
источник
3
Я получаю сообщение «Ошибка выполнения для задачи ': app: analysis'.> В проекте не применен плагин java». Если я добавлю «применить плагин: 'java'», мне скажут, что он несовместим с существующим плагином приложения для Android. Любые идеи?
Alex Black
Похоже, это что-то особенное с плагином приложения Android. Хотел бы я помочь, но у меня нет опыта работы с Android!
jstricker 06
В плагине есть ошибки, например, когда у вас есть статический вызов зависимости, которые не принимаются во внимание.
ToYonos
похоже, это не рекомендуется для подключаемого модуля
линтера
2

Я только что узнал об этом: https://plugins.gradle.org/plugin/com.autonomousapps.dependency-analysis

Github

Судя по всему, он находится в активной разработке, но я еще не тестировал.

Изменить: на самом деле это довольно круто, он дает множество советов (например, использовать ли api или реализацию)

sschrass
источник
0

Примечание редактора: этот ответ устарел. Пожалуйста, посмотрите верхний ответ .

Вы можете попробовать плагин Gradle com.github.nullstress.dependency-analysis.

Фрагмент скрипта сборки для использования во всех версиях Gradle:

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath "com.github.nullstress:DependencyAnalysisPlugin:1.0.3"
  }
}

apply plugin: "com.github.nullstress.dependency-analysis"

Фрагмент сценария сборки для нового инкубационного механизма плагинов, представленного в Gradle 2.1:

plugins {
  id "com.github.nullstress.dependency-analysis" version "1.0.3"
}

Кроме того, на форуме Gradle есть тема ( есть ли в Gradle эквивалент "mvn dependency: analysis"? ) По этому поводу.

EFernandes
источник
Этот плагин кажется мертвым проектом ... по крайней мере, с текущей версией Gradle.
cjstehno
0

Проекты по большинству исторических ответов мертвы, но gradle-dependency-analysis, похоже, живы по состоянию на 30 мая 2016 года .

Брэндон Маккензи
источник
Я вижу, как пару недель назад они внесли изменения в nebula-lint.
Построен в Пэррисе