2016-05-14 2 views
3

Вот что я пытаюсь сделать:Gradle задача: как ждать операции файла, чтобы завершить

  1. архив Copy (ZIP) от зависимостей buildscript во временном каталоге
  2. Распакуйте архив в другой каталог в build

Вот задача скопировать архив (работ)

task copyTpcds(type: Copy) { 
    file('build/zip').mkdirs() 
    from buildscript.configurations.classpath 
    include 'tpcds*' 
    into 'build/zip' 
} 

И задача распаковать, а затем удалить архив

task extractTpcds(type: Copy) { 
    def names = new FileNameFinder().getFileNames('build/zip', 'tpcds*') 
    def outDir = file('build/cmd/tpcds') 
    outDir.mkdirs() // make sure the directory exists 
    from zipTree(file(names[0])) // generates error when 
    into outDir 
    // now remove copied zip file 
    //zipFile.delete() // deletes file before the extractions completes? 
} 

Вот несколько сценариев:

  1. Если я поставил обе задачи в build.gradle и попытаться запустить что-нибудь, даже просто gradle tasks тогда я получаю эту ошибку: Neither path nor baseDir may be null or empty string. path='null' basedir='C:\dev\code\td\pdo\tpcds-tpg' из этого кода в задаче № 2: file(names[0])
  2. Если я закомментировать код во 2-й задаче, первая задача будет работать и скопировать почтовый файл build/zip
  3. Теперь я могу раскомментировать код во 2-й задаче (за исключением удаления) и выполнить gradle extractTpcds он будет работать и извлечь из архива

Так что, мне кажется, что операции

  1. файла оценивается во всех задачах, независимо от того, каких задачи являются выполненный
  2. Если у меня есть код, который копирует файл с некоторым последующим кодом, который пытается работать с копируемым файлом, тогда этот код не будет ждать завершения процесса копирования и не сработает, потому что файла еще нет.

Я нахожусь в убытке о том, как с этим бороться, и был бы очень признателен за ваши предложения

ответ

2

следующих работ для меня, используя Gradle 2.12 (и предполагая, что почтовый файл находится в files):

buildscript { 
    configurations { 
     classpath 
    } 

    dependencies { 
     classpath files("files/tpcds.zip") 
    } 
} 

def copyFiles = { -> 
    ant.mkdir(dir: "build/zip") 
    buildscript.configurations.classpath.each { def thisFile -> 
     if (thisFile.name ==~ /tpcds.*/) { 
      ant.copy(file: thisFile.absolutePath, todir: "build/zip") 
     } 
    } 
} 

tasks.whenTaskAdded { task -> 
    if (task.name == "extractTpcds") { 
     copyFiles() 
    } 
} 

task copyTpcds << { 
    copyFiles() 
} 

task extractTpcds(type: Copy) { 
    def names = new FileNameFinder().getFileNames('build/zip', 'tpcds*') 
    def outDir = file('build/cmd/tpcds') 
    outDir.mkdirs() // make sure the directory exists 
    from zipTree(file(names[0])) // generates error when 
    into outDir 
    // now remove copied zip file 
    //zipFile.delete() // deletes file before the extractions completes? 
} 

проблема с оригиналом предполагает несоответствие импеданса по отношению отношению к правилу Лёд: Инициализация фазы, фазы конфигурации и фазы выполнения. В частности, спецификация задачи «Копировать» находится в фазе конфигурации; как правило, на этапе выполнения выполняются принудительные действия (например, dependsOn). Задача extractTpcds имеет зависимость от другого кода во время фазы . Фаза конфигурации.

В моем примере есть 2 случая:

  • gradle copyTpcds будет вызывать метод copyFiles во время фазы исполнения. Значение << означает «сделать этот материал последним [на этапе выполнения]».
  • gradle tasks инициирует код в whenTaskAdded во время фазы конфигурации и вызывает copyFiles. Аналогично для gradle extractTpcds

Альтернативой этому является просто использовать AntBuilder в обеих задач и избежать Type: Copy полностью, как показано здесь:

buildscript { 
    configurations { 
     classpath 
    } 
    dependencies { 
     classpath files("files/tpcds.zip") 
    } 
} 

task copyTpcds << { 
    ant.mkdir(dir: "build/zip") 
    buildscript.configurations.classpath.each { def thisFile -> 
     if (thisFile.name ==~ /tpcds.*/) { 
      ant.copy(file: thisFile.absolutePath, todir: "build/zip") 
     } 
    } 
} 

task extractTpcds(dependsOn: 'copyTpcds') << { 
    def outDir = "build/cmd/tpcds" 
    ant.mkdir(dir: outDir) 
    def names = new FileNameFinder().getFileNames('build/zip', 'tpcds*') 
    names.eachWithIndex { zipFile, index -> 
     if (index == 0) { 
      ant.unzip(src: zipFile, dest: outDir) 
     } 
    } 
} 
+0

Это отлично работает, спасибо Майкл! Для завершения вы можете привести пример использования Ant для распаковки? – Bostone

+1

ОК, я добавил второй пример ... обратите внимание, что он распаковывает первый ZIP-файл, но может быть легко изменен по мере необходимости. –

0

Что-то вроде этого должно работать, но зачем вам нужно удалить почтовый индекс? цепочки задач с dependsOn означает, что вам нужно всего лишь запустить вторую задачу и copyTpcds будет автоматически запускаться, если входы или выходы не изменились (удалено)

task extractTpcds(type: Copy) { 

dependsOn(copyTpcds) //make this execute after 

def names = new FileNameFinder().getFileNames('build/zip', 'tpcds*') 
def outDir = file('build/cmd/tpcds') 
outDir.mkdirs() // make sure the directory exists 
from zipTree(file(names[0])) // generates error when 
into outDir 
// now remove copied zip file 
doLast { zipFile.delete() }// deletes file after the extractions completes 

}

+0

Это не работает. Как я уже сказал - это похоже на то, что вы пытаетесь запустить все переменные, включая встроенные, например. имена [0] оцениваются сразу по всему build.gradle. Поэтому, чтобы подчеркнуть смысл, если я попытаюсь запустить, казалось бы, несвязанную задачу, такую ​​как 'gradle tasks' или' gradle clean' gradle, выйдет с помощью 'Ни путь, ни baseDir может быть пустой или пустой строкой. path = 'null'' error – Bostone

+0

То есть, если zip-файл присутствует в каталоге build/zip в моем примере – Bostone

+0

Michael Ester дает объяснение, почему это не будет работать в его ответе – Bostone

Смежные вопросы