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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ruby): add Gemfile.Lock updater #1790

Merged
merged 1 commit into from
Jan 5, 2023
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
127 changes: 127 additions & 0 deletions __snapshots__/gemfile-lock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
exports['Gemfile.lock updateContent updates prerelease in Gemfile.lock 1'] = `
PATH
remote: .
specs:
foo (0.2.0.pre.alpha)

GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
foobar (1.0.1)
diff-lcs (1.5.0)
json (2.6.3)
parallel (1.22.1)
parser (3.1.3.0)
ast (~> 2.4.1)
rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.6.1)
rexml (3.2.5)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.0)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-support (3.12.0)
rubocop (1.39.0)
json (~> 2.3)
parallel (~> 1.10)
parser (>= 3.1.2.1)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.23.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.24.0)
parser (>= 3.1.1.0)
ruby-progressbar (1.11.0)
unicode-display_width (2.3.0)

PLATFORMS
ruby

DEPENDENCIES
bundler
foo!
foobar
rake
rspec
rubocop

BUNDLED WITH
2.3.26

`

exports['Gemfile.lock updateContent updates version in Gemfile.lock 1'] = `
PATH
remote: .
specs:
foo (0.2.0)

GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
foobar (1.0.1)
diff-lcs (1.5.0)
json (2.6.3)
parallel (1.22.1)
parser (3.1.3.0)
ast (~> 2.4.1)
rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.6.1)
rexml (3.2.5)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.0)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-support (3.12.0)
rubocop (1.39.0)
json (~> 2.3)
parallel (~> 1.10)
parser (>= 3.1.2.1)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.23.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.24.0)
parser (>= 3.1.1.0)
ruby-progressbar (1.11.0)
unicode-display_width (2.3.0)

PLATFORMS
ruby

DEPENDENCIES
bundler
foo!
foobar
rake
rspec
rubocop

BUNDLED WITH
2.3.26

`
25 changes: 25 additions & 0 deletions __snapshots__/version-rb.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,31 @@ end

`

exports['version.rb updateContent updates prerelease versions in version.rb 1'] = `
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

module Google
module Cloud
module Bigtable
VERSION = "10.0.0-alpha1".freeze
end
end
end

`

exports['version.rb updateContent updates version in version.rb 1'] = `
# Copyright 2019 Google LLC
#
Expand Down
11 changes: 11 additions & 0 deletions src/strategies/ruby.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {Changelog} from '../updaters/changelog';

// Ruby
import {VersionRB} from '../updaters/ruby/version-rb';
import {GemfileLock} from '../updaters/ruby/gemfile-lock';
import {BaseStrategy, BuildUpdatesOptions, BaseStrategyOptions} from './base';
import {ConventionalCommit} from '../commit';
import {Update} from '../update';
Expand Down Expand Up @@ -56,6 +57,16 @@ export class Ruby extends BaseStrategy {
version,
}),
});

updates.push({
path: this.addPath('Gemfile.lock'),
createIfMissing: false,
updater: new GemfileLock({
version,
gemName: this.component || '',
}),
});

return updates;
}

Expand Down
52 changes: 52 additions & 0 deletions src/updaters/ruby/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {Version} from '../../version';

// Ruby gem semver strings using `.` seperator for prereleases rather then `-`
// See https://guides.rubygems.org/patterns/

export const RUBY_VERSION_REGEX = /((\d+).(\d)+.(\d+)(.\w+.*)?)/g;

/**
* Stringify a version to a ruby compatible version string
*
* @param version The version to stringify
* @param useDotPrePreleaseSeperator Use a `.` seperator for prereleases rather then `-`
* @returns a ruby compatible version string
*/
export function stringifyRubyVersion(
version: Version,
useDotPrePreleaseSeperator = false
) {
if (!useDotPrePreleaseSeperator) {
return version.toString();
}

return `${version.major}.${version.minor}.${version.patch}${
version.preRelease ? `.${version.preRelease}` : ''
}`;
}

