-
-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Designated backup directory revised #84
base: master
Are you sure you want to change the base?
Designated backup directory revised #84
Conversation
I think that you can just change the other PR instead of making a new one when you have new commits. Or did you want to start fresh? |
I was trying to split the minimal changes into a different commit than the broader reformatting, which involved rewriting the history. (Maybe there is a more elegant way to do this with git/GitHub, but making a fresh branch was the simplest I could figure out.) I am giving thought to the Windows As far as handling the case that the user-specified directory no longer exists, it seems like the place to do that would be |
Actually, as I read |
Reading more from the Reference on Windows paths, it looks like Racket already handles avoiding
I think that means the only concern we have to deal with is whether the result of It does seem plausible that the result of |
fd22755
to
2c3f613
Compare
re rewriting history: yes, I think that's better than creating a new pull request (you're effectively deleting the old commits but keeping the conversation when you do that in this context, whereas creating a new pull request deletes the old commits and the old conversation (or, at least, loses the connection between them)). re windows paths under racket with re finding the max path length programmatically: I don't know how to access that; I guess the FFI would be involved. I think that a note in the source with a url pointer is probably better than trying to figure out how to make the ffi work in this case. re windows-specificity: I think that's unwise. We don't have enough of the core developers using windows so adding more conditionals like Instead of hashing, one thing that could work would be to just delete the characters in the middle. If that seems bad, then maybe we should add a bit more robustness to the encoding would already help. What about using the first byte to specify what the separator is. It can be As for how to hash, an S-box hash seems like a good way to go; easy to implement and it can use up the full 255 bytes (or maybe safer to just stick with 200). Here's some code that probably works. Maybe.
As for the toc, I realized that there already is one: https://github.com/racket/gui/blob/master/gui-lib/framework/private/autosave.rkt#L35 . I see that it isn't thread safe, tho. Maybe that's better left to another day? |
012eb39
to
2051d76
Compare
I like the idea of eliding some bytes from the middle: in most cases the resulting name would probably still be decipherable to the user (certainly more so than a hash). Since this solution doesn't have that major drawback, I agree that avoiding Windows-specific code seems to make sense. I had noticed that toc as well, though it only covers autosave files, not backups. I agree it makes sense to address that as a separate issue, especially since these generated names should be more-or-less human-readable. |
My experience with DrRacket is that the backup files aren't very useful. Maybe we should try to make them useful? |
I've added tests to confirm that I was unsure whether I should also add tests for excessively-long path elements, since that would require propagating the magic number 255 into another file. A similar question is what, if anything, the docs should say about this behavior. My initial inclination would be to describe how path elements that are "potentially excessively long" are transformed while leaving unspecified how we determine what is "potentially excessively long". (For the docs overall, I've adapted what the DrRacket docs say about backup and autosave files, though I need to make a few more updates to reflect subsequent changes.) |
Do you think we should check that the current user has write permission in the same places as |
Yes, it is a good idea to test long filenames (effective tests are, in general, tuned to the specific implementation; it is nice to have tests that aren't, but I don't think we can stop there as that would mean there are untested code paths). I think that the docs should explain what the function does concretely. If you think that this number will change then the right approach is to use the phrase "excessively long" but then add a note that "currently excessively long currently is 255". I do not think that this is likely to change ever, so I think just saying 255 is fine (but also mentioning where this limit comes from in the docs). I think checking that the directory exists and that there is write permission together is the right thing. (Filesystems are racy, tho, so checking it is only about handling common situations well; the operation might still fail right after the check succeeds in rare situations.) |
About checking write permission: this is my ignorance about the preference system, but, if the predicate function given to It is probably an edge case, but I can immagine using the same preference file while intentionally running programs as different users/with different permissions, so I think not currently having write permission for the directory specified by the preference should cause the generate- functions to fall back without overwriting the saved preference, since something else (or some future run) may have the necessary permission. That could be accomplished by only checking that there is write permission in Of course, if the predicate given to |
The framework's preference library writes to the file only when preference:set is called. When the file is read and a value doesn't satisfy the preference, it is just ignored and the default is used. But the preference file is intended to be used by only a single user. It seems like lots of things will go wrong if multiple users use the same preferences file. |
6d080b0
to
360a680
Compare
Ok, I have dealt with permissions, added tests for both that and long file names, and updated the docs accordingly. I've also edited the history back down to two commits. |
While running tests, I found two more todos:
|
On the first item, I think what I was seeing was a byproduct of working at the REPL in the same file where I'd run the tests: I think Running this program: #lang racket
(require framework)
(define pref-key
'a-fake-preference)
(preferences:set-default pref-key 'default (λ (v) #t))
(define pref
(preferences:get/set pref-key))
(define (do-work)
(let ([the-prefs-table (make-hash)])
(parameterize ([preferences:low-level-put-preferences
(λ (syms vals)
(for ([sym (in-list syms)]
[val (in-list vals)])
(hash-set! the-prefs-table sym val)))]
[preferences:low-level-get-preference
(λ (sym [fail void])
(hash-ref the-prefs-table sym fail))])
(preferences:set pref-key 'do-work)
the-prefs-table)))
(pref)
(do-work)
(pref) produces the same output every time: 'default
'#hash((plt:framework-pref:a-fake-preference . do-work))
'do-work and, if set a custom value interactively (e.g. So I think this was a false alarm on my part. |
360a680
to
561ccdc
Compare
I've written code to make On the other hand, it's easy enough to support and removes even the question of backwards-compatibility. |
I've added a commit to make |
This reorganizes the commits from #83
Modifies
path-utils:generate-autosave-name
andpath-utils:generate-backup-name
to respond to preferences stored under'path-utils:autosave-dir
and'path-utils:backup-dir
, respectively, which can be used to designate a directory for saving the corresponding automatically-generated files, rather than saving them in the same directory as the originals.This functionality is inspired by Emacs' ability to be configured to do likewise with backup and autosave files.