SoftwareComponentInternal and Usage

classic Classic list List threaded Threaded
21 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

SoftwareComponentInternal and Usage

Xavier Ducrohet
I'm looking at making sure the Android plugin works with the new publishing plugin.

SoftwareComponent doesn't associate any dependencies with the "component".

SoftwareComponentInternal does through the Usage interface but both are internal. Should I just start using those anyway? (I need that to publish Android Libraries).

What's the ETA for the feature to be stable and those API to move out of internal?

thanks.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Xavier Ducrohet
Looking at the code of DefaultMavenPublication I see that SoftwareComponent gets casted always into SoftwareComponentInternal, so I guess I have to use it anyway.

I'm looking at what Usage.getArtifacts() returns and I see that everything extends AbstractPublishArtifact instead of just implementing PublishArtifact.

If I don't extend AbstractPublishArtifact, will things not work?


On Tue, Jul 30, 2013 at 12:58 PM, Xavier Ducrohet <[hidden email]> wrote:
I'm looking at making sure the Android plugin works with the new publishing plugin.

SoftwareComponent doesn't associate any dependencies with the "component".

SoftwareComponentInternal does through the Usage interface but both are internal. Should I just start using those anyway? (I need that to publish Android Libraries).

What's the ETA for the feature to be stable and those API to move out of internal?

thanks.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Daz DeBoer-2

On 30 July 2013 15:12, Xavier Ducrohet <[hidden email]> wrote:
Looking at the code of DefaultMavenPublication I see that SoftwareComponent gets casted always into SoftwareComponentInternal, so I guess I have to use it anyway.

Yep, any public Gradle API that is annotated with @HasInternalProtocol has a matching internal interface that is required for Gradle to use an instance. This pattern is used for types that are designed for use, but have not been designed with user-implementation in mind.

In the Android case, implementing SoftwareComponent/SoftwareComponentInternal is likely the right way to go: the alternative would be to drive the MavenPublication/IvyPublication directly, but this will be a lot less convenient.
 

I'm looking at what Usage.getArtifacts() returns and I see that everything extends AbstractPublishArtifact instead of just implementing PublishArtifact. 

If I don't extend AbstractPublishArtifact, will things not work?

Anything that implements PublishArtifact should work. The relevant code is found in DefaultMavenPublication.from(SoftwareComponent) and MavenArtifactNotationParserFactory.
 


On Tue, Jul 30, 2013 at 12:58 PM, Xavier Ducrohet <[hidden email]> wrote:

What's the ETA for the feature to be stable and those API to move out of internal?

The new publishing DSL hasn't been getting much focus lately, so there's no ETA for this. The mapping of Usage to pom.xml/ivy.xml is very simplistic at this time, and the exact API is likely to change. But I'm pretty sure the fundamental concepts will remain. Adding Android to the mix of SoftwareComponents would be a nice way to drive out any required changes to the API. 
--
Darrell (Daz) DeBoer
Principal Engineer, Gradleware 
http://www.gradleware.com
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Xavier Ducrohet
Thanks Daz, I'll keep playing with it and send feedback/comments here.


On Tue, Jul 30, 2013 at 2:47 PM, Daz DeBoer <[hidden email]> wrote:

On 30 July 2013 15:12, Xavier Ducrohet <[hidden email]> wrote:
Looking at the code of DefaultMavenPublication I see that SoftwareComponent gets casted always into SoftwareComponentInternal, so I guess I have to use it anyway.

Yep, any public Gradle API that is annotated with @HasInternalProtocol has a matching internal interface that is required for Gradle to use an instance. This pattern is used for types that are designed for use, but have not been designed with user-implementation in mind.

In the Android case, implementing SoftwareComponent/SoftwareComponentInternal is likely the right way to go: the alternative would be to drive the MavenPublication/IvyPublication directly, but this will be a lot less convenient.
 

I'm looking at what Usage.getArtifacts() returns and I see that everything extends AbstractPublishArtifact instead of just implementing PublishArtifact. 

If I don't extend AbstractPublishArtifact, will things not work?

Anything that implements PublishArtifact should work. The relevant code is found in DefaultMavenPublication.from(SoftwareComponent) and MavenArtifactNotationParserFactory.
 


On Tue, Jul 30, 2013 at 12:58 PM, Xavier Ducrohet <[hidden email]> wrote:

What's the ETA for the feature to be stable and those API to move out of internal?

The new publishing DSL hasn't been getting much focus lately, so there's no ETA for this. The mapping of Usage to pom.xml/ivy.xml is very simplistic at this time, and the exact API is likely to change. But I'm pretty sure the fundamental concepts will remain. Adding Android to the mix of SoftwareComponents would be a nice way to drive out any required changes to the API. 
--
Darrell (Daz) DeBoer
Principal Engineer, Gradleware 
http://www.gradleware.com

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Adam Murdoch
In reply to this post by Xavier Ducrohet

On 31/07/2013, at 5:58 AM, Xavier Ducrohet <[hidden email]> wrote:

I'm looking at making sure the Android plugin works with the new publishing plugin.

SoftwareComponent doesn't associate any dependencies with the "component".

SoftwareComponentInternal does through the Usage interface but both are internal. Should I just start using those anyway? (I need that to publish Android Libraries).

What's the ETA for the feature to be stable and those API to move out of internal?

Once we can publish multiple variants of an Android library :)

The plan was to make these stable once we've solved a couple of major use cases. The first is to be able to publish and resolve a C++ component with multiple variants. The second is to formalise the lifecycle of a domain object to address things like laziness and mutability and so on, using the publication model to drive this.


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Adam Murdoch
In reply to this post by Daz DeBoer-2

On 31/07/2013, at 7:47 AM, Daz DeBoer <[hidden email]> wrote:


On 30 July 2013 15:12, Xavier Ducrohet <[hidden email]> wrote:
Looking at the code of DefaultMavenPublication I see that SoftwareComponent gets casted always into SoftwareComponentInternal, so I guess I have to use it anyway.

Yep, any public Gradle API that is annotated with @HasInternalProtocol has a matching internal interface that is required for Gradle to use an instance. This pattern is used for types that are designed for use, but have not been designed with user-implementation in mind.

Just to add: sometimes this is because we don't intend that there will be user implementations, such as `Project`, and sometimes this is because we aren't quite ready to open the interface up for user implementation.

For SoftwareComponent, the intention is very much that there will be custom implementations. So, at some point the internal interface will go away or there will be some way to mix the internal stuff in. For example, `Task` has an internal interface but you can easily implement this by extending `DefaultTask`.


In the Android case, implementing SoftwareComponent/SoftwareComponentInternal is likely the right way to go: the alternative would be to drive the MavenPublication/IvyPublication directly, but this will be a lot less convenient.

The plan is that you should describe the things you produce using SoftwareComponent, and that Gradle takes care of the mapping to Ivy or Maven (or whatever other repositories that Gradle ends up supporting).

