【问题标题】:how to create a simple build script for grails 2.5如何为 grails 2.5 创建一个简单的构建脚本
【发布时间】:2015-10-05 09:32:42
【问题描述】:

我已阅读文档here,其中给出了结构,但没有提供有关如何创建实际逻辑的任何帮助。

我想构建一个非常简单的脚本,它会进行清理、创建战争、创建源的 zip(没有目标目录,也没有任何 svn 目录),并创建迁移的 tar(最好是 gzip) dir 所以这可以与 liquibase 一起使用。这 3 个工件中的每一个都应在其名称中包含应用程序版本(就像现有的“grails 战争”一样。

项目结构如下:

svn
main-app
   grails-app
       migrations
       target
       :
exploded-plugin-1
   grails-app
   :
exploded-plugin-2
   grails-app
   :

这是我已经走了多远:

includeTargets << grailsScript("_GrailsInit")

target(packageUs: "Creates war, zips source, tars liquibase scripts") {
    depends(clean, war-us, zip-source, tar-liquibase)
}

setDefaultTarget(packageUs)

target ("war-us" : "creates war") {
    ant.war()  // this was a guess at calling the existing war - it doesnt work
}

target ("zip-source" : "zips sources") {
  // cd to top dir of project, i.e. above the app.
}

target ("tar-liquibase":"produces tar of migrations dir") {
    // tar up the migrations dir
    // name it with the app-version
    // put it in the target dir along side the war etc.
}

target ("clean") {
  // call the default clean some how, or cd to target dir, and delete everything
}

上面的脚本最初是用“grails create-script package-us”创建的

遗憾的是,即使这样也行不通,它会产生以下错误:

| Error Error executing script PackageUs: No signature of method: org.codehaus.gant.GantBinding$_initializeGantBinding_closure5.doCall() is applicable 
for argument types: (java.lang.String, PackageUs$_run_closure5) values: [clean, PackageUs$_run_closure5@5ed0b4e3]

除了链接中非常基本的概述之外,我找不到任何示例脚本或文档。

我什至无法让 ant.echo() 工作 - intellij 说只有一个 ant.echo 函数需要一个 LinkedHashmap、一个字符串和一个闭包,但 ant 文档说 echo 只需要一个“消息”字符串。 linkedhashmap、字符串和闭包应该是什么?我已经尝试了至少 30 种不同的变体,但都没有奏效。

更新 1:到目前为止我所做的工作

includeTargets << grailsScript("_GrailsInit")
target(packageUs: "Creates war, zips source, tars liquibase scripts") {
    depends(clean, "war-us", "zip-source")
}
setDefaultTarget(packageUs)

target ("war-us" : "creates war") {
   ant.echo(message:"hello") // this compiles and runs, but does nothing.
   println "hello there"  // this does work.
   // ant.war(?)
}

// puts in it wrong dir, and doen't have app version in name, but at least it zips the right content!
target ("zip-source" : "zips sources") {
    ant.delete(file: 'sources.zip')  // dont know how to add this to the clean cycle
    ant.zip(destfile: 'sources.zip', basedir: '..', excludes: "**/*.zip **/target/**  **.idea **/.classpath **/.iml")
}

我还没有弄清楚:

  1. 如何获取 app.version 以便它可以放入文件名。例如:println "creating war for $app.version" 不起作用
  2. 如何构建战争。不可能把它放在 depdends 列表中,不幸的是 ant.war("myfile.war") 不起作用。其他策略可能是在战争构建事件上运行此脚本,这并不理想,因为战争经常在不需要此的情况下构建,或者可能通过调用 shell 命令来调用“grails war”。

更新 2 - 不能产生“刺激”战争

在 Ashraf Purno 的帮助下,我们有一个脚本(如下),它创建一个战争,压缩源代码和 tar.gz liquibase 文件并生成我们的包。但是,它有一个主要缺陷,创建的战争始终是“开发”版本,因为当您将其部署到 tomcat 时,它会厌倦使用开发数据源和开发环境。似乎没有办法在构建脚本中更改它,并且在调用脚本的命令行上将环境设置为 prod(例如“grails prod myscript”)也没有影响 - 它还会生成开发版本的战争(没用的)

includeTargets << grailsScript("_GrailsInit")
includeTargets << grailsScript("_GrailsClean")
includeTargets << grailsScript("War")

target(warpack: "Creates war, zips source, tars liquibase scripts") {
    depends(cleanAll, cleanRealyAll, war, "zip-source", "tar-liquibase", "package-all")
}

setDefaultTarget(warpack)

target ("cleanRealyAll" : "Cleans stuff that clean-all wont touch") {
    println "wiping the target dir"
    ant.delete(dir: "target")
    ant.mkdir(dir: "target")
}

target ("zip-source" : "zips sources") {
    println "zipping sources for ${metadata.'app.version'}"

    String zipFile = "target/sources-${metadata.'app.version'}.zip"
    ant.delete(file: zipFile)
    ant.zip(destfile: zipFile, basedir: '..', excludes: "**/*.zip **/target/**  **.idea **/.classpath **/.iml")
}

target ("tar-liquibase":"produces tar of migrations dir") {
    println "tarring liquibase for ${metadata.'app.version'}"

    String tarFile = "target/migrations-${metadata.'app.version'}.tar"
    String gzipfile = "target/migrations-${metadata.'app.version'}.tar.gz"

    ant.tar(destfile:tarFile, basedir: "grails-app/migrations")
    ant.gzip(src: tarFile, destfile : gzipfile )
    ant.delete(file: tarFile)
}

target ("package-all":"puts it all together in one file, relies on externally running 'grails war' first") {
    println "creating package for ${metadata.'app.version'}"

    String packageFile = "target/ourpackage-${metadata.'app.version'}.tar"

    ant.delete(file: packageFile)
    ant.tar (destfile: packageFile, basedir:"target", includes: "*.war *.zip *.gz" )
}

【问题讨论】:

    标签: grails build


    【解决方案1】:

    经过一番谷歌搜索和浏览 grails 核心脚本后,我设法创建了一个脚本来执行您在问题中提到的事情。在这里

        import grails.util.Metadata
    
        includeTargets << grailsScript("_GrailsInit")
        includeTargets << grailsScript("_GrailsClean")
        includeTargets << grailsScript("_GrailsWar")
    
        target(pack: "Creates war, zips source, tars liquibase scripts") {
            depends(cleanAll, war)
    
            String appVersion = Metadata.current[Metadata.APPLICATION_VERSION],
                   zipFileName = "${basedir}/target/sources-${appVersion}.zip",
                   tarFileName = "${basedir}/target/migrations-${appVersion}.tar.gz"
    
            println "Creating Sources Zip"
            ant.delete(file: zipFileName)
            ant.zip(destfile: zipFileName, basedir: basedir, excludes: "**/target/**  **/.idea/** **/.classpath/** **/.iml/**")
    
            println "Creating Migrations Tar Ball"
            ant.delete(file: tarFileName)
            ant.tar(destfile: tarFileName, basedir: "${basedir}/grails-app/migrations")
        }
    
        setDefaultTarget(pack)
    

    为了简单起见,我将所有任务放在一个目标中。如果需要,您可以将它们分成几个目标并将它们添加到depends。我使用Grails 2.5.1 来测试这个脚本。

    您可以在此处查看 http://mrhaki.blogspot.com/2014/05/grails-goodness-run-groovy-scripts-in.html 以了解脚本中的一些可用道具/配置。

    【讨论】:

    • 哇,你是在谷歌上找到这个的吗?几天来我一直在谷歌上搜索示例或文档,结果大部分都是空白的。
    • 我确实找到了一种简单的方法来拉入 app.version: "xxx_${metadata.'app.version'}"
    • 你说得对,除了脚本中可用的应用程序属性列表之外,谷歌搜索并没有为我提供太多帮助。我主要从 grails 核心脚本源获得帮助。 "xxx_${metadata.'app.version'}" metadata 来自哪里?是自动注入的吗?
    • 奇怪的是,使用 warMain 依赖创建的战争不起作用。他们产生了一个与“grails war”不同的2个字节的战争,当放到tomcat上时,他们无法连接到数据库(连接被拒绝)。这很奇怪。
    • 我尝试仅仅依赖于“战争”,它产生了相同的结果 - 一场战争与执行 grails 战争有几个字节不同,一个无法连接到数据库(无法创建连接池)。难道是它使用了错误的环境? grails war = production,也许这是在尝试使用 dev?
    猜你喜欢
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多