Creating a recursive directory on Windows?

Hey guys, I’m sure this is something pretty simple, but I’ve yet to find a solid example online. I can create a single directory without issue, just nothing recursive. The final goal here is to create C:\Program Files\MVPSI\JAMS\Scheduler\ and I’ve tried it in a number of different ways, each one failing with an exception. The current way I’m trying (and failing with) is:

%w['C:\\Program Files\\MVPSI\\', 'C:\\Program Files\\MVPSI\\JAMS\\', 'C:\\Program Files\\MVPSI\\JAMS\\Scheduler\\'].each do |path|
directory path do
    action :create
end

Any assistance here would be fantastic.

What is the error message you are getting? There could be a syntax issue. Try removing the single quotes, and the comas in between each.

Hi Devon,
this should work, try this.

[‘C:\Program Files\MVPSI’, ‘C:\Program Files\MVPSI\JAMS’, ‘C:\Program Files\MVPSI\JAMS\Scheduler’].each do |path|
directory path do
action :create
recursive true
end
end

Thanks,
Lokesh Jangir

You’re mixing syntax a bit, ['a', 'b'] is the normal array syntax, but %w[a b] is the “word list” syntax. With the latter, you don’t use quotes or commas. So just pick which you want to use and it should be better.

Seemed to be closer, but unfortunately still no go :/. It seems to not like the space at 'Program Files' for some reason.. not sure why. This is the return I'm getting:"

[2017-09-21T19:38:18+00:00] WARN: No config file found or specified on command line, using command line options.
[2017-09-21T19:38:18+00:00] WARN: No cookbooks directory found at or above current directory. Assuming C:/Users/Administrator/chef-repo.
Starting Chef Client, version 13.2.20
resolving cookbooks for run list:
Synchronizing Cookbooks:
Installing Cookbook Gems:
Compiling Cookbooks...
[2017-09-21T19:38:24+00:00] WARN: Node EC2AMAZ-G7OH9E7 has an empty run list.
Converging 6 resources
Recipe: @recipe_files::C:/Users/Administrator/chef-repo/jams_install.rb

  • directory['C:\Program] action create

    ================================================================================
    Error executing action create on resource 'directory['C:\Program]'

    Errno::EINVAL

    Invalid argument @ dir_s_mkdir - 'C:

    Resource Declaration:

    In C:/Users/Administrator/chef-repo/jams_install.rb

    2: directory path do
    3: action :create
    4: recursive true
    5: end
    6: end

    Compiled Resource:

    Declared in C:/Users/Administrator/chef-repo/jams_install.rb:2:in `block in from_file'

    directory("'C:\Program") do
    action [:create]
    default_guard_interpreter :default
    path "'C:\Program"
    recursive true
    declared_type :directory
    cookbook_name "@recipe_files"
    recipe_name "C:/Users/Administrator/chef-repo/jams_install.rb"
    group nil
    mode nil
    owner nil
    end

    System Info:

    chef_version=13.2.20
    platform=windows
    platform_version=10.0.14393
    ruby=ruby 2.4.1p111 (2017-03-22 revision 58053) [i386-mingw32]
    program_name=C:/opscode/chefdk/modules/chef/../../bin/chef-client
    executable=C:/opscode/chefdk/bin/chef-client

Running handlers:
[2017-09-21T19:38:25+00:00] ERROR: Running exception handlers
Running handlers complete
[2017-09-21T19:38:25+00:00] ERROR: Exception handlers complete
Chef Client failed. 0 resources updated in 05 seconds
[2017-09-21T19:38:25+00:00] FATAL: Stacktrace dumped to C:/Users/Administrator/.chef/local-mode-cache/cache/chef-stacktrace.out
[2017-09-21T19:38:25+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2017-09-21T19:38:25+00:00] FATAL: Errno::EINVAL: directory['C:\Program] (@recipe_files::C:/Users/Administrator/chef-repo/jams_install.rb line 2) had an error: Errno::EINVAL: Invalid argument @ dir_s_mkdir - 'C:

You only need a single \ in the path name. Here is a working example that I am using:

%w(E:\scripts E:\data).each do |dir|
  directory dir do
    action :create
  end
end

Hey there, I used the two slashes as it seemed to be throwing an error when I only had a single one. It just doesn’t seem to be liking having any spaces in the Folder Name is the bigger issue I’m running into now.

I would then try leverage the other format:

Example

['E:\scripts', 'E:\data'].each do |dir|
  directory dir do
    action :create
  end
end

Yeah that’s the way I currently have it. I did a test creating C:\Test C:\Test\Test2 C:\Test\Test2\Test3 without issue, it just seems to be the space. Here’s what I’m currently at:

%w['C:\Program Files\MVPSI', 'C:\Program Files\MVPSI\JAMS', 'C:\Program Files\MVPSI\JAMS\Scheduler']. each do |path|
    directory path do
    action :create
    recursive true
    end
end

Why not simply define one path ( the leaf path ) a let the recursive true do rest of the job?

directory "C:\\Program Files\\MVPSI\\JAMS\\Scheduler" do
  action :create
  recursive true
end
2 Likes

Haha, wow - that absolutely did work. I had read a post on Stack Overflow showing it had to be done individually through the tree. Anyway, that did it for me, thanks again!

Glad to hear. Actually the root cause was the space in the folder name. To prevent that you have to use double quotes and within the double quotes you have have to escape the backward slashes.

If you care about permissions you will want to check that as permissions
are only applied to the leaf if you are setting them.

Permissions in this case I don’t need to worry about, but as I dive into things deeper it’ll come into play. Thanks!

Yeah, unfortunately my knowledge of Ruby at the moment is pretty weak, I was definitely noticing oddities in my IDE with the slashes needing to be escaped.