Skip to content

Commit

Permalink
feat(manager/bundler): improve ruby version detection (#30781)
Browse files Browse the repository at this point in the history
Signed-off-by: Akinori MUSHA <knu@idaemons.org>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
  • Loading branch information
knu and viceice committed Aug 16, 2024
1 parent f042ae4 commit 813bbf6
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 17 deletions.
15 changes: 12 additions & 3 deletions lib/modules/manager/bundler/artifacts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ describe('modules/manager/bundler/artifacts', () => {

it('works for default binarySource', async () => {
fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
fs.readLocalFile.mockResolvedValueOnce(null);
fs.readLocalFile.mockResolvedValueOnce(null); // .ruby-version
fs.readLocalFile.mockResolvedValueOnce(null); // .tool-versions
fs.localPathExists.mockResolvedValueOnce(true); // Gemfile.lock
fs.readLocalFile.mockResolvedValueOnce(null); // Gemfile.lock
const execSnapshots = mockExecAll();
git.getRepoStatus.mockResolvedValueOnce(
partial<StatusResult>({
Expand All @@ -150,7 +153,10 @@ describe('modules/manager/bundler/artifacts', () => {
it('works explicit global binarySource', async () => {
GlobalConfig.set({ ...adminConfig, binarySource: 'global' });
fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
fs.readLocalFile.mockResolvedValueOnce(null);
fs.readLocalFile.mockResolvedValueOnce(null); // .ruby-version
fs.readLocalFile.mockResolvedValueOnce(null); // .tool-versions
fs.localPathExists.mockResolvedValueOnce(true); // Gemfile.lock
fs.readLocalFile.mockResolvedValueOnce(null); // Gemfile.lock
const execSnapshots = mockExecAll();
git.getRepoStatus.mockResolvedValueOnce(
partial<StatusResult>({
Expand All @@ -173,7 +179,10 @@ describe('modules/manager/bundler/artifacts', () => {

it('supports conservative mode and updateType option', async () => {
fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
fs.readLocalFile.mockResolvedValueOnce(null);
fs.readLocalFile.mockResolvedValueOnce(null); // .ruby-version
fs.readLocalFile.mockResolvedValueOnce(null); // .tool-versions
fs.localPathExists.mockResolvedValueOnce(true); // Gemfile.lock
fs.readLocalFile.mockResolvedValueOnce(null); // Gemfile.lock
const execSnapshots = mockExecAll();
git.getRepoStatus.mockResolvedValueOnce(
partial<StatusResult>({
Expand Down
34 changes: 31 additions & 3 deletions lib/modules/manager/bundler/common.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe('modules/manager/bundler/common', () => {
expect(version).toBe('2.1.0');
});

it('extracts from lockfile', async () => {
it('extracts from gemfile', async () => {
const config = partial<UpdateArtifact>({
packageFileName: 'Gemfile',
newPackageFileContent: gemfile,
Expand All @@ -84,9 +84,37 @@ describe('modules/manager/bundler/common', () => {
newPackageFileContent: '',
config: {},
});
fs.readLocalFile.mockResolvedValueOnce('ruby-1.2.3');
fs.readLocalFile.mockResolvedValueOnce('2.7.8');
const version = await getRubyConstraint(config);
expect(version).toBe('2.7.8');
});

it('extracts from .tool-versions', async () => {
const config = partial<UpdateArtifact>({
packageFileName: 'Gemfile',
newPackageFileContent: '',
config: {},
});
fs.readLocalFile
.mockResolvedValueOnce(null)
.mockResolvedValueOnce('python\t3.8.10\nruby\t3.3.4\n');
const version = await getRubyConstraint(config);
expect(version).toBe('3.3.4');
});

it('extracts from lockfile', async () => {
const config = partial<UpdateArtifact>({
packageFileName: 'Gemfile',
newPackageFileContent: '',
config: {},
});
fs.localPathExists.mockResolvedValueOnce(true);
fs.readLocalFile
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(null)
.mockResolvedValueOnce(Fixtures.get('Gemfile.rubyci.lock'));
const version = await getRubyConstraint(config);
expect(version).toBe('1.2.3');
expect(version).toBe('2.6.5');
});

it('returns null', async () => {
Expand Down
29 changes: 18 additions & 11 deletions lib/modules/manager/bundler/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,24 @@ export async function getRubyConstraint(
logger.debug('Using ruby version from gemfile');
return rubyMatch;
}
const rubyVersionFile = getSiblingFileName(
packageFileName,
'.ruby-version',
);
const rubyVersionFileContent = await readLocalFile(rubyVersionFile, 'utf8');
if (rubyVersionFileContent) {
logger.debug('Using ruby version specified in .ruby-version');
return rubyVersionFileContent
.replace(regEx(/^ruby-/), '')
.replace(regEx(/\n/g), '')
.trim();
for (const file of ['.ruby-version', '.tool-versions']) {
const rubyVersion = (
await readLocalFile(getSiblingFileName(packageFileName, file), 'utf8')
)?.match(regEx(/^(?:ruby(?:-|\s+))?(\d[\d.]*)/m))?.[1];
if (rubyVersion) {
logger.debug(`Using ruby version specified in ${file}`);
return rubyVersion;
}
}
const lockFile = await getLockFilePath(packageFileName);
if (lockFile) {
const rubyVersion = (await readLocalFile(lockFile, 'utf8'))?.match(
regEx(/^ {3}ruby (\d[\d.]*)(?:[a-z]|\s|$)/m),
)?.[1];
if (rubyVersion) {
logger.debug(`Using ruby version specified in lock file`);
return rubyVersion;
}
}
}
return null;
Expand Down

0 comments on commit 813bbf6

Please sign in to comment.