Jak wykluczyć moduł z kompilacji reaktora Maven?


98

Mamy projekt Maven 2 z wieloma modułami. Przykład:

<modules>
  <module>common</module>
  <module>foo</module>
  <module>data</module>
  <module>bar</module>
  ... more ...
</module>

Załóżmy, że tworzenie modułu danych jest czasochłonne i chcemy go wykluczyć, gdy projekt jest budowany przez serwer CI. Obecnie używamy do tego dwóch plików pom.xml. Jeden zawiera wszystkie moduły, a drugi ma wszystkie moduły oprócz tych, które można pominąć dla CI. Ale to dość denerwujące, ponieważ czasami zapominamy o umieszczeniu nowego modułu w obu plikach.

Czy istnieje rozwiązanie, które nie wymaga dwóch oddzielnych list modułów?

Odpowiedzi:


73

Najłatwiej byłoby użyć w profilesten sposób:

<project>
  ...
  <modules>
    <module>common</module>
    <module>foo</module>
    <module>bar</module>
  <modules>
  ...
  <profiles>
    <profile>
      <id>expensive-modules-to-build</id>
      <modules>
        <module>data</module>
      </modules>
    </profile>
  </profiles>
</project>

Następnie sprawdź, jak możesz aktywować profile


Co byś zrobił, gdybyś potrzebował danych przed wspólnym? W takim przypadku moduły profilu zostaną umieszczone za modułami domyślnymi w kolejności reaktora. Czy istnieje wzór wymuszania porządku?
Peter Kahn

9
Kolejność modułów NIE jest kolejnością, w jakiej pojawią się w reaktorze. Jedynym sposobem, aby wpłynąć na kolejność, jest stworzenie zależności między modułami, czyli użycie tagu <dependency>. Nie możesz w tym celu polegać na kolejności deklaracji.
sobota,

7
@SaM Właściwie od Maven 3.0.5 Reactor weźmie pod uwagę kolejność w 'modułach' , chociaż kolejność podyktowana zależnościami ma wyższy priorytet.
hellodanylo

Spowoduje to zerwanie innych wtyczek, które nie wykryją modułu w profilu, nawet jeśli profil jest włączony
tribbloid

143

Dzięki Maven 3.2.1 możesz teraz użyć, -pl !<module_name>,!<module_name>aby wykluczyć niektóre moduły z kompilacji reaktora.

Zobacz tę prośbę o funkcję: https://issues.apache.org/jira/browse/MNG-5230


Czy przejście z 3.0.4 na 3.2.1 jest bezpieczne, czy też są większe zmiany?
sty

Przeszedłem z 3.1 do 3.2.1 bez żadnych problemów. Ale szczerze mówiąc, musiałbyś zrobić kompilację, aby to rozgryźć.
Yogesh_D

30
Nie zapomnij pominąć znaku wykrzyknika w linii poleceń powłoki. Ma bardzo szczególne znaczenie, patrz np. Unix.stackexchange.com/questions/3747/…
Pavel

5
Niestety, obecnie we wtyczce Jenkins maven-project jest otwarty problem, który nie obsługuje wykluczania modułów reaktora: Issues.jenkins-ci.org/browse/JENKINS-26472
Nick Vanderhoven

@Pavel: lub po prostu użyj -zamiast !, np.-pl -<module_name>
msa

45

Projekty do zbudowania można również określić w wierszu poleceń mvn. To wyeliminowałoby potrzebę oddzielnego pom, ale zamiast tego musiałbyś zmieniać konfigurację CI za każdym razem, gdy pojawia się nowy moduł.

-pl,--projects <arg>                Comma-delimited list of specified
                                    reactor projects to build instead
                                    of all projects. A project can be
                                    specified by [groupId]:artifactId
                                    or by its relative path.

Może połączenie tej flagi i --also-make-dependentslub --also-makezmniejszyłoby to obciążenie związane z utrzymaniem.

-am,--also-make                     If project list is specified, also
                                    build projects required by the
                                    list
-amd,--also-make-dependents         If project list is specified, also
                                    build projects that depend on
                                    projects on the list

Ma to takie same problemy, jak użycie dwóch oddzielnych pompek. Mamy miejsca, w których definiujemy moduły. Tego właśnie staram się uniknąć.
kayahr

To jest dobre rozwiązanie. Nie musisz aktualizować pliku pom. mvn clean install -pl mysubproject
nicolas-f

22

Zakładam, że chcesz, aby domyślna kompilacja zawsze tworzyła wszystko, niezależnie od szybkości, aby nowi programiści mogli szybko rozpocząć pracę bez konieczności rozumienia POM. Możesz używać takich profili:

<modules>
    <module>common</module>
    <module>foo</module>
    <module>bar</module>
  </modules>
  ...
  <profiles>
    <profile>
      <id>expensive-modules-to-build</id>
      <activation>
         <activeByDefault>true</activeByDefault>
      </activation>
      <modules>
        <module>data</module>
      </modules>
    </profile>
  </profiles>
</project>

Problem polega na tym, że jeśli programista określi inny profil w wierszu poleceń, plik expensive-modules-to-build to nie jest on uwzględniany (chyba że programista również go określi). To sprawia, że ​​zapamiętanie, które profile należy uwzględnić, jest skomplikowane.

Oto hacky sposób obejścia tego. Oba profile są zawsze uwzględniane, ponieważ plik pom.xml zawsze istnieje. Aby wykluczyć drogie moduły, możesz użyć -P!full-buildw wierszu poleceń.

