Much ado about scripting, Linux & Eclipse: card subject to change

Showing posts with label svn. Show all posts
Showing posts with label svn. Show all posts

2011-10-29

HOWTO: See what happened in SVN between builds

I was recently asked how to determine what changed between two builds. Jenkins provides nice interlinks into JIRA (issues), Fisheye (source changes), SVN (sources), but let's say you want to kick things a little more old school and investigate the old way... or the builds you want to compare are no longer shown in Jenkins because they expired and their metadata was automatically purged.

If you can't just look at the changelog in Jenkins to see what revision of source was used for the build, you can check the SVN log to find revision numbers based on the timestamp of the build.

So, if your build was generated on 2011-10-18, you can see that the log shows the last commit before that build was this:

$ svn log http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x/

...

r35735 | bfitzpat | 2011-10-17 15:35:23 -0400 (Mon, 17 Oct 2011) | 2 lines
Changed paths:
   A esb/plugins/.project
   M esb/plugins/org.jboss.tools.esb.project.core/src/org/jboss/tools/esb/core/runtime/ESBRuntimeResolver_410.java

JBDS-1889 - Now checking for juddi-client-3.1.2.jar as well as 3.1.0 and 3.1.1 when seeing if the runtime includes ESB 4.10

...

Want to see actual diffs between that build and the latest one?

$ svn diff http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x/@35735 http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x/

Or, if you want to collect just the section of log relevant to the change:

$ svn log -r35735:HEAD http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x/

Of course if you have all the sources locally, you don't need to log or diff via a URL - you can simply use local file paths. And if like me you use git-svn instead of pure svn, you can use that to diff or log too.

If you want to easily determine when a branch was created and get the SVN revision number for that branch point, use this:

# from r28571, returns -r28571:HEAD
rev=$(svn log --stop-on-copy \
  http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x \
  | egrep "r[0-9]+" | tail -1 | sed -e "s#\(r[0-9]\+\).\+#-\1:HEAD#")

If you'd like to view a specific svn revision in your browser, use !svn/bc/REVISION_NUMBER/ before the branch and path to file or folder:

http://svn.jboss.org/repos/jbosstools/!svn/bc/35735/branches/jbosstools-3.2.x/

2011-01-27

HOWTO: partially clone an SVN repo to Git, and work with branches

Skip to the code

I've blogged a few times now about Git (which I pronounce with a hard 'g' a la "get", as it's supposed to be named for Linus Torvalds, a self-described git, but which I've also heard called pronounced with a soft 'g' like "jet"). Either way, I'm finding it way more efficient and less painful than either CVS or SVN combined.

So, to continue this series ([1], [2], [3]), here is how (and why) to pull an SVN repo down as a Git repo, but with the omission of old (irrelevant) revisions and branches.

Using SVN for SVN repos

In days of yore when working with the JBoss Tools and JBoss Developer Studio SVN repos, I would keep a copy of everything in trunk on disk, plus the current active branch (most recent milestone or stable branch maintenance). With all the SVN metadata, this would eat up substantial amounts of disk space but still require network access to pull any old history of files. The two repos were about 2G of space on disk, for each branch. Sure, there's tooling to be able to diff and merge between branches w/o having both branches physically checked out, but nothing beats the ability to place two folders side by side OFFLINE for deep comparisons. So, at times, I would burn as much as 6-8G of disk simply to have a few branches of source for comparison and merging. With my painfullly slow IDE drive, this would grind my machine to a halt, especially when doing any SVN operation or counting files / disk usage.

Using Git for SVN repos naively

Recently, I started using git-svn to pull the whole JBDS repo into a local Git repo, but it was slow to create and still unwieldy. And the JBoss Tools repo was too large to even create as a Git repo - the operation would run out of memory while processing old revisions of code to play forward.

At this point, I was stuck having individual Git repos for each JBoss Tools component (major source folder) in SVN: archives, as, birt, bpel, build, etc. It worked, but replicating it when I needed to create a matching repo-collection for a branch was painful and time-consuming. As well, all the old revision information was eating even more disk than before:

  • jbosstools' trunk as multiple git-svn clones: 6.1G
  • devstudio's trunk as single git-svn clone: 1.3G

So, now, instead of a couple Gb per branch, I was at nearly 4x as much disk usage. But at least I could work offline and not deal w/ network-intense activity just to check history or commit a change. Still, far from ideal.

Cloning SVN with standard layout & partial history

