Como posso importar um script Gradle para outro?

97

Eu tenho um script gradle complexo que envolve uma carga de funcionalidade em torno da construção e implantação de uma série de projetos netbeans em vários ambientes.

O script funciona muito bem, mas basicamente é configurado por meio de meia dúzia de mapas contendo informações de projeto e ambiente.

Quero abstrair as tarefas em outro arquivo, para que possa simplesmente definir meus mapas em um arquivo de construção simples e importar as tarefas de outro arquivo. Dessa forma, posso usar as mesmas tarefas principais para vários projetos e configurar esses projetos com um simples conjunto de mapas.

Alguém pode me dizer como posso importar um arquivo gradle para outro, de maneira semelhante à tarefa do Ant? Pesquisei os documentos de Gradle sem sucesso até agora.

Informação adicional

Após a resposta de Tom abaixo, pensei em tentar esclarecer exatamente o que quero dizer.

Basicamente, tenho um script gradle que executa uma série de subprojetos. No entanto, os subprojetos são todos projetos Netbeans e vêm com seus próprios scripts de construção de formigas, então tenho tarefas no gradle para chamar cada um deles.

Meu problema é que tenho algumas configurações no topo do arquivo, como:

projects = [
    [name:"MySubproject1", shortname: "sub1", env:"mainEnv", cvs_module="mod1"],
    [name:"MySubproject2", shortname: "sub2", env:"altEnv", cvs_module="mod2"]
]

Em seguida, gero tarefas como:

projects.each({
    task "checkout_$it.shortname" << {
         // Code to for example check module out from cvs using config from 'it'.
    }
})

Eu tenho muitos desses trechos de geração de tarefas, e todos eles são genéricos - eles dependem inteiramente da configuração na lista de projetos.

Então, o que eu quero é uma maneira de colocar isso em um script separado e importá-lo da seguinte maneira:

projects = [
    [name:"MySubproject1", shortname: "sub1", env:"mainEnv", cvs_module="mod1"],
    [name:"MySubproject2", shortname: "sub2", env:"altEnv", cvs_module="mod2"]
]

import("tasks.gradle") // This will import and run the script so that all tasks are generated for the projects given above.

Portanto, neste exemplo, tasks.gradle terá todo o código de geração de tarefa genérica e será executado para os projetos definidos no arquivo build.gradle principal. Desta forma, tasks.gradle é um arquivo que pode ser usado por todos os grandes projetos que consistem em uma série de subprojetos com arquivos de construção do Netbeans.

Anthony Roy
fonte
3
Considere a construção "aplicar de: 'other.gradle'" para importar declarações externas. (Consulte "12.4. Configurando o projeto usando um script de compilação externo" aqui gradle.org/0.9-preview-1/docs/userguide/… )
Petr Gladkikh
@PetrGladkikh apply fromexecuta imediatamente as tarefas externas. Isso pode não ser preferível na lógica de execução (ou seja, eu gostaria de executar as tarefas quando eu quiser, não imediatamente).
IgorGanapolsky 01 de
Esta afirmação no comentário acima não é verdadeira : apply fromexecuta imediatamente as tarefas externas. Não se deixe enganar. Tarefas externas são configuradas, não executadas.
Jarekczek

Respostas:

17

A resposta à pergunta acabou estando no sistema de Plugins, onde você pode adicionar a funcionalidade desejada em um conjunto de plugins que podem ser arquivos bacanas localizados no diretório buildSrc/src/main/groovy. Plugins também podem ser empacotados como Jar, embora eu não tenha tentado isso.

Detalhes aqui: Plug-ins personalizados

Anthony Roy
fonte
Só para você saber que o link está quebrado - aqui está uma atualização gradle.org/docs/current/userguide/…
JARC
4

Bem, é difícil dizer o que é melhor para você sem realmente ver seu arquivo de construção.

Eu poderia supor que configurar seu ambiente como uma construção de vários projetos deve fornecer a abstração que você está procurando.

Na raiz do projeto, build.gradlevocê define todas as coisas específicas do seu domínio, bem como as coisas que se aplicam a todos os seus subprojetos:

repositories {
    add(new org.apache.ivy.plugins.resolver.FileSystemResolver()) {
        name = 'destRepo'
        addIvyPattern( file( project.properties['repo.dest.dir']).absolutePath + '/[organisation]/[module]/ivys/ivy(-[revision]).xml')
        addArtifactPattern( file( project.properties['repo.dest.dir']).absolutePath + '/[organisation]/[module]/[type]s/[artifact](-[revision]).[ext]')
        descriptor = 'optional'
        checkmodified = true
    }
    ...
}
...
subprojects {
    sourceCompatibility = 1.5
    targetCompatibility = 1.5
    group = 'my.group'
    version = '1.0'
    uploadArchives {
        uploadDescriptor = true
        repositories {
            add rootProject.repositories.destRepo
        }
    }
    apply{ type my.group.gradle.api.plugins.MyPlugin }
    ...
}

dependsOnChildren()

O diretório raiz do projeto também pode conter um gradle.propertiesarquivo onde você define as propriedades usadas por seus projetos:

buildDirName=staging
repo.dest.dir=/var/repo
...

Em seguida, em um arquivo adicional da raiz de seu projeto denominado, settings.gradlevocê realmente aponta para seus subprojetos:

include 'my-first-component',
        'my-second-component'
...
project(':my-first-component').projectDir = new File(rootDir, 'path/to/first/component')
project(':my-second-component').projectDir = new File(rootDir, 'path/to/second/component')
...

Cada diretório de subprojeto contém um build.gradlearquivo contendo apenas o material específico do subprojeto.

Não importa se você invoca a gradlepartir da raiz do projeto ou do diretório de subprojeto, o gradle considerará automaticamente todas as suas definições feitas nos vários arquivos.

Observe também que nenhuma tarefa de compilação será executada para a raiz do seu projeto, desde que você não carregue nenhum plug-in além do plug-in padrão no nível da raiz.

Tom
fonte
1
Obrigado por responder. Não estou tendo problemas com subprojetos, mas sim com a criação de uma 'biblioteca' de tarefas comuns. Eu editei minha pergunta original com mais informações e trechos de código para tornar as coisas mais claras.
Anthony Roy
1
Portanto, em vez de fazer a importação ("tasks.gradle") de sua amostra, você teria a seção de subprojetos {} especificando o código de geração de tarefa genérico usado por todos os seus subprojetos. Isso deve fornecer a mesma abstração que você está procurando !?
Tom
O plugin Ivy é realmente necessário aqui? O Gradle não pode ser usado sozinho?
IgorGanapolsky 01 de