Skip to content

Commit 6cca02c

Browse files
authored
feat: upgrade for deno_graph now handling redirects (#50)
1 parent 2d8dc23 commit 6cca02c

File tree

8 files changed

+83
-72
lines changed

8 files changed

+83
-72
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020

2121
steps:
2222
- name: Clone repository
23-
uses: actions/checkout@v3
23+
uses: actions/checkout@v4
2424
with:
2525
token: ${{ secrets.DENOBOT_PAT }}
2626

cache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ export class FetchCacher {
2121
checksum?: string,
2222
): Promise<LoadResponse | undefined> => {
2323
const url = new URL(specifier);
24-
return this.#fileFetcher.fetch(url, { cacheSetting, checksum });
24+
return this.#fileFetcher.fetchOnce(url, { cacheSetting, checksum });
2525
};
2626
}

deno.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525
],
2626
"exports": "./mod.ts",
2727
"imports": {
28-
"@deno/graph": "jsr:@deno/graph@^0.69.7",
29-
"@std/assert": "jsr:@std/assert@^0.218.2",
30-
"@std/fmt": "jsr:@std/fmt@^0.218.2",
31-
"@std/fs": "jsr:@std/fs@^0.218.2",
32-
"@std/io": "jsr:@std/io@^0.218.2",
33-
"@std/path": "jsr:@std/path@^0.218.2"
28+
"@deno/graph": "jsr:@deno/graph@^0.73.1",
29+
"@std/assert": "jsr:@std/assert@^0.223",
30+
"@std/fmt": "jsr:@std/fmt@^0.223",
31+
"@std/fs": "jsr:@std/fs@^0.223",
32+
"@std/io": "jsr:@std/io@^0.223",
33+
"@std/path": "jsr:@std/path@^0.223"
3434
}
3535
}

deno.lock

Lines changed: 33 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

disk_cache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright 2018-2024 the Deno authors. MIT license.
22

3-
import { ensureDir } from "@std/fs/ensure_dir";
3+
import { ensureDir } from "@std/fs/ensure-dir";
44
import { dirname, isAbsolute, join } from "@std/path";
55
import { readAll, writeAll } from "@std/io";
66
import { assert, CACHE_PERM } from "./util.ts";

file_fetcher.ts

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export class FileFetcher {
137137
options: ResolvedFetchOptions,
138138
httpCache: HttpCache,
139139
): Promise<LoadResponse> {
140-
const cached = this.#fetchCached(specifier, 0, options, httpCache);
140+
const cached = this.fetchCachedOnce(specifier, options, httpCache);
141141
if (cached) {
142142
return cached;
143143
}
@@ -163,26 +163,22 @@ export class FileFetcher {
163163
};
164164
}
165165