/**
* This function mimics Gem::Version parsing of version semver strings
*
* @param versionString The version string to resolve
* @returns A Gem::Version compatible version string
*/
export function resolveRubyGemfileLockVersion(versionString: string) {
// Replace `-` with `.pre.` as per ruby gem parsing
// See https://github.com/rubygems/rubygems/blob/master/lib/rubygems/version.rb#L229
return versionString.replace(/-/g, '.pre.');
}
60 changes: 60 additions & 0 deletions src/updaters/ruby/gemfile-lock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {DefaultUpdater, UpdateOptions} from '../default';
import {RUBY_VERSION_REGEX, resolveRubyGemfileLockVersion} from './common';

export interface GemfileLockOptions extends UpdateOptions {
gemName: string;
}

/**
* Builds a regex matching a gem version in a Gemfile.lock file.
* @example
* rails (7.0.1)
* rails (7.0.1.alpha1)
*/
export function buildGemfileLockVersionRegex(gemName: string) {
return new RegExp(`s*${gemName} \\(${RUBY_VERSION_REGEX.source}\\)`);
}

/**
* Updates a Gemfile.lock files which is expected to have a local path version string.
*/
export class GemfileLock extends DefaultUpdater {
gemName: string;

constructor(options: GemfileLockOptions) {
super(options);
this.gemName = options.gemName;
}

/**
* Given initial file contents, return updated contents.
* @param {string} content The initial content
* @returns {string} The updated content
*/
updateContent(content: string): string {
// Bundler will convert 1.0.0-alpha1 to 1.0.0.pre.alpha1, so we need to
// do the same here.
const versionString = resolveRubyGemfileLockVersion(
this.version.toString()
);

return content.replace(
buildGemfileLockVersionRegex(this.gemName),
`${this.gemName} (${versionString})`
);
}
}
9 changes: 7 additions & 2 deletions src/updaters/ruby/version-rb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
// limitations under the License.

import {DefaultUpdater} from '../default';
import {RUBY_VERSION_REGEX, stringifyRubyVersion} from './common';

const RUBY_VERSION_RB_REGEX = new RegExp(
`(["'])(${RUBY_VERSION_REGEX.source})(["'])`
);

/**
* Updates a versions.rb file which is expected to have a version string.
Expand All @@ -25,8 +30,8 @@ export class VersionRB extends DefaultUpdater {
*/
updateContent(content: string): string {
return content.replace(
/(["'])[0-9]+\.[0-9]+\.[0-9]+(-\w+)?["']/,
`$1${this.version}$1`
RUBY_VERSION_RB_REGEX,
`$1${stringifyRubyVersion(this.version)}$1`
);
}
}
7 changes: 5 additions & 2 deletions test/strategies/ruby.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {TagName} from '../../src/util/tag-name';
import {Version} from '../../src/version';
import {Changelog} from '../../src/updaters/changelog';
import {VersionRB} from '../../src/updaters/ruby/version-rb';
import {GemfileLock} from '../../src/updaters/ruby/gemfile-lock';
import {PullRequestBody} from '../../src/util/pull-request-body';

const sandbox = sinon.createSandbox();
Expand Down Expand Up @@ -96,9 +97,10 @@ describe('Ruby', () => {
latestRelease
);
const updates = release!.updates;
expect(updates).lengthOf(2);
expect(updates).lengthOf(3);
assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
assertHasUpdate(updates, 'lib/google/cloud/automl/version.rb', VersionRB);
assertHasUpdate(updates, 'Gemfile.lock', GemfileLock);
});
it('allows overriding version file', async () => {
const strategy = new Ruby({
Expand All @@ -113,9 +115,10 @@ describe('Ruby', () => {
latestRelease
);
const updates = release!.updates;
expect(updates).lengthOf(2);
expect(updates).lengthOf(3);
assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
assertHasUpdate(updates, 'lib/foo/version.rb', VersionRB);
assertHasUpdate(updates, 'Gemfile.lock', GemfileLock);
});
// TODO: add tests for tag separator
// TODO: add tests for post-processing commit messages
Expand Down