We'll probably retro-fit support for SoftwareComponent to the old publishing DSL as well, so that you describe the things you produce once via SoftwareComponent and there's a consistent mapping to Ivy or Maven regardless of whether the build is using the new or old publishing DSLs.


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Xavier Ducrohet
Makes sense. Right now I do want to add support for it so I'm going to use the internal stuff. We are aware that this might mean we are only compatible with a given version of Gradle and this is fine pre-1.0

I'm also going to start creating components for each variants, but only add one candidate to the DefaultArtifactPublicationSet so this should work by default like the old publication.

Once this is done I'd like to start talking about adding the hook in the dependency resolution to allow things like picking up a particular classifier (or additional ones to download javadoc/source).


Quick question: what's the name of the Usage instances used for?


On Tue, Jul 30, 2013 at 4:13 PM, Adam Murdoch <[hidden email]> wrote:

On 31/07/2013, at 7:47 AM, Daz DeBoer <[hidden email]> wrote:


On 30 July 2013 15:12, Xavier Ducrohet <[hidden email]> wrote:
Looking at the code of DefaultMavenPublication I see that SoftwareComponent gets casted always into SoftwareComponentInternal, so I guess I have to use it anyway.

Yep, any public Gradle API that is annotated with @HasInternalProtocol has a matching internal interface that is required for Gradle to use an instance. This pattern is used for types that are designed for use, but have not been designed with user-implementation in mind.

Just to add: sometimes this is because we don't intend that there will be user implementations, such as `Project`, and sometimes this is because we aren't quite ready to open the interface up for user implementation.

For SoftwareComponent, the intention is very much that there will be custom implementations. So, at some point the internal interface will go away or there will be some way to mix the internal stuff in. For example, `Task` has an internal interface but you can easily implement this by extending `DefaultTask`.


In the Android case, implementing SoftwareComponent/SoftwareComponentInternal is likely the right way to go: the alternative would be to drive the MavenPublication/IvyPublication directly, but this will be a lot less convenient.

The plan is that you should describe the things you produce using SoftwareComponent, and that Gradle takes care of the mapping to Ivy or Maven (or whatever other repositories that Gradle ends up supporting).

We'll probably retro-fit support for SoftwareComponent to the old publishing DSL as well, so that you describe the things you produce once via SoftwareComponent and there's a consistent mapping to Ivy or Maven regardless of whether the build is using the new or old publishing DSLs.


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Daz DeBoer-2
On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
Makes sense. Right now I do want to add support for it so I'm going to use the internal stuff. We are aware that this might mean we are only compatible with a given version of Gradle and this is fine pre-1.0

I'm also going to start creating components for each variants, but only add one candidate to the DefaultArtifactPublicationSet so this should work by default like the old publication.

Are you planning to publish multiple variants to the same GAV (publication), with variants differentiated by classifier? In that case, I'm not sure why you wouldn't just create a single component, with multiple artifacts. Each PublishArtifact can define a classifier, and all artifacts will be published.

Quick question: what's the name of the Usage instances used for?

For Maven publication, it's not currently used. For ivy, it provides the configuration that contains the published artifacts. The mapping of SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the moment, and we'd be very willing to extend enhance this with more use cases.

Daz
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Xavier Ducrohet

On Tue, Jul 30, 2013 at 4:47 PM, Daz DeBoer <[hidden email]> wrote:
On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
Makes sense. Right now I do want to add support for it so I'm going to use the internal stuff. We are aware that this might mean we are only compatible with a given version of Gradle and this is fine pre-1.0

I'm also going to start creating components for each variants, but only add one candidate to the DefaultArtifactPublicationSet so this should work by default like the old publication.

Are you planning to publish multiple variants to the same GAV (publication), with variants differentiated by classifier? In that case, I'm not sure why you wouldn't just create a single component, with multiple artifacts. Each PublishArtifact can define a classifier, and all artifacts will be published.

My variants can have different dependencies for libraries.

I guess when uploading application packages, I could have a single component. However I'm also thinking about letting developers upload side files besides their app (for instance ProGuard mapping file). I guess that I could use the same classifier as the matching app with a different type/extension?



Quick question: what's the name of the Usage instances used for?

For Maven publication, it's not currently used. For ivy, it provides the configuration that contains the published artifacts. The mapping of SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the moment, and we'd be very willing to extend enhance this with more use cases.


Are you talking about  org.gradle.api.artifacts.Configuration here? I noticed that in JavaLibrary, the returned Usage object is called "runtime".

How is all of this related to inter-project dependencies by the way? Right now we use project.artifacts.add("default", someAbstractArchiveTask) for both the old publication stuff and this seems to work.
When looking at the JavaPlugin I saw those two lines:

        project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(jarArtifact);
        project.getComponents().add(new JavaLibrary(jarArtifact, runtimeConfiguration.getAllDependencies()));

The 2nd one makes sense to me when I see the 'from components.java' section of a publication sample. I've been wondering if the 2nd one was for inter-project dependencies, but it takes an artifact instead of a Usage object, so there's not associated dependencies?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Xavier Ducrohet
Once I create new SoftwareComponents and Usage object, is there anything in Gradle to display the list, their properties,etc... to make sure it's all properly configured?


On Tue, Jul 30, 2013 at 5:01 PM, Xavier Ducrohet <[hidden email]> wrote:

On Tue, Jul 30, 2013 at 4:47 PM, Daz DeBoer <[hidden email]> wrote:
On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
Makes sense. Right now I do want to add support for it so I'm going to use the internal stuff. We are aware that this might mean we are only compatible with a given version of Gradle and this is fine pre-1.0

I'm also going to start creating components for each variants, but only add one candidate to the DefaultArtifactPublicationSet so this should work by default like the old publication.

Are you planning to publish multiple variants to the same GAV (publication), with variants differentiated by classifier? In that case, I'm not sure why you wouldn't just create a single component, with multiple artifacts. Each PublishArtifact can define a classifier, and all artifacts will be published.

My variants can have different dependencies for libraries.

I guess when uploading application packages, I could have a single component. However I'm also thinking about letting developers upload side files besides their app (for instance ProGuard mapping file). I guess that I could use the same classifier as the matching app with a different type/extension?



Quick question: what's the name of the Usage instances used for?

For Maven publication, it's not currently used. For ivy, it provides the configuration that contains the published artifacts. The mapping of SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the moment, and we'd be very willing to extend enhance this with more use cases.


Are you talking about  org.gradle.api.artifacts.Configuration here? I noticed that in JavaLibrary, the returned Usage object is called "runtime".

How is all of this related to inter-project dependencies by the way? Right now we use project.artifacts.add("default", someAbstractArchiveTask) for both the old publication stuff and this seems to work.
When looking at the JavaPlugin I saw those two lines:

        project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(jarArtifact);
        project.getComponents().add(new JavaLibrary(jarArtifact, runtimeConfiguration.getAllDependencies()));

