使用Gradle复制树并更改结构?

14

Gradle能否在复制时改变树的结构?

原始内容

  • mod/a/src
  • mod/b/src

期望结果

  • dest/mod-a/source
  • dest/mod-b/source
  • dest/mod-c/source

我不确定应该在哪里创建闭包并覆盖复制树逻辑。

我想实现类似于Ant的globmapper功能的Gradle等效功能。

<property name="from.dir" location=".."/>      
<property name="to.dir" location="dbutil"/>
<copy>
    <fileset dir="${from.dir}" ... />
    <globmapper from="${from.dir}/*/db" to="${to.dir}"/> 
</copy>

谢谢

Peter

3个回答

24

在更改文件名时,重命名似乎是一个不错的方法。当更改路径时,您可以覆盖 eachFile 并修改目标路径。

这个方法运行得非常好。

    copy {
    from("${sourceDir}") {
        include 'modules/**/**'
    }
    into(destDir)
    eachFile {details ->

        // Top Level Modules
        def targetPath = rawPathToModulesPath(details.path)
        details.path = targetPath
    }
}
....
def rawPathToModulesPath(def path) {
// Standard case modules/name/src -> module-name/src
def modified=path.replaceAll('modules/([^/]+)/.*src/(java/)?(.*)', {"module-${it[1]}/src/${it[3]}"})
return modified
}

4
这个对我来说是有效的,但它也会创建原始目录,这些目录仍然是空的。 - peez80
4
尝试设置 setIncludeEmptyDirs(false)。这会使空目录不被包含在内,并保持原意。 - BitPusher
4
如果您只想保留文件名并将其放入目标目录中,details.path = details.name - wrossmck
@eastwater 这只是移动文件,因此它应该对源、资源和充满MP3的目录保持中立。 - Petra Kahn

2
请参考下面的示例。Gradle 4.3没有重命名/移动方法,因此我们可以即时更改名称。
发生了什么:
1.将文件树加载到内存中。我在示例中使用了依赖项中的zip文件。
2.过滤目标文件夹中的项目。
3.所有结果项都将具有相同的前缀:如果我们从目录“A/B/C/”过滤文件,则所有文件都将像“A/B/C/file.txt”或“A/B/C/D/file.txt”一样。例如,它们都以相同的单词开头。
4.在最后一个语句eachFile中,我们将通过剪切目录前缀(例如,我们将剪切“A/B/C”)来更改最终名称。
5.重要:使用任务类型“Copy”,它具有增量编译的优化。如果以下所有项目都为真,则Gradle不会执行文件复制:
- 输入与上一次构建相同(对于我的情况-范围为“nativeDependenciesScope”的所有依赖项) - 您的函数返回与上一次构建相同的项目 - 目标文件夹与上一次构建具有相同的文件哈希值
task copyNativeDependencies(type: Copy) {
    includeEmptyDirs = false
    def subfolderToUse = "win32Subfolder"

    def nativePack = configurations.nativeDependenciesScope.singleFile // result - single dependency file

    def nativeFiles = zipTree(nativePack).matching { include subfolderToUse + "/*" } // result - filtered file tree

    from nativeFiles
    into 'build/native_libs'
    eachFile {
        print(it.path)

        // we filtered this folder above, e.g. all files will start from the same folder name
        it.path = it.path.replaceFirst("$subfolderToUse/", "")
    }
}

// and don't forget to link this task for something mandatory
test.dependsOn(copyNativeDependencies)
run.dependsOn(copyNativeDependencies)

1
以下代码可以正常工作,但是否有更符合Gradle风格的方法呢?
    ant.copy(todir: destDir) {
      fileset( dir: "${srcDir}/module", includes: '**/src/**')
      regexpmapper(from: '^(.*)/src/(.*)$', to: /module-\1\/src\/\2/)
    }

为什么我们不能使用 globmapper - IgorGanapolsky
可能可以。也许这是更符合Gradle的方法。有例子吗? - Petra Kahn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接