2014-01-17 2 views
14

Ich habe projektweite Einstellungen in einem Plugin namens parent, das versucht, das maven-publish-Plugin anzuwenden und anschließend die Veröffentlichungs-Erweiterung programmatisch zu konfigurieren. Dies scheint zu funktionieren, aber wenn ich dieses Plugin in einem build.gradle-Skript anwende, kann ich die Veröffentlichungserweiterung nicht konfigurieren, um die projektspezifischen Veröffentlichungen festzulegen.Wie kann man maven-publish publishing programmatisch konfigurieren und build.gradle erlauben, es zu ändern?

erhalte ich die Fehlermeldung:

Cannot configure the 'publishing' extension after it has been accessed. 

Meine Absicht, das Verlags Repository in der übergeordneten Plugin einzurichten war und dann jedes build.gradle Skript lassen Sie die entsprechenden Publikationen hinzuzufügen.

Gibt es eine Möglichkeit, dies zu tun?

Derzeit ParentPlugin.groovy wie folgt aussieht:

def void apply(Project project) { 
    project.getProject().apply plugin: 'maven-publish' 

    def publishingExtension = project.extensions.findByName('publishing') 

    publishingExtension.with { 
     repositories { 
      maven { 
       mavenLocal() 

       credentials { 
        username getPropertyWithDefault(project.getProject(), 'publishUserName', 'dummy') 
        password getPropertyWithDefault(project.getProject(), 'publishPassword', 'dummy') 
       } 

      } 
     } 
    } 
} 

Mein Klient build.gradle schlägt fehl, wenn es die Veröffentlichung Erweiterung zu konfigurieren versucht.

apply plugin: 'parent' 

publishing { 
     publications { 
      mavenJava(MavenPublication) { 
       groupId 'agroup' 
       artifactId 'anartifactid' 
       version '1.0.0-SNAPSHOT' 

       from components.java 
      } 
     } 
} 

Ist das möglich? Gibt es einen anderen Weg, auf den ich näher eingehen sollte?

Antwort

6

Um dies zu tun, schrieb ich ein anderes Plugin, das Änderungen an der Veröffentlichung verzögern kann, während auch ein "Lesen" der Erweiterung zu vermeiden, die es in den "konfigurierten" Zustand versetzen würde. Das Plugin heißt nebula-publishing-plugin, der Code für den "faulen" Block kann in der github repo gefunden werden. Es sieht wie folgt aus:

/** 
* All Maven Publications 
*/ 
def withMavenPublication(Closure withPubClosure) { 
    // New publish plugin way to specify artifacts in resulting publication 
    def addArtifactClosure = { 

     // Wait for our plugin to be applied. 
     project.plugins.withType(PublishingPlugin) { PublishingPlugin publishingPlugin -> 
      DefaultPublishingExtension publishingExtension = project.getExtensions().getByType(DefaultPublishingExtension) 
      publishingExtension.publications.withType(MavenPublication, withPubClosure) 
     } 
    } 

    // It's possible that we're running in someone else's afterEvaluate, which means we need to run this immediately 
    if (project.getState().executed) { 
     addArtifactClosure.call() 
    } else { 
     project.afterEvaluate addArtifactClosure 
    } 
} 

Sie würden dann call it like this:

withMavenPublication { MavenPublication t -> 
     def webComponent = project.components.getByName('web') 
     // TODO Include deps somehow 
     t.from(webComponent) 
    } 

Das Plugin in jcenter verfügbar ist() als 'com.netflix.nebula: Nebel-Publishing-Plugin: 1.9.1' .

+0

vielen Dank das ist hilfreich. Ich hatte gehofft, es einfacher zu machen, für jedes Projekt zu bauen, so dass sie die Standard-Publishing-Erweiterung verwenden können. Gibt es eine Möglichkeit für mein Plugin, seine eigene benutzerdefinierte Publishing-Erweiterung verfügbar zu machen, mit der Projekte Publikationen definieren können? – ditkin

+0

Sie haben mir gerade die Arbeit gerettet, dies selbst herauszufinden - sehr geschätzt! Hoffentlich werden Gradle Devs dies in den nächsten Revisionen behandeln. – Terence

5

