-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Add prefix argument to mktempdir() #23634
Conversation
@nalimilan, @fredrikekre, @vtjnash, @kshyatt, Please review #23237 here. @nalimilan Comments on the test cases are incorporated. On the |
base/file.jl
Outdated
template = prefix*"XXXXXX" | ||
tpath = joinpath(parent, template) | ||
|
||
req = Libc.malloc(_sizeof_uv_fs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Decision to be taken if readdir
or readlink
approach be taken in allocating this variable. @vtjnash to recommend.
base/file.jl
Outdated
eventloop(), req, tpath, C_NULL) | ||
if ret < 0 | ||
ccall(:uv_fs_req_cleanup, Void, (Ptr{Void},), req) | ||
uv_error("mktempdir", ret) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting to be fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, should be good after the few test fixes and validation by @vtjnash.
test/file.jl
Outdated
end | ||
|
||
else | ||
# '/' is accepted in a prefix but affects the overall path and permissions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/
does not seem to be accepted, according to the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/
only as the first character of a prefix creates problems. If a path is formed by $parent/someval/
where a path may exist in the system like say /tmp/. It will work. So technically, '/' is supported as a prefix character if the final path is writable by the process.
julia> mktempdir("/";prefix="tmp/")
"/tmp/9dLil5"
julia>
julia> mktempdir("/";prefix="tmp/s")
"/tmp/sZZDLWl"
julia> mktempdir(;prefix="/")
ERROR: mktempdir: permission denied (EACCES)
Stacktrace:
[1] uv_error at ./libuv.jl:68 [inlined]
[2] #mktempdir#12(::String, ::Function, ::String) at ./file.jl:359
[3] (::getfield(Base.Filesystem, Symbol("#kw##mktempdir")))(::Array{Any,1}, ::typeof(mktempdir), ::String) at ./<missing>:0 (repeats 2 times)
julia> mktempdir(;prefix="ss/")
ERROR: mktempdir: no such file or directory (ENOENT)
Stacktrace:
[1] uv_error at ./libuv.jl:68 [inlined]
[2] #mktempdir#12(::String, ::Function, ::String) at ./file.jl:359
[3] (::getfield(Base.Filesystem, Symbol("#kw##mktempdir")))(::Array{Any,1}, ::typeof(mktempdir), ::String) at ./<missing>:0 (repeats 2 times)
julia> mkdir("/tmp/ss");mktempdir(;prefix="ss/")
"/tmp/ss/ZDAbPm"
julia>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so just make the comment more explicit.
test/file.jl
Outdated
mkdir("c:/mydir") | ||
# The temp directory created is of form "C:\\XXXXXX" | ||
mktempdir("c:/mydir"; prefix="c:/") do tmpdir | ||
filename = basename(tmpdir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better also test the path before the base name to ensure that what the comment says actually happens. Same below and on Unix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you expect me to test for the following?
mktempdir("c:/mydir"; prefix="c:/") do tmpdir
@test isdir(tmpdir)
# Does not makes much of sense as mktempdir() will create the dir() anyway.
# Our focus is mostly the name of the dir created.
# Those must be tested as part of regular mktempdir (without prefix) test case.
filename = basename(tmpdir)
The file already has a large number of mktempdir(without prefix)
test cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant that since you say "The temp directory created is of form "C:\XXXXXX"", you should actually test that it's the case, i.e. that startswith(tempdir, C:\\")
.
base/file.jl
Outdated
@@ -356,12 +339,33 @@ is an open file object for this path. | |||
mktemp(parent) | |||
|
|||
""" | |||
mktempdir(parent=tempdir()) | |||
mktempdir(parent=tempdir(); prefix="$temp_prefix") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"$temp_prefix"
== temp_prefix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is to use the value of the global variable rather than repeating it. Seems to work as expected:
julia> x = 1
1
julia> """x = "$x" """
x
x
help?> x
x = "1"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My mistake --- I didn't notice this was in a doc string :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically $(repr(temp_prefix))
is more correct in case there are weird characters in the prefix (seems unlikely, but it is possible).
test/file.jl
Outdated
# The API accepts "c:/ and c:\\" as valid prefixes. | ||
# The parent directory is ignored in that case. | ||
|
||
mkdir("c:/mydir") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In most cases the user running Julia won't have access to that path (fortunately), so we'll have to find something else. Maybe pass tempdir()
as a prefix, since we know we can write there?
test/file.jl
Outdated
filename = basename(tmpdir) | ||
@test length(filename) == 6 | ||
end | ||
rm("c:/mydir") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to also remove the directory in other cases.
Yikes! That's quite a mess of different approaches in there. OTOH, you can use either approach here. |
Considering the comment from @vtjnash, I have committed only the formatting changes needed in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, as long as @vtjnash agrees.
The errors on CircleCI do not seem relevant to the PR and Travis is stuck for some reason. |
Both the Travis and CircleCI seem to report spurious errors. |
closing and reopening to rerun tests. |
Errors reported by Travis and CircleCI seem to be unrelated to the check-in. In fact in the earlier iterations the 64-bit version on Travis was passing while the Mac OS X tests didn't even kick off. Please review the changes for merge if any changes are needed let me know. |
@vtjnash Merge? |
base/file.jl
Outdated
if ret < 0 | ||
ccall(:uv_fs_req_cleanup, Void, (Ptr{Void},), req) | ||
uv_error("mktempdir", ret) | ||
assert(false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't need this assert
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed in latest check-in.
base/file.jl
Outdated
|
||
Create a temporary directory in the `parent` directory and return its path. | ||
If `parent` does not exist, throw an error. | ||
If `parent` does not exist, throw an error. An optional `prefix` to the directory name can |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wrapping seems odd here. If you wrap once at the period, I think the rest will fit on the following line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in latest check-in.
base/file.jl
Outdated
mktempdir(parent) | ||
function mktempdir(parent=tempdir(); prefix="$temp_prefix") | ||
template = prefix*"XXXXXX" | ||
tpath = joinpath(parent, template) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the intention of this API was to compute simply:
tpath = "$(parent)$(path_separator)$(template)XXXXXX"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean that it's simpler/more efficient to allocate the string in a single pass?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That doesn't matter here. However, the goal of the API appears to be to compute the simpler operation, not joinpath.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
joinpath
has 2 functions:
- Use the relevant $(path_separator)
- Provide a sane path relevant to the OS by stripping end separator.
ismatch(path_separator_re, a[end:end]) ? string(C,a,b) :
string(C,a,pathsep(a,b),b)
If the input to parent
variable ends with a $(path_separator)
then the path created will have 2 consecutive $path_separator
values. It does not fail but is not the correct return value.
Example:
julia> mktempdir("/tmp/"; prefix="abc")
"/tmp//abclEMi2T"
julia> mktempdir("/"; prefix="tmp/")
"//tmp/rXRggu"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vtjnash Can you review and suggest if joinpath
should be removed from the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it should. But to your point, yes we can add some logic here to avoid duplicating the path separator if already present at the end of parent:
if ismatch(path_separator_re, parent[end:end])
tpath = "$(parent)$(template)XXXXXX"
else
tpath = "$(parent)$(path_separator)$(template)XXXXXX"
end
Sorry for all of the incremental review. I know that's really annoying. But should be almost good to go :) |
The libuv is used for this implementation in a platform independent manner.
1. drive letters as prefix 2. Unicode symbols as prefix instead of codes.
The libuv is used for this implementation in a platform independent manner.
Consolidate pinv tests (#23627)
1. drive letters as prefix 2. Unicode symbols as prefix instead of codes.
There has been almost a few months we have been working on this PR. And I see very sporadic reviews and review fixes invariably gets into merge conflicts and rebase resolutions that unnecessarily complicate the check-ins. If we do not see much priority in this feature, may be we should discard this feature from the product. I think I have checked-in the last functional code at least 10 days back yet no further update. |
It's not that we don't want this functionality, but that this needs careful review before merging and people are busy – we're trying to get Julia 1.0 ready very soon. Adding features can always be done in the future. Is there some part of this PR that breaks existing functionality? |
AFAICT this should be ready to go, the remaining discussions where mostly about the best coding patterns. |
@nalimilan, could you review it, fix the conflicts and merge if it's good to go? (Please squash.) |
I've approved it already, @vtjnash is the one who had comments. |
@vtjnash, please approve if you feel that your comments have been addressed. |
Any reason still pending? |
@@ -381,13 +393,14 @@ function mktemp(fn::Function, parent=tempdir()) | |||
end | |||
|
|||
""" | |||
mktempdir(f::Function, parent=tempdir()) | |||
mktempdir(f::Function, parent=tempdir(); prefix="$(repr(temp_prefix))") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will include two sets of quotes (quotes are included in the output of repr
of a string).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See previous comment: #23634 (comment)
This is non-breaking and still not correct. Removing the triage label. |
|
||
tpath = "$(parent)$(path_separator)$(prefix)XXXXXX" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If prefix
contains the letter X
this is going to be wrong; it's hard to say if that's avoidable or not, given the way the underlying uv_fs_mkdtemp
API works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that the last 6 characters need to be X
, but it doesn't matter what the other characters are.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It's not even clear why these chars need to be X
rather than any other ASCII char.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Links to documentation for uv_fs_mkdtemp
and mkdtemp
given below:
http://docs.libuv.org/en/v1.x/fs.html
https://linux.die.net/man/3/mkdtemp
This is a new feature so doesn't need to be triaged right now. |
It would be great to revive this PR, as the feature is quite convenient. |
Continuation of #23237, which has all review comments (remerging and rebasing detached the old PR and I cannot reopen it).
Fixes #22922