The 2nd one makes sense to me when I see the 'from components.java' section of a publication sample. I've been wondering if the 2nd one was for inter-project dependencies, but it takes an artifact instead of a Usage object, so there's not associated dependencies?

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Daz DeBoer-2
On 31 July 2013 10:57, Xavier Ducrohet <[hidden email]> wrote:
Once I create new SoftwareComponents and Usage object, is there anything in Gradle to display the list, their properties,etc... to make sure it's all properly configured?

You can access all added components via the project.components container. So you should be able to do:

components.android.usages.each {
    println it.name
    println it.artifacts
    println it.dependencies
}


On Tue, Jul 30, 2013 at 5:01 PM, Xavier Ducrohet <[hidden email]> wrote:

On Tue, Jul 30, 2013 at 4:47 PM, Daz DeBoer <[hidden email]> wrote:
On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
Makes sense. Right now I do want to add support for it so I'm going to use the internal stuff. We are aware that this might mean we are only compatible with a given version of Gradle and this is fine pre-1.0

I'm also going to start creating components for each variants, but only add one candidate to the DefaultArtifactPublicationSet so this should work by default like the old publication.

Are you planning to publish multiple variants to the same GAV (publication), with variants differentiated by classifier? In that case, I'm not sure why you wouldn't just create a single component, with multiple artifacts. Each PublishArtifact can define a classifier, and all artifacts will be published.

My variants can have different dependencies for libraries.

I guess when uploading application packages, I could have a single component. However I'm also thinking about letting developers upload side files besides their app (for instance ProGuard mapping file). I guess that I could use the same classifier as the matching app with a different type/extension?



Quick question: what's the name of the Usage instances used for?

For Maven publication, it's not currently used. For ivy, it provides the configuration that contains the published artifacts. The mapping of SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the moment, and we'd be very willing to extend enhance this with more use cases.


Are you talking about  org.gradle.api.artifacts.Configuration here? I noticed that in JavaLibrary, the returned Usage object is called "runtime".

How is all of this related to inter-project dependencies by the way? Right now we use project.artifacts.add("default", someAbstractArchiveTask) for both the old publication stuff and this seems to work.
When looking at the JavaPlugin I saw those two lines:

        project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(jarArtifact);
        project.getComponents().add(new JavaLibrary(jarArtifact, runtimeConfiguration.getAllDependencies()));

The 2nd one makes sense to me when I see the 'from components.java' section of a publication sample. I've been wondering if the 2nd one was for inter-project dependencies, but it takes an artifact instead of a Usage object, so there's not associated dependencies?




--
Darrell (Daz) DeBoer
Principal Engineer, Gradleware 
http://www.gradleware.com
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Luke Daley-2
In reply to this post by Xavier Ducrohet

On 31/07/2013, at 1:01 AM, Xavier Ducrohet <[hidden email]> wrote:

> On Tue, Jul 30, 2013 at 4:47 PM, Daz DeBoer
> <[hidden email]>wrote:
>
>> On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
>>
>>> Makes sense. Right now I do want to add support for it so I'm going to
>>> use the internal stuff. We are aware that this might mean we are only
>>> compatible with a given version of Gradle and this is fine pre-1.0
>>>
>>> I'm also going to start creating components for each variants, but only
>>> add one candidate to the DefaultArtifactPublicationSet so this should work
>>> by default like the old publication.
>>>
>>
>> Are you planning to publish multiple variants to the same GAV
>> (publication), with variants differentiated by classifier? In that case,
>> I'm not sure why you wouldn't just create a single component, with multiple
>> artifacts. Each PublishArtifact can define a classifier, and all artifacts
>> will be published.
>>
>
> My variants can have different dependencies for libraries.

Which rules out the classifier approach.

> I guess when uploading application packages, I could have a single
> component. However I'm also thinking about letting developers upload side
> files besides their app (for instance ProGuard mapping file). I guess that
> I could use the same classifier as the matching app with a different
> type/extension?

This is unlikely to work. There are no clear rules on what should happen here.

My experience is that type/extension do not contribute to an artifact's identity. That is, you can't have an artifact with the same (name,group,version,classifier) but different type/extension. I've not tried this with Gradle, but have with other Maven Repository tooling and it's not worked.

>
>
>
>>> Quick question: what's the name of the Usage instances used for?
>>>
>>
>> For Maven publication, it's not currently used. For ivy, it provides the
>> configuration that contains the published artifacts. The mapping of
>> SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the
>> moment, and we'd be very willing to extend enhance this with more use cases.
>>
>>
> Are you talking about  org.gradle.api.artifacts.Configuration here? I
> noticed that in JavaLibrary, the returned Usage object is called "runtime".
>
> How is all of this related to inter-project dependencies by the way? Right
> now we use project.artifacts.add("default", someAbstractArchiveTask) for
> both the old publication stuff and this seems to work.
> When looking at the JavaPlugin I saw those two lines:
>
>
> project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(jarArtifact);
>        project.getComponents().add(new JavaLibrary(jarArtifact,
> runtimeConfiguration.getAllDependencies()));
>
> The 2nd one makes sense to me when I see the 'from components.java' section
> of a publication sample. I've been wondering if the 2nd one was for
> inter-project dependencies, but it takes an artifact instead of a Usage
> object, so there's not associated dependencies?

--
Luke Daley
Principal Engineer, Gradleware
http://gradleware.com


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Xavier Ducrohet

On Wed, Jul 31, 2013 at 11:02 AM, Luke Daley <[hidden email]> wrote:

On 31/07/2013, at 1:01 AM, Xavier Ducrohet <[hidden email]> wrote:

> On Tue, Jul 30, 2013 at 4:47 PM, Daz DeBoer
> <[hidden email]>wrote:
>
>> On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
>>
>>> Makes sense. Right now I do want to add support for it so I'm going to
>>> use the internal stuff. We are aware that this might mean we are only
>>> compatible with a given version of Gradle and this is fine pre-1.0
>>>
>>> I'm also going to start creating components for each variants, but only
>>> add one candidate to the DefaultArtifactPublicationSet so this should work
>>> by default like the old publication.
>>>
>>
>> Are you planning to publish multiple variants to the same GAV
>> (publication), with variants differentiated by classifier? In that case,
>> I'm not sure why you wouldn't just create a single component, with multiple
>> artifacts. Each PublishArtifact can define a classifier, and all artifacts
>> will be published.
>>
>
> My variants can have different dependencies for libraries.

Which rules out the classifier approach.


Hmm. I know it's a limitation of Maven, but what about Gradle's internal representation of dependencies? (this loops back on my question about how project to project publication/dependencies are handled).

In my case, I'd like to have a library have variants when it's used in a multi-project setup (so that it can have the same variants as the consumer project), but when published for external usage on a repository, then variant will probably not be allowed, or they'll have to be different artifacts.

For inter-project publication/consumption, what'd like is to be to able to have the consumer queries the different publication of the library project to choose the right one. Whether this is done by classifiers or not doesn't really matter in the end I guess.
 
