copycoffeescriptasteriskcakefile

copy task in Cakefile


I am trying to copy all the files in a list of directories and paste them into an output directory. The problem is whenever I use an *, the output says there is no file or directory by that name exists. Here is the specific error output:

cp: cannot stat `tagbox/images/*': No such file or directory
cp: cannot stat `votebox/images/*': No such file or directory

If I just put the name of a specific file instead of *, it works.

here is my Cakefile:

fs = require 'fs'

util = require 'util'
{spawn} = require 'child_process'

outputImageFolder = 'static'
imageSrcFolders = [
'tagbox/images/*'
'votebox/images/*'
]

task 'cpimgs', 'Copy all images from the respective images folders in tagbox, votebox, and omnipost into static folder', ->
  for imgSrcFolder in imageSrcFolders  
    cp = spawn 'cp', [imgSrcFolder, outputImageFolder]
    cp.stderr.on 'data', (data) ->
      process.stderr.write data.toString()
    cp.stdout.on 'data', (data) ->
      util.log data.toString()

Solution

  • You are using the * character, probably because that works for you in your shell. Using * and other wildcard characters that expand to match multiple paths is called "globbing" and while your shell does it automatically, most other programs including node/javascript/coffeescript will not do it by default. Also the cp binary itself doesn't do globbing, as you are discovering. The shell does the globbing and then passes a list of matching files/directories as arguments to cp. Look into the node module node-glob to do the globbing and give you back a list of matching files/directories, which you can then pass to cp as arguments if you like. Note that you could also use a filesystem module that would have this type of functionality built in. Note however that putting async code directly into a Cakefile can be problematic as documented here.