Closed Bug 804566 Opened 12 years ago Closed 12 years ago

[OS.File] Add an option ignoreExisting to OS.File.makeDir

Categories

(Toolkit Graveyard :: OS.File, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED
mozilla19

People

(Reporter: Yoric, Assigned: eduardn)

Details

(Keywords: dev-doc-complete, Whiteboard: [mentor=Yoric][lang=js][patch=bug-804566-fix])

Attachments

(2 files, 6 obsolete files)

One of the main uses of directory creation is ensuring that a directory exists, regardless of whether it already existed. We should add an option |ignoreExisting| to |OS.File.createDirectory|. If directory creation fails because a file or directory already exists at this path, it should simply ignore the error.
Whiteboard: [mentor=Yoric][lang=js]
I would like to work on this bug, could you tell me where to start. Thanks!
Flags: needinfo?(dteller)
Hi Eduard, and welcome aboard! This bug is about method |OS.File.makeDir|, which is defined in: - http://dxr.mozilla.org/mozilla-central/toolkit/components/osfile/osfile_unix_front.jsm.html#l322 (Unix version); - http://dxr.mozilla.org/mozilla-central/toolkit/components/osfile/osfile_win_front.jsm.html#l380 (Windows version). Both implementations proceed as follows: - decode options; - call the operating system's low-level function; - use throw_on_negative/throw_on_zero to convert any low-level error into an exception. In both versions, you will need to: - determine if |options.ignoreExisting| is true; - under Unix, if |options.ignoreExisting| is indeed true, and if the low-level function returns -1, and if |ctypes.errno| is |OS.Constants.libc.EEXIST|, return normally, otherwise throw an error; - under Windows, if |options.ignoreExisting| is indeed true, and if the low-level function returns 0, and if |ctypes.winLastError| is |OS.Constants.Win.ERROR_ALREADY_EXISTS|, return normally, otherwise throw an error. A second step will be to add a test for the new feature, but let's see that a little later.
Assignee: nobody → eduardnem
Flags: needinfo?(dteller)
Summary: [OS.File] Add an option ignoreExisting to OS.File.createDirectory → [OS.File] Add an option ignoreExisting to OS.File.makeDir
Attached patch First patch (obsolete) — Splinter Review
I took the liberty of creating a test (hope it's fine) but I can't seem to make it run.
Attachment #675286 - Flags: review?(dteller)
Attached patch Second patch (obsolete) — Splinter Review
Attachment #675286 - Attachment is obsolete: true
Attachment #675286 - Flags: review?(dteller)
Attachment #675330 - Flags: review?(dteller)
Comment on attachment 675330 [details] [diff] [review] Second patch Review of attachment 675330 [details] [diff] [review]: ----------------------------------------------------------------- Good start, Eduard. Could you please make the following changes? ::: toolkit/components/osfile/osfile_unix_front.jsm @@ +331,5 @@ > + return; > + } > + throw_on_negative("makeDir", > + UnixFile.mkDir(path, options)); > + } This would always fail, since you attempt to create the directory twice. ::: toolkit/components/osfile/osfile_win_front.jsm @@ +389,5 @@ > + return; > + } > + throw_on_zero("makeDir", > + WinFile.CreateDirectory(path, options)) > + } Same as the Unix version, this would always fail. ::: toolkit/components/osfile/tests/mochi/main_test_osfile_async.js @@ +472,5 @@ > test.ok(stat.isDir, "I have effectively created a directory"); > > + // Creating a directory with ignoreExisting (should succeed) > + yield OS.File.makeDir(DIRNAME, {ignoreExisting: true}); > + test.ok(true, "Creating a directory with ignoreExisting succeeds"); No, that won't work: if |makeDir| fails, this will just skip the test. Just do the same thing you did in worker_test_osfile_front.js, with a |yield|.
Attachment #675330 - Flags: review?(dteller) → feedback+
Attached patch Third Patch (obsolete) — Splinter Review
Attachment #675330 - Attachment is obsolete: true
Attachment #675705 - Flags: review?(dteller)
Comment on attachment 675705 [details] [diff] [review] Third Patch Review of attachment 675705 [details] [diff] [review]: ----------------------------------------------------------------- Good progress. I suspect that the next iteration will be the right one. ::: toolkit/components/osfile/osfile_unix_front.jsm @@ +334,1 @@ > }; I agree with the idea, but I have the impression that the |if (result == -1) {| is never closed. Also, the guidelines suggest doing the opposite: if (result != -1 || options.ignoreExisting ...) { ... } ::: toolkit/components/osfile/osfile_win_front.jsm @@ +392,1 @@ > }; Same remark as Unix version. ::: toolkit/components/osfile/tests/mochi/main_test_osfile_async.js @@ +472,5 @@ > test.ok(stat.isDir, "I have effectively created a directory"); > > + // Creating a directory with ignoreExisting (should succeed) > + let result = yield OS.File.makeDir(DIRNAME, {ignoreExisting: true}); > + test.ok(!result, "Creating a directory with ignoreExisting succeeds"); No, |result| here is meaningless. try { yield OS.File.makeDir(...) test.ok(true, ...); } catch(err) { test.ok(false, ...); } Task.js is that cool :)
Attachment #675705 - Flags: review?(dteller) → feedback+
Attached patch Last Patch (obsolete) — Splinter Review
Sorry for so many iterations, this should be the last one.
Attachment #675705 - Attachment is obsolete: true
Attachment #675825 - Flags: review?(dteller)
Comment on attachment 675825 [details] [diff] [review] Last Patch Review of attachment 675825 [details] [diff] [review]: ----------------------------------------------------------------- The tests and the Unix version look good, but the Windows version needs a small fix. Sorry, that's not the final version after all :) ::: toolkit/components/osfile/osfile_unix_front.jsm @@ +325,5 @@ > options = options || noOptions; > let omode = options.unixMode || DEFAULT_UNIX_MODE_DIR; > + let result = UnixFile.mkdir(path, omode); > + > + if (result != -1 || Just a nitpick: we generally avoid whitespaces at the end of a line. Since there are a few other things to fix, could you take the opportunity to remove the whitespaces here and in the Windows version? @@ +326,5 @@ > let omode = options.unixMode || DEFAULT_UNIX_MODE_DIR; > + let result = UnixFile.mkdir(path, omode); > + > + if (result != -1 || > + options.ignoreExisting && ctypes.errno == OS.Constants.libc.EEXIST) { I believe that operator precedence is correct, I hope that the test suite confirms is :) ::: toolkit/components/osfile/osfile_win_front.jsm @@ +384,5 @@ > let security = options.winSecurity || null; > + let result = WinFile.CreateDirectory(path, security); > + > + if (!result || > + options.ignoreExisting && ctypes.errno == OS.Constants.libc.EEXIST) { No, under Windows, |ctypes.errno| and OS.Constants.libc.* are mostly useless. You should rather use |ctypes.winLastError| and |OS.Constants.Win.*| – here |OS.Constants.Win.ERROR_ALREADY_EXISTS|.
Attachment #675825 - Flags: review?(dteller) → feedback+
Attached patch Last Patch (v2) (obsolete) — Splinter Review
I made the modifications you requested + successful build + ran the tests (no failures). The tests fail if I remove |ignoreExisting| which I believe is the expected behavior. Again, I hope you were not bothered by my many patches.
Attachment #675825 - Attachment is obsolete: true
Attachment #675889 - Flags: review?(dteller)
Comment on attachment 675889 [details] [diff] [review] Last Patch (v2) Review of attachment 675889 [details] [diff] [review]: ----------------------------------------------------------------- Looks good, thank you very much. I will handle the rest shortly (runnint this through the TryServer, adding a name to the patch, etc.)
Attachment #675889 - Flags: review?(dteller) → review+
Great, Thanks! :) I have a question: How can I get access to the try server? It would be easier if I tested the patch myself before uploading it and save the reviewer time.
You should become a level 1 committer: http://www.mozilla.org/hacking/committer/ I will vouch for you.
Attached patch Ready to uploadSplinter Review
By the way, for your next bug, you should take a look at http://blog.bonardo.net/2010/06/22/so-youre-about-to-use-checkin-needed
Attachment #675889 - Attachment is obsolete: true
Attachment #676352 - Flags: review+
Thanks for all your help and resources :) I'll apply for level 1 and let you know when I do so. Is it ok if I contact you on IRC when I create the access level bug?
Attached patch Little problem (obsolete) — Splinter Review
I saw that the tests on windows failed. I investigated the problem and it turns out that the problem is with this: if (!result || ..) which should be if (result || ..) because if the |result| is 0 in the first |if| the expression will evaluate to true and return but it should remain false and evaluate the right hand side.
Attachment #676508 - Flags: review?(dteller)
Good catch, thanks. In this case, I will let you apply the instructions to which I linked above, to produce a landable patch (i.e. you need to add a name to the patch). Also, yes, do not hesitate to ping me on IRC.
Attachment #676508 - Flags: review?(dteller) → review+
Attached patch bug-804566-fixSplinter Review
Attachment #676508 - Attachment is obsolete: true
Keywords: checkin-needed
Whiteboard: [mentor=Yoric][lang=js] → [mentor=Yoric][lang=js][patch=bug-804566-fix]
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla19
Product: Toolkit → Toolkit Graveyard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: