1

我有一些 jar 文件(自定义)需要从 Groovy 脚本发布到 Sonatype Nexus 存储库。

我在 Groovy 脚本工作的机器上的某个路径中有 jar(例如:c:\temp\module.jar)。

我的 Nexus 回购网址是 http://:/nexus/content/repositories/

在这个 repo 中,我的文件夹结构如下:folder1->folder2->folder3

在发布我的 jar 期间,我需要在 folder3 中创建:

  1. 带有模块版本的新目录(我的 Groovy 脚本知道这个版本)
  2. 上传jar到这个目录
  3. 为上传的 jar 创建 pom、md5 和 sha1 文件

经过几天的调查,我仍然不知道如何创建这样的脚本,但这种方式看起来很清楚,而不是使用直接上传。

我找到了http://groovy.codehaus.org/Using+Ant+Libraries+with+AntBuilder和其他一些东西(stackoverflow 非脚本解决方案)。

我知道如何在我的 Groovy 脚本中创建 ivy.xml,但我不明白如何动态创建 build.xml 和 ivysetting.xml 并设置整个系统工作。

您能否帮助理解 Groovy 的方式?

更新: 我发现以下命令对我来说很好:

curl -v -F r=thirdparty -F hasPom=false -F e=jar -F g=<my_groupId> -F a=<my_artifactId> -F v=<my_artifactVersion> -F p=jar -F file=@module.jar -u admin:admin123 http://<my_nexusServer>:8081/nexus/service/local/repositories

据我了解 curl 对 Nexus 服务执行 POST 请求。我对么?

现在我正在尝试使用 Groovy HTTPBuilder 构建 HTTP POST 请求。

我应该如何将 curl 命令参数转换为 Groovy 的 HTTPBuilder 请求?

4

2 回答 2

3

找到了一种使用 groovy HttpBuilder 的方法。

基于来自sonatype和其他一些来源的信息。

这适用于 http-builder 版本 0.7.2(不适用于早期版本)并且还需要一个额外的依赖项:'org.apache.httpcomponents:httpmime:4.2.1'

该示例还针对nexus 使用基本身份验证。

import groovyx.net.http.Method
import groovyx.net.http.ContentType;
import org.apache.http.HttpRequest
import org.apache.http.HttpRequestInterceptor
import org.apache.http.entity.mime.MultipartEntity
import org.apache.http.entity.mime.content.FileBody
import org.apache.http.entity.mime.content.StringBody
import org.apache.http.protocol.HttpContext
import groovyx.net.http.HttpResponseException;

class NexusUpload {
  def uploadArtifact(Map artifact, File fileToUpload, String user, String password) {
    def path = "/service/local/artifact/maven/content"
    HTTPBuilder http = new HTTPBuilder("http://my-nexus.org/")
    String basicAuthString = "Basic " + "$user:$password".bytes.encodeBase64().toString()

    http.client.addRequestInterceptor(new HttpRequestInterceptor() {
      void process(HttpRequest httpRequest, HttpContext httpContext) {
        httpRequest.addHeader('Authorization', basicAuthString)
      }
    })
    try {
      http.request(Method.POST, ContentType.ANY) { req ->
        uri.path = path

      MultipartEntity entity = new MultipartEntity()
      entity.addPart("hasPom", new StringBody("false"))
      entity.addPart("file", new FileBody(fileToUpload))
      entity.addPart("a", new StringBody("my-artifact-id"))
      entity.addPart("g", new StringBody("my-group-id"))
      entity.addPart("r", new StringBody("my-repository"))
      entity.addPart("v", new StringBody("my-version"))
      req.entity = entity

      response.success = { resp, reader ->
        if(resp.status == 201) {
          println "success!"
        }
      }
    }

    } catch (HttpResponseException e) {
      e.printStackTrace()
    }
  }
}

`

于 2015-02-25T11:38:33.587 回答
1

Ivy 是一个开源库,因此,一种方法是直接调用类。这种方法的问题在于很少有关于如何以编程方式调用 ivy的示例。

由于 groovy 对生成 XML 有很好的支持,所以我喜欢使用稍微笨拙的方法来创建我理解为 ivy 用户的文件。

以下示例旨在将文件发布到Nexus,生成 ivy 和 ivysettings 文件:

import groovy.xml.NamespaceBuilder
import groovy.xml.MarkupBuilder

// Methods
// =======
def generateIvyFile(String fileName) {
    def file = new File(fileName)

    file.withWriter { writer ->
        xml = new MarkupBuilder(writer)

        xml."ivy-module"(version:"2.0") {
            info(organisation:"org.dummy", module:"dummy")
            publications() {
                artifact(name:"dummy", type:"pom")
                artifact(name:"dummy", type:"jar")
            }
        }
    }

    return file
}

def generateSettingsFile(String fileName) {
    def file = new File(fileName)

    file.withWriter { writer ->
        xml = new MarkupBuilder(writer)

        xml.ivysettings() {
            settings(defaultResolver:"central")
            credentials(host:"myrepo.com" ,realm:"Sonatype Nexus Repository Manager", username:"deployment", passwd:"deployment123")
            resolvers() {
                ibiblio(name:"central", m2compatible:true)
                ibiblio(name:"myrepo", root:"http://myrepo.com/nexus", m2compatible:true)
            }
        }
    }

    return file
}

// Main program
// ============
def ant = new AntBuilder()
def ivy = NamespaceBuilder.newInstance(ant, 'antlib:org.apache.ivy.ant')

generateSettingsFile("ivysettings.xml").deleteOnExit()
generateIvyFile("ivy.xml").deleteOnExit()

ivy.resolve()
ivy.publish(resolver:"myrepo", pubrevision:"1.0", publishivy:false) {
    artifacts(pattern:"build/poms/[artifact].[ext]")
    artifacts(pattern:"build/jars/[artifact].[ext]")
}

笔记:

  • 更复杂?也许......但是,如果您没有生成 ivy 文件(使用它来管理您的依赖项),您可以在上传到 Nexus 之前轻松调用makepom任务来生成 Maven POM 文件。
  • Nexus 的 REST API 工作正常。我发现它们有点神秘,当然使用它们的解决方案不能支持多个存储库管理器(Nexus 不是唯一可用的存储库管理器技术)。
  • “deleteOnExit”文件方法调用可确保正确清理工作文件。
于 2013-06-05T21:05:30.457 回答