How Does Ivy Work With Version Control Tags - tags

I am currently trying to find out how the Ivy workflow would be when generating VC tags (We're using SVN, but it doesn't matter).
The thing is, we have developed multiple libraries that depend on each other. To ease development, the dependency tag within ivy.xmlhas the attribute rev set to latest.integration.
<dependencies>
<dependency org="my-company" name="my-lib" rev="latest.integration"/>
</dependencies>
It was actually the result form this question on StackOverflow. This helps so that we can make changes quickly in one library and that run unit test in our main application without the need to manually change the revision.
Once the development is done, we publish the libs to out internal shared Ivy repository and create an SVN tag.
The problem that arises is that once we need to rebuild the software from a tag Ivy still points to latest.integration which, at a later point in time, will most probably point to a another integration build, maybe even to a later published version (depending on the resolver config).
Now that question is obvious: what is the best way to have Ivy to resolve to the published revisions that were integration.latest at the time the VCS tag was created. And it would be very helpful if the answer is not "enter published revisions by hand before you create the tag". Maybe I need to add something to my ANT build script, maybe some changes in my settings.xml or ivy.xml.
Since Ivy is quite a smart and handy little tool, I guess there must be a way to do it...

The ivy deliver task is used to create a resolved ivy file from the project's original. By "resolved" I mean a file fit to be published into a remote repository. This means not only are the dynamic dependencies resolved, the optional revision and status attributes are set in the module's info tag.
The following example creates an ivy.xml file in the build directory:
<ivy:deliver deliverpattern="${build.dir}/ivy.xml" pubrevision="${project.version}" status="release"/>
Check the file you'll discover the dependency versions are set.
At this point it is worth noting that this ability is one of subtle but important points that separates ivy from Maven. Ivy allows your automated release system to simply create tag and run the build. Take a look at the convoluted steps required by Maven and automated by it's release plugin :
Check that there are no uncommitted changes in the sources
Check that there are no SNAPSHOT dependencies
Change the version in the POMs from x-SNAPSHOT to a new version (you will be prompted for the versions to use)
Transform the SCM information in the POM to include the final destination of the tag
Run the project tests against the modified POMs to confirm everything is in working order
Commit the modified POMs
Tag the code in the SCM with a version name (this will be prompted for)
Bump the version in the POMs to a new value y-SNAPSHOT (these values will also be prompted for)
Commit the modified POMs
Count carefully.... That's 2 commits and a tag operation..... All because Maven's module version is mandatory and we're trying to capture in the SCM the resolved dependencies....
So, my advise is to be wary of emulating Maven. When I tag my code I capture a point in time, when I built the code. I rely on the fact that the ivy file pushed to my remote repository is fully resolved. The truly paranoid could of course keep a local copy of this ivy file, but it would never be the file that was used to build the original. In practice it's never possible to truly reproduce the original binary, just something that approximates to it.
Additional info
To help understand how the deliver task is used, the following examples show how it's used to create resolved Maven POM files when publishing ANT artefacts into a Maven repository like Nexus:
Convert ivy.xml to pom.xml
Automate ivy revision increase for all my projects using ant script

Related

Why does a Maven clean (from Eclipse) pull files into the local repository?

