Francisco,
Francisco Peredo wrote on 03/24/2009 02:56 PM:
We download stuff at our houses, and then copy them in usb portable storage
and bring them to work.
[...]
So, we want to upload our WEB-INF\lib .jar files (for hibernate, seam,
spring, commons, etc) in to a shared repository to a server inside our
intranet...
[...]
I guess that to do that we need to use the task ivy:publish... Am I right?
But since we have hundreds of files, we would like to be able to do it in
single shot, something like
<ivy:publis-as-repository source-dir="WEB-INF\lib\">
Well, ivy:install makes more sense to me, as you don't have an ivy.xml
file for each module.
ivy:install is good for moving things from one repo to another. The
source repo could be the ibiblio default repo, the IvyRoundup packager
resolver, or a local filesystem.
You could take another approach, and just use your home bandwidth to
install all of your required jars (if you knew their org/module/rev)
to a local filesystem resolver on a USB stick, using ibiblio as the
source repo.
Is it possible to automate this with Ivy? or do I have to write my own
ivy:publis-as-repository ant task?
Well, it's probably not elegant, but when faced with the same problem,
I wrote the following perl script, parse_jars.pl, which will use ant
with a default target like this:
<target name="installjar"
depends="init-ivy"
description="--> install jar to shared repo">
<ivy:install
settingsRef="masergy.settings"
organisation="${org}"
module="${module}"
revision="${rev}"
type="jar"
from="${localjar.resolver}"
to="${to.resolver}" />
</target>
My ivysettings.xml includes:
<filesystem name="localjars">
<artifact pattern="${install.path}/[artifact]-[revision].[ext]" />
<artifact pattern="${install.path}/[artifact].[ext]" />
</filesystem>
The script will attempt to divine the correct org/module using 4
techniques: (1) the ozacc Maven search API; (2) pattern-matching on
the module name; (3) the top-level of the jar packages; (4) if all
else fails. just ask the user.
Note the script requires all jars to follow the naming convention
module-ver.jar. Too few jars have relevant and consistent metadata
within their MANIFEST to do otherwise.
Thanks,
---
Kirby Files
Software Architect
Masergy Communications
kfi...@masergy.com
8< ------------------------ parse_jars.pl ---------------------- >8
#!/usr/bin/perl
# Looks for jars in the incoming directory, attemps to parse the
# needed ivy info from the filename, and if successful, publishes
# the jar to the Masergy ivrep repository.
# If using linux with package mgmt, dependencies are:
# perl-libwww-perl
# perl-XML-Xpath
# perl-Archive-Zip
use LWP::UserAgent;
use XML::XPath;
use XML::XPath::XMLParser;
use Archive::Zip;
use Cwd;
use strict qw(vars);
use vars qw($indir $ant $rep $pre $post);
$indir = shift(@ARGV);
if ($indir !~ m#^/#) {
my $cwd = getcwd();
$indir =~ s/^/$cwd\//;
print "CWD: $indir\n";
}
$ant = "/usr/local/ant/bin/ant";
$rep = "newjars";
$pre="<ivy:install settingsRef=\"masergy.settings\" organisation=\"";
$post=" from=\"\${from.resolver}\" to=\"\${to.resolver}\" />";
open (DIR, "ls -1 $indir|") || die "could not open $indir\n";
while (<DIR>) {
my ($org, $module, $jar, $ver);
next unless /jar/;
chomp;
my $file = $indir . "/" . $_;
$org=$_;
$module=$_;
$jar=$_;
$ver=$_;
$module=~s/^(.*)\.jar/$1/;
$module=~s/([^.]*)-\d.*/$1/;
$ver=~s/^[^.]*-([\d.]+.*)\.jar/$1/;
$ver="unknown" unless $ver =~ /\d/;
## Figure out the org
## Ask the user, if there's ambiguity
$org = &maven_search_org( $module );
if (-1 == $org) {
$org = &guess_org($module);
print "Org guessed from module name:\n $org\n";
$org = &classes_org($file);
print "Org guessed from jar package naming:\n $org\n"
unless (-1 == $org);
do {
$org = &get_user_org();
} while ($org =~ /^$/);
}
if ($ver eq "unknown" || ($module !~ /^\w+$/) || $org !~ /\w+/) {
print "Skipping jar $jar:\n";
print " $org / $module / $ver\n";
next;
} else {
&publish_jar($jar, $org, $module, $ver);
}
#&write_ivy_conf($jar, $org, $module, $ver);
}
## Use ivy::install to publish the jar via sftp to ivyrep
sub publish_jar
{
my ($jar, $org, $module, $ver) = @_;
print "Uploading $org / $module / $jar ... ";
my $resp = `$ant -Dorg=$org -Dmodule=$module -Drev=$ver
-Dinstall.path=$indir 2>&1`;
if ($resp =~ /failed/i) {
print STDERR "Error uploading $jar:\n", $resp;
print "\n";
} else {
print "Done.\n";
}
}
## Find a directory in the jar to propose as the org
## searches for any dirs with two path elements
sub classes_org
{
my ($file) = @_;
my $somezip = Archive::Zip->new();
unless ( $somezip->read( $file ) == AZ_OK ) {
die "Error reading jarfile $file";
}
my @members = $somezip->members();
my @dirnames = ();
foreach (@members) {
if ($_->isDirectory()) {
my $fname = $_->fileName();
if ($fname =~ /^\w+\/\w+\/$/) {
$fname =~ s/^(\w+)\/(\w+)\/$/$1.$2/;
return $fname;
}
}
}
return -1;
}
## Ask the user for the best org name
sub get_user_org
{
print "Enter preffered org:> ";
my $line = <STDIN>;
chomp($line);
return $line;
}
## Make a guess about the org name from the module name
sub guess_org
{
my ($module) = @_;
my $org = $module;
$org=~s/spring.*/springframework/;
$org=~s/hiber.*/hibernate/;
$org=~s/standard.*/taglibs/;
$org=~s/jstl.*/taglibs/;
$org=~s/persistence.*/sun/;
$org=~s/jta.*/sun/;
$org=~s/servlet-api.*/tomcat/;
$org=~s/ojdbc.*/oracle/;
$org=~s/cglib.*/cglib/;
$org=~s/javassist.*/jboss/;
$org=~s/([^.]*)-\d.*jar/$1/;
$org=~s/(.*)\.jar/$1/;
return $org;
}
## Search the maven repo for a module matching this jar
## If found, return the module's organization
## if none, or more than one, are found, ask the user
sub maven_search_org
{
my ($module) = @_;
my $ua = LWP::UserAgent->new;
$ua->agent('Maven Repo Search');
my $service=
'http://maven.ozacc.com/search?format=xml&type=jar&keyword=';
my $url=URI->new($service . $module);
my $req=HTTP::Request->new;
$req->method('GET');
$req->uri($url);
my $resp = $ua->request($req)->content;
my $org = &parse_resp( $module, $resp );
return $org;
}
## Parse the XML response from the Maven search service
sub parse_resp
{
my ($module, $data) = @_;
my $xp = XML::XPath->new(xml => $data);
my $nodeset = $xp->find('//groupId'); # find all paragraphs
# Get rid of duplicates
my %uniq=();
foreach my $node ($nodeset->get_nodelist) {
$uniq{ $xp->getNodeText( $node ) } = 1;
}
my @keys = (sort keys %uniq);
if ($#keys == 0) {
return ($keys[0]);
} elsif ($#keys == -1) {
print "Found no module matching $module in Maven repo\n";
return -1;
} else {
print "Found multiple possible orgs for $module in Maven repo:\n";
foreach (@keys) {
print " $_\n";
}
return -1;
}
}
## (obsolete) Write ant task and ivy.xml conf lines to create repo
sub write_ivy_conf
{
my ($jar, $org, $module, $ver) = @_;
my $line = $pre . $org . "\" module=\"" . $module . "\"
revision=\"" . $ver . "\"". $post . "\n";
system("mkdir -p $rep/$org/$module/jars");
link "$indir/$jar", "$rep/$org/$module/jars/$jar";
print $line;
print "<dependency org=\"" . $org . "\" name=\"" . $module . "\"
rev=\"" . $ver . "\"/>\n";
}