Como excluir um módulo de uma construção de reator Maven?

98

Temos um projeto Maven 2 com vários módulos. Exemplo:

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

Digamos que o módulo de "dados" consuma muito tempo para construir e queremos excluí-lo quando o projeto é construído por um servidor CI. Atualmente, usamos dois arquivos pom.xml para fazer isso. Um tem todos os módulos e o outro tem todos os módulos, exceto aqueles que podem ser deixados de fora para o CI. Mas isso é muito chato porque às vezes esquecemos de colocar um novo módulo em ambos os arquivos.

Existe uma solução que não precisa de duas listas de módulos separadas?

Kayahr
fonte

Respostas:

73

O mais fácil pode ser usar profilesassim:

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

Você deve, então, verificar as maneiras de ativar perfis

SaM
fonte
O que você faria se precisasse que os dados acontecessem antes do comum? Neste caso, os módulos de perfil serão colocados após os módulos padrão na ordem do reator. Existe um padrão para forçar a ordem?
Peter Kahn
9
A ordem do módulo NÃO é a ordem em que eles aparecerão no reator. A única maneira de afetar a ordem é criar dependências entre os módulos, ou seja, usando a tag <dependency>. Você não pode confiar na ordem de declaração para isso.
SaM de
7
@SaM Na verdade, a partir do Maven 3.0.5 o Reactor levará em consideração a ordem dos 'módulos' , embora a ordem ditada pelas dependências seja de maior prioridade.
hellodanylo
Isso interromperá alguns outros plug-ins que não conseguem detectar o módulo no perfil, mesmo que o perfil esteja ativado
tribbloid
143

Com o Maven 3.2.1, agora você pode usar -pl !<module_name>,!<module_name>para excluir certos módulos da construção do reator.

Veja esta solicitação de recurso: https://issues.apache.org/jira/browse/MNG-5230

Yogesh_D
fonte
É seguro mudar de 3.0.4 para 3.2.1 ou há mudanças maiores?
janeiro de
Eu tinha mudado de 3.1 para 3.2.1 sem problemas. Mas, para ser honesto, você teria que fazer uma construção para descobrir.
Yogesh_D
30
Não se esqueça de escapar do ponto de exclamação na linha de comando do shell. Tem um significado muito especial, consulte, por exemplo, unix.stackexchange.com/questions/3747/…
Pavel
5
Infelizmente, há um problema aberto no plug-in do Jenkins maven-project que não oferece suporte à exclusão do módulo do reator: issues.jenkins-ci.org/browse/JENKINS-26472
Nick Vanderhoven
@Pavel: ou apenas use em -vez de !, ou seja,-pl -<module_name>
msa
45

Os projetos a serem construídos também podem ser especificados na linha de comando mvn. Isso eliminaria a necessidade de um pom separado, mas, em vez disso, você teria que alterar a configuração do CI sempre que houver um novo módulo.

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

Talvez uma combinação deste sinalizador e / --also-make-dependentsou --also-makereduzisse novamente a carga de manutenção.

-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
Jörn Horstmann
fonte
Isso tem os mesmos problemas que usar dois poms separados. Temos que lugares onde definimos os módulos. É isso que estou tentando evitar.
kayahr
Esta é uma boa solução. Não precisa atualizar o pom. mvn clean install -pl mysubproject
nicolas-f
22

Presumo que você queira que a construção padrão sempre crie tudo, independentemente da velocidade, para que novos desenvolvedores possam começar rapidamente sem ter que entender muito sobre o POM. Você pode usar perfis como este:

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

O problema com isso é que, se um desenvolvedor especificar outro perfil na linha de comando, o expensive-modules-to-buildnão será incluído (a menos que o desenvolvedor também o especifique). Isso torna complicado lembrar quais perfis devem ser incluídos.

Aqui está uma maneira hacky de contornar isso. Ambos os perfis estão sempre incluídos, porque o arquivo pom.xml sempre existe. Então, para excluir os módulos caros, você pode usar -P!full-buildna linha de 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>
Artbristol
fonte
Boa resposta. Mas você realmente precisa de dois perfis no segundo exemplo de código? Não funcionaria o único perfil do primeiro exemplo de código com um elemento de ativação alterado?
Arend v. Reinersdorff,
@ Arendv.Reinersdorff sim, seria, no entanto, essa resposta também funciona com outros perfis na construção que você pode querer incluir por padrão. No geral, porém, acho que a outra resposta com -pl !<module_name>,!<module_name>é melhor do que a anterior
artbristol,
1
Bom truque de ativação. Isso me resolveu os problemas com <activeByDefault> que nem sempre está ativo!
Gab
7

Outra ideia: os módulos do Reactor podem ser aninhados, portanto, deve ser possível agrupar seus módulos de construção rápida e lenta em poms separados e, em seguida, adicionar outro pom agregador contendo esses dois como módulos. Seu servidor CI só poderia fazer referência ao pom que contém os módulos de construção rápida.

<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>
Jörn Horstmann
fonte
1

Você poderia usar perfis maven . Em nosso ambiente de construção, criamos um perfil quickque desabilita muitos plug-ins e execução de teste.

Isso é feito por

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

E então invocamos o maven da seguinte maneira

mvn groupId:artifactId:goal -P quick

Você pode desabilitar a compilação e outros plug-ins padrão no pom do seu módulo para acelerá-lo.

Nr9
fonte
2
Sim, para desabilitar testes, isso funciona muito bem. Mas como posso usar perfis para excluir módulos SEM ter duas listas de módulos separadas no pom? Pelo que eu sei, preciso colocar a lista completa de módulos em uma seção de perfil e a lista de módulos de construção rápida em outra seção de perfil. Portanto, isso tem o mesmo problema de usar dois poms separados: eu tenho duas listas de módulos para manter.
kayahr
Excluir módulo não é realmente a maneira de fazer as coisas no maven e minha experiência com o maven é que é melhor continuar com a maneira como as coisas são feitas, senão você terá tantos problemas ... Então, o que estou propondo não é remova o módulo, mas para torná-lo menos demorado.
Nr9
O problema com o maven é que 'a maneira como as coisas são feitas' freqüentemente não está de acordo com 'a maneira como as coisas são feitas no mundo real', tornando a experiência do maven pobre e dolorosa. Os desenvolvedores fariam bem em receber uma dose de treinamento de experiência do usuário.
Ed Randall
0

Não era exatamente a resposta que essas pessoas estavam pedindo. Minha situação era que eu queria implantar apenas o pom pai. Estou usando o spring-boot-thin-layoutmódulo em um filho. Isso requer que o módulo pai seja implantado no artifactory. Eu adicionei o seguinte em meu projeto. Ele permite o salto installe / ou deployfase.

No meu pai 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 no meu pom (s) filho (s) ou qualquer módulo que você não deseja implantado com o pai:

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

Então, efetivamente, quando eu executar mvn deployno pom pai, ele compilará todos os módulos, não executará a instalação em nada e, no final, implementará qualquer módulo que não tenha <maven.deploy.skip>${disable.deploy}</maven.deploy.skip>em suas propriedades. Portanto, no meu caso, apenas implantar o pai.

ranma2913
fonte