Search code examples
rubyrakerakefile

Rake error: Permission denied - c:/xampp/htdocs/home/shared/data


I had a basic copy function working, but I extended it to handle sub directories when passed ancestors and now receive an error.

def copy_to(dest, src)

    files = FileList.new()
    EXT_ALLOWED.each {|ext| files.include "#{src}/**/*.#{ext}"}
    files.each do |file|
        dir = File.dirname(file)
        filename = File.basename(file)
        path = dir.match(/shared\/(.*)/)
        if dest == path[1] + '/'
            bin = dest
        else
            bin = File.join(dest, path[1] + '/')
        end
        puts "copying #{filename} to #{bin}"
        FileUtils.mkdir_p(bin)
        FileUtils.cp src, bin
    end

end

Here is how I am calling the function:

task :ui_gateway do
  copy_to 'static/', 'c:/xampp/htdocs/home/shared/css'
  copy_to 'static/', 'c:/xampp/htdocs/home/shared/fonts'
  copy_to 'static/', 'c:/xampp/htdocs/home/shared/images'
  copy_to 'static/', 'c:/xampp/htdocs/home/shared/lib'
  copy_to 'static/', 'c:/xampp/htdocs/home/shared/scripts'
  copy_to 'ui/', 'c:/xampp/htdocs/home/shared/ui'
end

The complete --trace:

C:\xampp\htdocs\home\app\gateway>rake ui_gateway --trace                       
(in C:/xampp/htdocs/home/app/gateway)                                              
** Invoke ui_gateway (first_time)                                                                 
** Execute ui_gateway                                                                             
copying controls.css to static/css/                                                            
rake aborted!                                                                                         
Permission denied - c:/xampp/htdocs/home/shared/css                                
C:/Ruby191/lib/ruby/1.9.1/fileutils.rb:1265:in `initialize'                                           
C:/Ruby191/lib/ruby/1.9.1/fileutils.rb:1265:in `copy_stream'                                          
C:/Ruby191/lib/ruby/1.9.1/fileutils.rb:1265:in `block in copy_file'                                   
C:/Ruby191/lib/ruby/1.9.1/fileutils.rb:1264:in `open'                                                 
C:/Ruby191/lib/ruby/1.9.1/fileutils.rb:1264:in `copy_file'                                            
C:/Ruby191/lib/ruby/1.9.1/fileutils.rb:471:in `copy_file'                                             
C:/Ruby191/lib/ruby/1.9.1/fileutils.rb:392:in `block in cp'                                           
C:/Ruby191/lib/ruby/1.9.1/fileutils.rb:1396:in `block in fu_each_src_dest'                            
C:/Ruby191/lib/ruby/1.9.1/fileutils.rb:1410:in `fu_each_src_dest0'                                    
C:/Ruby191/lib/ruby/1.9.1/fileutils.rb:1394:in `fu_each_src_dest'                                     
C:/Ruby191/lib/ruby/1.9.1/fileutils.rb:391:in `cp'                                                    
C:/xampp/htdocs/home/fugrosdes/src/oars/app/gateway/rakefile.rb:34:in `block in copy_to'              
C:/Ruby191/lib/ruby/1.9.1/rake.rb:1248:in `each'                                                      
C:/Ruby191/lib/ruby/1.9.1/rake.rb:1248:in `each'                                                      
C:/xampp/htdocs/home/fugrosdes/src/oars/app/gateway/rakefile.rb:23:in `copy_to'                       
C:/xampp/htdocs/home/fugrosdes/src/oars/app/gateway/rakefile.rb:62:in `block in <top (required)>'     
C:/Ruby191/lib/ruby/1.9.1/rake.rb:613:in `call'                                                       
C:/Ruby191/lib/ruby/1.9.1/rake.rb:613:in `block in execute'                                           
C:/Ruby191/lib/ruby/1.9.1/rake.rb:608:in `each'                                                       
C:/Ruby191/lib/ruby/1.9.1/rake.rb:608:in `execute'                                                    
C:/Ruby191/lib/ruby/1.9.1/rake.rb:574:in `block in invoke_with_call_chain'                            
C:/Ruby191/lib/ruby/1.9.1/monitor.rb:190:in `mon_synchronize'                                         
C:/Ruby191/lib/ruby/1.9.1/rake.rb:567:in `invoke_with_call_chain'                                     
C:/Ruby191/lib/ruby/1.9.1/rake.rb:560:in `invoke'                                                     
C:/Ruby191/lib/ruby/1.9.1/rake.rb:2012:in `invoke_task'                                               
C:/Ruby191/lib/ruby/1.9.1/rake.rb:1990:in `block (2 levels) in top_level'                             
C:/Ruby191/lib/ruby/1.9.1/rake.rb:1990:in `each'                                                      
C:/Ruby191/lib/ruby/1.9.1/rake.rb:1990:in `block in top_level'                                        
C:/Ruby191/lib/ruby/1.9.1/rake.rb:2029:in `standard_exception_handling'                               
C:/Ruby191/lib/ruby/1.9.1/rake.rb:1984:in `top_level'                                                 
C:/Ruby191/lib/ruby/1.9.1/rake.rb:1963:in `block in run'                                              
C:/Ruby191/lib/ruby/1.9.1/rake.rb:2029:in `standard_exception_handling'                               
C:/Ruby191/lib/ruby/1.9.1/rake.rb:1960:in `run'                                                       
C:/Ruby191/bin/rake:31:in `<main>'

The goal is to have a directory created in the destination directory which matches the directory(s) in the source. If the destination is static and the source is c:/xampp/htdocs/home/shared/css the resulting destination should be static/css/. Then the files from the shared directories would be copied to the destination. If the source has sub-directories they would need to be created as well and the dir.match() function seems to be getting the information required.

EDIT Added the following line if the if condition to make the appropriate directories and subs -

FileUtils.mkdir_p(bin)

This does create the appropriate directories and subs if I comment out the line which is suppose to perform the copy.


Solution

  • The file utilities in Ruby / Rake require that you are very specific about files in order to operate on them. In the original code src only refers to the path (2nd argument) sent to the copy_to function. The file names, as part of those paths, is not retrieved until the files.each loop:

    files.each do |file|
    

    At this point file contains the full path to the file as well as the file name. This is what must be the first argument in the copy function:

    FileUtils.cp file, bin
    

    PRIOR to attempting to copy any files all of the directories must be in place or you will get a different error:

    copying c:/xampp/htdocs/home/shared/css/controls.css to static/css/

    rake aborted!
    Invalid argument - static/css/

    Creating the new directories is done by adding the following line to the copy_to function just after the if condition:

    FileUtils.mkdir_p(bin)
    

    This creates the directory if it does not exist, which then allows the file to be copied into it.

    Suggestion for improvement - It seems inefficient to try the mkdir_p on every file, rewrite this such that the directories are checked and then created if need be. (The additional overhead might not be worth an extra check, worth exploring.)