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(internal): Switch to @renovate/ruby-semver library #5982

Merged
merged 5 commits into from Jul 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions lib/versioning/ruby/index.spec.ts
Expand Up @@ -278,6 +278,15 @@ describe('semverRuby', () => {
false
);
});

it('returns null for garbage version input', () => {
expect(
semverRuby.isLessThanRange('asdf', '> 1.2.2, ~> 2.0.0')
).toBeNull();
expect(
semverRuby.isLessThanRange(null as string, '> 1.2.2, ~> 2.0.0')
).toBeNull();
});
});

describe('.isValid', () => {
Expand Down
2 changes: 1 addition & 1 deletion lib/versioning/ruby/index.ts
Expand Up @@ -5,7 +5,7 @@ import {
minSatisfying,
satisfies,
valid,
} from '@snyk/ruby-semver';
} from '@renovatebot/ruby-semver';
import { logger } from '../../logger';
import { NewValueConfig, VersioningApi } from '../common';
import { isSingleOperator, isValidOperator } from './operator';
Expand Down
19 changes: 9 additions & 10 deletions lib/versioning/ruby/range.ts
@@ -1,5 +1,5 @@
import { parse as _parse } from '@snyk/ruby-semver/lib/ruby/gem-requirement';
import { create } from '@snyk/ruby-semver/lib/ruby/gem-version';
import { parse as _parse } from '@renovatebot/ruby-semver/dist/ruby/requirement';
import { Version, create } from '@renovatebot/ruby-semver/dist/ruby/version';
import { logger } from '../../logger';
import { EQUAL, GT, GTE, LT, LTE, NOT_EQUAL, PGTE } from './operator';

Expand Down Expand Up @@ -27,15 +27,14 @@ const parse = (range: string): Range => {
};
};

interface GemVersion {
release(): GemVersion;
compare(ver: GemVersion): number;
bump(): GemVersion;
}
type GemRequirement = [string, GemVersion];
type GemRequirement = [string, Version];

