Skip to content

Commit

Permalink
Adds extensionless url support (#5931)
Browse files Browse the repository at this point in the history
**What's the problem this PR addresses?**

The v2 never supported referencing packages exposed as extensionless tgz
tarballs, despite other clients being fine with them. Us being stricter
here doesn't provide any value, and just hurts compatibility.

Fixes #5929

**How did you fix it?**

Adds support for extensionless urls, which are now interpreted as
regular tarballs.

**Checklist**
<!--- Don't worry if you miss something, chores are automatically
tested. -->
<!--- This checklist exists to help you remember doing the chores when
you submit a PR. -->
<!--- Put an `x` in all the boxes that apply. -->
- [x] I have read the [Contributing
Guide](https://yarnpkg.com/advanced/contributing).

<!-- See
https://yarnpkg.com/advanced/contributing#preparing-your-pr-to-be-released
for more details. -->
<!-- Check with `yarn version check` and fix with `yarn version check
-i` -->
- [x] I have set the packages that need to be released for my changes to
be effective.

<!-- The "Testing chores" workflow validates that your PR follows our
guidelines. -->
<!-- If it doesn't pass, click on it to see details as to what your PR
might be missing. -->
- [x] I will check that all automated PR checks pass before the PR gets
reviewed.
  • Loading branch information
arcanis authored Nov 3, 2023
1 parent 38d2007 commit 29fa245
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 26 deletions.
24 changes: 24 additions & 0 deletions .yarn/versions/70b508e3.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
releases:
"@yarnpkg/cli": patch
"@yarnpkg/plugin-http": patch

declined:
- "@yarnpkg/plugin-compat"
- "@yarnpkg/plugin-constraints"
- "@yarnpkg/plugin-dlx"
- "@yarnpkg/plugin-essentials"
- "@yarnpkg/plugin-init"
- "@yarnpkg/plugin-interactive-tools"
- "@yarnpkg/plugin-nm"
- "@yarnpkg/plugin-npm-cli"
- "@yarnpkg/plugin-pack"
- "@yarnpkg/plugin-patch"
- "@yarnpkg/plugin-pnp"
- "@yarnpkg/plugin-pnpm"
- "@yarnpkg/plugin-stage"
- "@yarnpkg/plugin-typescript"
- "@yarnpkg/plugin-version"
- "@yarnpkg/plugin-workspace-tools"
- "@yarnpkg/builder"
- "@yarnpkg/core"
- "@yarnpkg/doctor"
10 changes: 2 additions & 8 deletions packages/plugin-http/sources/TarballHttpFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,11 @@ import {Fetcher, FetchOptions, MinimalFetchOptions} from '@yarnpkg/core';
import {Locator} from '@yarnpkg/core';
import {httpUtils, structUtils, tgzUtils} from '@yarnpkg/core';

import {TARBALL_REGEXP, PROTOCOL_REGEXP} from './constants';
import * as urlUtils from './urlUtils';

export class TarballHttpFetcher implements Fetcher {
supports(locator: Locator, opts: MinimalFetchOptions) {
if (!TARBALL_REGEXP.test(locator.reference))
return false;

if (PROTOCOL_REGEXP.test(locator.reference))
return true;

return false;
return urlUtils.isTgzUrl(locator.reference);
}

getLocalPath(locator: Locator, opts: FetchOptions) {
Expand Down
18 changes: 3 additions & 15 deletions packages/plugin-http/sources/TarballHttpResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,15 @@ import {Descriptor, Locator, Manifest} from '@yarnpkg
import {LinkType} from '@yarnpkg/core';
import {miscUtils, structUtils} from '@yarnpkg/core';

import {PROTOCOL_REGEXP, TARBALL_REGEXP} from './constants';
import * as urlUtils from './urlUtils';

export class TarballHttpResolver implements Resolver {
supportsDescriptor(descriptor: Descriptor, opts: MinimalResolveOptions) {
if (!TARBALL_REGEXP.test(descriptor.range))
return false;

if (PROTOCOL_REGEXP.test(descriptor.range))
return true;

return false;
return urlUtils.isTgzUrl(descriptor.range);
}

supportsLocator(locator: Locator, opts: MinimalResolveOptions) {
if (!TARBALL_REGEXP.test(locator.reference))
return false;

if (PROTOCOL_REGEXP.test(locator.reference))
return true;

return false;
return urlUtils.isTgzUrl(locator.reference);
}

shouldPersistResolution(locator: Locator, opts: MinimalResolveOptions) {
Expand Down
3 changes: 0 additions & 3 deletions packages/plugin-http/sources/constants.ts

This file was deleted.

16 changes: 16 additions & 0 deletions packages/plugin-http/sources/urlUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export function isTgzUrl(url: string) {
let parsed: URL;
try {
parsed = new URL(url);
} catch {
return false;
}

if (parsed.protocol !== `http:` && parsed.protocol !== `https:`)
return false;

if (!parsed.pathname.match(/(\.tar\.gz|\.tgz|\/[^.]+)$/))
return false;

return true;
}
17 changes: 17 additions & 0 deletions packages/plugin-http/tests/urlUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as urlUtils from '../sources/urlUtils';

const EXPECTATIONS: Array<[string, boolean]> = [
[`https://example.org/package.tar.gz`, true],
[`https://example.org/package.tgz`, true],
[`https://example.org/package`, true],
[`https://example.org/package.git`, false],
[`https://example.org/package.tgz.git`, false],
[`ftp://example.org/package.tgz`, false],
[`1.2.3`, false],
];

for (const [url, expected] of EXPECTATIONS) {
test(`isTgzUrl(${JSON.stringify(url)}) === ${JSON.stringify(expected)}`, () => {
expect(urlUtils.isTgzUrl(url)).toEqual(expected);
});
}

0 comments on commit 29fa245

Please sign in to comment.