Ein bisschen spät, aber ich fand eine Lösung, die kein zusätzliches Plugin benötigt: (Dies wurde von einem meiner internen Plugins übernommen, die mit alten und neuen Publishing, also dem ... withType funktionieren kann . ... Sachen

statt:

project.plugins.withType(MavenPublishPlugin) { 
     project.publishsing { 
      publications { 
       myPub(MavenPublication) { 
        artifact myJar 
       } 
      } 
     } 
    } 

dies tun:

project.plugins.withType(MavenPublishPlugin) { 
     project.extensions.configure PublishingExtension, new ClosureBackedAction({ 
      publications { 
       myPub(MavenPublication) { 
        artifact myJar 
       } 
      } 
     }) 
    } 

Dies wird die Erweiterung nicht sofort lösen, sondern appl y Die Konfiguration zu der Zeit, wenn sie von jemandem zuerst gelöst wird. Natürlich wäre es durchaus sinnvoll, diese Art der Konfiguration in Ihrem projektweiten Plugin zu verwenden, um die Repositories zu konfigurieren und die Publikationserweiterung wie gewohnt in den Build-Skripten zu verwenden. Dies würde Verwirrung für die Autoren von Buildscript vermeiden.

+0

Wenn ich versuche, dies zu tun, bevor die Veröffentlichungserweiterung geladen wird, bekomme ich: > Erweiterung des Typs 'PublishingExtension' existiert nicht. Derzeit registrierte Erweiterungstypen: [DefaultExtraPropertiesExtension]. Wenn ich es danach mache, ist es zurück > Kann nicht die "Publishing" Erweiterung konfigurieren, nachdem es zugegriffen wurde. –

15

Hinweis in Bezug auf Repositorys {} und Publikationen {} für Plugin Maven veröffentlichen:

Thema: Wie diese verwirrenden gradle fatal Fehlermeldung umgehen: Kann die ‚Publishing‘ Erweiterung nicht konfigurieren, nachdem es

zugegriffen wurde

Erste Sache (tiefe Magie): (beachten Sie "Projekt."Präfix ist optional) - Konfigurieren Publikationen und Repositorys nicht wie folgt aus:

project.publishing {publications {...}} 
project.publishing {repositories {...}} 

sondern wie diese empfohlen Stil:

project.publishing.publications {...} 
project.publishing.repositories {...} 

Es wäre lehrreich sein für ein gradle Guru zu erklären, warum Dieser Trick funktioniert

Eine andere bekannte Problemumgehung besteht darin, sicherzustellen, dass jede Anwendung des Plugins maven-publish im selben Projektcodeblock wieistproject.publishing.repositories und project.publishing.publications. Aber das ist komplexer und schwieriger zu tun als die erste Sache zu versuchen, da standardmäßig die CBF maven-publish und eine zweite Anwendung von selbst kann den gleichen Fehler verursachen. maven-publish wird normalerweise in pub/scripts/publish-maven.gradle, angewendet, es sei denn, PUB_PUBLISH_MAVEN ist so eingestellt, dass diese Dateiposition überschrieben wird. In diesem Fall sollte der Aufrufer plugin maven-publish anwenden. Siehe https://orareview.us.oracle.com/29516818 für, wie diese not-prefered Problemumgehung (für Projekt emcamps) während noch die CBF verwendet werden kann.

P.S. Eines Tages werde ich das mit minimalen Codebeispielen aufschreiben. Aber ich stelle dieses hart erkämpfte Wissen jetzt da draußen auf, um andere Leute davor zu bewahren, Tage mit dieser gewöhnlichen Maven-Veröffentlichung zu verschwenden.

+0

Danke, arbeitete für mich. Ich habe "publishing {publications {...}}" durch "publishing.publications {...}" ersetzt und der Fehler ist verschwunden! – jschreiner

+0

Danke für die Lösung! Ich hatte Probleme mit IntelliJ, die mein Mega-Projekt bewerten wollten. Es schien einen Prozess zum Synchronisieren zu geben, der sich von einem typischen Gradle-Build deutlich unterschied. –

+0

Es funktioniert, ich war zuerst glücklich, dann erkannte ich, dass es dunkle Magie ist, bitte verfluche mich nicht –

Verwandte Themen