This past week, I discovered two ways to make the git-svn experience at least an order of magnitude better:

  1. Standard layout (-s) - this allows your generated Git repo to contain the usual trunk, branches/* and tags/* layout that's present in the source SVN repo. This is a win because it means your repo will contain the branch information so you can easily switch between branches within the same repo on disk. No more remote network access needed!
  2. Revision filter (-r) - this allows your generated Git repo to start from a known revision number instead of starting at its birth. Now instead of taking hours to generate, you can get a repo in minutes by excluding irrelevant (ancient) revisions.

So, why is this cool? Because now, instead of having 2G of source+metadata to copy when I want to do a local comparison between branches, the size on disk is merely:

  • jbosstools' trunk as single git-svn clone w/ trunk and single branch: 1.3G
  • devstudio's trunk as single git-svn clone w/ trunk and single branch: 0.13G

So, not only is the footprint smaller, but the performance is better and I need never do a full clone (or svn checkout) again - instead, I can just copy the existing Git repo, and rebase it to a different branch. Instead of hours, this operation takes seconds (or minutes) and happens without the need for a network connection.


Okay, enough blather. Show me the code!

Check out the repo, including only the trunk & most recent branch

# Figure out the revision number based on when a branch was created, then 
# from r28571, returns -r28571:HEAD
rev=$(svn log --stop-on-copy \
  http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x \
  | egrep "r[0-9]+" | tail -1 | sed -e "s#\(r[0-9]\+\).\+#-\1:HEAD#")

# now, fetch repo starting from the branch's initial commit
git svn clone -s $rev http://svn.jboss.org/repos/jbosstools jbosstools_GIT

Now you have a repo which contains trunk & a single branch

git branch -a # list local (Git) and remote (SVN) branches

  * master
    remotes/jbosstools-3.2.x
    remotes/trunk

Switch to the branch

git checkout -b local/jbosstools-3.2.x jbosstools-3.2.x # connect a new local branch to remote one

  Checking out files: 100% (609/609), done.
  Switched to a new branch 'local/jbosstools-3.2.x'

git svn info # verify now working in branch

  URL: http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x
  Repository Root: http://svn.jboss.org/repos/jbosstools

Switch back to trunk

git checkout -b local/trunk trunk # connect a new local branch to remote trunk

  Switched to a new branch 'local/trunk'

git svn info # verify now working in branch

  URL: http://svn.jboss.org/repos/jbosstools/trunk
  Repository Root: http://svn.jboss.org/repos/jbosstools

Rewind your changes, pull updates from SVN repo, apply your changes; won't work if you have local uncommitted changes

git svn rebase

Fetch updates from SVN repo (ignoring local changes?)

git svn fetch

Create a new branch (remotely with SVN)

svn copy \
  http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x \
  http://svn.jboss.org/repos/jbosstools/branches/some-new-branch

2010-11-15

HOWTO: Contributing to JBoss Tools using Git

If you'd like to use Git instead of SVN as your SCM tool of choice, here's how you can connect to the JBoss Tools SVN repo, pull down all the sources, work on them locally, then either commit changes back into the SVN repo (or submit a patch, if you're not already a committer).

The instructions below assume you have either Linux, Mac OSX, or Windows w/ cygwin. If you have none of those, YMMV.

Fetch sources from SVN

First, fetch sources from SVN using git-svn. If you don't want to check out all the components, use a subset of the components listed below. The complete list is here.

# create a directory into which to check out the JBoss Tools projects
mkdir ~/trunk; cd ~/trunk;

# fetch projects - this will take quite some time
# Committers, use http://svn.jboss.org/repos/jbosstools/trunk/
# Contributors, use http://anonsvn.jboss.org/repos/jbosstools/trunk/
for d in \
  archives as birt bpel bpmn build cdi common \
  deltacloud documentation download.jboss.org drools \
  esb examples flow freemarker gwt hibernatetools \
  jbpm jmx jsf jst maven modeshape portlet profiler \
  requirements runtime seam site smooks struts \
  tests tptp usage vpe ws xulrunner; do \
    git svn clone http://anonsvn.jboss.org/repos/jbosstools/trunk/${d};
done

Configure Eclipse

Next, fire up Eclipse Helios 3.6 for Java EE Developers.

Install the latest eGit from http://download.eclipse.org/egit/updates.

Install the latest m2eclipse from http://m2eclipse.sonatype.org/sites/m2e/ and optionally, http://m2eclipse.sonatype.org/sites/m2e-extras/.

Restart when prompted.

Import Git projects into Eclipse

Now, import Git projects into Eclipse using:

File > Import 
    Git > Projects from Git
        Click 'Add' then browse for ~/trunk/ 
        Enable [x] Look for nested repositories 
        Click 'Search', then click 'OK' when done

        Select a local repo from the list, click 'Next'
        (*) Import Existing Projects
        (*) Try to share automatically
        Click 'Next'
        Click 'Select All', then click 'Finish'

Repeat for other components you want to import. You can add each component to a working set to keep your workspace sorted by component.

Resolve missing dependencies

While the Eclipse Helios 3.6 for Java EE Developers contains most of the dependencies against which JBoss Tools must be compiled, it does not contain everything. For that, you need to install extra dependencies. There are two places to go:

  1. JBoss Tools Target Platform p2 Repo (also available as an archived update site zip for offline use) - contains all the Eclipse.org, google.com, and sonatype.org features needed to compile / install all of JBoss Tools. You can install everything, or just the pieces you need.
  2. JBoss Tools Nightly Repo (Update Site) - if you don't have all the source projects in your workspace, you can resolve dependencies against this site and install them from here. Once again, you can install everything, or just the pieces you need.

Build & run tests

With m2eclipse installed, you can simply right-click a project and select 'Run As > Maven Build (ALT-SHIFT-X, M)', which will prompt you complete a run configuration dialog. Here are the simplest options you need to set:

   Goals: clean install
   [x] Resolve Workspace artifacts

You can also run Maven to build your projects outside Eclipse, if you prefer.

If running outside Eclipse, you can run tests which are still tied to the Eclipse debugger.

Commit changes to master repo

Because there's no support yet for 'git svn rebase' or 'git svn dcommmit' you're stuck pushing changes to the master repo using the commandline. However, you can shorten the amount of typing needed using an .alias file. See below.

Use an .alias file

To avoid having to type the same git commands over and over, I use these shortcuts in my ~/.alias file:

# update local git-svn repo from master SVN repo
alias   gitup='for d in $(find . -maxdepth 1 -type d); do cd $d; echo $d; if [[ -d .git ]]; then git svn rebase; fi; cd -; done'

# Push local changes to master SVN repo
alias   gp='git svn rebase; git svn dcommit'

# commit local changes to local git-svn repo
alias   ci='git commit -m'

# check status of local git-svn repo
alias   stat='git status'

So, after committing changes (with eGit or via commandline) I can push those to the master SVN repo w/ a simple 'gp'. If your shell doesn't read the .alias file, make sure your .bashrc loads the file using one of these commands:

source /home/yourUserName/.alias
. /home/yourUserName/.alias
Or, put them directly in your .bashrc file.

2010-11-03

Git vs. SVN - Basic Commandline Syntax Reference

Learning the git workflow takes a bit of brain retraining, but since I've been using SVN almost entirely via commandline (because Subversive sucks and locks up my Eclipse when I try to use it for anything beyond synching/updating/committing a handful of files), adopting git's commandline syntax is reasonably similar. Consider these simple operations:

Initial checkout from existing repo for a given branch git clone http://github.com/sonatype/sonatype-tycho.git; cd sonatype-tycho; git checkout origin/tycho-0.10.x svn checkout http://anonsvn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.0.Beta1/
Update locally checked out files from central repo git pull svn update
List locally changes files/folders git status svn stat
Diff locally changed file git diff somefile.txt svn diff somefile.txt
Revert locally changed file* git checkout somefile.txt svn revert somefile.txt
Revert ALL local changes (except untracked files)* git reset --hard HEAD svn revert . -R
Add new file git add file.txt svn add file.txt
Add new folder recursively git add folder svn add folder
Delete file git rm file.txt svn rm file.txt
Delete folder git rm -r folder (non-recursive by default; use -r to recurse) svn rm folder (recursive by default; use -N to not recurse)
Commit changed file to central repo git commit -m "message" file.txt; git push svn ci -m "message" file.txt
Ignore files/folders (in the current folder) echo "target
*.class
bin" > .gitignore; \
git ci -m "gitignore" .gitignore
svn propset svn:ignore "target
*.class
bin" .; \
svn ci -N -m "svn:ignore" .

Obviously you can do a lot more w/ Git than with SVN (like stashing local changes temporarily), but for the sake of simply moving from a VCS to a DVCS and being able to continue to work the same way you already do, the above table should provide a good introduction.

2010-10-01

JBoss Tools: making it easier to build against a complex target platform

So you want to be a JBoss Tools developer? Awesome. Welcome to the family. SVN sources are here, JIRA's over here and there's cold beer in the fridge*.

But you say it's a pain in the tuchus to download over 25 zips or add a whole bunch of update sites and hope you get everything you need? Yeah, no argument there. If only there was an easier way to resolve all the dependencies you need to get building, much less to even RUN this stuff.

To make this process simpler, I've created a p2 repo (update site) from our target platform file, which has been recently updated to include Helios SR1 dependencies. You can track subsequent work in progress here: JIRA JBIDE-6982. You can also report any issues there too.


So, now, just add this single site** into your vanilla Eclipse 3.6.1 Classic (or a Helios SR1 bundle), uncheck the box for 'Group Items by Category' and you can install everything listed. For great justice.


Some handy links:


Some handy HOWTOs:


* - Due to beer2peer limitations, YMMV.

** - I'm aware that the update site throws a 403 if you open it in a browser. I can't be arsed to generate an index.html just yet, nor are there categorized features. Because really, you don't need either - this site is only meant to be used by p2.

2010-05-25

My love-hate with SVN, Part 8: Installation Ease Of Use (UPDATED)

Back in July 2009, I blogged about My love-hate with SVN, Part 6: Installation Ease Of Use. With Helios just around the corner, I wanted to produce an updated repo for use with the latest & greatest Eclipse 3.6.

Now the <p2.mirror/> script will fetch and use Ant-Contrib automatically.

Here's the updated 15M update site zip, which includes the following:

Subversive 0.7.9
SVN Connector 2.2.2
SVNKit 1.3.3
JNA 3.2.3
ECF 3.1.0
Any problems, please report them in bug 284077.

2009-12-04

Feeding The Right Sources To Your Builds

I was recently asked the best approach for how to control the input to one's builds, and while there is no single solution to this that fits all projects, here are two ways you might want to go.

Freeze Then Branch

The current approach for JBoss Tools development involves continuous nightly builds from trunk until such time as the project is deemed frozen in prep for an upcoming milestone or release candidate. At that time, the trunk is copied to branches/JBossTools-3.1.0.M4, and very little is done to that branch - only urgent tweaks and fixes. A new Hudson job is cloned from the current one, and adjusted to point at the branched sources instead of trunk. The maps are also updated to point at the new source location in SVN.

This allows more nightly builds towards an upcoming stable development milestone, while new development can continue in parallel in trunk. When the milestone is released, the unneeded job is disabled or removed.

The only issue with this approach is that all plugins, built from the head of a branch (or trunk) are re-versioned w/ the latest timestamp every time they're compiled. Thus upgrading from one 80M update to the next requires another 80M download. To mitigate this, milestones are released only once every month or two.

Tag And Release

The current approach for numerous Eclipse.org projects, such as GEF, is to develop continuously in HEAD and when a number of changes are ready to be released, a tool such as the org.eclipse.releng.tools plugin can be used to, in a single operation, both tag the sources and release those tags into the map file.

This permits a granular approach to plugin versioning wherein only the plugins which have actually changed are renumbered, and thus incremental updates between releases is possible, and if only a single plugin changes from week to week, only that plugin will be upgraded.

This approach also allows your adopters to get more stable, weekly updates rather than hourly or ad hoc nightlies which may include incomplete changes. Sure, you can only watch for good builds in Hudson, but a more predictable schedule makes inter-build communication easier.

The only issue with this approach is that it introduces extra overhead, unless the tag&release process can be automated and run on a (weekly?) schedule. For CVS sources, there is the org.eclipse.releng.tools.tagandrelease crontab script available; for SVN, no such script (yet) exists. Want to help? See bug 264713.

Hybrid Approach

With the Athena Common Build, you can set up a Hudson job to run from tagged maps, but also override those tags on demand to force a build from head (or trunk) instead of from the specific repo tags.

To do so, pass in the following flags to EXTRAFLAGS via your build's job configuration / parameters. To build from the workspace's sources instead of fetching anything new from the repo (bug 252774):

-localSourceCheckoutDir /opt/users/hudsonbuild/.hudson/jobs/${JOB_NAME}/workspace/

To fetch from the repo, but ignore tags (bug 251926):

-forceContextQualifier -fetchTag HEAD

Or, like many projects on build.eclipse.org have done, set up two jobs: one for nightly from trunk, and one for weekly integration from maps. Then instead of doing CI builds when you remember to, they will run automatically when the repo changes so you'll have immediate feedback when something has broken. Add email, IRC, or Twitter notification to the job, and everyone else will know too.

2009-10-13

Dash Athena News, Oct 2009

Have you heard the latest? Here's what's been going on in the Dash Athena project lately.

Infrastructure Changes

  • There are now 43 Athena jobs on build.eclipse.org! Of those, 30 are green, 1 is yellow, and 6 have not yet been enabled. These jobs represent 29 different projects' builds! 6 of them use SVN sources instead of CVS.

  • bug 257074 comment 12 build.eclipse.org now has SVN 1.6.5; if your map files no longer work (your build complains it can't resolve plugin or features sources) then read this.

New Features

  • bug 291446 Provide hook for extra actions after fetching code from repo and before compiling it (e.g. code generation, parser generators, etc.)

  • bug 275529 Athena is now a full Project rather than a Component! Now if we could just get someone to design a logo... Do I need to offer up prizes? I will, if you comment on bug 272723 with some design ideas (or prize ideas).

Better Documentation

See also Older New & Noteworthy.

2009-09-07

Re-Return to Athena

Thanks to Miles for taking the time to slap Athena into submission on his local system - frequent and regular stress testing is what's going to make this facade over PDE bridge the gap between today and the far-flung future (namely B3).

Because he took the time to itemize his concerns / problems / gotchas, I thought I'd take the time to explain why these happen... and which are bugs vs. features. Speaking of bugs and features, Athena has a handy New & Noteworthy wiki page which I update about once a month. If you've never seen the N&N, it's here.

# skipPack=true is useful if you want to test locally. I found that the update manager does not work with pak'd jars when running locally. Perhaps P2 is relying on something on the web server side..?
If p2 isn't properly unpacking pack'd jars, the problem is either: you're using a JDK with pack200 bugs (like Sun 1.6), or you have jars which should never be packed. How can you exclude jars from packing? See JarProcessor Options.
# The build scripts appear to be simply searching for the occurrence of strings to determine wether a given map entry type is being used. They do not appear to respect the comment lines. I guess I should file a bug report on this one -- it cost a bit of time because I have a dodgy SVN setup on my home laptop. I'm actually still not sure what is going on with that (and does the mysterious Java 134 error msg have anything to do with it) but I'm trying to learn not to fix things for which I have a work-around, i.e. if ti works on a different machine, just use that instead!
The purpose of the collectMapTypes task is to simply know what types of maps are being used so that warnings can be echoed to the user if appropriate. If you use SVN on linux, there's a good chance you'll get this message:
[echo] If you get a SIGSEGV or Java Result: 134 when fetching from SVN, remove 
[echo] subversion-javahl and svnkit to force PDE to use commandline svn client.
Why? Because it's a pain in the butt to debug, and at least having a message in the build log gives you some tea leaves to read. I favour documentation over performance in this case.
# There is a somewhat lengthy description at http://wiki.eclipse.org/Common_Build_Infrastructure/Getting_Started of how to setup your local build to use a local cache CVS site but I'm not sure what scenario that would really be helpful in. I just use COPY and it works fine. I suppose that using the CVS approach might excercie some issues that you wouldn't run into with a plain COPY. And I'm not sure wether the local build copies over the binary files or not. If it does, you could get different build results if say your local environment happens to place some artifacts in the copied directories that aren't cleaned out by the PDE build. Not going to worry about it!
A more useful scenario is to take a dump of a CVS, SVN, or Git tree, and point your build at that folder using localSourceCheckoutDir=/path/to/full/source/tree/root in your build.properties file. Then it'll build against that local source cache instead of having to fetch from the repo. Once you have the dump of the repo, from Eclipse do File > Import > Existing projects, and you can have those same projects compilable/editable in your workspace. You can also use Eclipse (eg., with Subversive, Subclipse, eGit) to update the cache before doing a build.
# A useful hack when building locally is to pack up your difficult dependency(s) into a zip file and refer to them in your dependencyURL. It doesn't matter what you use for the URL, because it will use the cached file instead. For example, GEF3D doesn't yet have a build or update site. (We've been collaborating a bit on this so hopefully the build I've got working will help them get one up soon.) So instead of solving the the SVN stuff right away, I put that off until everything else worked. So I created a zip and added an entry for http://download.eclipse.org/tools/gef/fake/gef3d.zip. You have to be careful to have your zip file packaged up correctly or it won't work. That's easy to get wrong..your file structure needs to conform to the standard structure, i.e. eclipse/plugins/some.plugin. On the other hand, you have to be careful to remove these fake dependencies when you begin testing the real fetched versions! The fetch part then fails silently; your build succeeds but using the previously downloaded files.
I generally add comments (TODO, FIXME) in my build.properties to mark temporary hacks, or use a new file, like build.properties.local.hack so I'm not breaking the server-friendly version. (Just make sure you tell build.xml which build.properties file to use, if not the default one -- and DON'T CHECK IN the changed file.)
# But in any case getting the SVN map file right has been a major headache. Again, the only reason I want this is to grab the GEF3D sources, but I can't seem to let this one go as it seems that it should be so easy. The Athena build seems to mangle things in the fetch script; or perhaps this is a PDE Build issue. So I tried the sourceforge style entry and after a couple of hours of fiddling (see below) I found a magic incantation that seems to work -- plugin@org.eclipse.draw3d=SVN,trunk,http://dev.eclipse.org/svnroot/technology/org.eclipse.gef3d,,org.eclipse.draw3d@HEAD
@HEAD is optional; you only need to specify a tag if it's not the HEAD of the branch or trunk. Here's a sample SVN map.
# It would be super nice if there were a built-in dependency analyzer so that one could find the root plugin issues easily. As it is, if you have a bad dependency you get the whole tree and you have to walk the tree by hand to find out the root cause. Overall I think this is another demonstration of the ultimate weakness of the standard build systems out there. They are by nature linear (batch) approaches and so usually you can't do post hoc or inline analysis of issues. There is no semantic information in logs! You end up having to parse them back if you want to do any useful analysis. In a parallel lifetime, I would love to work on a simple semantic logging system that would allow structured analysis of this sort.
I believe the Buckminster guys are doing work in this area, so this may make its way into B3.
# Here is something else that I would love to do given time. The map files are pretty well structured - it would be nice to whip up a quick XText editor that would at least check syntax and more ambitiously provide a mechanism for hooking in semantic checks -- wouldn't it be nice if you could check that that SVN url is correct while editing the map file itself?!
Add that to the wishlist for B3!
# I'm still not sure how Athena determines what goes in the sdk vs. runtime vs. example zips so for now I'm just building the examples manually. Anyone come across documentation for this?
This arbitrary allocation of files is done in common.releng/tools/scripts/buildAllHelper.xml, lines 1063-1097, and is only done if the build.steps entry 'buildZips' is enabled. This behaviour is as far as I'm concerned deprecated, but in place simply to ease transition for existing builds using the old Common Modeling Build to the Athena Common Build. IMHO, no one needs these zips - you only need an update site zip. If you don't like what's in the zips, you can omit the 'buildZips' step and package your own zips by hand, eg:
 <zip destfile="${buildDirectory}/${buildLabel}/${SDKZip}" update="true">
   <zipfileset src="${buildDirectory}/${buildLabel}/${allZip}" dirmode="775" filemode="664" excludes="**/*.pack.gz, **/pack.properties, **/features/*.jar, **/${domainNamespace}.*.all*, **/${domainNamespace}.*.all*/**" />
 </zip>

(For those unfamiliar with the story of the Re-Return, you need to watch HIMYM, S1E15.)

2009-07-21

My love-hate with SVN, Part 7: Setting svn:ignore properties

If you've inherited code where someone has accidentally committed *.class files, here's how you can find those bin/ folders, wipe them out, and hopefully never see them in the Synchronize view again.

Sure, you could use Team > Add to svn:ignore... on a file or Team > Set Property... on a folder in Eclipse using Subversive, but this is faster and less clickity-click.

for d in $(find -maxdepth 1 -mindepth 1 -type d ~/workspace/ -name "org.eclipse.*"); do
  pushd $d
  svn up
  svn propset svn:ignore "bin
bin/*" .
  svn propget svn:ignore . 
  svn propset svn:ignore "*.class
*/*.class
**/*.class" bin
  svn propget svn:ignore bin
  cd bin
  rm -fr *
  svn delete org
  svn delete model
  # find other deleteables with `svn status`
  cd ..
  svn ci -m "svn:ignore"
  popd
done

2009-07-20

My love-hate with SVN, Part 6: Installation Ease Of Use

For months I've been annoyed by the fact that installation of Subversive (or Subclipse) requires fetching features and plugins from 3 or more update sites. No more!

Today, as an exercise to learn how to use the <p2.mirror/> task and provide a reproduceable, offline way to get Subversive into a virtual machine, I've created an update site zip, complete with site.xml and p2 metadata, which can be used to install Subversive from a single source. Here's the Ant script if you'd like to try this at home.

Because let's be real: you can only complain so long before it's time to roll up your sleeves and pitch in, right? That's how open source survives - thanks to people who care enough to complain AND care enough to help.

Here's the 13M update site zip, which includes the following:

Subversive 0.7.8
SVN Connector 2.2.1
SVNKit 1.2.3
JNA 3.0.9
ECF 3.0.0

Any problems, please report them in bug 284077.

2009-07-16

Tracking Build Status With Hudson Data APIs

A number of people have been twittering recently about Hudson Helper, and the fact that it can't (yet) support http access to Hudson servers. (There's just no pleasing some people, eh David?)

UPDATE: David reports that Hudson Helper has worked with both http and https since day one. He invites direct feedback if you're having problems.

To help fill this gap, I'd like to detail some of the handy API features of Hudson I've discovered since I first started using it back in October, which cane be fetched via http (or https) in a browser or via a script.

Datum Example
Latest Successful build number buildNumber
Latest Successful zip (published artifact) GEF-Update-*.zip
All checked out Project Set Files (Hudson workspace) *.psf
XML Digest of Latest Stable Build lastStableBuild/api/xml
SVN revision used for Latest Stable Build //changeSet/revision/revision

For more on the APIs available to the Latest Successful, Stable, Failed, or in fact simply the Latest Build, see:

  1. /lastSuccessfulBuild/api/
  2. /lastStableBuild/api/
  3. /lastFailedBuild/api/
  4. /lastBuild/api/

Of course, should you want details on a specific build rather than the latest, you can replace the "last*Build" token with an actual build number.

Finally, because no post about APIs should be complete with out some script showing how to exploit that interface, here's a quick example of how to fetch the latest successful, and as yet unreleased Drools 5.1 runtime library zip for use in our JBoss Tools 3.1.0.M2 builds. In this example, we fetch the build number for the last successful build and compare it to a cached version. We also fetch and cache the latest SVN revision number (in a build.properties file) so that we can later fetch Drools sources from the same point in time as the precompiled Drools binaries in the zip. This guarantees we're building from trunk, but only a good build in trunk, skipping over any failed builds or intermediate states (partial commits).

#!/bin/bash
droolsSNAPSHOTnum=drools-SNAPSHOT-num.txt
droolsSNAPSHOTrev=drools-SNAPSHOT-rev.txt
droolsSNAPSHOTzip=drools-SNAPSHOT-bin.zip
droolsSNAPSHOTurl=http://jboss-hudson-server/hudson/job/drools/lastSuccessfulBuild/artifact/trunk/target/drools-5.1.0.SNAPSHOT-bin.zip

buildNumOld=0; if [[ -f $droolsSNAPSHOTnum ]]; then buildNumOld=$(cat $droolsSNAPSHOTnum); fi
buildNumNew=$(wget -q --no-clobber -O - http://jboss-hudson-server/hudson/job/drools/lastSuccessfulBuild/buildNumber)

buildRevOld=0; if [[ -f $droolsSNAPSHOTrev ]]; then buildRevOld=$(cat $droolsSNAPSHOTrev); fi
buildRevNew=$(wget -q --no-clobber -O - http://jboss-hudson-server/hudson/job/drools/lastSuccessfulBuild/api/xml?xpath=//changeSet/revision/revision)

if [[ $buildNumNew -gt $buildNumOld ]]; then
 # get: 27013; must change to 27013 
 echo $buildRevNew > $droolsSNAPSHOTrev;
 sed -i "s#\|##g" $droolsSNAPSHOTrev 
 buildRevNew="$(cat $droolsSNAPSHOTrev)"; #echo "."$buildRevNew"."
 # replace "defaultTag=trunk:\d+" with defaultTag=trunk:${buildRevNew} in build.properties
 #  defaultSvnUrl=http://anonsvn.jboss.org/repos/labs/labs/jbossrules
 #  defaultTag=trunk:27013
 sed -i "s#defaultTag=trunk:\d\+#defaultTag=trunk:$buildRevNew#g" build.properties; # grep "defaultTag=trunk:" build.properties 

 echo $buildNumNew > $droolsSNAPSHOTnum; 
 echo "Download $droolsSNAPSHOTurl ..."
 wget -q --no-clobber -O $droolsSNAPSHOTzip $droolsSNAPSHOTurl 

 # ...

fi
Oh, and BTW, if you're ever looking for the latest hudson.war executable, it's always here.

2009-07-07

My love-hate with SVN, Part 5: Fedora 11 + Eclipse 3.5 + Subversion 1.6

Finally figured out how to make Eclipse 3.5 play nicely on Fedora 11 w/ Subversion, and I owe this bit of knowledge to our new MacPro. *sigh*

I also owe a great deal of gratitude to Cloudsmith for providing their Cloudsmith Galileo+ repository, which includes these features:

I still wish the version numbers would better align, in that I have to install the SVN Team Provider v0.7.8 with the SVN Connector v2.2.0 and the SVNKit 1.3.0 implementation v2.2.0 to make all this work with Subversion 1.6. Oof.

2009-06-25

My love-hate with SVN, Part 4: Corrupt Metadata & Going Over Quota

Ever had one of those days where nothing seems to work? Most of June's been that way for me...

This week I decided to trust my OS and let Fedora update me automatically to the latest release, Fedora 11. I've never tried a distribution upgrade; in the past I've only ever done a clean install (be it Windows, Ubuntu, MEPIS, AntiX, or Fedora). But I figured if @dougschaefer could do it, so could I.

It was fairly smooth sailing, though the handy gui tool preupgrade only downloaded packages but didn't do the upgrade, so on reboot (still in F10) I had to run preupgrade-cli "Fedora 11 (Leonidas)". I suspect I must have fatfingered my hard drive password when I rebooted he first time because it worked like a charm the second time. Overall, way more successful than attempts so far to make a Mac Pro get Fedora'd, thatsfersure (grub, video, and network card issues, to name but a few).

Anyway, now I have updated versions of subversion and python, and as a result, my Subversive projects in Eclipse don't work. After much cursing and experimenting (and updating my CollabNet Subversion version to 1.6.3, the solution seems to be simply this:

Check out the projects anew within Eclipse, and if necessary, diff local changes from old project to new project.

But, if the project is too big (jbosstools trunk folder is over 1.1G) you may get a heap error. You can check the whole project out via commandline, but Eclipse (or Subversive? or Mylyn?) uses too much memory and the whole thing dies, despite my running Eclipse w/ a half-gig of heap:

/home/nboldt/eclipse/eclipse/eclipse -clean \
  -showLocation -data /home/nboldt/eclipse/workspace-jboss \
  -vmargs -Djava.library.path=/opt/CollabNet_Subversion/lib \
  -Xmx512M -XX:PermSize=512M

In this case, the solution is to check out the project without recursing into folders.

Commandline on in the Console view, that looks like this:

svn checkout "https://svn.jboss.org/repos/jbosstools/trunk@HEAD" -r \
  HEAD --depth empty  "/home/nboldt/eclipse/workspace-jboss/jbosstools-trunk"

You can then copy stuff you already checked out into the new target project, then refresh the project in Eclipse. Of course in my case Eclipse then thought all the files were new, so I had to Override and Update from the repo.

Another 24374 files or 1.1G to download. No wonder I went over my quota this month!

(Really, it was due to several different .iso torrent downloads for Fedora and CentOS, along with the movie Dead Alive, just in time for BLITEOTW day!)

So, unfortunately, I haven't been able to enjoy any of the 33 projects in this years' Eclipse Galileo release, unlike others on the Planet and the BirdsNest have. Hopefully next month will see calmer seas.

On the plus side now that I'm running Fedora 11, I can use Delta RPMs thanks to the yum-presto plugin... so next month's bill should be much, much smaller.

2009-05-04

Git 'Er Done

The discussions in bug 257706: Host a git repository on Eclipse Foundation servers, support git as the repository of Eclipse projects rages on, wind blowing in both directions.

Let's look at the objections to Git @ Eclipse:

Implementing a common build infrastructure would also be complicated by additional code repositories as well.

Not true; the Athena system already supports CVS and SVN, plus a "build from local sources" mode which works w/ a cvs/svn tree dump, a workspace w/ checked out projects, or (TBD, we haven't tested this yet) with a git repo. And we have an open bug to make repo tree structure irrelevant to the local checkout mode. Party on. There is even a Git plugin for Hudson so you can use Hudson to watch your repo for changes, like it does with CVS and SVN.

Can't use unapproved or non-EPL code at Eclipse.org

Not true; from discussions w/ legal@eclipse.org, I've been told at least twice that as long as you're not SHIPPING code that falls under a non-EPL or non-approved-CQ you're entirely fine to USE that code as server-based infrastructure. Rock on.

Cannot include tooling in a release train or host its project at Eclipse.org

Not true; since eGit is EPL and jGit is BSD, I don't see a problem with distributing the tooling that would connect to a Git repo hosted at Eclipse.org. We worked around the license woes for SVN tooling support. We can do it again. (Of course IANAL, TINLA.)

Conclusion:

No legal concerns with use of Git as hosted server infrastructure. Dash Athena (Common Builder) will support Git. Tooling is safe for inclusion in release trains (either fully like CVS is or partially like SVN is).

Only remaining issue is therefore to get it installed and allocate resources to support/manage it. With all the erosion going on lately, this need should not be trivialized.


Before the thaw this spring, this tree was on top of the bluff. With nothing to support it, it was dropped like an unchampioned feature request.

However, in the spirit of open source, several people on the above bug have offered to help w/ setup, testing, support, etc. So the burden here will be shared, like many things at Eclipse (eg., Babel, Hudson). Erosion continues, but we can all help to shore up the loss.

As most people prolly already know, Sourceforge supports the whole spectrum of VCS and DVCS options. If we don't want people to host projects there, Eclipse has to at least offer something from the DVCS world to encourage participation here. Keep the barrier to entry high, and people will go elsewhere. Lower the barrier, and people will come here to party instead.

With everyone feeling the economic- and time-pinch these days, can we really afford to discourage contributions at Eclipse simply because, as the silverbacks say, "why, back in my day, we only had CVS, vi, and notepad, and dangit, that was good enough!" ?

After all, the new world is inevitable.

2008-12-04

My love-hate with SVN, Part 3: CollabNet Subversion (JavaHL)

Installing Subclipse w/ JavaHL (aka CollabNet Subversion)

  1. Download CollabNet Subversion for your operating system (Linux, Windows, MacOS X). This provides the JavaHL layer so that Subclipse can talk to SVN repos using pure Java (but not SVNKit). Install it.
  2. Download Eclipse 3.4.1 (or Fedora Eclipse). Start it up, making sure to pass in -Djava.library.path=/opt/CollabNet_Subversion/lib (linux only).
  3. Help > Software Updates... > Available Software > Manage Sites... > Add... > http://subclipse.tigris.org/update_1.4.x
  4. Install the whole site. Restart when prompted.
  5. Window > Preferences > Team > SVN > SVN Interface > Client > JavaHL (JNI)

Well, I feel I've been remiss in ranting about Subclipse. Turns out a fresh Eclipse + a fresh install (and a lot of trial and error / googling has fixed things.

You have not exactly given us a chance to help you with your Subclipse issues.
Mark, you're right, Subclipse does work -- it's just not the most straightforward thing to install. And when it breaks suddenly and for apparently no reason, losing hours of productivity to fighting w/ source control instead of writing and committing code, it's VERY frustrating, especially considering that Eclipse's CVS support Just. Works.
Does the JavaHL library exist in the folder you pointed to?
Well, given the wiki doesn't actually say what file(s) are supposed to be there, I had to guess. I have /usr/share/java/svnkit-javahl-1.1.4.jar and /usr/share/java/svnkit-javahl.jar (a symlink to the previous). Is that what Subclipse / Subversive are looking for? No idea.
Do the preferences say "Not available"?
They do. After much surfing, googling, testing, registering to download, waiting for a password, cursing, downloading and rpm -i ... I finally figured out that all I needed to do was get CollabNet Subversion Command-Line Client v1.5.4 (for Red Hat Linux), and (as noted in the wiki), add -Djava.library.path=/opt/CollabNet_Subversion/lib to my Eclipse startup. Could you save others this search by linking to the downloads page from the wiki? Or even linking to it from the Downloads page??
I think somehow an old version of their JAR is being loaded by your Eclipse and not the one in their plugin. Do you have their JAR installed in your Java extensions folder or something?
Reinstalling Eclipse and purging some jars of unknown pedigree & version seems to have worked. I have svnkit 1.1.4 in the above folder (/usr/share/java), and org.tmatesoft.svnkit_1.2.0.4949 in a linked folder in my dropins/.
Finally, as to your History error, Subclipse does not have this problem, but I know the cause. Your history view is setup to "Show Merged Revisions". I would assume that Subversive exposes this as an option in the UI that you can turn off. That is what we do in Subclipse.
I expected to find this as an option under Window > Preferences -- some digging showed me that, no, it's under the view's menu > Include Merged Revisions. Thanks for the tip!
Anyway, we also catch that exception when talking to older Subversion servers and just make the request again without asking for the merged revisions. If you have not already filed a bug report with Subversive you probably should.
Good idea -- see bug 257669. I just want something that will work, won't crash Eclipse, won't freeze up during an update, won't leave dozens of "not really there" files in my Synch view (that magically disappear when I click the 'collapse all' button in the view), won't throw errors when I try to look at file histories.

So, for the moment, I'm back to Subclipse. I've upped the permgen and heap for Eclipse to 400M and things are working again. Seems large projects + SVN = crashing/freezing/OOM errors. Maybe JavaHL won't be so greedy? We shall see.

2008-12-03

My love-hate with SVN, Part 2

The love-hate continues...

  1. Show History operation failed
    *** Show History
    svn: Retrieval of mergeinfo unsupported by 'https://svn.jboss.org/repos/devstudio/trunk/releng/org.jboss.ide.eclipse.releng/hudson/build.sh'
    *** Error (took 00:00.743)
    
    *** Show History
    svn: Retrieval of mergeinfo unsupported by 'https://svn.jboss.org/repos/devstudio/trunk/releng/org.jboss.ide.eclipse.releng/hudson/build.sh'
    *** Error (took 00:00.795)

    This is particularly fun because the error comes up twice, and keeps coming up as long as you have the History view shown. Solution? Time to switch back to Subclipse? No, I tried that, and despite adding -Djava.library.path=/usr/share/java to my Eclipse startup, I still can't use Subclipse anymore.

Oh, well... there's always kdesvn:

2008-12-02

My love-hate with SVN

Since joining JBoss, a division of Red Hat, I've gotten to know the foibles of SVN rather intimately. Here are my two favourites, both encountered this week:

  1. This client is too old to work with working copy; please get a newer Subversion client.
    Problems reported while synchronizing SVNStatusSubscriber. 2 of 3
    resources were synchronized.
    An error occurred synchronizing /devstudio-workspace: Error
    getting status for resource P/devstudio-workspace
    org.tigris.subversion.javahl.ClientException: svn: This client is
    too old to work with working copy; please
    get a newer Subversion client

    This happens if you use SVN 1.5.4 and Subclipse 1.4.6 with SVNKit & JavaHL plugins. Solution? Switch to Subversive 0.7.5, or follow this advice (so I'm told, I haven't tried yet).

  2. Installing subversion-javahl-1.5.4-3.i386 (on Fedora 10 Rawhide) causes Ant 1.7.1 to fail to do SVN checkouts.
    (from /var/log/yum.log)
    Nov 27 19:51:47 Installed: subversion-javahl-1.5.4-3.i386
    [java] fetchElement:
    [java] #
    [java] # An unexpected error has been detected by Java Runtime Environment:
    [java] #
    [java] #  SIGSEGV (0xb) at pc=0x05984ec5, pid=24986, tid=3086982032
    [java] #
    [java] # Java VM: Java HotSpot(TM) Server VM (11.0-b15 mixed mode linux-x86)
    [java] # Problematic frame:
    [java] # C  [libapr-1.so.0+0x1fec5]  apr_threadkey_private_get+0x15
    [java] #
    [java] # An error report file with more information is saved as:
    [java] # /opt/public/jbt-jbds/nightly-20081128-0002/org.jboss.ide.eclipse.
             releng/builders/hs_err_pid24986.log
    [java] #
    [java] # If you would like to submit a bug report, please visit:
    [java] #   http://java.sun.com/webapps/bugreport/crash.jsp
    [java] # The crash happened outside the Java Virtual Machine in native code.
    [java] # See problematic frame for where to report the bug.
    [java] #
    [java] Java Result: 134
    (from /var/log/yum.log)
    Dec 02 11:19:23 Erased: subversion-javahl

    And now it works again!