Page 1 of 1

Delete Directory

PostPosted: Mon Oct 17, 2016 02:55
by octacian
How can I delete all the files and subdirectories with their files inside of a directory? I'm working on the finishing touches of the new file system for my mod digicompute, and need to be able to remove the computer directory on destruct. The directory I'm trying to delete is in worldpath/digicompute/<playername>/<computername>, in this case that being digicompute/digicompute/singleplayer/oct6.

call to rm directory function:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
on_destruct = function(pos)
      local meta = minetest.get_meta(pos) -- get meta
      digicompute.fs.rm(pos)
    end,


rm directory function:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
-- [function] de-initialize fs (delete)
function digicompute.fs.rm(pos)
  local meta = minetest.get_meta(pos) -- meta
  local player = meta:get_string("owner") -- owner username
  local cname = meta:get_string("name") -- name

  -- [local function] remove files
  local function rm_files(ppath, files)
    for i in files do
      os.remove(ppath.."/"..i)
    end
  end

  -- [local function] check and rm dir
  local function rm_dir(dpath)
    local files = minetest.get_dir_list(cpath, false)
    local subdirs = minetest.get_dir_list(cpath, true)
    rm_files(files, dpath)
    if subdirs then
      for i in subdirs do
        rm_dir(dpath.."/"..i)
      end
    end
    os.remove(dpath)
  end

  rm_dir(path.."/"..player.."/"..cname)
end


This combination throws the following error:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
2016-10-16 19:32:59: WARNING[Server]: Undeclared global variable "cpath" accessed at ...minetest/worlds/digicompute/worldmods/digicompute/fs.lua:40
2016-10-16 19:32:59: ERROR[Main]: ServerError: Lua: Runtime error from mod 'digicompute' in callback node_on_dig(): Runtime error from mod 'digicompute' in callback node_on_destruct(): ...minetest/worlds/digicompute/worldmods/digicompute/fs.lua:40: bad argument #1 to 'get_dir_list' (strin
2016-10-16 19:32:59: ERROR[Main]:  expected, got nil)
2016-10-16 19:32:59: ERROR[Main]: stack traceback:
2016-10-16 19:32:59: ERROR[Main]:    [C]: in function 'get_dir_list'
2016-10-16 19:32:59: ERROR[Main]:    ...minetest/worlds/digicompute/worldmods/digicompute/fs.lua:40: in function 'rm_dir'
2016-10-16 19:32:59: ERROR[Main]:    ...minetest/worlds/digicompute/worldmods/digicompute/fs.lua:51: in function 'rm'
2016-10-16 19:32:59: ERROR[Main]:    ...etest/worlds/digicompute/worldmods/digicompute/c_api.lua:102: in function <...etest/worlds/digicompute/worldmods/digicompute/c_api.lua:100>
2016-10-16 19:32:59: ERROR[Main]:    [C]: in function 'remove_node'
2016-10-16 19:32:59: ERROR[Main]:    /usr/local/share/minetest/builtin/game/item.lua:488: in function </usr/local/share/minetest/builtin/game/item.lua:441>
2016-10-16 19:32:59: ERROR[Main]: stack traceback:
2016-10-16 19:32:59: ERROR[Main]:    [C]: in function 'remove_node'
2016-10-16 19:32:59: ERROR[Main]:    /usr/local/share/minetest/builtin/game/item.lua:488: in function </usr/local/share/minetest/builtin/game/item.lua:441>


Thanks!

Re: Delete Directory

PostPosted: Mon Oct 17, 2016 07:30
by Byakuren
You can see in the error message that you are using the variable "cpath", which is nil. Maybe you meant dpath?

Re: Delete Directory

PostPosted: Mon Oct 17, 2016 14:30
by kaeza
Other issues I can see:

  • You have:
    Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
    Code: Select all
    local function rm_files(ppath, files)

    But you call it as:
    Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
    Code: Select all
    rm_files(files, dpath)
  • The `for` loop is incorrect:
    Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
    Code: Select all
    for i in files do

    To make it short, you need something like this:
    Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
    Code: Select all
    for _, f in ipairs(files) do

    Please have a read of section 2.4.5 of the Lua manual.
  • I'm not 100% sure if `os.remove(somedir)` is portable. It may work in your case but fail on others. This is a minor point.

Re: Delete Directory

PostPosted: Mon Oct 17, 2016 15:46
by octacian
Thanks kaeza! Can't believe I didn't notice some of those mistakes.. Anyways, I got it working. In the end, my entire rm function looked like this:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
-- [function] de-initialize fs (delete)
function digicompute.fs.rm(pos)
  local meta = minetest.get_meta(pos) -- meta
  local player = meta:get_string("owner") -- owner username
  local cname = meta:get_string("name") -- name

  -- [local function] remove files
  local function rm_files(ppath, files)
    for _, f in ipairs(files) do
      os.remove(ppath.."/"..f)
    end
  end

  -- [local function] check and rm dir
  local function rm_dir(dpath)
    local files = minetest.get_dir_list(dpath, false)
    local subdirs = minetest.get_dir_list(dpath, true)
    rm_files(dpath, files)
    if subdirs then
      for _, d in ipairs(subdirs) do
        rm_dir(dpath.."/"..d)
      end
    end
    os.remove(dpath)
  end

  rm_dir(path.."/"..player.."/"..cname)
end


Then I could simply call it with the node's on_destruct like this:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
on_destruct = function(pos)
      local meta = minetest.get_meta(pos) -- get meta
      if meta:get_string("owner") then digicompute.fs.rm(pos) end -- if owner, rm dir
end,


So anyways, thanks again!