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

feat: support non-semver versions in the yarn packager, for example 'github:' references #478

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
30 changes: 25 additions & 5 deletions src/packagers/yarn.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { any, isEmpty, reduce, replace, split, startsWith } from 'ramda';
import { satisfies } from 'semver';
import { satisfies, valid as isValidSemver } from 'semver';

import type { DependenciesResult, DependencyMap, PackagerOptions } from '../types';
import { SpawnError, spawnProcess } from '../utils';
Expand All @@ -23,11 +23,27 @@ export interface YarnDeps {
}

const getNameAndVersion = (name: string): { name: string; version: string } => {
const atIndex = name.lastIndexOf('@');
/*
* This regex supports these cases:
* - package@version (single '@' is the separator) => returns 'package'
* - @org/package@version ('@' for org name and version separator) => returns '@org/package'
* - @org/package@git+ssh://[email protected]/org/package (last '@' is not a name / version separator) => returns '@org/package'
*/
const packageNameMatch = name.match(/^(@[^@]+|[^@]+)/);

if (!packageNameMatch) {
return {
name,
version: '',
};
}

// Everything after the name is the version (separated by a single '@'):
const versionStartIndex = (packageNameMatch?.index || 0) + packageNameMatch[0].length + 1;

return {
name: name.slice(0, atIndex),
version: name.slice(atIndex + 1),
name: packageNameMatch[0],
version: name.slice(versionStartIndex),
};
};

Expand Down Expand Up @@ -134,7 +150,11 @@ export class Yarn implements Packager {

if (tree.shadow) {
// Package is resolved somewhere else
if (dependency && satisfies(dependency.version, version)) {
// If either version is not valid semver, we can't compare, so include the package by default. For e.g. 'github:' references where semver doesn't apply.
if (
dependency &&
(satisfies(dependency.version, version) || !isValidSemver(dependency.version) || !isValidSemver(version))
) {
// Package is at root level
// {
// "name": "[email protected]", <- MATCH
Expand Down