在 gradle 构建中自定义启动脚本的位置

dos*_*ant 5 java gradle

我刚开始尝试打包我的一个小项目。在构建我的发行包时,结构如下:

my-project.zip
|
+- my-project
   |
   +- bin (containing start scripts)
   +- lib
   +- xyz (folders from src/dist)
Run Code Online (Sandbox Code Playgroud)

我想要实现的是将启动脚本放在项目根文件夹而不是子bin文件夹中(我知道这是某种约定,但我也喜欢从应用程序文件夹中启动我的应用程序):

my-project.zip
|
+- my-project
   |
   +- lib
   +- xyz (folders from src/dist)
   +- my-project.bat
   +- my-project.sh
Run Code Online (Sandbox Code Playgroud)

这可能吗?

我尝试过设置tasks.startScripts.outputDir但没有成功(脚本已从发行包中完全删除)。

更新

除了 lu.koerfer 的回答之外,我还必须修改启动脚本以考虑更改后的 APP_HOME:

startScripts {
    startScripts.applicationName = artefactsBaseName
    doLast {
        def windowsScriptFile = file getWindowsScript()
        def unixScriptFile = file getUnixScript()
        windowsScriptFile.text = windowsScriptFile.text.replace('set APP_HOME=%DIRNAME%..', 'set APP_HOME=%DIRNAME%')
        unixScriptFile.text = unixScriptFile.text.replace('cd "`dirname \"$PRG\"`/.." >/dev/null', 'cd "`dirname \"$PRG\"`" >/dev/null')
    }
}
Run Code Online (Sandbox Code Playgroud)

Luk*_*fer 6

您不想关心启动脚本(startScripts任务)的创建,而是关心 zip 文件(任务)的创建distZip来控制文件的放置位置。为此,您可以直接使用distZip任务或DistributionContainerGradle 分发插件中的任务,该插件会自动与 Gradle 应用程序插件一起应用。允许DistributionContainer您管理 Gradle 项目中多个发行版的创建,并且应用程序插件main默认使用该发行版。

distributions.main {
    contents {
        from startScripts
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码只是将startScripts任务的输出添加到main分发内容中。它们将被放置在该发行版的根文件夹中,因为您没有指定CopySpec具有into方法的子级。

我假设您只希望启动脚本位于根文件夹中,而不是位于该bin文件夹中。由于您只能Copy根据源路径而不是目标路径排除任务的文件,因此您需要在复制它们时通过方法排除它们eachFile(因为这样它们的目标是已知的):

distZip {
    eachFile { file ->
        if (file.path.contains('bin')) {
            file.exclude()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,这段代码将从binzip 文件中删除整个目录,因此您可能需要为其他用例重新描述闭包中的条件。