Copy subdirectory of fileTree into dest vs top level folder

(Christopher Dieringer) #1


i have a fileTree. suppose it’s:

      ... (files) ...

i then have a copy closure:

  copy {
    into myDest

on run, what i get is /path/to/myDest/lib/file1.jar.

what i desire is /path/to/myDest/file1.jar. note, no lib is in that path.

it’s not clear to me how to achieve this simple task. thanks!

(Janito Vaqueiro Ferreira Filho) #2

There’s probably an easier way, but the only way I know is to iterate through all files in the file tree, and add only normal files (no sub-directories):

copy {
    fileTree('lib').each { file ->
        if (file.isFile())
            from file

(Christopher Dieringer) #3

hey @jvff, thanks. Unfortunately, the code you presented flattens the folder structure. What i’m looking to do instead is move a subdir from within a fileTree to a target.

(Janito Vaqueiro Ferreira Filho) #4

Ok, that should be easier :slight_smile:

I think you can convert it from a FileTree into a path, then add it with the desired sub-path.

copy {
    from myFileTree.asPath + '/lib'
    into myDest

If you need to obtain the directories in the first level of the file tree, you can transform it into a file and list its contents, adding all directories:

copy {
    myFileTree.singleFile().listFiles().each { entry ->
        if (entry.isDirectory())
            from entry
    into myDest

I’m not sure if the myFile.singleFile() call works. If it doesn’t, you can try file(myFileTree.asPath).

Hope this helps :slight_smile:

(Lance Java) #5

from(myFileTree.files) should have the desired effect. It will ‘flatten’ the tree to a set of files

(Schalk Cronjé) #6

There are two opinionated solutions I can see:

The more simplistic solution where one just include the lib part in the from.

copy {
  from "${myLibTree}/lib", {
    include '**'
  into myDest

A more generic solution which will handle deeper paths:

copy {
  from myLIbTree
  into myDest
  eachFile { fcd ->
    def relPath = fcd.relativePath
    if(relPath.lastName == 'lib' && fcd.isDirectory()) {
    } else if(relPath.parent.lastName == 'lib') {
        def segments = relPath.segments
        fcd.relativePath = new RelativePath( !fcd.isDirectory() ,(segments.take(segments.size()-2) + segments[-1]) as String[]  )

The only problem with the second solution is that it leaves a dangling empty lib folder in the destination. It is something I have traditionally solved by adding a doLast { delete '/path/to/lib' } action to the task.

(Christopher Dieringer) #7

hey @Lance_Java, thank you, however flattened is not desired. ref

(Christopher Dieringer) #8

awesome! i’ll try the top solution! thx

(Jocca) #9

Hi, sorry, this is an old thread, but it appears in the top result of search machines.

The solution below worked for me:

task copyDirAndFiles(type: Copy) {
  def tree = fileTree('lib') {
    include '**/*'
  from tree
  into 'myDest'