13

Is it possible to upload/download an entire directory and all of the sub-directories within it to/from a Nexus repository server?

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
Peter
  • 131
  • 1
  • 1
  • 3

3 Answers3

5

In case you want to actually deploy a hierarchy of files, I hacked together a solution using GMaven (groovy embedded in maven).

Use the pom below, supply a few properties and hit mvn install. The folder will be crawled and all files inside it will be deployed using an artifactId taken from the relative path. e.g.

Given the base folder

c:\a\b\c

the file

c:\a\b\c\def\ghi\jkl.mno

would have the artifactId def-ghi-jkl and the packaging mno, this can of course be changed to something else.

The repository info will be taken from the pom, so you need to supply a distributionManagement element in the pom.

Here it is (a lot of this code is taken from the deploy:deploy-file mojo):

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany</groupId>
    <artifactId>folderdeployer</artifactId>
    <packaging>jar</packaging>
    <version>SNAPSHOT</version>

    <properties>
        <!-- This is where your artifacts are -->
        <deploy.basefolder>c:\temp\stuff</deploy.basefolder>

        <!-- This will be used as groupId -->
        <deploy.groupId>my.groupid</deploy.groupId>

        <!-- this will be used as version -->
        <deploy.version>1.2.3</deploy.version>
    </properties>
    <build>
        <plugins>

            <plugin>
                <groupId>org.codehaus.groovy.maven</groupId>
                <artifactId>gmaven-plugin</artifactId>
                <version>1.0</version>
                <dependencies>
                    <dependency>
                        <groupId>commons-io</groupId>
                        <artifactId>commons-io</artifactId>
                        <version>1.4</version>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <id>deploy-files</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>execute</goal>
                        </goals>
                        <configuration>
                            <source>
                            <![CDATA[
// read components from plexus container             
def layout = session.lookup(
    'org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout');
def repoFactory = session.lookup(
    'org.apache.maven.artifact.repository.ArtifactRepositoryFactory');
def repository = repoFactory.createDeploymentArtifactRepository(
    pom.distributionManagement.repository.id,
    pom.distributionManagement.repository.url,
    layout, true );
def localRepository = session.localRepository;
def helper =
    session.lookup("org.apache.maven.project.MavenProjectHelper");
def afm = session.lookup(
    'org.apache.maven.artifact.handler.manager.ArtifactHandlerManager');
def factory = new org.apache.maven.artifact.factory.DefaultArtifactFactory();
factory.class.getDeclaredField("artifactHandlerManager").accessible = true;
factory.artifactHandlerManager=afm;

def deployer = session.lookup(
    'org.apache.maven.artifact.deployer.ArtifactDeployer');

// initialize properties
def baseFolder = new File(pom.properties['deploy.basefolder']);
def groupId = pom.properties['deploy.groupId'];
def version = pom.properties['deploy.version'];

// iterate over all files recursively
baseFolder.eachFileRecurse{
    if(it.isDirectory())return;

    // packaging = file.extension
    def packaging = it.name.replaceAll( /.+\./ , '' );
    // artifactId = file.relativePath.replace '/' , '-'
    def artifactId = it.absolutePath
        .replace(baseFolder.absolutePath, '')
        .substring(1)
        .replaceFirst( /\..*?$/ , '')
        .replaceAll( /\W+/ , '-' );
    def artifact = 
        factory.createBuildArtifact( 
            groupId, artifactId, version, packaging );

    // create pom for artifact
    def model = new org.apache.maven.model.Model();
    model.setModelVersion( "4.0.0" );
    model.setGroupId( groupId );
    model.setArtifactId( artifactId );
    model.setVersion( version );
    model.setPackaging( packaging );
    File pomFile = File.createTempFile( "mvndeploy", ".pom" );
    pomFile.deleteOnExit();
    fw = org.codehaus.plexus.util.WriterFactory.newXmlWriter( pomFile );
    new org.apache.maven.model.io.xpp3.MavenXpp3Writer().write( fw, model );
    org.apache.commons.io.IOUtils.closeQuietly( fw );

    def metadata = 
        new org.apache.maven.project.artifact.ProjectArtifactMetadata(
                    artifact, pomFile );
    artifact.addMetadata( metadata );

    // deploy file
    deployer.deploy(it, artifact, repository, localRepository );
}
                                    ]]>
                            </source>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <distributionManagement>
        <repository>
            <id>your repo id here</id>
            <url>scp://your.repo.url/here</url>
            <layout>default</layout>
        </repository>
    </distributionManagement>