166-
#fetchCached(
166+
fetchCachedOnce(
167167
specifier: URL,
168-
redirectLimit: number,
169168
options: ResolvedFetchOptions,
170169
httpCache: HttpCache,
171170
): LoadResponse | undefined {
172-
if (redirectLimit < 0) {
173-
throw new Deno.errors.Http(
174-
`Too many redirects.\n Specifier: "${specifier.toString()}"`,
175-
);
176-
}
177-
178171
const headers = httpCache.getHeaders(specifier);
179172
if (!headers) {
180173
return undefined;
181174
}
182175
const location = headers["location"];
183176
if (location != null && location.length > 0) {
184177
const redirect = new URL(location, specifier);
185-
return this.#fetchCached(redirect, redirectLimit - 1, options, httpCache);
178+
return {
179+
kind: "redirect",
180+
specifier: redirect.toString(),
181+
};
186182
}
187183
const content = httpCache.get(specifier, options);
188184
if (content == null) {
@@ -196,22 +192,14 @@ export class FileFetcher {
196192
};
197193
}
198194

199-
async #fetchRemote(
195+
async #fetchRemoteOnce(
200196
specifier: URL,
201-
redirectLimit: number,
202197
options: ResolvedFetchOptions,
203198
httpCache: HttpCache,
204199
): Promise<LoadResponse | undefined> {
205-
if (redirectLimit < 0) {
206-
throw new Deno.errors.Http(
207-
`Too many redirects.\n Specifier: "${specifier.toString()}"`,
208-
);
209-
}
210-
211200
if (shouldUseCache(options.cacheSetting, specifier)) {
212-
const response = this.#fetchCached(
201+
const response = this.fetchCachedOnce(
213202
specifier,
214-
redirectLimit,
215203
options,
216204
httpCache,
217205
);
@@ -283,6 +271,25 @@ export class FileFetcher {
283271
}
284272

285273
async fetch(
274+
specifier: URL,
275+
// Providing a checksum here doesn't make sense because the provided
276+
// checksum will change based on the specifier being requested, which
277+
// could be invalided by a redirect
278+
options?: Omit<FetchOptions, "checksum">,
279+
): Promise<LoadResponse | undefined> {
280+
for (let i = 0; i <= 10; i++) {
281+
const response = await this.fetchOnce(specifier, options);
282+
if (response?.kind !== "redirect") {
283+
return response;
284+
}
285+
specifier = new URL(response.specifier);
286+
}
287+
throw new Deno.errors.Http(
288+
`Too many redirects.\n Specifier: "${specifier.toString()}"`,
289+
);
290+
}
291+
292+
async fetchOnce(
286293
specifier: URL,
287294
options?: FetchOptions,
288295
): Promise<LoadResponse | undefined> {
@@ -306,9 +313,8 @@ export class FileFetcher {
306313
`A remote specifier was requested: "${specifier.toString()}", but --no-remote is specified.`,
307314
);
308315
} else {
309-
const response = await this.#fetchRemote(
316+
const response = await this.#fetchRemoteOnce(
310317
specifier,
311-
10,
312318
this.#resolveOptions(options),
313319
await this.#resolveHttpCache(),
314320
);

file_fetcher_test.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ Deno.test({
2727
{
2828
// should error
2929
await assertRejects(async () => {
30-
await fileFetcher.fetch(
30+
await fileFetcher.fetchOnce(
3131
new URL("https://deno.land/x/oak@v10.5.1/mod.ts"),
3232
{
3333
checksum: "bad",
3434
},
3535
);
3636
});
3737
// ok for good checksum
38-
await fileFetcher.fetch(
38+
await fileFetcher.fetchOnce(
3939
new URL("https://deno.land/x/oak@v10.5.1/mod.ts"),
4040
{
4141
checksum:
@@ -52,7 +52,7 @@ Deno.test({
5252
const denoDir = new DenoDir();
5353
const fileFetcher = new FileFetcher(() => denoDir.createHttpCache());
5454
await assertRejects(async () => {
55-
await fileFetcher.fetch(
55+
await fileFetcher.fetchOnce(
5656
new URL("https://deno.land/x/oak@v10.5.1/mod.ts"),
5757
{
5858
cacheSetting: "reload",
@@ -68,10 +68,13 @@ Deno.test({
6868
async fn() {
6969
const denoDir = new DenoDir();
7070
const fileFetcher = new FileFetcher(() => denoDir.createHttpCache());
71-
await fileFetcher.fetch(new URL("https://deno.land/x/oak@v10.5.1/mod.ts"), {
72-
cacheSetting: "reload",
73-
checksum:
74-
"7a1b5169ef702e96dd994168879dbcbd8af4f639578b6300cbe1c6995d7f3f32",
75-
});
71+
await fileFetcher.fetchOnce(
72+
new URL("https://deno.land/x/oak@v10.5.1/mod.ts"),
73+
{
74+
cacheSetting: "reload",
75+
checksum:
76+
"7a1b5169ef702e96dd994168879dbcbd8af4f639578b6300cbe1c6995d7f3f32",
77+
},
78+
);
7679
},
7780
});

http_cache.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import { isAbsolute } from "@std/path";
44
import { assert } from "./util.ts";
55
import {
6-
GlobalHttpCache,
6+
type GlobalHttpCache,
77
instantiate,
8-
LocalHttpCache,
8+
type LocalHttpCache,
99
} from "./lib/deno_cache_dir.generated.js";
1010

1111
export interface HttpCacheCreateOptions {

0 commit comments

Comments
 (0)