You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@buildr.apache.org by Trejkaz <tr...@trypticon.org> on 2016/10/08 05:06:30 UTC
Dependencies are naturally version ranges, not single versions
Continuing from https://issues.apache.org/jira/browse/BUILDR-274
Let's suppose that version ranged dependencies don't exist.
Let's also suppose that:
* Library A depends on Library C 1.0.
* Library B depends on Library C 1.1.
* The changes from C 1.0 to C 1.1 were done according to semver (all
libraries should be doing this), and therefore code written to 1.0
will work against 1.1.
Now suppose your application wants to depend on both A and B. Now you
have a transitive dependency on both C 1.0 and 1.1. If you're using
OSGi, this _may_ be okay, though there are cases where it is not - for
instance, if two libraries are expected to pass between themselves
objects of a class defined in a third. If you're not using OSGi or a
similar runtime which allows running two different versions of the
same library, now you can't run your code. If you have an application
with a large number of dependencies, you end up having to go to
multiple libraries and begging them to update to some minor patch
release just so that your build can resolve the dependencies.
The problem, as I see it, is that A doesn't _really_ depend on C 1.0.
By definition, C 1.1 introduced backwards-compatible changes, so A
should also work against C 1.1. _If_ A also works against C 1.1, then
saying it depends on 1.0 is a lie. As a library developer, I would
prefer to specify my dependencies in a way which represents what I
actually support, even if the build only runs against one specific
version of it. Compiling should be done against the _lowest_ version
in the supported range, if it isn't checked against all of them.
*Ideally*, tests should be run against all combinations of
dependencies. I do see some projects doing this, presumably to be
doubly-sure that their dependencies are correct.
An an application developer and someone who wants to build the
integrated project, I would like all libraries to declare their
dependencies accurately, so that the build tool can reliably detect
actual conflicts. If B suddenly starts depending on C 2.0, I want to
know about that. But today's build tools only give me two
unsatisfactory options:
(a) All your versions have to match, which they never do, so your
build is always conflicting, and you have to manually inspect other
people's code to see whether it will work with a newer version or not.
(b) Allow versions not to match, but when they clash, always pick
the latest one, and eventually you will get some NoClassDefFoundError
when someone accidentally updates a library which another library
actually needed.
Accurately specified dependencies should also not make my build
unreproducible, as implied by the comment on the ticket. There are
multiple reasons why:
1. As long as nobody is specifying open-ended version ranges, it
shouldn't even be possible for a new incompatible version to suddenly
break the build. You should only be specifying dependencies you have
actually tested anyway.
2. If you update a library and the dependency of the updated version
was a newer version of some other library, the build didn't break
because of version ranges, it broke because you actually changed
something.
3. Even problems of specifying open-ended version ranges have been
solved by other dependency-resolution systems. For instance, RubyGems
keeps a "lock" file which contains the actual versions of everything
used last build, so the next build will use those versions until
someone actually updates something deliberately. It seems to be
working.
TX
Re: Dependencies are naturally version ranges, not single versions
Posted by Trejkaz <tr...@trypticon.org>.
On Sun, Oct 9, 2016 at 12:16 PM, Antoine Toulme <an...@toulme.name> wrote:
> Thank you for taking the time to write down your thoughts.
>
> BUILDR-274 is very much something we want to get to eventually.
>
> Maven supports version ranges. How they do it might be different from the behavior you describe. I need to compare both, did you by any chance look into that?
No, I'm not too familiar with Maven myself.
From being forced to use Gradle, that seems to support ranges but it
does so in the awful way where it bumps you up to the highest one even
if it conflicts.
The OSGi runtime is the only version resolution stuff I have seen
working sanely, but I don't know what people in that space are doing
about compile-time.
Of course, the other problem with all this is getting libraries to
specify their versions accurately. Far too many have a single static
version specified. Almost no libraries we depend on for the
application at work have done so. :/
TX
Re: Dependencies are naturally version ranges, not single versions
Posted by Antoine Toulme <an...@toulme.name>.
Thank you for taking the time to write down your thoughts.
BUILDR-274 is very much something we want to get to eventually.
Maven supports version ranges. How they do it might be different from the behavior you describe. I need to compare both, did you by any chance look into that?
> On Oct 7, 2016, at 22:06, Trejkaz <tr...@trypticon.org> wrote:
>
> Continuing from https://issues.apache.org/jira/browse/BUILDR-274
>
> Let's suppose that version ranged dependencies don't exist.
> Let's also suppose that:
>
> * Library A depends on Library C 1.0.
> * Library B depends on Library C 1.1.
> * The changes from C 1.0 to C 1.1 were done according to semver (all
> libraries should be doing this), and therefore code written to 1.0
> will work against 1.1.
>
> Now suppose your application wants to depend on both A and B. Now you
> have a transitive dependency on both C 1.0 and 1.1. If you're using
> OSGi, this _may_ be okay, though there are cases where it is not - for
> instance, if two libraries are expected to pass between themselves
> objects of a class defined in a third. If you're not using OSGi or a
> similar runtime which allows running two different versions of the
> same library, now you can't run your code. If you have an application
> with a large number of dependencies, you end up having to go to
> multiple libraries and begging them to update to some minor patch
> release just so that your build can resolve the dependencies.
>
> The problem, as I see it, is that A doesn't _really_ depend on C 1.0.
>
> By definition, C 1.1 introduced backwards-compatible changes, so A
> should also work against C 1.1. _If_ A also works against C 1.1, then
> saying it depends on 1.0 is a lie. As a library developer, I would
> prefer to specify my dependencies in a way which represents what I
> actually support, even if the build only runs against one specific
> version of it. Compiling should be done against the _lowest_ version
> in the supported range, if it isn't checked against all of them.
> *Ideally*, tests should be run against all combinations of
> dependencies. I do see some projects doing this, presumably to be
> doubly-sure that their dependencies are correct.
>
> An an application developer and someone who wants to build the
> integrated project, I would like all libraries to declare their
> dependencies accurately, so that the build tool can reliably detect
> actual conflicts. If B suddenly starts depending on C 2.0, I want to
> know about that. But today's build tools only give me two
> unsatisfactory options:
> (a) All your versions have to match, which they never do, so your
> build is always conflicting, and you have to manually inspect other
> people's code to see whether it will work with a newer version or not.
> (b) Allow versions not to match, but when they clash, always pick
> the latest one, and eventually you will get some NoClassDefFoundError
> when someone accidentally updates a library which another library
> actually needed.
>
> Accurately specified dependencies should also not make my build
> unreproducible, as implied by the comment on the ticket. There are
> multiple reasons why:
>
> 1. As long as nobody is specifying open-ended version ranges, it
> shouldn't even be possible for a new incompatible version to suddenly
> break the build. You should only be specifying dependencies you have
> actually tested anyway.
>
> 2. If you update a library and the dependency of the updated version
> was a newer version of some other library, the build didn't break
> because of version ranges, it broke because you actually changed
> something.
>
> 3. Even problems of specifying open-ended version ranges have been
> solved by other dependency-resolution systems. For instance, RubyGems
> keeps a "lock" file which contains the actual versions of everything
> used last build, so the next build will use those versions until
> someone actually updates something deliberately. It seems to be
> working.
>
>
> TX
Re: Dependencies are naturally version ranges, not single versions
Posted by Trejkaz <tr...@trypticon.org>.
On Thu, Oct 13, 2016 at 3:00 PM, Antoine Toulme <an...@toulme.name> wrote:
> Interesting. Is Buildr behaving differently, better or worse?
I haven't been using Builder heavily and in a work setting yet,
because some jackass is blocking switching to it at work. I wish we
could switch...
In a hobby context, a few of my GitHub projects do use it to build,
and I haven't yet seen it (or any of the repos it contacts) do the
download variation thing, or if it's doing it, it's hiding it well. I
have, however, seen Buildr builds work one month and then fail the
next, because something on a repo changed in some other way. :/
TX
Re: Dependencies are naturally version ranges, not single versions
Posted by Antoine Toulme <an...@toulme.name>.
Interesting. Is Buildr behaving differently, better or worse?
> On Oct 12, 2016, at 8:58 PM, Trejkaz <tr...@trypticon.org> wrote:
>
>> I’ve seen this happen with snapshots, but not with release builds. We banned snapshots at $work.
>
> I have seen it happen with release builds of external projects too.
> One time we even saw a POM change where the jar file didn't, and
> amazingly, *that* was enough to break someone's build. (And that team
> is using Maven proper.)
>
> All the weird stuff with builds failing which just worked happened to
> us (and still happen to us) on Gradle as well.
>
> TX
Re: Dependencies are naturally version ranges, not single versions
Posted by Trejkaz <tr...@trypticon.org>.
> I’ve seen this happen with snapshots, but not with release builds. We banned snapshots at $work.
I have seen it happen with release builds of external projects too.
One time we even saw a POM change where the jar file didn't, and
amazingly, *that* was enough to break someone's build. (And that team
is using Maven proper.)
All the weird stuff with builds failing which just worked happened to
us (and still happen to us) on Gradle as well.
TX
Re: Dependencies are naturally version ranges, not single versions
Posted by Antoine Toulme <an...@toulme.name>.
> On Oct 12, 2016, at 7:40 PM, Trejkaz <tr...@trypticon.org> wrote:
>
> On Wed, Oct 12, 2016 at 7:02 PM, Antoine Toulme <an...@toulme.name> wrote:
>> Good job Michael, I look forward to using the lock_jar gem in my projects.
>>
>> Trejkaz, is lock_jar covering your use case?
>
> It does appear to and will be something I'll investigate. I'll also go
> digging for whether the similar plugins for Gradle will give us a
> similar result.
>
>> I hate non-reproducible builds and semver-relaxed dep-of-the-dep issues, but,
>> while a broken dep fails the build for lots of people (downside), the upside of this
>> is that very quickly (within hours of a new dep being published) there will be lots
>> angry people complaining about it on GitHub, and a faulty dep will be typically
>> quickly rolled back / superseded with a patch. Otherwise, some bugs might be
>> sitting hidden for a long time.
>
> What we find is that obscure broken dependencies are not found
> immediately after the commit. Most of the time, they are not even
> found before release, or during testing. They are found the first week
> after release, or in some cases, 2 months after release, when it can
> do the most damage.
>
>> When Maven came about, it’s biggest value-add compared to Ant or makefiles
>> was that it made builds reproducible.
>
> Not true. What Maven actually did was to bring non-reproducible builds
> into the mainstream.
>
> Ant builds were *very* reproducible, because the only easy way to get
> your dependencies was to check in your jars. And although it's true
> that the repository is also external, if you have corruption in that,
> you're pretty much screwed, no matter which build tool you want to
> use.
Fair enough.
>
> But using Maven, if we want to use a library, we're supposed to get it
> from an "artifact server". These servers can give you different data
> for two identical requests a few minutes apart, without you even
> changing anything in your code. I have even *seen* our artifact server
> at work doing that while we have been using Gradle, which is no better
> than Maven in this regard.
>
> Sometimes, someone will try to gloss over this problem by saying
> things like, "but the local cache will ensure that two builds will be
> the same!". This is ridiculous as well, because other people who build
> your software don't have the same cache as you. Different members of
> the team have different caches. Different slaves within the build
> cluster for the same team don't even share the same cache. So I can
> only assume people who make that sort of claim are working on toy
> projects with one developer, where one computer can still build
> everything they make in a reasonable time frame. Or perhaps they don't
> write any tests, thus making their builds fairly fast.
I’ve seen this happen with snapshots, but not with release builds. We banned snapshots at $work.
>
> So basically, with Maven, we can't even have a *truly reproducible
> build*, as long as there is at least one dependency.
>
> Remind me again, though, what *did* Maven improve exactly? It has
> never really been clear to me. Every time I check out a project from
> somewhere and try to run the Maven build, it has failed to build.
That is very far from my experience, contributing to various Apache, Eclipse and other projects.
I welcome you to read the blog post that the original committer wrote when announcing Buildr (2007!)
http://web.archive.org/web/20070427081228/http://blog.labnotes.org/ <http://web.archive.org/web/20070427081228/http://blog.labnotes.org/>
>
> TX
Re: Dependencies are naturally version ranges, not single versions
Posted by Peter Donald <pe...@realityforge.org>.
On Thu, Oct 13, 2016 at 1:40 PM, Trejkaz <tr...@trypticon.org> wrote:
>
> Remind me again, though, what *did* Maven improve exactly? It has
> never really been clear to me.
A set of conventions on how to lay out a project. Before maven people used
to files in all sorts of different places and would spend an inordinate
amount of time arguing about why their convention was better. I saw this in
both commercial and oss projects. Now everyone seems to have mostly default
to maven conventions if at all possible, regardless of whether they are
using maven or not.
--
Cheers,
Peter Donald
Re: Dependencies are naturally version ranges, not single versions
Posted by Trejkaz <tr...@trypticon.org>.
On Wed, Oct 12, 2016 at 7:02 PM, Antoine Toulme <an...@toulme.name> wrote:
> Good job Michael, I look forward to using the lock_jar gem in my projects.
>
> Trejkaz, is lock_jar covering your use case?
It does appear to and will be something I'll investigate. I'll also go
digging for whether the similar plugins for Gradle will give us a
similar result.
> I hate non-reproducible builds and semver-relaxed dep-of-the-dep issues, but,
> while a broken dep fails the build for lots of people (downside), the upside of this
> is that very quickly (within hours of a new dep being published) there will be lots
> angry people complaining about it on GitHub, and a faulty dep will be typically
> quickly rolled back / superseded with a patch. Otherwise, some bugs might be
> sitting hidden for a long time.
What we find is that obscure broken dependencies are not found
immediately after the commit. Most of the time, they are not even
found before release, or during testing. They are found the first week
after release, or in some cases, 2 months after release, when it can
do the most damage.
> When Maven came about, it’s biggest value-add compared to Ant or makefiles
> was that it made builds reproducible.
Not true. What Maven actually did was to bring non-reproducible builds
into the mainstream.
Ant builds were *very* reproducible, because the only easy way to get
your dependencies was to check in your jars. And although it's true
that the repository is also external, if you have corruption in that,
you're pretty much screwed, no matter which build tool you want to
use.
But using Maven, if we want to use a library, we're supposed to get it
from an "artifact server". These servers can give you different data
for two identical requests a few minutes apart, without you even
changing anything in your code. I have even *seen* our artifact server
at work doing that while we have been using Gradle, which is no better
than Maven in this regard.
Sometimes, someone will try to gloss over this problem by saying
things like, "but the local cache will ensure that two builds will be
the same!". This is ridiculous as well, because other people who build
your software don't have the same cache as you. Different members of
the team have different caches. Different slaves within the build
cluster for the same team don't even share the same cache. So I can
only assume people who make that sort of claim are working on toy
projects with one developer, where one computer can still build
everything they make in a reasonable time frame. Or perhaps they don't
write any tests, thus making their builds fairly fast.
So basically, with Maven, we can't even have a *truly reproducible
build*, as long as there is at least one dependency.
Remind me again, though, what *did* Maven improve exactly? It has
never really been clear to me. Every time I check out a project from
somewhere and try to run the Maven build, it has failed to build.
TX
Re: Dependencies are naturally version ranges, not single versions
Posted by Peter Donald <pe...@realityforge.org>.
On Wed, Oct 12, 2016 at 7:02 PM, Antoine Toulme <an...@toulme.name> wrote:
> For some reason, the JS community seems to prefer just trusting that new
> versions won't break anything. Its either very brave of them really (or
> maybe just foolish).
>
I think there is a few features that distinguish the js community wrt
libraries.
* The libraries are untyped so don't fail to compile if something changes,
only fail at runtime if actually use the feature that changed.
* They have had semver integrated into their community at least in theory
from very early on where in java or ruby it tends to be up to each
community to follow or not.
* Their tools have supported semver from the beginning.
* Their libraries are usually much smaller, and people often write new ones
rather than reuse.
* The ecosystem has not really stabilized so if you are not constantly
updating you are probably running into other issues ;)
That said - I still much prefer fixed versions for stability, particularly
if you have to support it over many years.
--
Cheers,
Peter Donald
Re: Dependencies are naturally version ranges, not single versions
Posted by Antoine Toulme <an...@toulme.name>.
Good job Michael, I look forward to using the lock_jar gem in my projects.
Trejkaz, is lock_jar covering your use case?
Antoine
PS:
In the news, the talk of Yarn, the new Javascript dependency manager, and some interesting comments on HN:
http://yehudakatz.com/2016/10/11/im-excited-to-work-on-yarn-the-new-js-package-manager-2/ <http://yehudakatz.com/2016/10/11/im-excited-to-work-on-yarn-the-new-js-package-manager-2/>
https://news.ycombinator.com/item?id=12684980 <https://news.ycombinator.com/item?id=12684980>
Some interesting tidbits:
In fairness to the language and tools, this seems to be more of a cultural problem than anything.
You can do the same kind of version range tricks in typical Java builds, for example (Maven), but most people hardcode the values to keep builds as deterministic as possible.
For some reason, the JS community seems to prefer just trusting that new versions won't break anything. Its either very brave of them really (or maybe just foolish).
I hate non-reproducible builds and semver-relaxed dep-of-the-dep issues, but, while a broken dep fails the build for lots of people (downside), the upside of this is that very quickly (within hours of a new dep being published) there will be lots angry people complaining about it on GitHub, and a faulty dep will be typically quickly rolled back / superseded with a patch. Otherwise, some bugs might be sitting hidden for a long time.
When Maven came about, it’s biggest value-add compared to Ant or makefiles was that it made builds reproducible.
Using version ranges makes that impossible - but using the approach that Michael borrowed from Bundler (and is again reused by Yarn from my quick reading) makes the resolution explicit.
> On Oct 9, 2016, at 2:04 AM, Peter Donald <pe...@realityforge.org> wrote:
>
> Hi,
>
> We have talked about this problem in the past but unfortunately at the time
> no one on the buildr team had the cycles to have a shot at it. Luckily
> someone from the community Michael Guymon, took the idea and ran with it.
> First with
>
> https://github.com/mguymon/buildr-resolver
>
> but this got deprecated in favour of
>
> https://github.com/mguymon/lock_jar
>
> I have never used it but have been quite impressed by the idea, design and
> code. I think there is probably a way we could better integrate it with
> Buildr if someone wanted to try and get it as the default/recommended
> mechanisms in buildr but you may also be able to use it as is with little
> to no friction.
>
> I have CC'ed the developer who may want to advocate for it's use too ;)
>
>
> On Sat, Oct 8, 2016 at 4:06 PM, Trejkaz <tr...@trypticon.org> wrote:
>
>> Continuing from https://issues.apache.org/jira/browse/BUILDR-274
>>
>> Let's suppose that version ranged dependencies don't exist.
>> Let's also suppose that:
>>
>> * Library A depends on Library C 1.0.
>> * Library B depends on Library C 1.1.
>> * The changes from C 1.0 to C 1.1 were done according to semver (all
>> libraries should be doing this), and therefore code written to 1.0
>> will work against 1.1.
>>
>> Now suppose your application wants to depend on both A and B. Now you
>> have a transitive dependency on both C 1.0 and 1.1. If you're using
>> OSGi, this _may_ be okay, though there are cases where it is not - for
>> instance, if two libraries are expected to pass between themselves
>> objects of a class defined in a third. If you're not using OSGi or a
>> similar runtime which allows running two different versions of the
>> same library, now you can't run your code. If you have an application
>> with a large number of dependencies, you end up having to go to
>> multiple libraries and begging them to update to some minor patch
>> release just so that your build can resolve the dependencies.
>>
>> The problem, as I see it, is that A doesn't _really_ depend on C 1.0.
>>
>> By definition, C 1.1 introduced backwards-compatible changes, so A
>> should also work against C 1.1. _If_ A also works against C 1.1, then
>> saying it depends on 1.0 is a lie. As a library developer, I would
>> prefer to specify my dependencies in a way which represents what I
>> actually support, even if the build only runs against one specific
>> version of it. Compiling should be done against the _lowest_ version
>> in the supported range, if it isn't checked against all of them.
>> *Ideally*, tests should be run against all combinations of
>> dependencies. I do see some projects doing this, presumably to be
>> doubly-sure that their dependencies are correct.
>>
>> An an application developer and someone who wants to build the
>> integrated project, I would like all libraries to declare their
>> dependencies accurately, so that the build tool can reliably detect
>> actual conflicts. If B suddenly starts depending on C 2.0, I want to
>> know about that. But today's build tools only give me two
>> unsatisfactory options:
>> (a) All your versions have to match, which they never do, so your
>> build is always conflicting, and you have to manually inspect other
>> people's code to see whether it will work with a newer version or not.
>> (b) Allow versions not to match, but when they clash, always pick
>> the latest one, and eventually you will get some NoClassDefFoundError
>> when someone accidentally updates a library which another library
>> actually needed.
>>
>> Accurately specified dependencies should also not make my build
>> unreproducible, as implied by the comment on the ticket. There are
>> multiple reasons why:
>>
>> 1. As long as nobody is specifying open-ended version ranges, it
>> shouldn't even be possible for a new incompatible version to suddenly
>> break the build. You should only be specifying dependencies you have
>> actually tested anyway.
>>
>> 2. If you update a library and the dependency of the updated version
>> was a newer version of some other library, the build didn't break
>> because of version ranges, it broke because you actually changed
>> something.
>>
>> 3. Even problems of specifying open-ended version ranges have been
>> solved by other dependency-resolution systems. For instance, RubyGems
>> keeps a "lock" file which contains the actual versions of everything
>> used last build, so the next build will use those versions until
>> someone actually updates something deliberately. It seems to be
>> working.
>>
>>
>> TX
>>
>
>
>
> --
> Cheers,
>
> Peter Donald
Re: Dependencies are naturally version ranges, not single versions
Posted by Peter Donald <pe...@realityforge.org>.
Hi,
We have talked about this problem in the past but unfortunately at the time
no one on the buildr team had the cycles to have a shot at it. Luckily
someone from the community Michael Guymon, took the idea and ran with it.
First with
https://github.com/mguymon/buildr-resolver
but this got deprecated in favour of
https://github.com/mguymon/lock_jar
I have never used it but have been quite impressed by the idea, design and
code. I think there is probably a way we could better integrate it with
Buildr if someone wanted to try and get it as the default/recommended
mechanisms in buildr but you may also be able to use it as is with little
to no friction.
I have CC'ed the developer who may want to advocate for it's use too ;)
On Sat, Oct 8, 2016 at 4:06 PM, Trejkaz <tr...@trypticon.org> wrote:
> Continuing from https://issues.apache.org/jira/browse/BUILDR-274
>
> Let's suppose that version ranged dependencies don't exist.
> Let's also suppose that:
>
> * Library A depends on Library C 1.0.
> * Library B depends on Library C 1.1.
> * The changes from C 1.0 to C 1.1 were done according to semver (all
> libraries should be doing this), and therefore code written to 1.0
> will work against 1.1.
>
> Now suppose your application wants to depend on both A and B. Now you
> have a transitive dependency on both C 1.0 and 1.1. If you're using
> OSGi, this _may_ be okay, though there are cases where it is not - for
> instance, if two libraries are expected to pass between themselves
> objects of a class defined in a third. If you're not using OSGi or a
> similar runtime which allows running two different versions of the
> same library, now you can't run your code. If you have an application
> with a large number of dependencies, you end up having to go to
> multiple libraries and begging them to update to some minor patch
> release just so that your build can resolve the dependencies.
>
> The problem, as I see it, is that A doesn't _really_ depend on C 1.0.
>
> By definition, C 1.1 introduced backwards-compatible changes, so A
> should also work against C 1.1. _If_ A also works against C 1.1, then
> saying it depends on 1.0 is a lie. As a library developer, I would
> prefer to specify my dependencies in a way which represents what I
> actually support, even if the build only runs against one specific
> version of it. Compiling should be done against the _lowest_ version
> in the supported range, if it isn't checked against all of them.
> *Ideally*, tests should be run against all combinations of
> dependencies. I do see some projects doing this, presumably to be
> doubly-sure that their dependencies are correct.
>
> An an application developer and someone who wants to build the
> integrated project, I would like all libraries to declare their
> dependencies accurately, so that the build tool can reliably detect
> actual conflicts. If B suddenly starts depending on C 2.0, I want to
> know about that. But today's build tools only give me two
> unsatisfactory options:
> (a) All your versions have to match, which they never do, so your
> build is always conflicting, and you have to manually inspect other
> people's code to see whether it will work with a newer version or not.
> (b) Allow versions not to match, but when they clash, always pick
> the latest one, and eventually you will get some NoClassDefFoundError
> when someone accidentally updates a library which another library
> actually needed.
>
> Accurately specified dependencies should also not make my build
> unreproducible, as implied by the comment on the ticket. There are
> multiple reasons why:
>
> 1. As long as nobody is specifying open-ended version ranges, it
> shouldn't even be possible for a new incompatible version to suddenly
> break the build. You should only be specifying dependencies you have
> actually tested anyway.
>
> 2. If you update a library and the dependency of the updated version
> was a newer version of some other library, the build didn't break
> because of version ranges, it broke because you actually changed
> something.
>
> 3. Even problems of specifying open-ended version ranges have been
> solved by other dependency-resolution systems. For instance, RubyGems
> keeps a "lock" file which contains the actual versions of everything
> used last build, so the next build will use those versions until
> someone actually updates something deliberately. It seems to be
> working.
>
>
> TX
>
--
Cheers,
Peter Donald