Skip to content

Commit

Permalink
feat(internal): Switch to @renovate/ruby-semver library (#5982)
Browse files Browse the repository at this point in the history
  • Loading branch information
zharinov committed Jul 5, 2020
1 parent 6ec460b commit 52e4b4c
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 146 deletions.
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

0 comments on commit 52e4b4c

Please sign in to comment.