Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(workspaces): Allow patterns with non-semver ranges to match workspace packages #6012

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions __tests__/workspace-layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* @flow */

import WorkspaceLayout from '../src/workspace-layout.js';
import Config from '../src/config.js';
import NoopReporter from '../src/reporters/noop-reporter';
import type {WorkspacesManifestMap} from '../src/types';

const workspaceMap: WorkspacesManifestMap = Object.freeze({
pkgA: {
loc: './pkgA',
manifest: {
_uid: '1',
name: 'pkgA',
version: '1.2.3',
},
},
'@yarn/pkgB': {
loc: './pkgB',
manifest: {
_uid: '1',
name: '@yarn/pkgB',
version: '1.2.3',
},
},
});

describe('WorkspaceLayout.getManifestByPattern()', () => {
test('returns null when workspace does not contain a package with requested name', () => {
const layout = new WorkspaceLayout(workspaceMap, new Config(new NoopReporter()));
const result = layout.getManifestByPattern('does-not-exist');
expect(result).toBe(null);
});

test('returns null when workspace contains a package with requested name but version does not match', () => {
const layout = new WorkspaceLayout(workspaceMap, new Config(new NoopReporter()));
const result = layout.getManifestByPattern('pkgA@^9.0.0');
expect(result).toBe(null);
});

test('returns manifest when workspace contains a package with requested name and version matches', () => {
const layout = new WorkspaceLayout(workspaceMap, new Config(new NoopReporter()));
const result = layout.getManifestByPattern('pkgA@^1.0.0');
expect(result).toBe(workspaceMap.pkgA);
});

test('returns null when workspace contains a package with requested name and version is not a semver range', () => {
const layout = new WorkspaceLayout(workspaceMap, new Config(new NoopReporter()));
const result = layout.getManifestByPattern('pkgA@git+https://git@github.com/yarnpkg/test-package.git');
expect(result).toBe(workspaceMap.pkgA);
});

test('returns manifest when workspace contains a scoped package with requested name and version matches', () => {
const layout = new WorkspaceLayout(workspaceMap, new Config(new NoopReporter()));
const result = layout.getManifestByPattern('@yarn/pkgB@^1.0.0');
expect(result).toBe(workspaceMap['@yarn/pkgB']);
});
});
20 changes: 18 additions & 2 deletions src/workspace-layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,25 @@ export default class WorkspaceLayout {
getManifestByPattern(pattern: string): ?{loc: string, manifest: Manifest} {
const {name, range} = normalizePattern(pattern);
const workspace = this.getWorkspaceManifest(name);
if (!workspace || !semver.satisfies(workspace.manifest.version, range, this.config.looseSemver)) {
if (!workspace) {
// the dependency specifies a package name that does not exist in this workspace.
return null;
}
return workspace;
if (!semver.validRange(range)) {
// if the dependency specifies a range that isn't valid semver.
// It is probably an "exotic" pattern like a github url,
// or has no range at all as in the case of running the command
// yarn workspace @yarnpkg/pkgB add @yarnpkg/pkgA
// For these, we just match on the package name and allow the workspace package to be used.
return workspace;
}
if (semver.satisfies(workspace.manifest.version, range, this.config.looseSemver)) {
// the dependency specifies a package name that exists in this workspace
// and the workspace package's version matches the requested range. Use the workspace package.
return workspace;
}
// the dependency specifies a package name that exists in this workspace,
// but the workspace package is a version that does not match the requeted range.
return null;
}
}