<profiles>
    <profile>
        <id>full-build</id>
        <activation>
            <file>
                <exists>pom.xml</exists>
            </file>
        </activation>
        <modules>
            <module>data</module>
        </modules>
    </profile>
    <profile>
        <id>short-build</id>
        <activation>
            <file>
                <exists>pom.xml</exists>
            </file>
        </activation>
        <modules>
           <module>common</module>
           <module>foo</module>
           <module>bar</module>
        </modules>
    </profile>
</profiles>

Niezła odpowiedź. Ale czy naprawdę potrzebujesz dwóch profili w drugim przykładzie kodu? Czy pojedynczy profil z pierwszego przykładu kodu ze zmienionym elementem aktywacyjnym nie zadziała?
Arend przeciwko Reinersdorff,

@ Arendv.Reinersdorff tak, ale ta odpowiedź działa również z innymi profilami w kompilacji, które możesz chcieć uwzględnić domyślnie. Ogólnie rzecz biorąc, myślę, że druga odpowiedź -pl !<module_name>,!<module_name>jest lepsza niż ta stara
artbristol

1
Dobra sztuczka aktywacyjna. Rozwiązało mi to problemy z <activeByDefault>, które nie zawsze jest aktywne!
Gab

7

Inny pomysł: moduły Reactor można zagnieżdżać, więc powinno być możliwe zgrupowanie szybko i wolno budujących się modułów w oddzielne poms, a następnie dodanie kolejnego agregatora pom zawierającego te dwa jako moduły. Twój serwer CI mógłby wtedy odnosić się tylko do pom zawierającego moduły szybkiego budowania.

<artifactId>fast</artifactId>
<modules>
    <module>fast-a</module>
    <module>fast-b</module>
    <module>fast-c</module>
</module>

<artifactId>all</artifactId>
<modules>
    <module>fast</module>
    <module>slow</module>
</module>

1

Możesz użyć profili maven . W naszym środowisku kompilacji stworzyliśmy profil, quickktóry wyłącza wiele wtyczek i wykonywanie testów.

Odbywa się to przez

    <profile>
        <id>quick</id>
        <properties>
            <skipTests>true</skipTests>
            <!-- others... -->
        </properties>   
        <build>
            <plugins>
                 <!-- configuration... -->
            </plugins>
        </build>
    </profile>

A potem wywołujemy maven w następujący sposób

mvn groupId:artifactId:goal -P quick

Możesz wyłączyć kompilację i inne standardowe wtyczki w pomie swojego modułu, aby przyspieszyć ten proces.


2
Tak, w przypadku wyłączania testów działa to świetnie. Ale jak mogę używać profili do wykluczania modułów BEZ dwóch oddzielnych list modułów w pom? O ile wiem, muszę umieścić pełną listę modułów w jednej sekcji profilu, a listę modułów szybkiego budowania w drugiej sekcji profilu. Więc to ma ten sam problem, co używanie dwóch oddzielnych pomów: mam dwie listy modułów do utrzymania.
kayahr

Wykluczanie modułu nie jest tak naprawdę sposobem na robienie rzeczy w maven, a moje doświadczenie z maven jest takie, że lepiej trzymać się sposobu, w jaki się robi, inaczej napotkasz tak wiele problemów ... Więc tak naprawdę proponuję, aby tego nie robić wyjmij moduł, ale aby ten moduł był mniej czasochłonny.
Nr9

Problem z maven polega na tym, że „sposób załatwiania rzeczy” często nie jest zgodny ze „sposobem, w jaki robi się rzeczy w prawdziwym świecie”, co sprawia, że ​​maven jest biedny i bolesny. Deweloperzy dobrze by zrobili, gdyby wzięli dawkę szkolenia UX.
Ed Randall,

0

Nie do końca odpowiedź, o którą prosili ci ludzie. Moja sytuacja była taka, że ​​chciałem wdrożyć tylko macierzysty pom. Używam spring-boot-thin-layoutw module podrzędnym. Wymaga to wdrożenia modułu nadrzędnego w artefaktorze. Dodałem do mojego projektu: Umożliwia pominięcie installi / lubdeploy fazę.

W moim pompie rodzica:

<properties>
    <disable.install>true</disable.install>
    <disable.deploy>true</disable.deploy>
    <enable.deployAtEnd>true</enable.deployAtEnd>
</properties>

<profiles>
    <profile>
        <id>deploy-parent</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <disable.install>true</disable.install>
            <disable.deploy>true</disable.deploy>
            <deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
        </properties>
        <build>
            <finalName>${project.version}</finalName>
        </build>
    </profile>
</profiles>

A w moich podrzędnych pom (ach) lub dowolnym module, którego nie chcesz wdrożyć z rodzicem:

<properties>
    <maven.install.skip>${disable.install}</maven.install.skip>
    <maven.deploy.skip>${disable.deploy}</maven.deploy.skip>
    <deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
</properties>

Tak więc efektywnie, gdy uruchomię mvn deployna pom-nadrzędnym pom, skompiluje on wszystkie moduły, nie uruchomi instalacji na niczym, a na koniec wdroży każdy moduł, który nie ma <maven.deploy.skip>${disable.deploy}</maven.deploy.skip>w swoich właściwościach. Więc w moim przypadku wdrażam tylko rodzica.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.