Skip to content

Commit

Permalink
fix two URL-related bugs: #20 (WSL) & #22 (Windows) (#21)
Browse files Browse the repository at this point in the history
* fix WSL bug: url hash params cut-off (closes #20)

* handle long paths/URLs on Windows & WSL (closes #22)

* WSL fix (`try ispath`; cmd `stat()` is not a thing)

* add (manual) test file for #20 and #22

better than nothing at all, no

* factor out the 'is ok to relpath' check (makes the `open` function a bit cleaner)

* Use `function` for `_powershell_start_cmd`, give it a docstring. Absorb the other two only-once-used functions into `open`

* factor out `_open_cmd` from `open`. Test this cmd on all OS'es. Add Win & Mac to CI

* rm `test/windows.jl` (that's a stray; similar code is now in main `runtests.jl`; and is run in CI too)

* CI: only apt-get on linux

* no replace `isnothing` by `== nothing` for julia 1.0
  • Loading branch information
tfiers committed Feb 9, 2023
1 parent 2af8998 commit 14df0ff
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 31 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:
- 'nightly'
os:
- ubuntu-latest
- macos-latest
- windows-latest
arch:
- x64
steps:
Expand All @@ -44,7 +46,8 @@ jobs:
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/julia-buildpkg@v1
- run: |
- if: runner.os == 'Linux'
run: |
sudo apt-get install xdg-utils
cp $GITHUB_WORKSPACE/test/extra/save-argument /usr/local/bin/
- uses: julia-actions/julia-runtest@v1
Expand Down
62 changes: 52 additions & 10 deletions src/DefaultApplication.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,69 @@ Open a file with the default application determined by the OS.
The argument `wait` is passed to `run`.
"""
function open(filename; wait = false)
cmd = _open_cmd(filename)
if cmd == nothing
@warn("Opening files with the default application is not supported on this OS.",
KERNEL = Sys.KERNEL)
else
run(cmd; wait = wait)
end
end

"""
DefaultApplication._open_cmd(path)
`Cmd` that, when, run, opens the given path with the default application
for the OS.
"""
function _open_cmd(path)
@static if Sys.isapple()
run(`open $(filename)`; wait = wait)
return `open $(path)`
elseif _is_wsl
# Powershell can open *relative* paths in WSL, hence using relpath
# Could use wslview instead, but powershell is more universally available.
# Could use cmd + wslpath instead, but cmd complains about the working directory.
# Quotes around the filename are to deal with spaces.
relfile = relpath(filename)
cmd = `powershell.exe -NoProfile -NonInteractive -Command start \"$(relfile)\"`
run(cmd; wait = wait)
try
if ispath(path)
path = relpath(path)
else
# Leave e.g. URLs alone (`relpath` deletes one of the
# slashes in `https://`, and removes `#` parameters)
end
catch
# `stat` (which is called by `ispath`) fails if the given path
# is too long (`IOError: … (ENAMETOOLONG)`). In that case,
# also leave `path` as is.
end
return _powershell_start_cmd(path)
elseif Sys.islinux() || Sys.isbsd()
run(`xdg-open $(filename)`; wait = wait)
return `xdg-open $(path)`
elseif Sys.iswindows()
cmd = get(ENV, "COMSPEC", "cmd.exe")
run(`$(cmd) /c start $(filename)`; wait = wait)
cmd_exe = get(ENV, "COMSPEC", "cmd.exe")
cmd = `$(cmd_exe) /c start $(path)`
if length(string(cmd)) > 8191
# Command too long for CMD.exe; use Powershell instead.
# (https://learn.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/command-line-string-limitation)
cmd = _powershell_start_cmd(path)
end
return cmd
else
@warn("Opening files the default application is not supported on this OS.",
KERNEL = Sys.KERNEL)
return nothing
end
end

"""
DefaultApplication._powershell_start_cmd(path)
PowerShell command to open the given path with its default application.
Useable in both Windows and WSL.
"""
function _powershell_start_cmd(path)
return `powershell.exe -NoProfile -NonInteractive -Command start \"$(path)\"`
# Quotes around the filename are to deal with spaces.
# (The ''-quotes added by ``-interpolation are not enough).
end

"""
DefaultApplication.test()
Expand Down
70 changes: 50 additions & 20 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,54 @@ import DefaultApplication

CI = get(ENV, "CI", "false") == "true"

if Sys.islinux()
if CI
# ensure clean slate
sentinel = "/tmp/saved-argument"
rm(sentinel; force = true)
# set up test file
testfile = "/tmp/test.txt"
write(testfile, "test text")
## uncomment lines below for debug information
@info("environment",
XDGMIMETYPE = chomp(read(`xdg-mime query filetype $(testfile)`, String)),
XDGMIMEDEFAULT = chomp(read(`xdg-mime query default text/plain`, String)))
@info "opening $(testfile)"
DefaultApplication.open(testfile)
sleep(1)
@info "test that file was opened"
@test chomp(read(sentinel, String)) == testfile
else
@warn "Tests are only ran in CI."
end
if CI && Sys.islinux()
# ensure clean slate
sentinel = "/tmp/saved-argument"
rm(sentinel; force = true)
# set up test file
testfile = "/tmp/test.txt"
write(testfile, "test text")
## uncomment lines below for debug information
@info("environment",
XDGMIMETYPE = chomp(read(`xdg-mime query filetype $(testfile)`, String)),
XDGMIMEDEFAULT = chomp(read(`xdg-mime query default text/plain`, String)))
@info "opening $(testfile)"
DefaultApplication.open(testfile)
sleep(1)
@info "test that file was opened"
@test chomp(read(sentinel, String)) == testfile
end


path = "blah.txt"
url = "https://julialang.org#params"
path_long = "long_long_man" * "n"^8200

cmd_path = DefaultApplication._open_cmd(path)
cmd_url = DefaultApplication._open_cmd(url)
cmd_path_long = DefaultApplication._open_cmd(path_long)

if Sys.isapple()
@test cmd_path == `open 'blah.txt'`
@test cmd_url == `open 'https://julialang.org#params'`
@test cmd_path_long == `open $path_long`

elseif DefaultApplication._is_wsl
@test cmd_path == `powershell.exe -NoProfile -NonInteractive -Command start \"'blah.txt'\"`
@test cmd_url == `powershell.exe -NoProfile -NonInteractive -Command start \"'https://julialang.org#params'\"`
@test cmd_path_long == `powershell.exe -NoProfile -NonInteractive -Command start \"$(path_long)\"`

elseif Sys.islinux() || Sys.isbsd()
@test cmd_path == `xdg-open 'blah.txt'`
@test cmd_url == `xdg-open 'https://julialang.org#params'`
@test cmd_path_long == `xdg-open $path_long`

elseif Sys.iswindows()
cmd_exe = get(ENV, "COMSPEC", "cmd.exe")
@test cmd_path == `$(cmd_exe) /c start 'blah.txt'`
@test cmd_url == `$(cmd_exe) /c start 'https://julialang.org#params'`
@test cmd_path_long == `powershell.exe -NoProfile -NonInteractive -Command start \"$(path_long)\"`

else
@warn "OS not tested"
end

0 comments on commit 14df0ff

Please sign in to comment.