jolt-lang / jolt-lang/jolt

Windows: `jolt C:/…/file.clj` is read as project-relative — `open-input-file` fails for `./C:/…`

Closed Beginner friendly
#992 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Scheme
Stars
290
Forks
22
Avg merge
4h 54m
Merged PRs (30d)
259

Description

**Environment:** jolt v0.8.7 (`jolt-v0.8.7-x86_64-windows.zip`, `jolt.exe` invoked
directly — `JOLT_PWD` unset, so `project-dir` is `"."`, `main.clj:9`),
Windows 11, Git Bash. Reproduced from any cwd.
**Area:** `jolt-core/jolt/main.clj` (`file-arg`).

## Summary

An absolute Windows path passed as the FILE argument — `jolt C:/Users/x/hello.clj`,
`jolt run C:/Users/x/hello.clj`, any `C:/…` or `C:\…` — is classified as
project-relative because `file-arg` recognizes POSIX absolutes only. It becomes
`/C:/…`, so the prebuilt binary tries `./C:/…` and the file cannot
be opened, even though the path is correct.

## Repro

```clojure
;; jolt-core/jolt/main.clj:320-327
(defn- file-arg [x]
(cond
(= "-" x) "/dev/stdin"
(str/starts-with? x "/") x
;; a ./-prefixed argument is already project-relative: joining it as is
;; reported the file as ././x.clj
(str/starts-with? x "./") (str (project-dir) "/" (subs x 2))
:else (str (project-dir) "/" x)))
```

```
$ jolt C:/Users/x/hello.clj
Unhandled exception (IOException): open-input-file: failed for ./C:/Users/x/hello.clj: invalid argument
trace:
oif
read-file-string
load-jolt-file

$ jolt run C:/Users/x/hello.clj # same failure
```

Backslash form (`jolt C:\Users\x\hello.clj`) and any cwd behave the same — the
`:else` branch only ever sees a path it joins to `project-dir`.

The relative spellings work, from any cwd — which is why this is easy to miss:

```
$ jolt hello.clj # ok
$ jolt ./hello.clj # ok
```

## Suggested fix

Route the `:else` branch through a Windows-aware path classification instead of
`starts-with? "/"`: `jolt.deps/native-path-kind-for`
(`jolt-core/jolt/deps.clj:195-214`) already distinguishes drive-absolute
(`C:/x`), UNC (`//server/share`), root-relative (`/x`) and drive-relative (`C:x`),
and `io.ss`'s `jfile-abs` handles absolute Windows paths as well. The `"-"` →
`/dev/stdin` case stays first.

**Workaround:** pass a path relative to the cwd (`jolt Users/x/hello.clj` from
`C:\` works — verified), or use `-e` / stdin.

---

A related, independent defect — `File.getCanonicalPath` returning `/C:/…`, which
breaks reads and writes with the returned value — is filed as
[jolt#991](https://github.com/jolt-lang/jolt/issues/991).

Contributor guide

Open the contributing guide

Research direction

Start in jolt-core/jolt/main.clj at file-arg (around lines 320-327), then read jolt.deps/native-path-kind-for in jolt-core/jolt/deps.clj:195-214 and the io.ss jfile-abs behavior. Check the existing relative and stdin cases, then verify that drive-absolute, UNC, root-relative, drive-relative, and POSIX paths are classified correctly without regressing ./ paths. Reproduce the CLI commands from the issue to confirm absolute files open successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
clojure
Domain
cli, operating-systems
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.