const ltr = (version: string, range: string): boolean => {
const gemVersion: GemVersion = create(version);
const ltr = (version: string, range: string): boolean | null => {
const gemVersion = create(version);
if (!gemVersion) {
logger.warn(`Invalid ruby version '${version}'`);
return null;
}
const requirements: GemRequirement[] = range.split(',').map(_parse);

const results = requirements.map(([operator, ver]) => {
Expand Down
2 changes: 1 addition & 1 deletion lib/versioning/ruby/strategies/bump.ts
@@ -1,4 +1,4 @@
import { gte, lte } from '@snyk/ruby-semver';
import { gte, lte } from '@renovatebot/ruby-semver';
import { logger } from '../../../logger';
import { EQUAL, GT, GTE, LT, LTE, NOT_EQUAL, PGTE } from '../operator';
import { parse as parseRange } from '../range';
Expand Down
2 changes: 1 addition & 1 deletion lib/versioning/ruby/strategies/replace.ts
@@ -1,4 +1,4 @@
import { satisfies } from '@snyk/ruby-semver';
import { satisfies } from '@renovatebot/ruby-semver';
import { logger } from '../../../logger';
import bump from './bump';

Expand Down
99 changes: 64 additions & 35 deletions lib/versioning/ruby/version.ts
@@ -1,11 +1,23 @@
import { diff, major, minor, patch, prerelease } from '@snyk/ruby-semver';
import { create } from '@snyk/ruby-semver/lib/ruby/gem-version';
import { eq, major, minor, patch, prerelease } from '@renovatebot/ruby-semver';
import {
SegmentElement,
create,
} from '@renovatebot/ruby-semver/dist/ruby/version';

interface RubyVersion {
major: number;
minor: number;
patch: number;
prerelease: string[];
prerelease: string[] | null;
}

function releaseSegments(version: string): SegmentElement[] {
const v = create(version);
if (v) {
return v.release().getSegments();
}
/* istanbul ignore next */
return [];
}

const parse = (version: string): RubyVersion => ({
Expand All @@ -18,13 +30,14 @@ const parse = (version: string): RubyVersion => ({
const adapt = (left: string, right: string): string =>
left.split('.').slice(0, right.split('.').length).join('.');

const floor = (version: string): string =>
[...create(version).release().getSegments().slice(0, -1), 0].join('.');
const floor = (version: string): string => {
return [...releaseSegments(version).slice(0, -1), 0].join('.');
};

// istanbul ignore next
const incrementLastSegment = (version: string): string => {
const segments = create(version).release().getSegments();
const nextLast = parseInt(segments.pop(), 10) + 1;
const segments = releaseSegments(version);
const nextLast = parseInt(segments.pop() as string, 10) + 1;

return [...segments, nextLast].join('.');
};
Expand All @@ -47,45 +60,61 @@ const incrementPatch = (ptch: number, pre: string[]): number =>

// istanbul ignore next
const increment = (from: string, to: string): string => {
const { major: maj, minor: min, patch: ptch, prerelease: pre } = parse(from);
const parsed = parse(from);
const { major: maj, prerelease: pre } = parsed;
let { minor: min, patch: ptch } = parsed;
min = min || 0;
ptch = ptch || 0;

let nextVersion: string;
switch (diff(from, adapt(to, from))) {
case 'major':
nextVersion = [incrementMajor(maj, min, ptch, pre || []), 0, 0].join('.');
break;
case 'minor':
nextVersion = [maj, incrementMinor(min, ptch, pre || []), 0].join('.');
break;
case 'patch':
nextVersion = [maj, min, incrementPatch(ptch, pre || [])].join('.');
break;
case 'prerelease':
nextVersion = [maj, min, ptch].join('.');
break;
default:
return incrementLastSegment(from);
const adapted = adapt(to, from);
if (eq(from, adapted)) {
return incrementLastSegment(from);
}

const isStable = (x: string): boolean => /^[0-9.-/]+$/.test(x);
if (major(from) !== major(adapted)) {
nextVersion = [incrementMajor(maj, min, ptch, pre || []), 0, 0].join('.');
} else if (minor(from) !== minor(adapted)) {
nextVersion = [maj, incrementMinor(min, ptch, pre || []), 0].join('.');
} else if (patch(from) !== patch(adapted)) {
nextVersion = [maj, min, incrementPatch(ptch, pre || [])].join('.');
} else if (isStable(from) && isStable(adapted)) {
nextVersion = [maj, min, incrementPatch(ptch, pre || [])].join('.');
} else {
nextVersion = [maj, min, ptch].join('.');
}

return increment(nextVersion, to);
};

// istanbul ignore next
const decrement = (version: string): string => {
const segments = create(version).release().getSegments();
const segments = releaseSegments(version);
const nextSegments = segments
.reverse()
.reduce((accumulator: number[], segment: number, index: number) => {
if (index === 0) {
return [segment - 1];
}

if (accumulator[index - 1] === -1) {
return [...accumulator.slice(0, index - 1), 0, segment - 1];
}

return [...accumulator, segment];
}, []);
.reduce(
(
accumulator: number[],
segment: SegmentElement,
index: number
): number[] => {
if (index === 0) {
return [(segment as number) - 1];
}

if (accumulator[index - 1] === -1) {
return [
...accumulator.slice(0, index - 1),
0,
(segment as number) - 1,
];
}

return [...accumulator, segment as number];
},
[]
);

return nextSegments.reverse().join('.');
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -110,7 +110,7 @@
"dependencies": {
"@renovate/pep440": "0.4.1",
"@sindresorhus/is": "2.1.1",
"@snyk/ruby-semver": "2.2.2",
"@renovatebot/ruby-semver": "0.1.5",
"@yarnpkg/lockfile": "1.1.0",
"aws-sdk": "2.709.0",
"azure-devops-node-api": "10.1.1",
Expand Down