Skip to content

Commit

Permalink
feat(ruby): Switch to @renovate/ruby-semver library (#5116)
Browse files Browse the repository at this point in the history
  • Loading branch information
zharinov committed Apr 16, 2020
1 parent 55a73b9 commit dd0d11d
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 56 deletions.
9 changes: 9 additions & 0 deletions lib/versioning/ruby/index.spec.ts
Original file line number Diff line number Diff line change
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')).toBe(
null
);
expect(
semverRuby.isLessThanRange(null as string, '> 1.2.2, ~> 2.0.0')
).toBe(null);
});
});

describe('.isValid', () => {
Expand Down
2 changes: 1 addition & 1 deletion lib/versioning/ruby/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
satisfies,
maxSatisfying,
minSatisfying,
} from '@snyk/ruby-semver';
} from '@renovatebot/ruby-semver';
import { VersioningApi, NewValueConfig } from '../common';
import { logger } from '../../logger';
import { parse as parseVersion } from './version';
Expand Down
19 changes: 9 additions & 10 deletions lib/versioning/ruby/range.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { create } from '@snyk/ruby-semver/lib/ruby/gem-version';
import { parse as _parse } from '@snyk/ruby-semver/lib/ruby/gem-requirement';
import { create, Version } from '@renovatebot/ruby-semver/dist/ruby/version';
import { parse as _parse } from '@renovatebot/ruby-semver/dist/ruby/requirement';
import { logger } from '../../logger';
import { EQUAL, NOT_EQUAL, GT, LT, GTE, LTE, 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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { gte, lte } from '@snyk/ruby-semver';
import { gte, lte } from '@renovatebot/ruby-semver';
import { logger } from '../../../logger';
import { EQUAL, NOT_EQUAL, GT, LT, GTE, LTE, PGTE } from '../operator';
import { floor, increment, decrement } from '../version';
Expand Down
2 changes: 1 addition & 1 deletion lib/versioning/ruby/strategies/replace.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { satisfies } from '@snyk/ruby-semver';
import { satisfies } from '@renovatebot/ruby-semver';
import bump from './bump';
import { logger } from '../../../logger';

Expand Down
99 changes: 64 additions & 35 deletions lib/versioning/ruby/version.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
import last from 'lodash/last';
import { create } from '@snyk/ruby-semver/lib/ruby/gem-version';
import { diff, major, minor, patch, prerelease } from '@snyk/ruby-semver';
import {
create,
SegmentElement,
} from '@renovatebot/ruby-semver/dist/ruby/version';
import { eq, major, minor, patch, prerelease } from '@renovatebot/ruby-semver';

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 @@ -19,13 +31,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(last(segments), 10) + 1;
const segments = releaseSegments(version);
const nextLast = parseInt(last(segments) as string, 10) + 1;

return [...segments.slice(0, -1), nextLast].join('.');
};
Expand All @@ -48,45 +61,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
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@
},
"dependencies": {
"@renovate/pep440": "0.4.1",
"@renovatebot/ruby-semver": "0.1.3",
"@sindresorhus/is": "2.1.0",
"@snyk/ruby-semver": "2.1.0",
"@yarnpkg/lockfile": "1.1.0",
"aws-sdk": "2.656.0",
"azure-devops-node-api": "10.1.1",
Expand Down
12 changes: 5 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,11 @@
dependencies:
xregexp "4.2.0"

"@renovatebot/ruby-semver@0.1.3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@renovatebot/ruby-semver/-/ruby-semver-0.1.3.tgz#dfa43139d5a465dddec9e0e712d9d359bf7ea167"
integrity sha512-tGd5CMTCrFrmJhGxIhLP2Imv5bkzfZQY/6gfV+T6TOhMfca9hRBA7hj/xAexSDLAFN5QmEjGPK0SFusVUPPHIw==

"@semantic-release/commit-analyzer@^8.0.0":
version "8.0.1"
resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-8.0.1.tgz#5d2a37cd5a3312da0e3ac05b1ca348bf60b90bca"
Expand Down Expand Up @@ -1296,13 +1301,6 @@
resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5"
integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==

"@snyk/ruby-semver@2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@snyk/ruby-semver/-/ruby-semver-2.1.0.tgz#d76cc02fc20860c224da2646fe9cc1bb0b0d1d15"
integrity sha512-u8ez8kWyqge+N+FxRDx/uPBmcHzY7BMfODvzEVeoTOeoD0CHPymEaVlkEKA8ZHtxzXjUzPIl2I8f2siZEzLjYg==
dependencies:
lodash "^4.17.14"

"@szmarczak/http-timer@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
Expand Down

0 comments on commit dd0d11d

Please sign in to comment.