> I guess when uploading application packages, I could have a single
> component. However I'm also thinking about letting developers upload side
> files besides their app (for instance ProGuard mapping file). I guess that
> I could use the same classifier as the matching app with a different
> type/extension?

This is unlikely to work. There are no clear rules on what should happen here.

My experience is that type/extension do not contribute to an artifact's identity. That is, you can't have an artifact with the same (name,group,version,classifier) but different type/extension. I've not tried this with Gradle, but have with other Maven Repository tooling and it's not worked.


Good to know. Thanks. I think I'll have to have a DSL to allow devs to choose how each variant gets published (as far as groupId, artifactId). Then I can use the classifiers for extra components (proguard mapping for instance).
>
>
>
>>> Quick question: what's the name of the Usage instances used for?
>>>
>>
>> For Maven publication, it's not currently used. For ivy, it provides the
>> configuration that contains the published artifacts. The mapping of
>> SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the
>> moment, and we'd be very willing to extend enhance this with more use cases.
>>
>>
> Are you talking about  org.gradle.api.artifacts.Configuration here? I
> noticed that in JavaLibrary, the returned Usage object is called "runtime".
>
> How is all of this related to inter-project dependencies by the way? Right
> now we use project.artifacts.add("default", someAbstractArchiveTask) for
> both the old publication stuff and this seems to work.
> When looking at the JavaPlugin I saw those two lines:
>
>
> project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(jarArtifact);
>        project.getComponents().add(new JavaLibrary(jarArtifact,
> runtimeConfiguration.getAllDependencies()));
>
> The 2nd one makes sense to me when I see the 'from components.java' section
> of a publication sample. I've been wondering if the 2nd one was for
> inter-project dependencies, but it takes an artifact instead of a Usage
> object, so there's not associated dependencies?

--
Luke Daley
Principal Engineer, Gradleware
http://gradleware.com


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Xavier Ducrohet
So I'm making progress but running into a evaluation issue.

Since the android plugin needs to evaluate the whole project before creating the variants and tasks, we create the tasks in afterEvaluate {}

This means that putting this in build.gradle

publishing {
    publications {
        test(MavenPublication) {
            from components.android
        }
    }
}

fails since the component doesn't exist yet. Not putting the component line only publishes a pom but not the artifact even though I have this line in the plugin:

            project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(theComponent);

Configuring the publishing extension in afterEvaluate fails with:

A problem occurred configuring root project 'baseLibrary'.
> Failed to notify project evaluation listener.
   > Cannot configure the 'publishing' extension after it has been accessed.

At this point I'm not sure how to proceed.




On Wed, Jul 31, 2013 at 11:54 AM, Xavier Ducrohet <[hidden email]> wrote:

On Wed, Jul 31, 2013 at 11:02 AM, Luke Daley <[hidden email]> wrote:

On 31/07/2013, at 1:01 AM, Xavier Ducrohet <[hidden email]> wrote:

> On Tue, Jul 30, 2013 at 4:47 PM, Daz DeBoer
> <[hidden email]>wrote:
>
>> On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
>>
>>> Makes sense. Right now I do want to add support for it so I'm going to
>>> use the internal stuff. We are aware that this might mean we are only
>>> compatible with a given version of Gradle and this is fine pre-1.0
>>>
>>> I'm also going to start creating components for each variants, but only
>>> add one candidate to the DefaultArtifactPublicationSet so this should work
>>> by default like the old publication.
>>>
>>
>> Are you planning to publish multiple variants to the same GAV
>> (publication), with variants differentiated by classifier? In that case,
>> I'm not sure why you wouldn't just create a single component, with multiple
>> artifacts. Each PublishArtifact can define a classifier, and all artifacts
>> will be published.
>>
>
> My variants can have different dependencies for libraries.

Which rules out the classifier approach.


Hmm. I know it's a limitation of Maven, but what about Gradle's internal representation of dependencies? (this loops back on my question about how project to project publication/dependencies are handled).

In my case, I'd like to have a library have variants when it's used in a multi-project setup (so that it can have the same variants as the consumer project), but when published for external usage on a repository, then variant will probably not be allowed, or they'll have to be different artifacts.

For inter-project publication/consumption, what'd like is to be to able to have the consumer queries the different publication of the library project to choose the right one. Whether this is done by classifiers or not doesn't really matter in the end I guess.
 
> I guess when uploading application packages, I could have a single
> component. However I'm also thinking about letting developers upload side
> files besides their app (for instance ProGuard mapping file). I guess that
> I could use the same classifier as the matching app with a different
> type/extension?

This is unlikely to work. There are no clear rules on what should happen here.

My experience is that type/extension do not contribute to an artifact's identity. That is, you can't have an artifact with the same (name,group,version,classifier) but different type/extension. I've not tried this with Gradle, but have with other Maven Repository tooling and it's not worked.


Good to know. Thanks. I think I'll have to have a DSL to allow devs to choose how each variant gets published (as far as groupId, artifactId). Then I can use the classifiers for extra components (proguard mapping for instance).
>
>
>
>>> Quick question: what's the name of the Usage instances used for?
>>>
>>
>> For Maven publication, it's not currently used. For ivy, it provides the
>> configuration that contains the published artifacts. The mapping of
>> SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the
>> moment, and we'd be very willing to extend enhance this with more use cases.
>>
>>
> Are you talking about  org.gradle.api.artifacts.Configuration here? I
> noticed that in JavaLibrary, the returned Usage object is called "runtime".
>
> How is all of this related to inter-project dependencies by the way? Right
> now we use project.artifacts.add("default", someAbstractArchiveTask) for
> both the old publication stuff and this seems to work.
> When looking at the JavaPlugin I saw those two lines:
>
>
> project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(jarArtifact);
>        project.getComponents().add(new JavaLibrary(jarArtifact,
> runtimeConfiguration.getAllDependencies()));
>
> The 2nd one makes sense to me when I see the 'from components.java' section
> of a publication sample. I've been wondering if the 2nd one was for
> inter-project dependencies, but it takes an artifact instead of a Usage
> object, so there's not associated dependencies?

--
Luke Daley
Principal Engineer, Gradleware
http://gradleware.com


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Adam Murdoch
In reply to this post by Xavier Ducrohet

On 31/07/2013, at 10:01 AM, Xavier Ducrohet <[hidden email]> wrote:


On Tue, Jul 30, 2013 at 4:47 PM, Daz DeBoer <[hidden email]> wrote:
On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
Makes sense. Right now I do want to add support for it so I'm going to use the internal stuff. We are aware that this might mean we are only compatible with a given version of Gradle and this is fine pre-1.0

I'm also going to start creating components for each variants, but only add one candidate to the DefaultArtifactPublicationSet so this should work by default like the old publication.

Are you planning to publish multiple variants to the same GAV (publication), with variants differentiated by classifier? In that case, I'm not sure why you wouldn't just create a single component, with multiple artifacts. Each PublishArtifact can define a classifier, and all artifacts will be published.

My variants can have different dependencies for libraries.

