dirtree

function dirtree( dir ) --> iter

Description

Provides a Lua iterator function that recursively iterates over the files and subdirectories in a given directory(dir).

Parameters

dir

The directory that should be loaded.

Return Values

iter

Iterator that delivers the dirname and basename of each entry at any level.

Code

local lfs = require( "lfs" ) --ZREQ-lfs
--ZFUNC-dirtree-v1
local function dirtree( dir ) --> iter
   --ZFUNC-isdodd-v1
   local function isdodd( e )
      if e == "." or e == ".." then
         return true
      end

      return false
   end

   assert( dir and dir ~= "", "directory parameter is missing or empty" )
   if string.sub( dir, -1 ) == "/" then
      dir = string.sub( dir, 1, -2 )
   end

   local function yieldtree( dir )
      for base in lfs.dir( dir ) do
         if not isdodd( base ) then
            entry = dir.."/"..base
            local mode = lfs.attributes( entry, "mode" )
            coroutine.yield( dir, base )
            if mode == "directory" then
               yieldtree( dir.."/"..base )
            end
         end
      end
   end

   return coroutine.wrap( function() yieldtree( dir ) end )
end

return dirtree

Examples

local t = require( "taptest" )
local countlen = require( "countlen" )
local dirtree = require( "dirtree" )
local mkdirtree = require( "mkdirtree" )
local rmdirtree = require( "rmdirtree" )
local same = require( "same" )

-- setup
t( mkdirtree{
   tmp_dirtree = {
      dir1 = {
         file1 = "content1",
         file2 = "content2"
      },
      dir2 = {
         file3 = "content3"
      }
   }
}, true )

-- test
entries = {}
for dir, base in dirtree( "tmp_dirtree" ) do
   entries[ base ] = dir
end

t( countlen( entries ), 5 )
t( same( entries.dir1, "tmp_dirtree" ), true )
t( same( entries.file1, "tmp_dirtree/dir1" ), true )
t( same( entries.file2, "tmp_dirtree/dir1" ), true )
t( same( entries.dir2, "tmp_dirtree" ), true )
t( same( entries.file3, "tmp_dirtree/dir2" ), true )

-- teardown
t( rmdirtree( "tmp_dirtree" ), true )

t()