On 25/10/2012, at 9:35 PM, Luke Daley wrote:
> Hi all,
>
> I'm working on our new publication stuff. The question has come up of where
> the different components need to to go to support a standalone dependency
> management library.
>
> I can't remember ever having the conversation on just what this would mean.
> That is, exactly what services would a standalone dependency management
> library provide, and what would the API be like?
>
> Note: this is not a pressing issue. For the time being we'll be developing in
> a new module, but I thought this would be a good discussion to start now.
>
>
> For dependency resolution, you in theory don't need much. It's conceivable
> that you don't even need a Project object. For publication, things are
> different.
>
> A quick example:
>
> interface Publication extends Buildable {}
>
> class PublishTask extends DefaultTask {
> @Input Publication publication
> ArtifactRepository repository
> }
>
> The implementation of this task would use all kind of internal machinery for
> working out just how to move this publication's files to the repository. If
> we design this as *the* public API for invoking publication,
It is for now, because we haven't needed to expose a public API for a
publication service yet. The plan is to add such an API at some point.
Extracting a standalone API would be something that would trigger this.
> it starts to look like our standalone dependency management library gets
> pretty big. It needs to have projects, a task graph etc.
>
> I would think that this is too much. To use our dependency management stuff,
> you shouldn't need a Project and tasks. So this would mean that (eventually)
> there needs to be public API that works outside of a task (e.g.
> publication.publish(repository) - just illustrative).
>
> There are other issues of course. If a publication is to be used standalone
> (without task machinery), then does Buildable make sense? If Publication has
> to work standalone, making it Buildable makes it too easy to make design
> decisions based on being in a task environment.
I don't think Project, Task or Buildable make sense for a standalone API.
However, one of the goals for this library is that another build tool can use
it to implement dependency management, and this means the build tool is going
to have to be able to implement its analogue of project dependencies and
buildable things.
I can think of a few strategies we could use for implementing the standalone
API:
1. Take our existing domain objects exactly as they are and make them usable
outside of a Gradle build. Initially, they'd drag in a whole bunch of
unnecessary stuff. Gradually detangle from the things that aren't required.
2. Extract public APIs out of the services that our domain objects use. Our
dependency management domain objects are all just factories for some data that
is handed to some service that does the actual work, and a wrapper over the
result. So, we can expose this pattern. Start with the absolute minimum
required to resolve external dependencies. Grow from there.
3. Combine the 2 approaches, so that we start with #1 and use #2 as the 'how'
for detangling.
Initially I was thinking of going with #1, but now I'm wondering if #2 might be
a better way to go. We'd have something usable much sooner with #1, but #2
keeps the library relatively minimal from the start. Going with #1 would force
us to decouple the domain objects from the Gradle execution model and chop them
up in various ways. This will benefit Gradle users and plugin authors, too, as
they'll be able to extend and integrate deeply with the dependency management
system.
--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com