Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions renovate-config.json5
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,21 @@
],
"versioningTemplate": "{{#if versioning}}{{{versioning}}}{{/if}}",
},
// Pinned conda-forge dependencies in Conda environment files.
{
"customType": "regex",
"description": "Update pinned conda-forge dependencies in Conda environment files",
"managerFilePatterns": [
"/(^|/)environment[.]ya?ml$/",
],
"matchStrings": [
"(?<indentation>[ \\t]*)-[ \\t]*(?<depName>[A-Za-z0-9_.-]+)[ \\t]*=[ \\t]*(?<currentValue>[^=\\s#][^\\s#]*)",
],
"datasourceTemplate": "conda",
"packageNameTemplate": "conda-forge/{{{depName}}}",
"versioningTemplate": "conda",
"autoReplaceStringTemplate": "{{{indentation}}}- {{{depName}}}={{{newVersion}}}",
},
// CPM Package Lock
{
"customType": "regex",
Expand Down
73 changes: 73 additions & 0 deletions tests/renovate-config.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import test from 'node:test';
import JSON5 from 'json5';
import {extractPackageFile as extractCdnUrlPackageFile} from 'renovate/dist/modules/manager/cdnurl/index.js';
import {extractPackageFile as extractRegexPackageFile} from 'renovate/dist/modules/manager/custom/regex/index.js';
import {compile} from 'renovate/dist/util/template/index.js';

const renovateConfig = JSON5.parse(fs.readFileSync('renovate-config.json5', 'utf8'));
const githubRefManager = renovateConfig.customManagers.find(
Expand All @@ -18,6 +19,10 @@ const sourceNpmCdnManager = renovateConfig.customManagers.find(
manager => manager.datasourceTemplate === 'npm'
&& manager.managerFilePatterns.some(pattern => pattern.includes('docs/source/conf')),
);
const condaEnvironmentManager = renovateConfig.customManagers.find(
manager => manager.datasourceTemplate === 'conda'
&& manager.managerFilePatterns.some(pattern => pattern.includes('environment')),
);

function matchesManagerFilePattern(fileName, patterns) {
return patterns.some(pattern => {
Expand Down Expand Up @@ -56,6 +61,16 @@ function extractGitHubRefDependencies(fileName, content) {
}));
}

function extractCondaDependencies(fileName, content) {
assert.ok(condaEnvironmentManager, 'Expected to find the Conda environment custom manager');
assert.ok(
matchesManagerFilePattern(fileName, condaEnvironmentManager.managerFilePatterns),
`Expected the Conda environment manager to scan ${fileName}`,
);

return extractRegexPackageFile(content, fileName, condaEnvironmentManager)?.deps ?? [];
}

test('extracts the actionlint release and jsDelivr commit', () => {
const fileName = '.github/workflows/__call-common-lint.yml';
const content = fs.readFileSync(fileName, 'utf8');
Expand Down Expand Up @@ -90,6 +105,64 @@ test('extracts a GitHub branch and jsDelivr commit from a composite action', ()
);
});

test('extracts and updates pinned conda-forge dependencies from environment files', () => {
const fileName = 'environment.yml';
const content = `
---
name: RTD
channels:
- conda-forge
- defaults
dependencies:
- doxygen=1.2.3
- graphviz = 4.5.6 # Keep an inline comment.
- nodejs
- pip:
- example==7.8.9
`;
const dependencies = extractCondaDependencies(fileName, content);

assert.deepEqual(
dependencies.map(dependency => ({
currentValue: dependency.currentValue,
datasource: dependency.datasource,
depName: dependency.depName,
packageName: dependency.packageName,
versioning: dependency.versioning,
})),
[
{
currentValue: '1.2.3',
datasource: 'conda',
depName: 'doxygen',
packageName: 'conda-forge/doxygen',
versioning: 'conda',
},
{
currentValue: '4.5.6',
datasource: 'conda',
depName: 'graphviz',
packageName: 'conda-forge/graphviz',
versioning: 'conda',
},
],
);

const dependency = dependencies[0];
const newVersion = nextTestVersion(dependency.currentValue);
const updatedReplaceString = compile(
condaEnvironmentManager.autoReplaceStringTemplate,
{...dependency, newVersion},
false,
);
const updatedContent = content.replace(dependency.replaceString, updatedReplaceString);
const updatedDependencies = extractCondaDependencies(fileName, updatedContent);

assert.equal(updatedDependencies[0].currentValue, newVersion);
assert.match(updatedContent, new RegExp(` - doxygen=${newVersion.replaceAll('.', '\\.')}`));
assert.match(updatedContent, / - graphviz = 4\.5\.6 # Keep an inline comment\./);
});

function nextTestVersion(currentValue) {
const match = /^(.*?)(\d+)$/.exec(currentValue);
assert.ok(match, `Expected a version ending in a number: ${currentValue}`);
Expand Down