I guess when uploading application packages, I could have a single component. However I'm also thinking about letting developers upload side files besides their app (for instance ProGuard mapping file). I guess that I could use the same classifier as the matching app with a different type/extension?



Quick question: what's the name of the Usage instances used for?

For Maven publication, it's not currently used. For ivy, it provides the configuration that contains the published artifacts. The mapping of SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the moment, and we'd be very willing to extend enhance this with more use cases.


Are you talking about  org.gradle.api.artifacts.Configuration here? I noticed that in JavaLibrary, the returned Usage object is called "runtime".

How is all of this related to inter-project dependencies by the way? Right now we use project.artifacts.add("default", someAbstractArchiveTask) for both the old publication stuff and this seems to work.
When looking at the JavaPlugin I saw those two lines:

        project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(jarArtifact);
        project.getComponents().add(new JavaLibrary(jarArtifact, runtimeConfiguration.getAllDependencies()));

The 2nd one makes sense to me when I see the 'from components.java' section of a publication sample. I've been wondering if the 2nd one was for inter-project dependencies, but it takes an artifact instead of a Usage object, so there's not associated dependencies?

Currently, project dependencies use the same stuff as the old publication DSL, which means they use the dependencies declared in the configurations and the artefacts attached to them.

The plan is to shift project dependencies to use the components of the target project instead. Making this work in a backwards-compatible way will be a little tricky, but I think we can solve that.

The result will be that you describe whatever it is you produce as a component, then this can be used to publish via the old and new DSL, and between projects via project dependencies, and within the same project, too, so that a component produced by a project can be used as an input for something else in the same project (for example, having the test app use the library as input).


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Adam Murdoch
In reply to this post by Xavier Ducrohet

On 01/08/2013, at 10:19 AM, Xavier Ducrohet <[hidden email]> wrote:

So I'm making progress but running into a evaluation issue.

Since the android plugin needs to evaluate the whole project before creating the variants and tasks, we create the tasks in afterEvaluate {}

This means that putting this in build.gradle

publishing {
    publications {
        test(MavenPublication) {
            from components.android
        }
    }
}

fails since the component doesn't exist yet. Not putting the component line only publishes a pom but not the artifact even though I have this line in the plugin:

            project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(theComponent);

Configuring the publishing extension in afterEvaluate fails with:

A problem occurred configuring root project 'baseLibrary'.
> Failed to notify project evaluation listener.
   > Cannot configure the 'publishing' extension after it has been accessed.

At this point I'm not sure how to proceed.

From my point of view, it would be best if you could wait until we've have a chance to get the publishing stuff a little closer to how we want it to be. It's just a bit too early to be trying to extend it. We can do this fairly soon, if you can hold off for a while. I think it will just be a less frustrating exercise for you.






On Wed, Jul 31, 2013 at 11:54 AM, Xavier Ducrohet <[hidden email]> wrote:

On Wed, Jul 31, 2013 at 11:02 AM, Luke Daley <[hidden email]> wrote:

On 31/07/2013, at 1:01 AM, Xavier Ducrohet <[hidden email]> wrote:

> On Tue, Jul 30, 2013 at 4:47 PM, Daz DeBoer
> <[hidden email]>wrote:
>
>> On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
>>
>>> Makes sense. Right now I do want to add support for it so I'm going to
>>> use the internal stuff. We are aware that this might mean we are only
>>> compatible with a given version of Gradle and this is fine pre-1.0
>>>
>>> I'm also going to start creating components for each variants, but only
>>> add one candidate to the DefaultArtifactPublicationSet so this should work
>>> by default like the old publication.
>>>
>>
>> Are you planning to publish multiple variants to the same GAV
>> (publication), with variants differentiated by classifier? In that case,
>> I'm not sure why you wouldn't just create a single component, with multiple
>> artifacts. Each PublishArtifact can define a classifier, and all artifacts
>> will be published.
>>
>
> My variants can have different dependencies for libraries.

Which rules out the classifier approach.


Hmm. I know it's a limitation of Maven, but what about Gradle's internal representation of dependencies? (this loops back on my question about how project to project publication/dependencies are handled).

In my case, I'd like to have a library have variants when it's used in a multi-project setup (so that it can have the same variants as the consumer project), but when published for external usage on a repository, then variant will probably not be allowed, or they'll have to be different artifacts.

For inter-project publication/consumption, what'd like is to be to able to have the consumer queries the different publication of the library project to choose the right one. Whether this is done by classifiers or not doesn't really matter in the end I guess.
 
> I guess when uploading application packages, I could have a single
> component. However I'm also thinking about letting developers upload side
> files besides their app (for instance ProGuard mapping file). I guess that
> I could use the same classifier as the matching app with a different
> type/extension?

This is unlikely to work. There are no clear rules on what should happen here.

My experience is that type/extension do not contribute to an artifact's identity. That is, you can't have an artifact with the same (name,group,version,classifier) but different type/extension. I've not tried this with Gradle, but have with other Maven Repository tooling and it's not worked.


Good to know. Thanks. I think I'll have to have a DSL to allow devs to choose how each variant gets published (as far as groupId, artifactId). Then I can use the classifiers for extra components (proguard mapping for instance).
>
>
>
>>> Quick question: what's the name of the Usage instances used for?
>>>
>>
>> For Maven publication, it's not currently used. For ivy, it provides the
>> configuration that contains the published artifacts. The mapping of
>> SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the
>> moment, and we'd be very willing to extend enhance this with more use cases.
>>
>>
> Are you talking about  org.gradle.api.artifacts.Configuration here? I
> noticed that in JavaLibrary, the returned Usage object is called "runtime".
>
> How is all of this related to inter-project dependencies by the way? Right
> now we use project.artifacts.add("default", someAbstractArchiveTask) for
> both the old publication stuff and this seems to work.
> When looking at the JavaPlugin I saw those two lines:
>
>
> project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(jarArtifact);
>        project.getComponents().add(new JavaLibrary(jarArtifact,
> runtimeConfiguration.getAllDependencies()));
>
> The 2nd one makes sense to me when I see the 'from components.java' section
> of a publication sample. I've been wondering if the 2nd one was for
> inter-project dependencies, but it takes an artifact instead of a Usage
> object, so there's not associated dependencies?

--
Luke Daley
Principal Engineer, Gradleware
http://gradleware.com


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email






--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Adam Murdoch
In reply to this post by Xavier Ducrohet

On 01/08/2013, at 10:19 AM, Xavier Ducrohet <[hidden email]> wrote:

So I'm making progress but running into a evaluation issue.

Since the android plugin needs to evaluate the whole project before creating the variants and tasks, we create the tasks in afterEvaluate {}

This means that putting this in build.gradle

publishing {
    publications {
        test(MavenPublication) {
            from components.android
        }
    }
}

fails since the component doesn't exist yet. Not putting the component line only publishes a pom but not the artifact even though I have this line in the plugin:

            project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(theComponent);

Configuring the publishing extension in afterEvaluate fails with:

