How to make sure a tycho build doesn't include snapshot dependencies - eclipse-rcp

During a non-tycho release, Maven checks if there are snapshot dependencies in the project being built.
Is there a way to do the same thing with an E4 project, built with Tycho?

p2 repositories don't have a (formal) notion of snapshot and non-snapshot artifacts. So technically you never have snapshot dependencies in a Tycho build, as long as you don't use SNAPSHOT artifacts from Maven repositories via pomDependencies=consider. The latter can be prevented in the same way as in Maven, i.e. by controlling the Maven repositories in your settings.xml (see e.g. this other answer).
But probably this isn't what you are looking for. You probably want to make sure that you don't reference artifacts which will disappear eventually and make your build non-reproducible. For this, you have to check the retention policy of the referenced p2 repositories and make sure that you only reference p2 repositories which are retained "forever". (Example: Retention policy of the Eclipse project p2 repositories.)
If the retention policies are not good enough (or you don't trust the providers to actually stick to them), you need to store copies of the referenced p2 repositories. You can for example download the p2 repositories as zip (or mirror the repository and zip it yourself), deploy it to a Nexus OSS and access it from your build via the Unzip Plugin. (Disclaimer: The Unzip Plugin is an offering of the Tycho project, of which I am a committer.)

Have a look at the Maven Settings References:
Repositories:
releases, snapshots: These are the policies for each type of artifact, Release or snapshot. With these two sets, a POM has the power to alter the policies for each type independent of the other within a single repository. For example, one may decide to enable only snapshot downloads, possibly for development purposes.
enabled: true or false for whether this repository is enabled for the respective type (releases or snapshots).
updatePolicy: This element specifies how often updates should attempt to occur. Maven will compare the local POM's timestamp (stored in a repository's maven-metadata file) to the remote. The choices are: always, daily (default), interval:X (where X is an integer in minutes) or never.
checksumPolicy: When Maven deploys files to the repository, it also deploys corresponding checksum files. Your options are to ignore, fail, or warn on missing or incorrect checksums.
layout: In the above description of repositories, it was mentioned that they all follow a common layout. This is mostly correct. Maven 2 has a default layout for its repositories; however, Maven 1.x had a different layout. Use this element to specify which if it is default or legacy.
I think the setting you're after could approximate the following.
<repository>
<id>my-repo</id>
<name>My Repo</name>
<url>http://my.repo.org</url>
<snapshots>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>

Related

What is default of repository in maven

I am new to use maven to build projects, and IDE I am using is eclipse. For projects I built before, I never used attributes <repository> in POM file and they are running very well.
But when I read some projects in github, they always come with a POM file containing quite a lot of <repository>. After reading maven official website, I know that <repositories> are location to download jar files, but I am able to import all classes only specifying <dependencies> not <repositories>.
My question is why can I download libs without specify <repositories>? Is there a default value for repositories.
Yes there is the Maven Central repository, which is automatically bundled with your pom.xml / settings.xml if you don't specify one.
You usually specify a repo in your pom.xml when you need to access an artifact that your company produces internally, or when you want to reference snapshots or the third-party company you're working with hasn't given their artifacts to Central.

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.

How Does Ivy Work With Version Control 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

non-jar SVN dependency management

Hypothetically there were two software companies, A & B. Both companies have about a couple of hundred Eclipse projects. Both have a few application end-products. Each end-product project has a dependency different from the others.
A relies on maven for dependency management. It practices code freezing and therefore decouples projects from each other and hence is able to mavenize dependencies.
B relies on Eclipse Subversive plugin. For any particular end-product project, all projects it depends on will be checked out of SVN and included in the Eclipse project build path. If a project has dependencies on 50 projects, all 50 projects will be subject to source code modification and that is why they do not use Maven.
The two companies merged into AB. The desire is to have a maven like dependency management that would also work on SVN repositories. That is, the hypothetical POM should be able to specify either jar dependency (company A style) or SVN source-code dependency (company B style). If the dependency is a jar, it should pull the dependency from the repository into the developer's workstation's maven cache. If the dependency is source code in SVN, it should check it out into the SVN working directory.
How should company AB proceed with their vision unifying the two build attitudes, technologically? I specify "technologically" to avert answers that would deal with micromanaging or modifying the philosophical attitudes of developers of the merged company.
Would Gradle be of any help? If so, how and why? What other alternatives?
Presumably the projects that company B created create packaged (jar) products as part of their delivery/build. If this is the case, then company AB could create their own artifact repository (my company uses Artifactory) and the projects from company B could be manually (or automatically) added to that repository as versioned releases or as snapshots. Then company A projects could specify their dependencies as jar dependencies and pull from artifactory.
For projects that are deeply dependent and frequently edited concurrently I'd suggest making them sub-projects of one root project.
None of my suggestions above require the use of Gradle, but Gradle makes much of this easy to implement.
svn:externals are a technical solution. Then educate the developers abusing svn that Maven dependencies are less worse.

Maven local repository in CVS?

I would like to use my CVS as maven repository.. can anyone give suggestions?
There are 2 ways:
a) If you want to use it only in one project place a 'repo' directory at the toplevel. Than add jars in the maven convention (groupid in folders/artifactid/version/artifactif-version.jar).
To use this as a repository declare a file based repository in your pom.
<repositories>
<repository>
<id>some-repo</id>
<name>some-repo</name>
<url>file://${basedir}/repo</url>
<releases>
<checksumPolicy>ignore</checksumPolicy>
</releases>
</repository>
</repositories>
If you use this from a module pom you have to use a url relative to your module pom.
b) if you want to use it for several projects there are socalled 'wagons'. There is one for svn. These maven plugins let you use a SCM as repository. I don't know whether there is a cvs-wagon.
I would not put the dependencies in an SCM system like CVS for many reasons.
Each time you update a dependency in the pom, you need to manually add the corresponding dependency jar - in the exact same folder structure as expected by maven.
You need to worry about transitive dependencies and it can be overwhelming.
Since these dependencies do not change (except if they are SNAPSHOTS), SCM is an overkill for them. Each time there is a new version of the dependency, it needs to be in a different folder structure.
If you want to have control over the dependencies, you could create your own maven mirror using a repository manager. These store the dependencies typically using some content management libraries and can be backed up/archived.
On a related note, Maven Wagon SCM Provider can be used to publish projects to an SCM, but has not been tested with SCM based remote repository.