diff --git a/functions/dir_split.pp b/functions/dir_split.pp index b74ae74..b8598b2 100644 --- a/functions/dir_split.pp +++ b/functions/dir_split.pp @@ -1,25 +1,26 @@ # @summary Splits the given directory or directories into individual paths. # # Use this function when you need to split a absolute path into multiple absolute paths # that all descend from the given path. # # @param dirs [Variant[Stdlib::Absolutepath, Array[Stdlib::Absolutepath]]] - either an absolute path or a array of absolute paths. # @return [Array[String]] - an array of absolute paths after being cut into individual paths. # @example calling the function # extlib::dir_split('/opt/puppetlabs') => ['/opt', '/opt/puppetlabs'] -function extlib::dir_split(Variant[Stdlib::Absolutepath, Array[Stdlib::Absolutepath]] $dirs) >> Array[String] { +function extlib::dir_split(Variant[Stdlib::Absolutepath, Array[Stdlib::Absolutepath]] *$values) >> Array[String] { + $dirs = $values.flatten.unique $sep = extlib::file_separator() - $dirs_array = [$dirs].flatten.unique.map | Stdlib::Absolutepath $dir | { + $dirs_array = $dirs.map | Stdlib::Absolutepath $dir | { $dir.split(shell_escape($sep)).reduce([]) |Array $acc, $value | { $counter = $acc.length - 1 $acc_value = ($acc[$counter] =~ Undef) ? { true => '', false => $acc[$counter] } unless empty($value) { $acc + extlib::path_join([$acc_value, $value]) } else { $acc } } } $dirs_array.flatten.unique } diff --git a/functions/mkdir_p.pp b/functions/mkdir_p.pp index ddefe56..ecd9964 100644 --- a/functions/mkdir_p.pp +++ b/functions/mkdir_p.pp @@ -1,20 +1,22 @@ # @summary Like the unix command mkdir_p except with puppet code. # This creates file resources for all directories and utilizes the dir_split() function # to get a list of all the descendant directories. You will have no control over any other parameters # for the file resource. If you wish to control the file resources you can use the dir_split() function # and get an array of directories for use in your own code. Please note this does not use an exec resource. # # @param dirs [Variant[Stdlib::Absolutepath, Array[Stdlib::Absolutepath]]] - the path(s) to create # @return [Array[Stdlib::Absolutepath]] # @example How to use # extlib::mkdir_p('/opt/puppetlabs/bin') => ['/opt', '/opt/puppetlabs', '/opt/puppetlabs/bin'] # @note splits the given directories into paths that are then created using file resources # @note if you wish to create the directories manually you can use the extlib::dir_split() function in the same manner -function extlib::mkdir_p(Variant[Stdlib::Absolutepath, Array[Stdlib::Absolutepath]] $dirs) >> Array[Stdlib::Absolutepath] { - $dirs_array = extlib::dir_split($dirs) +function extlib::mkdir_p(Variant[Stdlib::Absolutepath, Array[Stdlib::Absolutepath]] *$dirs) >> Array[Stdlib::Absolutepath] { + $dirs_array = $dirs.flatten.unique.map |$dir| { + extlib::dir_split($dir) + }.flatten.unique.sort @file { $dirs_array: ensure => directory, } realize(File[$dirs_array]) $dirs_array } diff --git a/functions/path_join.pp b/functions/path_join.pp index 7ddcfeb..7513de2 100644 --- a/functions/path_join.pp +++ b/functions/path_join.pp @@ -1,29 +1,30 @@ # @summary Take one or more paths and join them together using the os specific separator. # Because in how windows uses a different separator this function # will format a windows path into a equilivent unix like path. This type of unix like # path will work on windows. # # @param dirs Joins two or more directories by file separator. # @return [Stdlib::Absolutepath] The joined path # @example Joining Unix paths to return `/tmp/test/libs` # extlib::path_join(['/tmp', 'test', 'libs']) # @example Joining Windows paths to return `/c/test/libs` # extlib::path_join(['c:', 'test', 'libs']) -function extlib::path_join(Array[String] $dirs) >> Stdlib::Absolutepath { +function extlib::path_join(Variant[String, Array[String]] *$values) >> Stdlib::Absolutepath { $unix_sep = '/' $sep_regex = /\/|\\/ + $dirs = $values.flatten $first_value = $dirs[0] # when first value is absolute path, append all other elements # by breaking the path into pieces first, then joining if $first_value =~ Stdlib::Absolutepath { $fixed_dirs = $first_value.split($sep_regex) + $dirs.delete($first_value) } else { $fixed_dirs = $dirs } $no_empty_dirs = $fixed_dirs.filter |$dir| { !empty($dir) } $dirs_without_sep = $no_empty_dirs.map |String $dir | { # remove : and file separator $dir.regsubst($sep_regex, '').regsubst(':', '') } join([$unix_sep,$dirs_without_sep.join($unix_sep)]) } diff --git a/spec/functions/extlib/dir_split_spec.rb b/spec/functions/extlib/dir_split_spec.rb index 6df1af9..d96300d 100644 --- a/spec/functions/extlib/dir_split_spec.rb +++ b/spec/functions/extlib/dir_split_spec.rb @@ -1,60 +1,68 @@ require 'spec_helper' describe 'extlib::dir_split' do describe 'windows' do let(:dirs) do 'c:\windows\puppetlabs\puppet\embedded\gems' end let(:facts) do { kernel: 'windows' } end it { is_expected.to run.with_params(dirs).and_return(['/c', '/c/windows', '/c/windows/puppetlabs', '/c/windows/puppetlabs/puppet', '/c/windows/puppetlabs/puppet/embedded', '/c/windows/puppetlabs/puppet/embedded/gems']) } describe 'multiple_dirs' do let(:dirs) do ['c:\windows\puppetlabs\puppet\embedded\gems', 'c:\temp\gems'] end it { is_expected.to run.with_params(dirs).and_return(['/c', '/c/windows', '/c/windows/puppetlabs', '/c/windows/puppetlabs/puppet', '/c/windows/puppetlabs/puppet/embedded', '/c/windows/puppetlabs/puppet/embedded/gems', '/c/temp', '/c/temp/gems']) } end end describe 'not_windows' do let(:dirs) do '/opt/puppetlabs/puppet/embedded/bin/gems' end let(:facts) do { kernel: 'linux' } end it { is_expected.to run.with_params(dirs).and_return(['/opt', '/opt/puppetlabs', '/opt/puppetlabs/puppet', '/opt/puppetlabs/puppet/embedded', '/opt/puppetlabs/puppet/embedded/bin', '/opt/puppetlabs/puppet/embedded/bin/gems']) } describe 'multiple_dirs' do let(:dirs) do ['/opt/puppetlabs/puppet/embedded/bin/gems', '/tmp/gems'] end it { is_expected.to run.with_params(dirs).and_return(['/opt', '/opt/puppetlabs', '/opt/puppetlabs/puppet', '/opt/puppetlabs/puppet/embedded', '/opt/puppetlabs/puppet/embedded/bin', '/opt/puppetlabs/puppet/embedded/bin/gems', '/tmp', '/tmp/gems']) } end + + describe 'multiple_dirs using comma' do + it { + is_expected.to run.with_params('/opt/puppetlabs/puppet/embedded/bin/gems', '/tmp/gems').and_return(['/opt', '/opt/puppetlabs', '/opt/puppetlabs/puppet', + '/opt/puppetlabs/puppet/embedded', '/opt/puppetlabs/puppet/embedded/bin', + '/opt/puppetlabs/puppet/embedded/bin/gems', '/tmp', '/tmp/gems']) + } + end end end diff --git a/spec/functions/extlib/mkdir_p_spec.rb b/spec/functions/extlib/mkdir_p_spec.rb index 62fddf6..e7c552d 100644 --- a/spec/functions/extlib/mkdir_p_spec.rb +++ b/spec/functions/extlib/mkdir_p_spec.rb @@ -1,61 +1,73 @@ require 'spec_helper' describe 'extlib::mkdir_p' do describe 'windows' do let(:dirs) do 'c:\windows\puppetlabs\puppet\embedded\gems' end let(:facts) do { kernel: 'windows' } end it { is_expected.to run.with_params(dirs).and_return(['/c', '/c/windows', '/c/windows/puppetlabs', '/c/windows/puppetlabs/puppet', '/c/windows/puppetlabs/puppet/embedded', '/c/windows/puppetlabs/puppet/embedded/gems']) } describe 'multiple_dirs' do let(:dirs) do ['c:\windows\puppetlabs\puppet\embedded\gems', 'c:\temp\gems'] end it { - is_expected.to run.with_params(dirs).and_return(['/c', '/c/windows', '/c/windows/puppetlabs', - '/c/windows/puppetlabs/puppet', '/c/windows/puppetlabs/puppet/embedded', - '/c/windows/puppetlabs/puppet/embedded/gems', '/c/temp', '/c/temp/gems']) + is_expected.to run.with_params(dirs).and_return(["/c", "/c/temp", "/c/temp/gems", + "/c/windows", "/c/windows/puppetlabs", "/c/windows/puppetlabs/puppet", + "/c/windows/puppetlabs/puppet/embedded", + "/c/windows/puppetlabs/puppet/embedded/gems"]) } end end describe 'not_windows' do let(:dirs) do '/opt/puppetlabs/puppet/embedded/bin/gems' end let(:facts) do { kernel: 'linux' } end it { is_expected.to run.with_params(dirs).and_return(['/opt', '/opt/puppetlabs', '/opt/puppetlabs/puppet', '/opt/puppetlabs/puppet/embedded', '/opt/puppetlabs/puppet/embedded/bin', '/opt/puppetlabs/puppet/embedded/bin/gems']) } describe 'multiple_dirs' do let(:dirs) do ['/opt/puppetlabs/puppet/embedded/bin/gems', '/tmp/gems'] end let(:expected_dirs) do ['/opt', '/opt/puppetlabs', '/opt/puppetlabs/puppet', '/opt/puppetlabs/puppet/embedded', '/opt/puppetlabs/puppet/embedded/bin', '/opt/puppetlabs/puppet/embedded/bin/gems', '/tmp', '/tmp/gems'] end it { is_expected.to run.with_params(dirs).and_return(expected_dirs) } end + + describe 'multiple_dirs with comma' do + + let(:expected_dirs) do + ['/opt', '/opt/puppetlabs', '/opt/puppetlabs/puppet', + '/opt/puppetlabs/puppet/embedded', '/opt/puppetlabs/puppet/embedded/bin', + '/opt/puppetlabs/puppet/embedded/bin/gems', '/tmp', '/tmp/gems'] + end + + it { is_expected.to run.with_params('/opt/puppetlabs/puppet/embedded/bin/gems', '/tmp/gems').and_return(expected_dirs) } + end end end diff --git a/spec/functions/extlib/path_join_spec.rb b/spec/functions/extlib/path_join_spec.rb index e2df2fe..43cdee7 100644 --- a/spec/functions/extlib/path_join_spec.rb +++ b/spec/functions/extlib/path_join_spec.rb @@ -1,34 +1,48 @@ require 'spec_helper' describe 'extlib::path_join' do describe 'windows' do let(:dirs) do ['c:', 'tmp', 'test', 'test.txt'] end let(:facts) do { kernel: 'windows' } end it { is_expected.to run.with_params(dirs).and_return('/c/tmp/test/test.txt') } it { is_expected.to run.with_params(['c:\\windows\\puppetlabs\\puppet\\embedded\\gems']).and_return('/c/windows/puppetlabs/puppet/embedded/gems') } it { is_expected.to run.with_params(['/c']).and_return('/c') } end describe 'not_windows' do let(:dirs) do ['/tmp', 'test', 'test'] end let(:facts) do { kernel: 'linux' } end it { is_expected.to run.with_params(dirs).and_return('/tmp/test/test') } it { is_expected.to run.with_params(['/tmp']).and_return('/tmp') } end + + describe 'multiple dirs with comma' do + let(:dirs) do + ['/tmp', 'test', 'test'] + end + + let(:facts) do + { + kernel: 'linux' + } + end + it { is_expected.to run.with_params(dirs).and_return('/tmp/test/test') } + it { is_expected.to run.with_params('/tmp', 'test', 'test').and_return('/tmp/test/test') } + end end