A problem occurred configuring root project 'baseLibrary'.
> Failed to notify project evaluation listener.
   > Cannot configure the 'publishing' extension after it has been accessed.

At this point I'm not sure how to proceed.

As far as the solution to the above goes, the plan is to give you a replacement for afterEvaluate { } so that Gradle can make sure that your plugin has done its work before `components.android` is used, but after your extension has been configured.

This means that Gradle would sequence things so that:

1. The build script is executed.
2. The Android plugin defines the `android` extension
3. The `android` extension is configured.
4. The Android plugin uses the `android` extension to define tasks and components.
5. The `publishing` extension is configured. It's not until this point that the `from components.android` statement is executed, and the `android` component is fully populated by this point.

At some point later, we'd bust up #4 into smaller pieces, so that the tasks are defined only when required, and so on.






On Wed, Jul 31, 2013 at 11:54 AM, Xavier Ducrohet <[hidden email]> wrote:

On Wed, Jul 31, 2013 at 11:02 AM, Luke Daley <[hidden email]> wrote:

On 31/07/2013, at 1:01 AM, Xavier Ducrohet <[hidden email]> wrote:

> On Tue, Jul 30, 2013 at 4:47 PM, Daz DeBoer
> <[hidden email]>wrote:
>
>> On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
>>
>>> Makes sense. Right now I do want to add support for it so I'm going to
>>> use the internal stuff. We are aware that this might mean we are only
>>> compatible with a given version of Gradle and this is fine pre-1.0
>>>
>>> I'm also going to start creating components for each variants, but only
>>> add one candidate to the DefaultArtifactPublicationSet so this should work
>>> by default like the old publication.
>>>
>>
>> Are you planning to publish multiple variants to the same GAV
>> (publication), with variants differentiated by classifier? In that case,
>> I'm not sure why you wouldn't just create a single component, with multiple
>> artifacts. Each PublishArtifact can define a classifier, and all artifacts
>> will be published.
>>
>
> My variants can have different dependencies for libraries.

Which rules out the classifier approach.


Hmm. I know it's a limitation of Maven, but what about Gradle's internal representation of dependencies? (this loops back on my question about how project to project publication/dependencies are handled).

In my case, I'd like to have a library have variants when it's used in a multi-project setup (so that it can have the same variants as the consumer project), but when published for external usage on a repository, then variant will probably not be allowed, or they'll have to be different artifacts.

For inter-project publication/consumption, what'd like is to be to able to have the consumer queries the different publication of the library project to choose the right one. Whether this is done by classifiers or not doesn't really matter in the end I guess.
 
> I guess when uploading application packages, I could have a single
> component. However I'm also thinking about letting developers upload side
> files besides their app (for instance ProGuard mapping file). I guess that
> I could use the same classifier as the matching app with a different
> type/extension?

This is unlikely to work. There are no clear rules on what should happen here.

My experience is that type/extension do not contribute to an artifact's identity. That is, you can't have an artifact with the same (name,group,version,classifier) but different type/extension. I've not tried this with Gradle, but have with other Maven Repository tooling and it's not worked.


Good to know. Thanks. I think I'll have to have a DSL to allow devs to choose how each variant gets published (as far as groupId, artifactId). Then I can use the classifiers for extra components (proguard mapping for instance).
>
>
>
>>> Quick question: what's the name of the Usage instances used for?
>>>
>>
>> For Maven publication, it's not currently used. For ivy, it provides the
>> configuration that contains the published artifacts. The mapping of
>> SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the
>> moment, and we'd be very willing to extend enhance this with more use cases.
>>
>>
> Are you talking about  org.gradle.api.artifacts.Configuration here? I
> noticed that in JavaLibrary, the returned Usage object is called "runtime".
>
> How is all of this related to inter-project dependencies by the way? Right
> now we use project.artifacts.add("default", someAbstractArchiveTask) for
> both the old publication stuff and this seems to work.
> When looking at the JavaPlugin I saw those two lines:
>
>
> project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(jarArtifact);
>        project.getComponents().add(new JavaLibrary(jarArtifact,
> runtimeConfiguration.getAllDependencies()));
>
> The 2nd one makes sense to me when I see the 'from components.java' section
> of a publication sample. I've been wondering if the 2nd one was for
> inter-project dependencies, but it takes an artifact instead of a Usage
> object, so there's not associated dependencies?

--
Luke Daley
Principal Engineer, Gradleware
http://gradleware.com


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email






--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Xavier Ducrohet
In reply to this post by Adam Murdoch
OK I can hold off.

I was mostly trying to make our plugin work with the new publishing stuff as some external devs asked for it.


On Wed, Jul 31, 2013 at 6:04 PM, Adam Murdoch <[hidden email]> wrote:

On 01/08/2013, at 10:19 AM, Xavier Ducrohet <[hidden email]> wrote:

So I'm making progress but running into a evaluation issue.

Since the android plugin needs to evaluate the whole project before creating the variants and tasks, we create the tasks in afterEvaluate {}

This means that putting this in build.gradle

publishing {
    publications {
        test(MavenPublication) {
            from components.android
        }
    }
}

fails since the component doesn't exist yet. Not putting the component line only publishes a pom but not the artifact even though I have this line in the plugin:

            project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(theComponent);

Configuring the publishing extension in afterEvaluate fails with:

A problem occurred configuring root project 'baseLibrary'.
> Failed to notify project evaluation listener.
   > Cannot configure the 'publishing' extension after it has been accessed.

At this point I'm not sure how to proceed.

From my point of view, it would be best if you could wait until we've have a chance to get the publishing stuff a little closer to how we want it to be. It's just a bit too early to be trying to extend it. We can do this fairly soon, if you can hold off for a while. I think it will just be a less frustrating exercise for you.






On Wed, Jul 31, 2013 at 11:54 AM, Xavier Ducrohet <[hidden email]> wrote:

On Wed, Jul 31, 2013 at 11:02 AM, Luke Daley <[hidden email]> wrote:

On 31/07/2013, at 1:01 AM, Xavier Ducrohet <[hidden email]> wrote:

> On Tue, Jul 30, 2013 at 4:47 PM, Daz DeBoer
> <[hidden email]>wrote:
>
>> On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
>>
>>> Makes sense. Right now I do want to add support for it so I'm going to
>>> use the internal stuff. We are aware that this might mean we are only
>>> compatible with a given version of Gradle and this is fine pre-1.0
>>>
>>> I'm also going to start creating components for each variants, but only
>>> add one candidate to the DefaultArtifactPublicationSet so this should work
>>> by default like the old publication.
>>>
>>
>> Are you planning to publish multiple variants to the same GAV
>> (publication), with variants differentiated by classifier? In that case,
>> I'm not sure why you wouldn't just create a single component, with multiple
>> artifacts. Each PublishArtifact can define a classifier, and all artifacts
>> will be published.
>>
>
> My variants can have different dependencies for libraries.

Which rules out the classifier approach.


