Как программно выполнить определенный плагин /Mojo из pom.xml?

Я являюсь автором одного из плагинов Maven (а не Apache/Codehaus, полностью инди). Иногда я получаю запросы поддержки или тестовые примеры, когда мне действительно нужно отлаживать выполнение моего плагина с существующим pom.xml. В основном тестовые примеры, которые я получаю, представляют собой образец/тестовый проект (pom.xml с src/main/resoures, src/main/java и т.д.).

Мне нужен способ:

  • Загрузите существующий pom.xml.
  • Найти конкретное выполнение моего плагина там (обычно это единственный).
  • Получить экземпляр MyMojo - полностью инициализированный /condigured, со всеми компонентами и параметрами, которые были введены непосредственно.
  • Выполнить MyMojo.
  • Что важно, что тестовые проекты представляют собой отдельные проекты, я не хочу их копировать в модуль Maven моего плагина.
  • Я бы хотел сделать это без удаленной отладки.

Отладка Я имею в виду, чтобы иметь возможность устанавливать и останавливать точки останова (также условные), входить/выходить/завершать исходный код.

В идеале я хотел бы иметь возможность executeMyMojoFrom(new File("pom.xml")) - например, в тесте JUnit или методе main для некоторого класса. (Я могу предоставить groupId, artifactId и т.д. Все остальные определения должны быть загружены только из этого pom.xml.)

Как я могу достичь этого?


Что я пробовал до сих пор:

  • Debug As... on pom.xml в Eclipse - не работает достаточно хорошо (исходный код не найден, точка останова не работает как его не контекст Java-проекта)
  • Решения Maven Embedder/Invoker - создавать события в отдельных процессах через CLI. Забудьте точки останова, нет отладки.
  • Удаленная отладка с помощью mvnDebug, а затем удаленная отладка из Eclipse, как предложено Pascal Thivent здесь. Это лучший вариант. Однако удаленная отладка означает запуск mvnDebug по отдельности, а также не гарантирует, что JAR файлы, которые у меня есть в Eclipse, точно такие же, что и mvnDebug. Итак, здесь есть определенное расстояние.
  • maven-plugin-testing-harness - Я действительно думал, что это выполнит эту задачу. Но сначала я прыгал через обручи в течение нескольких часов, чтобы начать. Все важные зависимости "предоставляются", поэтому я сначала должен был найти правильную комбинацию версий этих артефактов. И тогда - только чтобы обнаружить, что AbstractMojoTestCase работает только в модуле плагина, который вы хотите протестировать. Вероятно, я ошибся, когда подумал, что maven-plugin-testing-harness является тестовым жгутом для плагинов Maven. Кажется, что это тестовый жгут для плагина из этого модуля плагина. Что нелогично, но не помогает моему делу. Я бы хотел проверить свой плагин в других модулях.

Итак, сейчас у меня лучшие результаты с удаленным решением для отладки. Но то, что я ищу, действительно похоже на maven-plugin-testing-harness, но не подключено к модулю плагина. Есть ли у кого-нибудь намек, если такой метод существует где-то в артефактах Maven?

Чтобы быть более конкретным, я хотел бы написать что-то вроде:

 public void testSomething()
        throws Exception
    {
        File pom = getTestFile( "pom.xml" );
        assertNotNull( pom );
        assertTrue( pom.exists() );

        MyMojo myMojo = (MyMojo) lookupMojo( "myGroupId", "myArtifactid", ...,
                                             "myGoal", pom );
        assertNotNull( myMojo );
        myMojo.execute();

        ...
    }

Сравните это с MyMojoTest здесь - это почти там. Следует просто не подключаться к модулю MyMojo Maven (как в maven-plugin-testing-harness).


Обновление

Несколько ответов на вопросы в комментариях:

Вы хотите сказать, что вы не хотите, чтобы такой тестовый класс, т.е. MyMojoTest, находился внутри того же проекта, что и MyMojo, т.е. ваш проект плагина? Почему это?

Совершенно верно. Я хочу отлаживать выполнение плагина в существующем проекте Maven, я не хочу сначала перенести этот проект в свой проект плагина, чтобы выполнить тест. Я хочу иметь возможность тестировать/отлаживать существующий проект. В идеале мне просто нужно добавить my-maven-plugin-testing зависимость и подкласс MyMojoTest в проекте src/test/jaca. Это было бы хорошим инструментом для отладки исполнения. Перетаскивание целевого проекта в мой проект Mojo - это слишком много накладных расходов - и в основном это не те тесты, которые я хочу сохранить в долгосрочной перспективе. Надеюсь, это ответы, почему.

Во всяком случае, это просто соглашение о сохранении project-to-test/pom.xml внутри src/test/resources вашего модуля плагина, а не правила...

Моя проблема заключается не в местоположении pom.xml project-to-test, который легко настраивается. Моя трудность заключается в том, что maven-plugin-testing-harness как-то жестко запрограммирован в проекте Mojo. Он использует pom.xml Mojo, ищет другие специальные файлы/дескрипторы в содержащем проекте. Так что я как-то не могу использовать его в проекте без Mojo, или я могу? Это мой вопрос.

И я не уверен, почему Debug As... не помог вам...

Не уверен, но (1) точки останова не работали и (2) по какой-то причине исходный код не был "прикреплен".

Ответы

Ответ 1

Если Debug as не работал для вас, как и должен, вы можете попытаться использовать mojo-executor с небольшим количеством работы.

https://github.com/TimMoore/mojo-executor

Таким образом, вы программно выполните цель copy-dependencies Maven Dependency Plugin:

executeMojo(
    plugin(
        groupId("org.apache.maven.plugins"),
        artifactId("maven-dependency-plugin"),
        version("2.0")
    ),
    goal("copy-dependencies"),
    configuration(
        element(name("outputDirectory"), "${project.build.directory}/foo")
    ),
    executionEnvironment(
        mavenProject,
        mavenSession,
        pluginManager
    )
);

Переменные project, session и pluginManager должны вводиться через обычную инъекцию Mojo. Да, это означает, что это должно выполняться из контекста другого плагина maven. Теперь, когда я думаю об этом, поможет ли это вам каким-либо образом, все еще вопрос, потому что он все еще полагается на инъекцию таких компонентов базовым контейнером plexus.

Моя первоначальная идея заключалась в том, что вы создали плагин maven, который будет вызывать ваш плагин jaxb2 через mojo-executor, как указано выше, затем сериализуйте mavenProject, mavenSession, pluginManager, то есть все plexus, а затем использовать эти объекты для запуска вашего плагина jaxb2 в будущем из автономного класса без встроенного плагина.