2017-01-28 18 views
1

maven-publishプラグインを使用して公開するRuleSource内からmavenパブリケーションを作成したいとします。パブリケーションのアーティファクトは、ルールから作成された一連の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ディレクトリに存在します。上記のようにそれを適用することができるようにするには、以下のプロパティファイルが必要です。

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

プラグインはx=[0..4]someTaskxと呼ばれるタスクの数を作成します。

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

は非常に単純なプラグインファイルです。 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

これはなぜ「サイクル」なのか完全に理解していませんが、ルールメソッドは常に1つの可変部分(件名)と0個以上の不変(入力)を持っています。 2番目の方法では、変更する件名としてpublishingと入力としてtasksを渡しています。私はそれが大丈夫だろうと思ったが、明らかにそうではない。

メソッドの引数を切り替え、最初にタスクを渡してからPublishingExtensionを渡そうとしたかもしれませんが、それを変更することはできません(gradleのドキュメントは不変であると言います)。

私はあなたのユースケースが正確ではないと、ルールやプラグインをまったく使用しない簡単な解決策があるかもしれません。多分あなたは、この特定の問題ではなく元の要件で別の質問をすることができます。

しかし、問題に戻ってください。あなたの問題を解決するには、次のようなものかもしれません:

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前に実行する必要があります)最初のタスクのミューテータを実行し、タスクを保存することですので、我々はしないでください後でそれらを求める必要があります。ルールには静的な最終フィールドが含まれる可能性があるため、ここでリストを使用します。

次に、発行エンハンサーを実行します。あなたが使用したコードは動作しません。これはconfig部分では動作しますが、groovyクラスでは動作しません。だから私は出版物を準備して、バッファからアーティファクトを追加しました。

私は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' 

は、だから、それが働いているようです。

関連する問題