Hmm. I know it's a limitation of Maven, but what about Gradle's internal representation of dependencies? (this loops back on my question about how project to project publication/dependencies are handled).

In my case, I'd like to have a library have variants when it's used in a multi-project setup (so that it can have the same variants as the consumer project), but when published for external usage on a repository, then variant will probably not be allowed, or they'll have to be different artifacts.

For inter-project publication/consumption, what'd like is to be to able to have the consumer queries the different publication of the library project to choose the right one. Whether this is done by classifiers or not doesn't really matter in the end I guess.
 
> I guess when uploading application packages, I could have a single
> component. However I'm also thinking about letting developers upload side
> files besides their app (for instance ProGuard mapping file). I guess that
> I could use the same classifier as the matching app with a different
> type/extension?

This is unlikely to work. There are no clear rules on what should happen here.

My experience is that type/extension do not contribute to an artifact's identity. That is, you can't have an artifact with the same (name,group,version,classifier) but different type/extension. I've not tried this with Gradle, but have with other Maven Repository tooling and it's not worked.


Good to know. Thanks. I think I'll have to have a DSL to allow devs to choose how each variant gets published (as far as groupId, artifactId). Then I can use the classifiers for extra components (proguard mapping for instance).
>
>
>
>>> Quick question: what's the name of the Usage instances used for?
>>>
>>
>> For Maven publication, it's not currently used. For ivy, it provides the
>> configuration that contains the published artifacts. The mapping of
>> SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the
>> moment, and we'd be very willing to extend enhance this with more use cases.
>>
>>
> Are you talking about  org.gradle.api.artifacts.Configuration here? I
> noticed that in JavaLibrary, the returned Usage object is called "runtime".
>
> How is all of this related to inter-project dependencies by the way? Right
> now we use project.artifacts.add("default", someAbstractArchiveTask) for
> both the old publication stuff and this seems to work.
> When looking at the JavaPlugin I saw those two lines:
>
>
> project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(jarArtifact);
>        project.getComponents().add(new JavaLibrary(jarArtifact,
> runtimeConfiguration.getAllDependencies()));
>
> The 2nd one makes sense to me when I see the 'from components.java' section
> of a publication sample. I've been wondering if the 2nd one was for
> inter-project dependencies, but it takes an artifact instead of a Usage
> object, so there's not associated dependencies?

--
Luke Daley
Principal Engineer, Gradleware
http://gradleware.com


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email






--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Xavier Ducrohet
In reply to this post by Adam Murdoch
Sounds good, thanks!


On Wed, Jul 31, 2013 at 6:12 PM, Adam Murdoch <[hidden email]> wrote:

On 01/08/2013, at 10:19 AM, Xavier Ducrohet <[hidden email]> wrote:

So I'm making progress but running into a evaluation issue.

Since the android plugin needs to evaluate the whole project before creating the variants and tasks, we create the tasks in afterEvaluate {}

This means that putting this in build.gradle

publishing {
    publications {
        test(MavenPublication) {
            from components.android
        }
    }
}

fails since the component doesn't exist yet. Not putting the component line only publishes a pom but not the artifact even though I have this line in the plugin:

            project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(theComponent);

Configuring the publishing extension in afterEvaluate fails with:

A problem occurred configuring root project 'baseLibrary'.
> Failed to notify project evaluation listener.
   > Cannot configure the 'publishing' extension after it has been accessed.

At this point I'm not sure how to proceed.

As far as the solution to the above goes, the plan is to give you a replacement for afterEvaluate { } so that Gradle can make sure that your plugin has done its work before `components.android` is used, but after your extension has been configured.

This means that Gradle would sequence things so that:

1. The build script is executed.
2. The Android plugin defines the `android` extension
3. The `android` extension is configured.
4. The Android plugin uses the `android` extension to define tasks and components.
5. The `publishing` extension is configured. It's not until this point that the `from components.android` statement is executed, and the `android` component is fully populated by this point.

At some point later, we'd bust up #4 into smaller pieces, so that the tasks are defined only when required, and so on.






On Wed, Jul 31, 2013 at 11:54 AM, Xavier Ducrohet <[hidden email]> wrote:

On Wed, Jul 31, 2013 at 11:02 AM, Luke Daley <[hidden email]> wrote:

On 31/07/2013, at 1:01 AM, Xavier Ducrohet <[hidden email]> wrote:

> On Tue, Jul 30, 2013 at 4:47 PM, Daz DeBoer
> <[hidden email]>wrote:
>
>> On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
>>
>>> Makes sense. Right now I do want to add support for it so I'm going to
>>> use the internal stuff. We are aware that this might mean we are only
>>> compatible with a given version of Gradle and this is fine pre-1.0
>>>
>>> I'm also going to start creating components for each variants, but only
>>> add one candidate to the DefaultArtifactPublicationSet so this should work
>>> by default like the old publication.
>>>
>>
>> Are you planning to publish multiple variants to the same GAV
>> (publication), with variants differentiated by classifier? In that case,
>> I'm not sure why you wouldn't just create a single component, with multiple
>> artifacts. Each PublishArtifact can define a classifier, and all artifacts
>> will be published.
>>
>
> My variants can have different dependencies for libraries.

Which rules out the classifier approach.


Hmm. I know it's a limitation of Maven, but what about Gradle's internal representation of dependencies? (this loops back on my question about how project to project publication/dependencies are handled).

In my case, I'd like to have a library have variants when it's used in a multi-project setup (so that it can have the same variants as the consumer project), but when published for external usage on a repository, then variant will probably not be allowed, or they'll have to be different artifacts.

For inter-project publication/consumption, what'd like is to be to able to have the consumer queries the different publication of the library project to choose the right one. Whether this is done by classifiers or not doesn't really matter in the end I guess.
 
> I guess when uploading application packages, I could have a single
> component. However I'm also thinking about letting developers upload side
> files besides their app (for instance ProGuard mapping file). I guess that
> I could use the same classifier as the matching app with a different
> type/extension?

This is unlikely to work. There are no clear rules on what should happen here.

My experience is that type/extension do not contribute to an artifact's identity. That is, you can't have an artifact with the same (name,group,version,classifier) but different type/extension. I've not tried this with Gradle, but have with other Maven Repository tooling and it's not worked.


Good to know. Thanks. I think I'll have to have a DSL to allow devs to choose how each variant gets published (as far as groupId, artifactId). Then I can use the classifiers for extra components (proguard mapping for instance).
>
>
>
>>> Quick question: what's the name of the Usage instances used for?
>>>
>>
>> For Maven publication, it's not currently used. For ivy, it provides the
>> configuration that contains the published artifacts. The mapping of
>> SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the
>> moment, and we'd be very willing to extend enhance this with more use cases.
>>
>>
> Are you talking about  org.gradle.api.artifacts.Configuration here? I
> noticed that in JavaLibrary, the returned Usage object is called "runtime".
>
> How is all of this related to inter-project dependencies by the way? Right
> now we use project.artifacts.add("default", someAbstractArchiveTask) for
> both the old publication stuff and this seems to work.
> When looking at the JavaPlugin I saw those two lines:
>
>
> project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(jarArtifact);
>        project.getComponents().add(new JavaLibrary(jarArtifact,
> runtimeConfiguration.getAllDependencies()));
>
> The 2nd one makes sense to me when I see the 'from components.java' section
> of a publication sample. I've been wondering if the 2nd one was for
> inter-project dependencies, but it takes an artifact instead of a Usage
> object, so there's not associated dependencies?