I would guess a clean might either delete jars from the repo or leave it untouched. But when I manually deleted the existing repo and then cleaned all the existing projects in Eclipse, the repository was recreated. The problem at least is that it takes a long time. So I am firstly curious as to why this behavior occurs and secondly wonder if there is a way not to have this occur.
The maven install is really little more than a bootstrap. All maven actions are implemented as plugins, downloaded from a Maven repository, and cached in the local repository. This architecture makes Maven extremely extensible (if you know what you're doing).
To improve build performance you are best advised to setup a local Maven repository manager. This will cache jars that would otherwise have to be downloaded from Maven Central.
Running a Maven repository manager is not hard nowadays. It offers the additional features of providing a place to manage dependencies that may not be available from a remote repo and as a place to share jars between different project builds.
The clean phase of the clean lifecycle does not clean your local repository. Instead, it does "remove all files generated by the previous build" (in your project's target directory, if you use Maven's Standard Directory Layout). See Introduction to the Build Lifecycle, Lifecycle Reference, Clean Lifecycle.
The "Why?" is answered by Mark O'Connor.
The answer to "How to avoid?" is: Don't delete your local repo completely.
You can delete sub-directories of libraries/artifacts you once tried out or tested but decided to abandon using them without any impact, though.

Red exclamation in Eclipse after build - on classes dir

First, there are no problems with my build path, and there's no problem in the "problems" window regarding this error. What happens is:
I check a project out of SVN
I then build that project
SVN "version" and link gets removed from classes and build directories (and red ! appears)
I can no longer commit project as a whole, as I get this error:
svn: Commit failed (details follow):
svn: Working copy 'C:\Users\<me>\Documents\eclipseSDK\<project>\classes' is missing or not locked
It's NOT missing, it just was "refreshed" during build
I've also tried to delete the dir on the SVN side, but the red arrows still appear and committing throws an error - even though those dirs are no longer part of the checked resources.
Also, basically, any "Team" menu option will no longer work on those two dirs, if I try to Team>Add to Version Control, nothing shows up in the Resources window.
I don't even know if I care about the red exclamation as much as just getting those two dirs out of the SVN process. Like I said, I've deleted on the SVN side even, so they are no longer there.
Are your compiled classes file part of your Subversion repository? If so, GET RID OF THEM FROM SUBVERSION!.
Sorry about the screaming, but files that can be built (like classes and jar files) should not be stored in version control. It just doesn't make sense.
Source control allows you to see the history of changes. You can see who made what changes in the source, but you can't do that in class files or jars. Source control allows you to branch and merge changes. You can't do that with class files. And, they go stale very quickly. No one cares about class files that were built last month.
The biggest issue is sheer size. Binary files don't diff well (and many version control systems don't even try). Let's say you build 15 megabytes worth of class files each time you do a build. That's probably at least 12 megabytes added to your repository each and every time. With in a year, you could be adding, 1 gigabyte to your repository. You can easily end up with the vast majority (and I mean in the 90% range of your source repository being nothing more than compiled code. Compiled code that no one cares about. Compiled code that can't help you understand your development history. Compiled code that clogs up your repository.
Go to your classes directory, and do an revert from the Team menu on that directory. You'll lose all of your changes, but so what? They shouldn't be there. This will set things up, so you can at least commit your changes.
Then, delete that classes directory and all of its contents from Subversion and commit. Eclipse will create the directory when it does a build, and you can make the directory in Ant's build file before you compile the code. You should then set an svn:ignore property on the directory parent to prevent people from checking in the classes directory.
If you need to store jar files for other projects to use, use a release repository. In fact, use a Maven repository like Artifactory or Nexus. You don't have to use Maven. Ant can use Ivy to fetch the files from a Maven repository, or you can simply use URLs to download the files as needed via wget or the <get/> task in Ant.
OK, I deleted [build & classes] from local, and deleted from SVN. Made a minor edit to a file, just to be able to run Commit - which worked fine.
That's good.
Both local & SVN were in sync. build & classes are (and were) part of ANT build file, so ran build again. build & classes reappeared (with ? this time), and added to svn:ignore.
Any file that's not in the repository will show up with a question mark. Those question marks will disappear if you add the svn:ignore property to the parent directory with classes, sync, and build in it.
Made another file change, but now I cannot commit the entire project, as I'm getting more/different errors now (e.g. "out of date").
The out of date means that someone somewhere modified a file that was in the repository and committed it. It's very likely that the change is one of the *.class files that you removed. You will have to do an update before a commit. When you do the update, you will likely see a lot of conflicts where a class file was changed, but you had removed it. Resolve these changes, update, and commit again.
By the way, I have a pre-commit hook that is useful in this situation. First, it can prevent people from adding that classes directory to the repository (and any files under it). Second it can make sure that the svn:ignore is setup correctly.

How do I add a basic file version to CVS, then don't commit personal changes to it?

Some development files and resources of a project are checked in to a CVS repository.
Policy states that the version on CVS should build correctly when checked out into a local Eclipse IDE.
Therefore, some files are added that only contain a basic set up.
The developers will change those files to suit their personal needs, but also according to their test environment (containing local paths, etc.).
(I'm not talking IDE configuration here, those files aren't checked in of course.)
CVS won't let me add files to .cvsignore that are already checked in.
How do I maintain a basic version of the files in the CVS repo but have a modified copy in my local working copy that I don't want to commit?
My only solution so far is not committing project or even folder-wise, but only single files excluding those special ones manually. Can I improve on that?
The only improvement you can do to create one point only where you switch configuration in order to minimize the number of files that need customization by developer. For example, if you have Java servlet, you could add something like this
<context-param>
<param-name>configuration</param-name>
<param-value>productionSetup.xml</param-value>
</context-param>
to your web.xml file and then put your setting into that file. In this case, productionSetup.xml will be the official production configuration. William, the developer, will checkout the productionSetup.xml, will do a copy williamEnviroment.xml and will edit his personal settings. To run the servlet with his own configuration, he needs only to change the web.xml in param-value attribute without doing commit on that file.
Of course web.xml can be changed in future to add new parameters or whatever needed by the servlet. William has to manually check if there are new versions of that file, but it's one file only to be monitored and the merge will be trivial.
This answer is partially based on a similar experience I had at work.

How to Properly Use NuGet with Team Development?

So I would like to use NuGet to manage the various projects I use for a specific project my team and I are working on. Up to this point, I have placed my .js library files in the /Scripts directory of my web solution (ASP.NET MVC 2) and referenced those. Of course, this was manual and was annoying to manage during upgrades, etc.
Now that I am using NuGet, I realize that the entire goal of NuGet is to make this fairly painless. In addition, it appears that I shouldn't have to check my packages into my repository (AKA I don't need to manage my external libraries anymore). However, when I grab jQuery (for example) from NuGet, it places its specific files in the /Scripts directory of my project.
Where I get confused - what, if anything, should I check into source control at this point? Do I still check in the /Scripts directory?
In addition, if someone else is working on this project and checks out the solution from source control, are the packages automatically downloaded (assuming the solution comes with a valid packages.config)?
I'm just trying to clarify a couple points before we start using NuGet full-time.
There are two scenarios for NuGet vs VCS: to check-in or not to check-in, that's the question.
Both are valid in my opinion, but when using TFS as VCS, I'd definitely go for a no-checkin policy for NuGet packages.
That being said, even when using a no-checkin policy for NuGet packages, I'd still checkin the content changes that those NuGet packages have done to my projects. The \Scripts folder would be checked-in in its entirety (not selective, not ignored).
The no-checkin policy for packages to me means: not checking in the \Packages folder (cloak it, ignore it), except for the \Packages\repositories.config file.
As such, you are effectively not committing any NuGet packages, and when using Enable-PackageRestore from the NuGetPowerTools (this will be built-in in NuGet v1.6 just around the corner), any machine that checks out the code and builds, will fetch all required NuGet dependencies in a pre-build step.
This is true for both local development machines as for build servers, as long as Enable-PackageRestore is enabled in your solution and points to the correct NuGet repositories (local, internal, external).
If you think about it, when installing a NuGet package that only adds references to some binaries, you'd already be doing the samething in a no-checkin scenario: you would not commit the \Packages folder's subfolders, but still, you'd commit the project changes (the added reference).
I'd say, be consistent (for any type of package), whether it contains binaries only, content only, or a mix. Do not commit the packages themselves, do commit the changes to your sources. (if only to avoid the hassle of looking up what changed content-wise)
NuGet, like Nexus, are artifact repository (artifact being any type of deliverable, including potentially large binary).
The side-effect is for you to not store in an VCS (Version Control System) elements that:
wouldn't benefit from VCS features (branching, merging)
would increase significantly the size of the VCS repository (no delta or weak delta storage)
would be quite hard to remove from a VCS repository (designed primarily to keep the history)
But the goal is for you to declare what you need (and let NuGet fetch it for you) instead of storing it yourself.
So you can version /Scripts as a placeholder, but you don't need anymore to versioned any of its content now fetched automatically.

