Порядок выполнения закрытия расширений Gradle и плагинов - PullRequest
0 голосов
/ 08 мая 2020

У меня есть 3 плагина «A», «B» и «C». Плагин 'A' включает плагин 'B' с:

project.getPlugins().apply(B.class);

Плагин 'B' включает плагин 'C' с:

project.getPlugins().apply(C.class);

Подводя итог, зависимости следующие: > B> C

Плагин «A» имеет настраиваемую задачу «T_A» и настраиваемое расширение «E_A». Плагин 'C' имеет собственное расширение 'E_ C'.

Когда я использую следующий build.gradle и выполняю gradlew T_A, все работает, как ожидалось, это означает, что свойства установлены раньше T_A выполняется:

plugins {
  id 'A'
}

E_A {
  prop_a = 'hello'
}

E_C {
  prop_c = 'world'
}

НО, со следующим build.gradle:

plugins {
  id 'A'
}

E_C {
  prop_c = 'world'
}

E_A {
  prop_a = 'hello'
}

... тогда prop_a не будет установлен до того, как задача будет выполнена.

Я застрял и действительно не понимаю, почему могу ошибаться.

Важен ли порядок закрытия расширений в файле build.gradle?

1 Ответ

0 голосов
/ 15 мая 2020

На этапе настройки, когда вызываются ваши применяемые функции, не гарантируется, что некоторые значения будут установлены . Так что порядок имеет значение, но полагаться на него - плохая практика. Сложные расширения, такие как NamedDomainObjectContainer, всегда лениво настраиваются.

Во-первых, вы можете использовать Property в своих задачах, их значения устанавливаются, когда они требуются. Это предпочтительный способ, потому что он сводит к минимуму конфигурацию задачи, но может очень сбивать с толку, руководство, показывающее, как использовать свойства: Ленивая конфигурация: соединение свойств вместе Хотя он использует Groovy, должно быть легко перевести в Java.

Есть еще одно решение, которое заключается в добавлении слушателя оценки поста. Он вызывается после того, как все плагины и расширения настроены, но это может вызвать путаницу, если несколько плагинов настраивают одни и те же задачи. См. Эту ветку, в которой обсуждается проект после использования . Кстати, некоторые официальные плагины Gradle по-прежнему настраивают задачи по значению.

class PluginA implements Plugin<Project> {
    ExtensionA a;
    public void apply(Project project) {
        a = project.getExtension().create("E_A", ExtensionA.class);
        project.getTasks().register("T_A");   //prop_a may not be set here
        project.getTasks().findByName("T_A").doLast(t -> System.out.println(a.prop_a));
        project.afterEvaluate(p -> 
            //prop_a will be set here
            p.getTasks().findByName("T_A").doLast(t -> System.out.println(a.prop_a));
        );
    }
}

Очевидно, вы могли бы сделать это намного чище.

Я рекомендую вам поиграть со слушателями, чтобы лучше понять жизненный цикл Gradle.

...