ant-ivy-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Xavier Hanin" <xavier.ha...@gmail.com>
Subject Re: Opt out of the cache for a resolver
Date Tue, 26 Dec 2006 08:38:06 GMT
Hello All,

Interesting discussion here, I don't have time to read everything and catch
u^p on the discussion, but I'd like to give my opinion:
- I agree with Stephane and John that a version is a version and you should
never change what has been released. Even adding deprecated annotations can
change line numbers if you are not careful, and you will have troubles
inspecting a stack trace if your line numbers are not correct. And this is
just an example of all the problems you may run into when you don't actually
know the exact content of a jar when you know its version
- Even if I believe a version is a version and should never change, Ivy
support two kind of changes in a version:
** the module descriptor change (i.e. a change in the ivy.xml) when you
enable checkModified
** a change of the artifacts (i.e. a jar for instance), when you declare it
as a changing revision (either in your ivy.xml or by using the
changingPattern)

In this last case I think that supporting cache invalidation as requested by
Eric woud be consistent with the behaviour expected. And when you say that
your revision is changing Ivy has to check if the cache is valid each time,
so it wouldn't introduce a new performance overhead.

Regards,
Xavier


On 12/24/06, Eric Crahen <eric.crahen.lists@gmail.com> wrote:
>
> 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