How to automatically change Eclipse build path when I check out Git branches

I'm using Eclipse Helios and EGit 0.11.3.
I have a project where different branches use different versions of some of the libraries on my Java build path. For example, branch_old uses foo_lib_v1.0.jar while branch_new uses foo_lib_v2.0.jar.
If I'm working on branch_new and I need to checkout branch_old to test something, it's a bit of a hassle: I must manually reconfigure the build path in Eclipse before the project can build successfully.
Is there a way to store Eclipse's Java build path configuration for my project in git, so that when I check out a branch the build path is automatically modified? If not, is there another way to achieve the same result?
Thanks.
I see several choices here:
store project files (.classpath and .project) in Git as part of your branch. This way you would have to store all your dependencies in Git too, which is a hassle if you have a lot of them.
use Maven (m2eclipse plugin) and store project definition (pom.xml) file as part of your version control. Maven will greatly simplify your project dependency configuration
More information on m2eclipse plugin can be found at http://www.sonatype.com/books/m2eclipse-book/reference/
Should work: Put the .buildpath under version control. So its checkouted every time you switch the branches.
AFAIK Eclipse stores his build classpath in a file like .classpath(?) You can just add the file to git and have an own config for each branch.
Define several user libraries in your workspace, such as FooLib1, FooLib2, FooLib2. Then in the project's build path at a given branch reference the appropriate version of the library. Make sure you include project metadata files such as .classpath in your git repository and you should be set.