Подтвердить что ты не робот

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, и вот где я застрял. Я понятия не имею, как получить путь к файлу, чтобы я мог разархивировать его. Любая помощь?

Большое спасибо

4b9b3361

Ответ 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 '.'
        }
    }
}

Преимущество этого решения заключается в том, что он работает против разрешенных (в отличие от запрошенных) артефактов.