Gradle взорвать zip в buildDir
Мой проект имеет удаленную зависимость, которая на самом деле является просто zip определенных файлов, которую нужно разархивировать где-то, так что сборка может генерировать новые источники java из файлов. (Я говорю в общем, чтобы сосредоточиться на основной проблеме, а не на специфике)
Я бы не ожидал, что это будет так сложно, но я не смог заставить его работать. Вот то, что я создал:
Я определил новую конфигурацию:
configurations {
newConf
}
Позже я определил одну зависимость для этой настройки. Он разрешает zip файл, который мне нужно взорвать:
dependencies {
newConf "group:name:[email protected]"
}
Пока все это пахнет правильно, хотя, если кто-то не согласен, я слушаю.
Наконец, мне нужно определить задачу, которая взрывает zip в каталог, который затем становится входом для более поздней команды генерации кода.
task explodeModel {
description = "unzip model into the specified 'modelSrc' directory"
//input is a "files" collection (usually just one: the zip)
//output is the specified modelSrc dir
File modelSrc = new File("$buildDir/modelSrc")
outputs.files modelSrc
doLast {
configurations.newConf.allArtifacts.each { artifact -> println artifact }
}
}
Очевидно, что doLast еще не распаковывает ничего, я просто пытаюсь получить абсолютный путь к самому zipfile, и вот где я застрял. Я понятия не имею, как получить путь к файлу, чтобы я мог разархивировать его. Любая помощь?
Большое спасибо
Ответы
Ответ 1
Я сделал что-то подобное в плагине, который я написал. Это должно сработать для вас:
configurations.newConf.singleFile
Предполагается, что существует только один файл. Тип возврата java.io.File
.
Для получения дополнительной информации проверьте этот класс GaePlugin.groovy. Метод релевантности configureDownloadSdk
. Задача, которая делает unzip, GaeDownloadSdkTask.groovy.
Ответ 2
Попробуйте что-нибудь в этом направлении, оно должно работать:
task explodeModel(type: Copy){
configurations.newConf.filter { it.toString().endsWith(".zip") }.each{
from zipTree(it)
}
into 'output/dir'
}
Конечно, вы можете опустить часть фильтрации .zip
, если вы уверены, что артефакты в конфигурации являются zips.
Ответ 3
Вот что я делал в последнее время, и я был доволен этим:
(Этот пример предполагает конфигурацию с именем zipFiles
, которая включает только файлы ZIP.)
ext.unpackedZipFiles = fileTree("$buildDir/unpackedZipFiles") { builtBy 'unpackZipFiles' }
task unpackZipFiles(type: Copy) {
from configurations.zipFiles.files.collect { zipTree(it) }
into unpackedZipFiles.dir
}
Подробнее
Есть несколько вещей, которые мне нравятся в этом подходе:
-
Вместо того, чтобы начертать волшебную строку "$buildDir/unpackedZipFiles"
по всей сборке, вывод unzip представлен фактическим FileTree
. Это делает использование результатов в будущих копировальных задачах довольно простым:
aCopyLikeTask(type: Copy) {
from unpackedZipFiles
// ...
}
-
Задачи, использующие распакованные файлы, не зависят непосредственно от задачи, которая распаковывает файлы. Скорее они зависят от самого FileTree
, который знает, как распаковать файлы. Обратите внимание, что FileTree
расширяет Buildable
и поэтому может быть зависимостью задачи:
aNonCopyTask(dependsOn: unpackedZipFiles) << {
// ... do stuff that references unpackedZipFiles.dir
}
-
Project.fileTree()
действительно возвращает ConfigurableFileTree
, поэтому мы можем указать одну или несколько задач, которые она построена. Этот интерфейс также предоставляет File
корня дерева через свойство dir
, что часто бывает удобно. Например:
myExecTask(dependsOn: unpackedZipFiles) << {
"${unpackedZipFiles.dir}/bin/runMe".execute([], unpackedZipFiles.dir)
}
Ответ 4
Мое решение (адаптированное к нашему коду) было бы чем-то вроде строк
task explodeModel(type: Copy) {
configurations.newConf.resolvedConfiguration.resolvedArtifacts.each { artifact ->
if (artifact.file.name.endsWith('.zip')) {
from zipTree(artifact.file)
into '.'
}
}
}
Преимущество этого решения заключается в том, что он работает против разрешенных (в отличие от запрошенных) артефактов.