2017-01-28 3 views
1

Я хочу создать публикацию maven из RuleSource, которая будет опубликована через плагин maven-publish. Артефакты публикации - это результаты из серии задач Zip, созданных из правил. Когда я пытаюсь добавить артефакты, я получаю исключение из кругового правила.Gradle: как создать созданный правило ZipTask как публикацию артефакта maven

Вот мой очень простой build.gradle:

buildscript { 
    repositories { 
     mavenCentral() 
    } 

    dependencies { 
    } 
} 

task wrapper(type: Wrapper) { 
    gradleVersion = '3.3' 
} 

apply plugin: 'groovy' 
apply plugin: 'testpub' 

repositories { 
    mavenCentral() 
} 

dependencies { 
    compile 'org.codehaus.groovy:groovy-all:2.4.7' 
} 

testpub плагин существует в каталоге buildSrc. Для того, чтобы иметь возможность применять его, как указано выше, требуется подать следующие свойства:

// buildSrc/src/main/resources/META_INF/gradle-plugins/testpub.properties 
implementation-class=TestPubPlugin 

Вот очень простой плагин файла:

import org.gradle.api.Project 
import org.gradle.api.Plugin 
import org.gradle.model.RuleSource 
import org.gradle.api.Task 
import org.gradle.model.Mutate 
import org.gradle.model.Finalize 
import org.gradle.api.tasks.bundling.Zip 
import org.gradle.model.ModelMap 
import org.gradle.api.publish.PublishingExtension 
import org.gradle.api.publish.maven.MavenPublication 


class TestPubPlugin implements Plugin<Project> { 
    void apply(Project project) {  
     project.configure(project) { 
      apply plugin: 'maven-publish' 

      publishing { 
       repositories { 
        maven { 
         url "someUrl" 
        } 
       } 
      } 

     } 
    } 

    static class TestPubPluginRules extends RuleSource { 

     @Mutate 
     public void createSomeTasks(final ModelMap<Task> tasks) { 
      5.times { suffix -> 
       tasks.create("someTask${suffix}", Zip) { 
        from "src" 
        destinationDir(new File("build")) 
        baseName "someZip${suffix}" 
       } 
      } 
     } 

     @Mutate 
     public void configurePublishingPublications(final PublishingExtension publishing, final ModelMap<Task> tasks) {  

      // Intention is to create a single publication whose artifacts are formed by the `someTaskx` tasks 
      // where x = [0..4] 
      publishing { 
       publications { 
        mavPub(MavenPublication) { 
         tasks.matching {it.name.startsWith('someTask')}.each { task -> 
          artifact(task) 
         } 
        }  
       }   
      } 
     } 
    } 
} 

Плагин создает ряд задач под названием someTaskx где x=[0..4]. Они просто застегивают каталог src. Я хочу добавить выходные файлы как артефакты к одной MavenPublication. Однако я получаю следующее исключение:

* What went wrong: 
A problem occurred configuring root project 'testpub'. 
> A cycle has been detected in model rule dependencies. References forming the cycle: 
    tasks 
    \- TestPubPlugin.TestPubPluginRules#createSomeTasks(ModelMap<Task>) 
    \- MavenPublishPlugin.Rules#realizePublishingTasks(ModelMap<Task>, PublishingExtension, File) 
     \- PublishingPlugin.Rules#tasksDependOnProjectPublicationRegistry(ModelMap<Task>, ProjectPublicationRegistry) 
      \- projectPublicationRegistry 
       \- PublishingPlugin.Rules#addConfiguredPublicationsToProjectPublicationRegistry(ProjectPublicationRegistry, PublishingExtension, ProjectIdentifier) 
       \- publishing 
        \- TestPubPlugin.TestPubPluginRules#configurePublishingPublications(PublishingExtension, ModelMap<Task>) 
         \- tasks 

Что не так и как его исправить?

ответ

0

Я не совсем понимаю, почему это «цикл», но методы правил всегда имеют одну изменчивую часть (субъект) и ноль или более неизменяемый (входы). В вашем втором методе вы передаете publishing в качестве темы, которую хотите изменить, и введите tasks. Я думал, что все будет хорошо, но, очевидно, это не так.

Возможно, вы попытались переключить аргументы метода, сначала перенесите задачи, а затем PublishingExtension, но вы, вероятно, не сможете его изменить (как говорят градиенты, это неизменяемо).

Я не уверен, что именно ваш прецедент, и может быть проще решение, которое не использует правила или плагин вообще. Возможно, вы можете задать другой вопрос с оригинальным требованием вместо этой конкретной проблемы.

Но вернемся к вашей проблеме. Решение вашей проблемы может быть что-то вроде этого:

import org.gradle.api.Plugin 
import org.gradle.api.Project 
import org.gradle.api.Task 
import org.gradle.api.publish.PublishingExtension 
import org.gradle.api.publish.maven.MavenPublication 
import org.gradle.api.tasks.bundling.Zip 
import org.gradle.model.Defaults 
import org.gradle.model.ModelMap 
import org.gradle.model.Mutate 
import org.gradle.model.RuleSource 

class TestPubPlugin implements Plugin<Project> { 
    void apply(Project project) { 
     project.configure(project) { 
      apply plugin: 'maven-publish' 

      publishing { 
       publications { 
        maven(MavenPublication) { 
         groupId 'com.example' 
         artifactId 'artifact' 
        } 
       } 
       repositories { 
        maven { 
         url "someUrl" 
        } 
       } 
      } 

     } 
    } 

    static class TestPubPluginRules extends RuleSource { 
     static final def buffer = [] 

     @Defaults 
     public void createSomeTasks(final ModelMap<Task> tasks) { 
      5.times { suffix -> 
       tasks.create("someTask${suffix}", Zip) { 
        from "src" 
        destinationDir(new File("build")) 
        baseName "someZip${suffix}" 
       } 
      } 
      tasks.each { task -> 
       if (task.name.startsWith('someTask')) 
        buffer << task 
      } 
     } 

     @Mutate 
     public void configurePublishingPublications(PublishingExtension extension) { 
      MavenPublication p = extension.publications[0] 
      buffer.each { task -> 
       p.artifact(task) 
      } 
     } 
    } 
} 

хак здесь, чтобы запустить мутатор задач первого (@Defaults фаза должна выполняться до @Mutate) и сохраните задачи, поэтому мы не делаем нужно попросить их позже. Правила могут включать статические конечные поля, поэтому мы используем список здесь.

Затем мы запускаем усилитель публикации. Код, который вы использовали, не будет работать. Он работает в части конфигурации, но не в классном классе. Поэтому я подготовил публикацию, а затем просто добавил артефакты из буфера.

Я побежал gradlew publish и получил:

Execution failed for task ':publishMavenPublicationToMavenRepository'. 
> Failed to publish publication 'maven' to repository 'maven' 
    > Invalid publication 'maven': artifact file does not exist: 'build\someZip0.zip' 

Так что, похоже, что это работает.

Смежные вопросы