Skip to content

Commit 2f2a3ba

Browse files
committed
Better URL resolution for url-file
- Expose the URL() constructor's resolution behavior via url.js - Add slashes '/' between the base and path to give what we think is the least surprising behavior for punning filesystem and URL – so url-file("https://a.com/b/c", "../d.arr") resolves to "https://a.com/b/d.arr", not "https://a.com/d.arr" And this: url-file("https://a.com/b/c", "d.arr") resolves to "https://a.com/b/c/d.arr" Without inserting the trailing slashes, URL and path resolution would be pretty different: URL resolution would always "chop off" the part of the path after the last slash - Write a test for this behavior getting the correct module identity when ".." is used in some url-file paths and not others
1 parent 862112d commit 2f2a3ba

File tree

5 files changed

+51
-2
lines changed

5 files changed

+51
-2
lines changed

src/arr/compiler/cli-module-loader.arr

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import filesystem as Filesystem
1313
import file as F
1414
import error as ERR
1515
import system as SYS
16+
import url as URL
1617
import file("js-ast.arr") as J
1718
import file("concat-lists.arr") as C
1819
import file("compile-lib.arr") as CL
@@ -308,6 +309,13 @@ fun get-real-path(current-load-path :: String, this-path :: String):
308309
end
309310
end
310311

312+
fun maybe-add-slash(s):
313+
last-index = string-length(s) - 1
314+
if string-char-at(s, last-index) == "/": s
315+
else: s + "/"
316+
end
317+
end
318+
311319
fun locate-file(ctxt :: CLIContext, rel-path :: String):
312320
clp = ctxt.current-load-path
313321
real-path = get-real-path(clp, rel-path)
@@ -329,7 +337,8 @@ fun module-finder(ctxt :: CLIContext, dep :: CS.Dependency):
329337
else if protocol == "url":
330338
CL.located(UL.url-locator(dep.arguments.get(0), CS.standard-globals), ctxt)
331339
else if protocol == "url-file":
332-
full-url = args.get(0) + "/" + args.get(1)
340+
base = maybe-add-slash(args.get(0))
341+
full-url = URL.resolve(args.get(1), base)
333342
cases(CS.UrlFileMode) ctxt.url-file-mode:
334343
| all-remote =>
335344
CL.located(UL.url-locator(full-url, CS.standard-globals), ctxt)

src/js/trove/url.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
({
2+
provides: {
3+
values: {
4+
resolve: ["arrow", ["String", "String"], "String"]
5+
},
6+
types: {},
7+
},
8+
requires: [ ],
9+
nativeRequires: [],
10+
theModule: function(runtime, _, uri) {
11+
function resolve(path, base) {
12+
runtime.checkArgsInternal2("url", "resolve", path, runtime.String, base, runtime.String);
13+
try {
14+
return new URL(path, base).href;
15+
}
16+
catch(e) {
17+
runtime.ffi.throwMessageException("url.resolve() failed: " + String(e));
18+
}
19+
}
20+
return runtime.makeModuleReturn({
21+
resolve: runtime.makeFunction(resolve)
22+
}, {});
23+
}
24+
})

tests/io-tests/tests/library-code.arr

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

33
provide *
44

5-
x = "same dir library code"
5+
x = "same dir library code"
6+
7+
data D: d() end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import url-file("http://0.0.0.0:7999/nested/", "../library-code.arr") as LC
2+
3+
provide from LC:
4+
data D
5+
end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
###> Looks shipshape
2+
3+
import url-file("http://0.0.0.0:7999/", "library-code.arr") as LC
4+
import url-file("http://0.0.0.0:7999/", "nested/imports-library-with-dotdot.arr") as N
5+
6+
check:
7+
N.d() is LC.d()
8+
end
9+

0 commit comments

Comments
 (0)