Come escludere un modulo da una build di reattore Maven?


98

Abbiamo un progetto Maven 2 con molti moduli al suo interno. Esempio:

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

Supponiamo che la compilazione del modulo "dati" richieda molto tempo e che vogliamo escluderlo quando il progetto viene compilato da un server CI. Attualmente utilizziamo due file pom.xml per ottenere questo risultato. Uno ha tutti i moduli e l'altro ha tutti i moduli tranne quelli che possono essere lasciati fuori per CI. Ma è piuttosto fastidioso perché a volte ci dimentichiamo di inserire un nuovo modulo in entrambi i file.

Esiste una soluzione che non necessita di due elenchi di moduli separati?

Risposte:


73

Il modo più semplice potrebbe essere usare in profilesquesto modo:

<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>

Dovresti quindi controllare i modi in cui puoi attivare i profili


Che cosa faresti se avessi bisogno che i dati accadessero prima del comune? In questo caso i moduli del profilo verranno posizionati dopo i moduli predefiniti nell'ordine del reattore. Esiste un modello per forzare l'ordine?
Peter Kahn

9
L'ordine del modulo NON è l'ordine in cui appariranno nel reattore. L'unico modo per influenzare l'ordine è creare dipendenze tra i moduli, cioè utilizzando il tag <dependency>. Non puoi fare affidamento sull'ordine di dichiarazione per questo.
SaM

7
@SaM In realtà, a partire da Maven 3.0.5 il Reactor terrà conto dell'ordine in 'moduli' , sebbene l'ordine dettato dalle dipendenze abbia una priorità più alta.
hellodanylo

Ciò interromperà alcuni altri plug-in che non riescono a rilevare il modulo nel profilo anche se il profilo è abilitato
tribbloid

143

Con Maven 3.2.1, ora puoi usare -pl !<module_name>,!<module_name> per escludere alcuni moduli dalla build del reattore.

Vedi questa richiesta di funzionalità: https://issues.apache.org/jira/browse/MNG-5230


È sicuro passare dalla 3.0.4 alla 3.2.1 o sono previste modifiche più importanti?
gennaio

Sono passato dalla 3.1 alla 3.2.1 senza problemi. Ma ad essere onesti, dovresti fare una build per capirlo.
Yogesh_D

30
Non dimenticare di evitare il punto esclamativo sulla riga di comando della shell. Ha un significato molto speciale, vedere ad esempio unix.stackexchange.com/questions/3747/…
Pavel

5
Sfortunatamente al momento c'è un problema aperto nel plugin Jenkins maven-project che non supporta l'esclusione del modulo del reattore: issues.jenkins-ci.org/browse/JENKINS-26472
Nick Vanderhoven

@Pavel: o usa semplicemente al -posto di !, ie-pl -<module_name>
msa

45

I progetti da compilare possono anche essere specificati sulla riga di comando mvn. Ciò eliminerebbe la necessità di un pom separato, ma invece dovresti cambiare la configurazione CI ogni volta che c'è un nuovo modulo.

-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.

Forse una combinazione di questo flag --also-make-dependentseo --also-makeridurrebbe nuovamente questo onere di manutenzione.

-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

Questo ha gli stessi problemi dell'utilizzo di due pon separati. Dobbiamo luoghi in cui definiamo i moduli. È quello che sto cercando di evitare.
kayahr

Questa è una buona soluzione. Non devi aggiornare il pom. mvn clean install -pl mysubproject
nicolas-f

22

Presumo che tu voglia che la build predefinita crei sempre tutto, indipendentemente dalla velocità, in modo che i nuovi sviluppatori possano iniziare rapidamente senza dover capire molto sul POM. Puoi usare profili come questo:

<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>

Il problema con questo è che se uno sviluppatore specifica un altro profilo sulla riga di comando, il file expensive-modules-to-build non è incluso (a meno che lo sviluppatore non lo specifichi anche). Ciò rende complicato ricordare quali profili devono essere inclusi.

Ecco un modo hacky per aggirare questo. Entrambi i profili sono sempre inclusi, perché il file pom.xml esiste sempre. Quindi, per escludere i moduli costosi, puoi usare -P!full-buildsulla riga di comando.

<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>

Bella risposta. Ma hai davvero bisogno di due profili nel secondo esempio di codice? Il singolo profilo del primo esempio di codice con un elemento di attivazione modificato non funzionerebbe?
Arend contro Reinersdorff

@ Arendv.Reinersdorff sì, tuttavia questa risposta funziona anche con altri profili nella build che potresti voler includere per impostazione predefinita. Nel complesso, però, penso che l'altra risposta -pl !<module_name>,!<module_name>sia migliore di questa vecchia
artbristol

1
Buon trucco di attivazione. Mi ha risolto i problemi con <activeByDefault> che non è sempre attivo!
Gab

7

Un'altra idea: i moduli Reactor possono essere annidati, quindi dovrebbe essere possibile raggruppare i moduli di costruzione veloce e lenta in poms separati e quindi aggiungere un altro aggregatore pom contenente questi due come moduli. Il tuo server CI potrebbe quindi fare riferimento solo al pom contenente i moduli di costruzione rapida.

<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

Potresti usare profili esperti . Nel nostro ambiente di compilazione, abbiamo creato un profilo quickche disabilita molti plugin e l'esecuzione di test.

Questo viene fatto da

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

E poi invochiamo Maven nel modo seguente

mvn groupId:artifactId:goal -P quick

Potresti forse disabilitare la compilazione e altri plugin standard nel pom del tuo modulo per velocizzarlo.


2
Sì, per disabilitare i test funziona benissimo. Ma come posso utilizzare i profili per escludere i moduli SENZA avere due elenchi di moduli separati nel pom? Per quanto ne so, ho bisogno di mettere l'elenco completo dei moduli in una sezione del profilo e l'elenco dei moduli di costruzione rapida in un'altra sezione del profilo. Quindi questo ha lo stesso problema dell'uso di due poms separati: ho due elenchi di moduli da mantenere.
kayahr

L'esclusione del modulo non è davvero il modo di fare le cose in Maven e la mia esperienza con Maven è che è meglio restare fedeli al modo in cui vengono fatte le cose, altrimenti incappi in così tanti problemi ... Quindi quello che sto proponendo è di non farlo rimuovere il modulo, ma per rendere questo modulo meno dispendioso in termini di tempo.
Nr9

Il problema con Maven è che "il modo in cui vengono fatte le cose" spesso non è in linea con "il modo in cui vengono fatte le cose nel mondo reale", rendendo l'esperienza di Maven povera e dolorosa. Gli sviluppatori farebbero bene a prendere una dose di formazione UX.
Ed Randall

0

Non esattamente la risposta che queste persone stavano chiedendo. La mia situazione era che volevo schierare solo il genitore pom. Sto usando spring-boot-thin-layoutin un modulo figlio. Ciò richiede che il modulo genitore sia distribuito in artifactory. Ho aggiunto quanto segue nel mio progetto. Consente di saltare installe / odeploy fase.

Nel mio genitore pom:

<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>

E i pom di mio figlio o qualsiasi modulo che non vuoi distribuire con il genitore:

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

Quindi efficacemente quando eseguo mvn deployil pom genitore, compilerà tutti i moduli, non eseguirà l'installazione su nulla, e quindi alla fine distribuirà qualsiasi modulo che non abbia <maven.deploy.skip>${disable.deploy}</maven.deploy.skip>nelle sue proprietà. Quindi nel mio caso distribuendo solo il genitore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.