</project>

EDIT:

I elaborated on this on my blog

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • Interesting, I will look into it. Thanks! – Peter Aug 24 '10 at 20:29
  • 3
    Helpful! I modified it to fit local repository folder structure. https://gist.github.com/aleung/5194777 – aleung Mar 19 '13 at 09:35
  • 3
    We've been using a modified version of @aleung script for almost a year now without problems The modifications to handle 'maven-metadata.xml' and '.sha' and '.md5' files can be found in the forked gist: https://gist.github.com/jakub-bochenski/7802ee7f44b8e3b99bdd69b2ab150e6c – Jakub Bochenski Nov 29 '17 at 16:31
4

You can always zip the directory and ship it as a zip file. the users of this folder can download it from Nexus and unzip using dependency:unpack.

rperez
  • 8,430
  • 11
  • 36
  • 44
  • Yes, this is definitely one way to do it but does not completely satisfy the requirements. Thanks for the input though =) – Peter Aug 24 '10 at 20:29
0

Not by default. But you can use the API of Nexus to upload by script. Here my script to upload the content of a local repository-folder. It uses the provided Information of the pom-files for upload of the artifacts.

Saves a lot of time and worked well for my usecase.

#!/bin/bash

# this script needs a "artifacts" file right next to it.  Create it by using following script in your .m2-folder
#       find -iname "*.pom" -printf "%h\n" > files; find -iname "*.jar" -printf "%h\n" >> files; cat files | sort | uniq -u > artifacts; rm files

NEXUS_USERNAME="admin"
NEXUS_PASSWORD="nexus"
NEXUS_URL="localhost:8081"

cat artifacts | while read i; do

    pompath=$(find $i -name *.pom)
    jarpath=$(find $i -name *.jar)
    
    # extracting metainformations from pom
    groupId=$(echo $pompath | xargs xpath -e 'project/groupId/text()')
    artifactId=$(echo $pompath | xargs xpath -e 'project/artifactId/text()')
    version=$(echo $pompath | xargs xpath -e 'project/version/text()')
    if test -z "$groupId"
    then 
        echo "project-groupId is empty - using parent/groupId"
        groupId=$(echo $pompath | xargs xpath -e 'project/parent/groupId/text()')
    fi
    
    if test -z "$version"
    then 
        echo "project-version of jar-pom is empty - using parent/version"
        version=$(echo $pompath | xargs xpath -e 'project/parent/version/text()')
    fi


    # choosing upload-strategy, preferring jar-upload
    if test -z "$jarpath"
    then
        echo "uploading $artifactId as pom"
        # a 400 error means that the artifactId already exists
        mvn deploy:deploy-file \
         -DgroupId=$groupId \
         -DartifactId=$artifactId \
         -Dversion=$version \
         -Dpackaging=pom \
         -Dfile=$pompath \
         -Durl="http://${NEXUS_USERNAME}:${NEXUS_PASSWORD}@${NEXUS_URL}/repository/maven-releases/"
        echo "uploading $pompath with groupId: $groupId; artifactId: $artifactId; version: $version"
    else 
        echo "uploading $artifactId as jar"
        # a 400 error means that the artifactId already exists
        mvn deploy:deploy-file \
         -DgroupId=$groupId \
         -DartifactId=$artifactId \
         -Dversion=$version \
         -Dpackaging=jar \
         -DgeneratePom=true \
         -Dfile=$jarpath \
         -Durl="http://${NEXUS_USERNAME}:${NEXUS_PASSWORD}@${NEXUS_URL}/repository/maven-releases"      
        echo "uploading $jarpath with groupId: $groupId; artifactId: $artifactId; version: $version"
    fi 
  
done 

echo 'done uploading artifacts'
Kolja
  • 21
  • 8