скопировать дерево с помощью gradle и изменить структуру?

может ли gradle изменять структуру дерева При копировании?

оригинал

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

нужные

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

Я не уверен, где я должен создать закрытие и переопределить логику дерева копирования

Я хотел бы сделать эквивалент gradle функциональность globmapper муравья

<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>

спасибо

Петр

3 ответов


при изменении имени файла переименование кажется хорошим подходом. При изменении пути вы можете переопределить 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
}

следующие работы, но есть ли более gradle-ish способ сделать это?

    ant.copy(todir: destDir) {
      fileset( dir: "${srcDir}/module", includes: '**/src/**')
      regexpmapper(from: '^(.*)/src/(.*)$', to: /module-\/src\//)
    }

пожалуйста, см. Образец ниже. Gradle 4.3 не имеет методов переименования/перемещения, поэтому мы можем сделать переименование на лету.

что было:

  1. загрузить дерево файлов в память. Я использовал zip-файл из зависимостей в моем примере
  2. фильтровать элементы, которые находятся в целевой папке
  3. все элементы результатов будут иметь один и тот же префикс: если мы фильтруем файлы из каталога "A/B/C/", то все файлы будут похожи на "A/B/C/file.txt " или " A/B/C/D / file.формат txt." Е. Г. все из них Начнем с тех же слов
  4. в последнем заявлении каждый файл мы изменим окончательное имя, вырезав префикс каталога (например, мы будем вырезать "A/B/C").
  5. важно: используйте тип задачи "копировать", который имеет оптимизации для инкрементной компиляции. Gradle не будет копировать файл, если все элементы ниже true:
    • вход тот же (для моего случая - все зависимости области "nativeDependenciesScope") с предыдущим 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)