Ubuntu 9.10 (Karmic Koala) has a little issue with Midnight Commander – it does not browse into zipped files, and shows empty contents instead. After searching the web I found out that the problem can be solved by setting property “op_has_zipinfo” to “1″ in file “/usr/share/mc/extfs/uzip”. For the truly lazy people I prepared this little commandline fixing that (no need to open the editor):
sudo sed '/op_has_zipinfo/{s:0:1:}' /usr/share/mc/extfs/uzip >x && sudo chmod 755 x && sudo mv x /usr/share/mc/extfs/uzip
Enjoy!
It’s quite a common situation that you have a bunch of files, most or all of them committed in svn, and need to make a release of this so that it can be reused with the Maven’s dependency mechanism.
There are several ways how to accomplish that:
- use maven-assembly-plugin
- use maven-antrun-plugin to build and build-helper-maven-plugin to attach
- create custom plugin that handles both packaging and attaching
Each of them has its advantages in some situations, but my favorite is the second option for most cases.
Real life example – artifact with various svn output files
In some of my projects, I need to check that the code works properly with xml output files from Subversion. I could easily put such files among test resources, but the it would be there many times, and I would always have to check if it is “representative” enough etc.
So I decided to create a module, which will create the data during its build (see the maven-antrun-plugin).
These data are packaged into a zip file which is then marked as output artifact with type “zip” (see the build-helper-maven-plugin).
Look at this pom excerpt (complete pom.xml is available here):
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>net.sf.buildbox.testdata</groupId>
<artifactId>svn-mvn-testdata</artifactId>
<version>1-SNAPSHOT</version>
<packaging>pom</packaging>
...
<build>
<outputDirectory>target/output</outputDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
... phase=package, goal=run
<configuration>
<tasks>
<mkdir dir="${project.build.outputDirectory}"/>
<exec executable="svn" failonerror="true" dir="${project.build.outputDirectory}" taskname="svn-checkout">
...
</exec>
...
<zip destfile="${project.build.directory}/${project.build.finalName}.zip">
...
</zip>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.2</version>
<executions>
... phase=package, goal=attach-artifact
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}.zip</file>
<type>zip</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
What are the advantages over other mentioned alternatives ?
- extensibility – the “generator” part is straightforward, so, as long as ant is enough for us it costs just a few lines of ant code
- compactness – we could reach similar result with several invocations of exec-maven-plugin for preparing data, plus maven-assembly-plugin to pack and attach it, but that would be far far more verbose and harder to maintain
Just for completenes, it’s good to say when using the other approaches is more relevant:
- custom maven plugin – when the algorithm for generating data is too complex to be written in ant, or needs other sources that are not reachable from antrun, like dependencies
- maven-assembly-plugin – when we need to control file permissions in tgz/gz packages while running the build on windows
Do you have experience in this area ? Then please post your comments…
When writing a bash script launching a tool used directly on commandline, it is often convenient for the user to have various ways of invocation.
It is not a problem with trivial scripts, but those who need to access files with known location relative to the script, there are little troubles.
First, the script needs to determine its own absolute location on filesystem – because the user can “stay” in any directory. The user can also invoke it directly, using relative or absolute path; and finally, user can invoke a symlink pointing to it, again using relative or absolute path.
Following snippet shows how to handle such cases:
#!/bin/bash
D=${0%/*}
F=$( find $0 -printf %l )
if [ -z "$F" ]; then
# it is not symlink
case "$0" in
/*) F=$0;;
*) F=$PWD/$0
esac
else
# it is symlink
case "$F" in
/*);;
*) F="$D/$F";;
esac
fi
# now F=absolute path here
F=${F//\/\.\///}
D="${F%/*}"
# now F contains the script's pathname,
# D contains its containing directory