Bug 923540 - Add a function to recursively remove directories. r=Yoric

This commit is contained in:
Marco Castelluccio 2013-10-10 10:59:49 -04:00
parent 5934eb6acc
commit 57cb4e91c7
7 changed files with 133 additions and 0 deletions

View File

@ -771,6 +771,11 @@ File.writeAtomic = function writeAtomic(path, buffer, options = {}) {
options], [options, buffer]);
};
File.removeDir = function(path, options = {}) {
return Scheduler.post("removeDir",
[Type.path.toMsg(path), options], path);
};
/**
* Information on a file, as returned by OS.File.stat or
* OS.File.prototype.stat

View File

@ -286,6 +286,9 @@ if (this.Components) {
options
);
},
removeDir: function(path, options) {
return File.removeDir(Type.path.fromMsg(path), options);
},
new_DirectoryIterator: function new_DirectoryIterator(path, options) {
let directoryPath = Type.path.fromMsg(path);
let iterator = new File.DirectoryIterator(directoryPath, options);

View File

@ -394,5 +394,39 @@ AbstractFile.writeAtomic =
return bytesWritten;
};
/**
* Remove an existing directory and its contents.
*
* @param {string} path The name of the directory.
* @param {*=} options Additional options.
* - {bool} ignoreAbsent If |false|, throw an error if the directory doesn't
* exist. |true| by default.
* - {boolean} ignorePermissions If |true|, remove the file even when lacking write
* permission.
*
* @throws {OS.File.Error} In case of I/O error, in particular if |path| is
not a directory.
*/
AbstractFile.removeDir = function(path, options = {}) {
let iterator = new OS.File.DirectoryIterator(path);
if (!iterator.exists() && options.ignoreAbsent) {
return;
}
try {
for (let entry in iterator) {
if (entry.isDir) {
OS.File.removeDir(entry.path, options);
} else {
OS.File.remove(entry.path, options);
}
}
} finally {
iterator.close();
}
OS.File.removeEmptyDir(path);
};
exports.OS.Shared.AbstractFile = AbstractFile;
})(this);

View File

@ -817,6 +817,7 @@
File.read = exports.OS.Shared.AbstractFile.read;
File.writeAtomic = exports.OS.Shared.AbstractFile.writeAtomic;
File.removeDir = exports.OS.Shared.AbstractFile.removeDir;
/**
* Get the current directory by getCurrentDirectory.

View File

@ -756,6 +756,7 @@
File.read = exports.OS.Shared.AbstractFile.read;
File.writeAtomic = exports.OS.Shared.AbstractFile.writeAtomic;
File.removeDir = exports.OS.Shared.AbstractFile.removeDir;
/**
* Get the current directory by getCurrentDirectory.

View File

@ -0,0 +1,88 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
Components.utils.import("resource://gre/modules/osfile.jsm");
Components.utils.import("resource://gre/modules/Task.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
do_register_cleanup(function() {
Services.prefs.setBoolPref("toolkit.osfile.log", false);
});
function run_test() {
Services.prefs.setBoolPref("toolkit.osfile.log", true);
run_next_test();
}
add_task(function() {
// Set up profile. We create the directory in the profile, because the profile
// is removed after every test run.
do_get_profile();
let file = OS.Path.join(OS.Constants.Path.profileDir, "file");
let dir = OS.Path.join(OS.Constants.Path.profileDir, "directory");
let file1 = OS.Path.join(dir, "file1");
let file2 = OS.Path.join(dir, "file2");
let subDir = OS.Path.join(dir, "subdir");
let fileInSubDir = OS.Path.join(subDir, "file");
// Sanity checking for the test
do_check_false((yield OS.File.exists(dir)));
// Remove non-existent directory
let exception = null;
try {
yield OS.File.removeDir(dir);
} catch (ex) {
exception = ex;
}
do_check_true(!!exception);
do_check_true(exception instanceof OS.File.Error);
// Remove non-existent directory with ignoreAbsent
yield OS.File.removeDir(dir, {ignoreAbsent: true});
// Remove file
yield OS.File.writeAtomic(file, "content", { tmpPath: file + ".tmp" });
exception = null;
try {
yield OS.File.removeDir(file);
} catch (ex) {
exception = ex;
}
do_check_true(!!exception);
do_check_true(exception instanceof OS.File.Error);
// Remove empty directory
yield OS.File.makeDir(dir);
yield OS.File.removeDir(dir);
do_check_false((yield OS.File.exists(dir)));
// Remove directory that contains one file
yield OS.File.makeDir(dir);
yield OS.File.writeAtomic(file1, "content", { tmpPath: file1 + ".tmp" });
//yield OS.File.open(file1, {create:true});
yield OS.File.removeDir(dir)
do_check_false((yield OS.File.exists(dir)));
// Remove directory that contains multiple files
yield OS.File.makeDir(dir);
yield OS.File.writeAtomic(file1, "content", { tmpPath: file1 + ".tmp" });
yield OS.File.writeAtomic(file2, "content", { tmpPath: file2 + ".tmp" });
yield OS.File.removeDir(dir)
do_check_false((yield OS.File.exists(dir)));
// Remove directory that contains a file and a directory
yield OS.File.makeDir(dir);
yield OS.File.writeAtomic(file1, "content", { tmpPath: file1 + ".tmp" });
yield OS.File.makeDir(subDir);
yield OS.File.writeAtomic(fileInSubDir, "content", { tmpPath: fileInSubDir + ".tmp" });
yield OS.File.removeDir(dir);
do_check_false((yield OS.File.exists(dir)));
});

View File

@ -9,3 +9,4 @@ tail =
[test_logging.js]
[test_creationDate.js]
[test_path_constants.js]
[test_removeDir.js]