ant-ivy-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Eric Crahen" <eric.crahen.li...@gmail.com>
Subject Re: Opt out of the cache for a resolver
Date Sun, 24 Dec 2006 17:44:28 GMT
Thanks, I think we have just both described the need to invalidate a
version in the ivy cache. I'll compare the two approaches objectively:

In both cases I'm using a chain resolver in which the first element is
just my local filesystem and the second is the shared repository which
contains offical/approved copies of all internal and external libraries.
In both cases all changes are visible only to me because we publish
only to our filesystem.

The key parts of your description are:
"change the version for Y, then update your references."

This effectively means,

#1 checkout Y, change the version, fix it, publish it
#2 checkout X, change the version because I'm changing its dependencies
     to point to the fixed Y, publish it.
#3 check out D, change the version because I'm changing its dependencies
     to point to the fixed Y, publish it.
#4 check out C, change the version because I'm changing its dependencies
     to point to the fixed D, publish it.
#5 check out B, change the version because I'm changing its dependencies
     to point to the fixed C, publish it.
#6 check out A, change the version because I'm changing its dependencies
     to point to the fixed B, publish it.
#7 Hope that I chose version numbers that will become automatically obsolete
     when the official fix is released.

So to fix a simple bug, locally using private versions only I can see, in 1
package,
I actually have to alter 6 ivy.xmls and perform 6 builds.

With what I suggested I would change 2 packages.

#1 checkout Y, fix it, publish it to the local override resolver
#2 checkout A, build it.

This required changing no ivy.xmls and building only 2 packages.

Ultimately we have accomplished the same thing.


The difference is that you preferred to use a very strict version scheme,
where as I opted to use the fact that something exists in my local resolver
as an implicit private local version.

The strong version comes at the cost of more work, and the amount of
that work (changing ivy.xml and building files) is proportional to the
number of packages. I would actually need to transitively enumerate
my dependencies and be sure that I update the versions correctly
in all dependencies - which may be tedious and error prone.

The implied version uses the chain to resolver preference to let
ivy to the transitive traversal for me; and since this is an unnamed
implied version, there was no need to guess a version number.

Both have visual cues, it depends on where you look. The cue in the
strong version is in the ivy.xml and the cue in the implied version is
existence of a file in the local repository.

Which one is most suitable is a choice a developer is free to make. I
don't Ivy needs to dictate one or the other, this really is a matter of
preference
and a matter of what a developer is comfortable with. Both very possible
and valid solutions. There are situations when both are useful.
I do not want to engage in a subject discussion about which is the right
thing to do.

Now here is what we have not addressed, which is the reason for the entire
thread.
** How do we evict these private copies from the cache when they are no
longer
needed? **

In the case of the strong versioning approach, part of what we have done is
hope to have chosen versions that would be considered older than the
official
version once released. We may not have guessed right and need to remove that
private local copy from the ivy cache. After all its lifetime is over, this
was a private
local copy that should no longer exist in the cache; we may to choose to
keep it
in the local resolver where it can be selected at any time, but it certainly
has no
need to be in the cache once its outlived its usefulness. Unless someone
never
makes mistakes, then maybe they will never need to invalidate the cache.
Maybe
some of us are just that good but I make mistakes, so I would really like
the ability
to do so when needed when I use this approach.

In the case of the implied version approach, we used the simple fact that
artifacts
existed in the local filesystem repository to indicate that those are the
preferred
artifacts to use. Now that we have a better release available in the shared
repository
we'd like to invalidate the artifacts in the cache and remove these files
from the resolver.

BOTH describe a use-case for invalidating the ivy cache for a particular
verison.

---

One possible way to do invalidate the cache would be that erasing resolver I
described which
would only work in association with a local filesystem resolver.
When I published any version, then it would invalidate that version in the
cache.

This would allow me to use that same resolver chain

// psuedo-chain
<chain>
  <filesystem name="local" local="true"/>
  <url name="shared/>
</chain>

<invalidate name="invalidate" ref="local" erase=<<optional>> />

With either approach my workflow for making local changes, regardless of how
I choose to
version, is

Check out.
Resolve with chain.
Build.
Publish to local repository.
Publish to invalidate when its time to invalidate the cache.

Erasing the copy of that version from the local resolver could be optional
to support both
use cases where people do want to remove packages, and use cases where
people do
not.

---

You said that you feared that people using this patching/overriding
logic means people could make a mistake in external repositories.
This can happen at any time regardless of the technique used to
make local changes. This is orthogonal to using one technique or
the other for local changes. Releases require care, which is another
issue entirely.

As to your other points 1-5 at the end or you post, this is good advice
but orthogonal to solving the problem of making a local change and
effectively invalidating the cache when its no longer needed.


On 12/24/06, Stephane Bailliez <sbailliez@gmail.com> wrote:
>
> Eric Crahen wrote:
>
> > I've found that there is a bug in Y.
> > Several things need to happen for me at this point:
> > #1.
> > I need to keep working on A. So I need to be able to patch Y.
> > This means I need a local copy. Now you can label this
> > Eric's-hacked-library
>
> This means fix the bug, change the version number or append an
> additional string or whatever that match your status. Then store it in
> your repository. Then update your references so that you force the use
> of this specific version.
>
> You must strive to have y-1.1-patched-by-eric.jar > y-1.1.jar or
> y-1.1-patched-by-eric.jar evicting y-1.1.jar depending your internal
> policy., etc...
> When a version 1.2 will be released (which hopefully will incorporate
> your patch), then 1.2 automatically obsolete 1.1-patched-by-eric (unless
> the version is really forced with force=true)
>
> When you do this dependencies are really managed rather than hacked and
> there is always the visual element to make sure that the version that is
> included is really the latest version and it conveys immediately the
> information that this dependency is patched.
>
>
> If we follow this patching/overriding logic, that means that people
> could well do the same on external repositories and silently swap one
> jar with another patched version because they are too lazy to do a
> release, which basically means that 2 people could be using the same
> version with a different code. That's brilliant to convince developers
> to commit suicide. :)
>
> And this is also another reason why I don't use external repositories.
> 1) I trust no one.
> 2) dependencies are generally not well expressed
> 3) versioning is sometimes not even well done correctly
> 4) I keep full control of all my dependencies
> 5) I have flexibility.
>
> -- stephane
>



-- 

- Eric

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message