Flattening of File Tree when using Grunt Copy Task

Not sure if I'm missing something but I have the following grunt setup for grunt-contrib-copy tasks.

copy: {
  build: {
    files: {
      "server-dist/": "server/**/*.!(coffee)",
      "client-dist/": "client/**/*.!(coffee)"
    }
  }
}

The client-dist copies as I expect recursively running through the file tree but the server-dist all sub-folders get flattened to the base folder. Any ideas why this is happening? Here is the i/o

server/
  views/
    errors/
      404.jade
    layouts/
      base.jade

becomes

server/
  errors/
  layouts/
    base.jade

the views folder gets completely blown out. One more thing...when I removed !(coffee) it works but I need to exclude coffee files since I have a grunt-coffee watch task running.

A followup to zacks comment:

copy: {  
    mytask: {  
        files: [  
        {expand:true, cwd:'dev-js/abc/', dest:'js/test/', src:['def.js']}  
        ]  
    }  
}  

This copies the file ./dev-js/abc/def.js to ./js/test/def.js - at least on my 0.4.1 version. Zacks comment and the link included was very helpful, especially the fact, that basePath has been replaced.

Apparently the grunt-contrib-copy task has a sophisticated logic that's trying to automatically detect the base directory for copying source files (see related issue)

The solution is to explicitly specify the basePath option:

copy: {
  build: {
    files: {
      "server-dist/": "server/**/*!(.coffee)"
    },
    options: {
      basePath: 'server' // base directory in the source path
    }
  }
}

P.S. I'm not sure, however, why removing !(.coffee) changes the behaviour for you. I tried the same on my local machine and get the same results when specifying "server/**/*" instead of "server/**/*.!(coffee)" (i.e. the views folder is skipped)