--
Luke Daley
Principal Engineer, Gradleware
http://gradleware.com


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email






--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SoftwareComponentInternal and Usage

Adam Murdoch
In reply to this post by Xavier Ducrohet

On 01/08/2013, at 11:19 AM, Xavier Ducrohet <[hidden email]> wrote:

OK I can hold off.

Great. I'll finish up the tooling API stuff I'm doing for Alex and then can have a look at making the publishing stuff work better.

One way to tackle it would be something like:

1. Change project dependencies so that they resolve to a component.
2. Change dependency resolution so that a variant can be selected from a component.
3. Add some replacement for `afterEvaluated { }` for the Android plugin to use to create its tasks.
4. Change the new publishing DSL so that it can map a component with multiple variants to a publication.
5. (Maybe) change the old publishing DSL so that it also understands components. Might only be able to handle a single-variant component.

After #1 and #2 you'd be able to have project dependencies on an Android library with multiple variants, but you wouldn't yet be able to publish those variants to a repository.

After #3 and #4 you'd be able to use the new publishing DSL to publish an Android library or application with multiple variants.

And #5 just rounds it out. If we've made enough progress by this point, it could make more sense to un-incubate the new DSL instead of #5, so that you can only publish Android stuff (and C++ stuff and multi-variant jvm stuff) via the new DSL.



I was mostly trying to make our plugin work with the new publishing stuff as some external devs asked for it.


On Wed, Jul 31, 2013 at 6:04 PM, Adam Murdoch <[hidden email]> wrote:

On 01/08/2013, at 10:19 AM, Xavier Ducrohet <[hidden email]> wrote:

So I'm making progress but running into a evaluation issue.

Since the android plugin needs to evaluate the whole project before creating the variants and tasks, we create the tasks in afterEvaluate {}

This means that putting this in build.gradle

publishing {
    publications {
        test(MavenPublication) {
            from components.android
        }
    }
}

fails since the component doesn't exist yet. Not putting the component line only publishes a pom but not the artifact even though I have this line in the plugin:

            project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(theComponent);

Configuring the publishing extension in afterEvaluate fails with:

A problem occurred configuring root project 'baseLibrary'.
> Failed to notify project evaluation listener.
   > Cannot configure the 'publishing' extension after it has been accessed.

At this point I'm not sure how to proceed.

From my point of view, it would be best if you could wait until we've have a chance to get the publishing stuff a little closer to how we want it to be. It's just a bit too early to be trying to extend it. We can do this fairly soon, if you can hold off for a while. I think it will just be a less frustrating exercise for you.






On Wed, Jul 31, 2013 at 11:54 AM, Xavier Ducrohet <[hidden email]> wrote:

On Wed, Jul 31, 2013 at 11:02 AM, Luke Daley <[hidden email]> wrote:

On 31/07/2013, at 1:01 AM, Xavier Ducrohet <[hidden email]> wrote:

> On Tue, Jul 30, 2013 at 4:47 PM, Daz DeBoer
> <[hidden email]>wrote:
>
>> On 30 July 2013 17:23, Xavier Ducrohet <[hidden email]> wrote:
>>
>>> Makes sense. Right now I do want to add support for it so I'm going to
>>> use the internal stuff. We are aware that this might mean we are only
>>> compatible with a given version of Gradle and this is fine pre-1.0
>>>
>>> I'm also going to start creating components for each variants, but only
>>> add one candidate to the DefaultArtifactPublicationSet so this should work
>>> by default like the old publication.
>>>
>>
>> Are you planning to publish multiple variants to the same GAV
>> (publication), with variants differentiated by classifier? In that case,
>> I'm not sure why you wouldn't just create a single component, with multiple
>> artifacts. Each PublishArtifact can define a classifier, and all artifacts
>> will be published.
>>
>
> My variants can have different dependencies for libraries.

Which rules out the classifier approach.


Hmm. I know it's a limitation of Maven, but what about Gradle's internal representation of dependencies? (this loops back on my question about how project to project publication/dependencies are handled).

In my case, I'd like to have a library have variants when it's used in a multi-project setup (so that it can have the same variants as the consumer project), but when published for external usage on a repository, then variant will probably not be allowed, or they'll have to be different artifacts.

For inter-project publication/consumption, what'd like is to be to able to have the consumer queries the different publication of the library project to choose the right one. Whether this is done by classifiers or not doesn't really matter in the end I guess.
 
> I guess when uploading application packages, I could have a single
> component. However I'm also thinking about letting developers upload side
> files besides their app (for instance ProGuard mapping file). I guess that
> I could use the same classifier as the matching app with a different
> type/extension?

This is unlikely to work. There are no clear rules on what should happen here.

My experience is that type/extension do not contribute to an artifact's identity. That is, you can't have an artifact with the same (name,group,version,classifier) but different type/extension. I've not tried this with Gradle, but have with other Maven Repository tooling and it's not worked.


Good to know. Thanks. I think I'll have to have a DSL to allow devs to choose how each variant gets published (as far as groupId, artifactId). Then I can use the classifiers for extra components (proguard mapping for instance).
>
>
>
>>> Quick question: what's the name of the Usage instances used for?
>>>
>>
>> For Maven publication, it's not currently used. For ivy, it provides the
>> configuration that contains the published artifacts. The mapping of
>> SoftwareComponent/Usage => Maven/Ivy model is pretty brain-dead at the
>> moment, and we'd be very willing to extend enhance this with more use cases.
>>
>>
> Are you talking about  org.gradle.api.artifacts.Configuration here? I
> noticed that in JavaLibrary, the returned Usage object is called "runtime".
>
> How is all of this related to inter-project dependencies by the way? Right
> now we use project.artifacts.add("default", someAbstractArchiveTask) for
> both the old publication stuff and this seems to work.
> When looking at the JavaPlugin I saw those two lines:
>
>
> project.getExtensions().getByType(DefaultArtifactPublicationSet.class).addCandidate(jarArtifact);
>        project.getComponents().add(new JavaLibrary(jarArtifact,
> runtimeConfiguration.getAllDependencies()));
>
> The 2nd one makes sense to me when I see the 'from components.java' section
> of a publication sample. I've been wondering if the 2nd one was for
> inter-project dependencies, but it takes an artifact instead of a Usage
> object, so there's not associated dependencies?

--
Luke Daley
Principal Engineer, Gradleware
http://gradleware.com


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email






--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com






--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com



12
Loading...