copy tree with gradle and change structure?

前端 未结 3 1260
终归单人心
终归单人心 2021-02-05 14:51

Can gradle alter the structure of the tree while copying?

original

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

desired

相关标签:
3条回答
  • 2021-02-05 15:21

    The following works, but is there a more gradle-ish way to do this?

        ant.copy(todir: destDir) {
          fileset( dir: "${srcDir}/module", includes: '**/src/**')
          regexpmapper(from: '^(.*)/src/(.*)$', to: /module-\1\/src\/\2/)
        }
    
    0 讨论(0)
  • 2021-02-05 15:22

    Please see sample below. Gradle 4.3 does not have rename/move methods, so we can do renaming on the fly.

    What was happened:

    1. Load file tree into the memory. I used zip file from dependencies in my example
    2. Filter items, which are in the target folder
    3. All result items will have the same prefix: if we filter files from directory "A/B/C/", then all files will be like "A/B/C/file.txt" or "A/B/C/D/file.txt". E.g. all of them will start with the same words
    4. In the last statement eachFile we will change final name by cutting the directory prefix (e.g. we will cut "A/B/C").
    5. Important: use type of task "Copy", which has optimizations for incremental compilation. Gradle will not do file copy if all of items below are true:
      • Input is the same (for my case - all dependencies of scope "nativeDependenciesScope") with previous build
      • Your function returned the same items with the previous build
      • Destination folder has the same file hashes, with the previous build
    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)
    
    0 讨论(0)
  • 2021-02-05 15:27

    When changing file name, rename seems a good approach. When changing path you can override eachFile and modify the destination path.

    This works pretty well.

        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
    }
    
    0 讨论(0)
提交回复
热议问题