feat: Cargo manager use toml parser (#3505)

This commit is contained in:
Nikita Chashchinskii 2019-04-09 11:25:13 +03:00 committed by Rhys Arkins
parent ec16c8b2b8
commit 9476c80f3d
11 changed files with 753 additions and 307 deletions

View file

@ -1,165 +1,105 @@
const toml = require('toml');
const semver = require('../../versioning/cargo'); const semver = require('../../versioning/cargo');
module.exports = { module.exports = {
extractPackageFile, extractPackageFile,
getDep,
getInlineTableDep,
getTableDep,
}; };
/* Quote from TOML spec. */
/*
Inline tables are intended to appear on a single line. No newlines are
allowed between the curly braces unless they are valid within a value.
Even so, it is strongly discouraged to break an inline table onto
multiples lines. If you find yourself gripped with this desire, it
means you should be using standard tables.
*/
// TODO: Find and fix all corner cases
function extractPackageFile(content, fileName) { function extractPackageFile(content, fileName) {
logger.trace(`cargo.extractPackageFile(${fileName})`); logger.trace(`cargo.extractPackageFile(${fileName})`);
let deps = []; let parsedContent;
let lineNumber = 0; try {
const lines = content.split('\n'); parsedContent = toml.parse(content);
for (const line of lines) { } catch (err) {
if (line.trim()[0] !== '#') { logger.debug({ err }, 'Error parsing Cargo.toml file');
const match = line.match('dependencies[.]');
if (match) {
const dep = getTableDep(match, lines, lineNumber);
if (dep) {
deps.push(dep);
}
} else if (line.match('dependencies')) {
const sectionDeps = getDeps(lines, lineNumber);
deps = [].concat(deps, sectionDeps);
}
lineNumber += 1;
}
}
if (!deps.length) {
return null; return null;
} }
for (let i = 0; i < deps.length; i += 1) { /*
const dep = deps[i]; There are the following sections in Cargo.toml:
deps[i].purl = 'pkg:cargo/' + deps[i].depName; [dependencies]
deps[i].datasource = 'cargo'; [dev-dependencies]
if (dep && !dep.skipReason && dep.currentValue) { [build-dependencies]
if (!semver.isValid(dep.currentValue)) { [target.*.dependencies]
deps[i].skipReason = 'unknown-version'; */
} const targetSection = parsedContent.target;
} // An array of all dependencies in the target section
let targetDeps = [];
if (targetSection) {
const targets = Object.keys(targetSection);
targets.forEach(target => {
const targetContent = parsedContent.target[target];
// Dependencies for `${target}`
const deps = [
...extractFromSection(targetContent, 'dependencies', target),
...extractFromSection(targetContent, 'dev-dependencies', target),
...extractFromSection(targetContent, 'build-dependencies', target),
];
targetDeps = targetDeps.concat(deps);
});
}
const deps = [
...extractFromSection(parsedContent, 'dependencies'),
...extractFromSection(parsedContent, 'dev-dependencies'),
...extractFromSection(parsedContent, 'build-dependencies'),
...targetDeps,
];
if (!deps.length) {
return null;
} }
return { deps }; return { deps };
} }
// Get dependencies in a [dependencies], or [dev-dependencies], function extractFromSection(parsedContent, section, target) {
// or [build-dependencies], etc section
function getDeps(lines, lineNumber) {
const deps = []; const deps = [];
for ( const sectionContent = parsedContent[section];
let i = 1; if (!sectionContent) {
lineNumber + i < lines.length && lines[lineNumber + i].trim()[0] !== '['; return [];
i += 1 }
) { Object.keys(sectionContent).forEach(depName => {
let dep = null; let skipReason;
const l = lines[lineNumber + i]; let currentValue = sectionContent[depName];
// Ignore comments let nestedVersion = false;
if (l.trim()[0] !== '#') { if (typeof currentValue !== 'string') {
if (l.match('{*}')) { const version = sectionContent[depName].version;
dep = getInlineTableDep(l); const path = sectionContent[depName].path;
const git = sectionContent[depName].git;
if (version) {
currentValue = version;
nestedVersion = true;
if (path) {
skipReason = 'path-dependency';
}
if (git) {
skipReason = 'git-dependency';
}
} else if (path) {
currentValue = '';
skipReason = 'path-dependency';
} else if (git) {
currentValue = '';
skipReason = 'git-dependency';
} else { } else {
dep = getDep(l); currentValue = '';
} skipReason = 'invalid-dependency-specification';
if (dep) {
dep.lineNumber = lineNumber + i;
deps.push(dep);
} }
} }
} const dep = {
depName,
depType: section,
currentValue,
nestedVersion,
datasource: 'cargo',
purl: 'pkg:cargo/' + depName,
};
if (skipReason) {
dep.skipReason = skipReason;
} else if (!semver.isValid(dep.currentValue)) {
dep.skipReason = 'unknown-version';
}
if (target) {
dep.target = target;
}
deps.push(dep);
});
return deps; return deps;
} }
// Get a normal dependency name and version
// Example: foo = '1.2.3'
function getDep(line) {
const entry = line.split('=');
const remaining = entry.slice(1).join('=');
const dep = {};
const depName = entry[0].trim();
if (depName) {
const currentValue = remaining
.trim()
.replace(/['"]+/g, '')
.trim();
dep.currentValue = currentValue;
dep.depName = depName;
dep.depType = 'normal';
return dep;
}
return null;
}
// Get dependency name and version from an inline table
// Example: pcap-sys = { version = "0.1", path = "pcap-sys" }
function getInlineTableDep(line) {
const dep = {};
let content = line.split('=');
dep.depName = content[0].trim();
content = content.slice(1);
content = content.join('=');
content = content.trim().replace(/[{}]+/g, '');
const fields = content.split(',');
for (let i = 0; i < fields.length; i += 1) {
const field = fields[i].split('=');
const remaining = field.slice(1).join('=');
const name = field[0].trim();
const value = remaining.trim();
if (name === 'path') {
dep.skipReason = 'path-dependency';
}
if (name === 'version') {
dep.currentValue = value.replace(/['"]+/g, '').trim();
dep.depType = 'inlineTable';
}
}
if (dep.currentValue || dep.skipReason) {
return dep;
}
return null;
}
// Get dependency name and version from a standard TOML table
function getTableDep(match, lines, lineNumber) {
const dep = {};
let input = match.input;
if (input.trim()[0] === '#') {
return null;
}
input = input.replace(/[[\]]+/g, '');
input = input.split('.');
dep.depName = input[input.length - 1];
// Record the line number of [*dependencies.<depName>] expression
dep.lineNumber = lineNumber;
let name = '';
for (let i = 1; lineNumber + i < lines.length; i += 1) {
const field = lines[lineNumber + i].split('=');
const remaining = field.slice(1).join('=');
name = field[0].trim();
if (name === 'path') {
dep.skipReason = 'path-dependency';
}
if (name === 'version') {
dep.currentValue = remaining
.trim()
.replace(/['"]+/g, '')
.trim();
dep.depType = 'standardTable';
dep.versionLineNumber = lineNumber + i;
}
}
if (dep.currentValue || dep.skipReason) {
return dep;
}
return null;
}

View file

@ -1,39 +1,125 @@
const { getDep, getInlineTableDep, getTableDep } = require('./extract'); const _ = require('lodash');
const toml = require('toml');
module.exports = { module.exports = {
updateDependency, updateDependency,
}; };
function updateDependency(currentFileContent, upgrade) { // Return true if the match string is found at index in content
logger.trace({ config: upgrade }, 'cargo.updateDependency()'); function matchAt(content, index, match) {
const { depName, depType, lineNumber, newValue } = upgrade; return content.substring(index, index + match.length) === match;
const lines = currentFileContent.split('\n'); }
let dep;
let currentValue; // Replace oldString with newString at location index of content
let versionLineNumber = lineNumber; function replaceAt(content, index, oldString, newString) {
const line = lines[lineNumber]; logger.debug(`Replacing ${oldString} with ${newString} at index ${index}`);
if (depType === 'normal') { return (
dep = getDep(line); content.substr(0, index) +
} else if (depType === 'inlineTable') { newString +
dep = getInlineTableDep(line); content.substr(index + oldString.length)
} else if (depType === 'standardTable' && line) { );
const match = line.match('dependencies[.]'); }
// Might need handling comments in getTableDep
dep = getTableDep(match, lines, lineNumber); function updateDependency(fileContent, upgrade) {
if (dep) { logger.trace({ config: upgrade }, 'poetry.updateDependency()');
versionLineNumber = dep.versionLineNumber; if (!upgrade) {
} return fileContent;
} }
if (dep && !dep.skipReason) { const { target, depType, depName, newValue, nestedVersion } = upgrade;
currentValue = dep.currentValue; let parsedContent;
if (dep.depName.match(depName)) { try {
lines[versionLineNumber] = lines[versionLineNumber].replace( parsedContent = toml.parse(fileContent);
currentValue, } catch (err) {
newValue logger.debug({ err }, 'Error parsing Cargo.toml file');
return fileContent;
}
let section;
if (target) {
section = parsedContent.target[target];
if (section) {
section = section[depType];
}
} else {
section = parsedContent[depType];
}
if (!section) {
if (target) {
logger.info(
{ config: upgrade },
`Error: Section [target.${target}.${depType}] doesn't exist in Cargo.toml file, update failed`
); );
} else { } else {
logger.debug(dep, upgrade, 'Invalid upgrade.lineNumber'); logger.info(
{ config: upgrade },
`Error: Section [${depType}] doesn't exist in Cargo.toml file, update failed`
);
}
return fileContent;
}
let oldVersion;
const oldDep = section[depName];
if (!oldDep) {
logger.info(
{ config: upgrade },
`Could not get version of dependency ${depName}, update failed (most likely name is invalid)`
);
return fileContent;
}
oldVersion = section[depName];
// if (typeof oldVersion !== 'string') {
// if (oldVersion.version) {
// oldVersion = oldVersion.version;
// } else {
// oldVersion = null;
// }
// }
if (nestedVersion) {
oldVersion = oldVersion.version;
}
if (!oldVersion) {
logger.info(
{ config: upgrade },
`Could not get version of dependency ${depName}, update failed (most likely name is invalid)`
);
return fileContent;
}
if (oldVersion === newValue) {
logger.info('Version is already updated');
return fileContent;
}
if (nestedVersion) {
section[depName].version = newValue;
} else {
section[depName] = newValue;
}
if (target) {
parsedContent.target[target][depType] = section;
} else {
parsedContent[depType] = section;
}
const searchString = `"${oldVersion}"`;
const newString = `"${newValue}"`;
let newFileContent = fileContent;
let searchIndex = fileContent.indexOf(`${depName}`) + depName.length;
for (; searchIndex < fileContent.length; searchIndex += 1) {
// First check if we have a hit for the old version
if (matchAt(fileContent, searchIndex, searchString)) {
logger.trace(`Found match at index ${searchIndex}`);
// Now test if the result matches
const testContent = replaceAt(
fileContent,
searchIndex,
searchString,
newString
);
// Compare the parsed toml structure of old and new
if (_.isEqual(parsedContent, toml.parse(testContent))) {
newFileContent = testContent;
break;
} else {
logger.debug('Mismatched replace at searchIndex ' + searchIndex);
}
} }
} }
return lines.join('\n'); return newFileContent;
} }

View file

@ -6,24 +6,24 @@ Array [
"currentValue": "=0.2.43", "currentValue": "=0.2.43",
"datasource": "cargo", "datasource": "cargo",
"depName": "libc", "depName": "libc",
"depType": "normal", "depType": "dependencies",
"lineNumber": 16, "nestedVersion": false,
"purl": "pkg:cargo/libc", "purl": "pkg:cargo/libc",
}, },
Object { Object {
"currentValue": "1.0.4", "currentValue": "1.0.4",
"datasource": "cargo", "datasource": "cargo",
"depName": "bitflags", "depName": "bitflags",
"depType": "normal", "depType": "dependencies",
"lineNumber": 17, "nestedVersion": false,
"purl": "pkg:cargo/bitflags", "purl": "pkg:cargo/bitflags",
}, },
Object { Object {
"currentValue": "=0.1", "currentValue": "=0.1",
"datasource": "cargo", "datasource": "cargo",
"depName": "pcap-sys", "depName": "pcap-sys",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 18, "nestedVersion": true,
"purl": "pkg:cargo/pcap-sys", "purl": "pkg:cargo/pcap-sys",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -31,27 +31,105 @@ Array [
"currentValue": "0.21.0", "currentValue": "0.21.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "pnet", "depName": "pnet",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 19, "nestedVersion": true,
"purl": "pkg:cargo/pnet", "purl": "pkg:cargo/pnet",
}, },
Object { Object {
"currentValue": "0.4.2", "currentValue": "0.1.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "winapi", "depName": "git_dep_with_version",
"depType": "standardTable", "depType": "dependencies",
"lineNumber": 21, "nestedVersion": true,
"purl": "pkg:cargo/winapi", "purl": "pkg:cargo/git_dep_with_version",
"versionLineNumber": 26, "skipReason": "git-dependency",
},
Object {
"currentValue": "",
"datasource": "cargo",
"depName": "git_dep",
"depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/git_dep",
"skipReason": "git-dependency",
},
Object {
"currentValue": "0.0.0",
"datasource": "cargo",
"depName": "same_version_1__",
"depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/same_version_1__",
},
Object {
"currentValue": "0.0.0",
"datasource": "cargo",
"depName": "same_version_1_",
"depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/same_version_1_",
},
Object {
"currentValue": "0.0.0",
"datasource": "cargo",
"depName": "same_version_1",
"depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/same_version_1",
}, },
Object { Object {
"currentValue": "0.4.2", "currentValue": "0.4.2",
"datasource": "cargo", "datasource": "cargo",
"depName": "dep1", "depName": "dep1",
"depType": "standardTable", "depType": "dependencies",
"lineNumber": 25, "nestedVersion": true,
"purl": "pkg:cargo/dep1", "purl": "pkg:cargo/dep1",
"versionLineNumber": 26, },
Object {
"currentValue": "=0.3.6",
"datasource": "cargo",
"depName": "winapi",
"depType": "dependencies",
"nestedVersion": true,
"purl": "pkg:cargo/winapi",
"target": "cfg(windows)",
},
Object {
"currentValue": "0.2.37",
"datasource": "cargo",
"depName": "wasm-bindgen",
"depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/wasm-bindgen",
"target": "cfg(target_arch = \\"wasm32\\")",
},
Object {
"currentValue": "0.3.14",
"datasource": "cargo",
"depName": "js-sys",
"depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/js-sys",
"target": "cfg(target_arch = \\"wasm32\\")",
},
Object {
"currentValue": "",
"datasource": "cargo",
"depName": "js_relative_import",
"depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/js_relative_import",
"skipReason": "path-dependency",
"target": "cfg(target_arch = \\"wasm32\\")",
},
Object {
"currentValue": "0.3.14",
"datasource": "cargo",
"depName": "web-sys",
"depType": "dependencies",
"nestedVersion": true,
"purl": "pkg:cargo/web-sys",
"target": "cfg(target_arch = \\"wasm32\\")",
}, },
] ]
`; `;
@ -62,8 +140,8 @@ Array [
"currentValue": "0.2.0", "currentValue": "0.2.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "amethyst_animation", "depName": "amethyst_animation",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 53, "nestedVersion": true,
"purl": "pkg:cargo/amethyst_animation", "purl": "pkg:cargo/amethyst_animation",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -71,8 +149,8 @@ Array [
"currentValue": "0.3.0", "currentValue": "0.3.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "amethyst_assets", "depName": "amethyst_assets",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 54, "nestedVersion": true,
"purl": "pkg:cargo/amethyst_assets", "purl": "pkg:cargo/amethyst_assets",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -80,8 +158,8 @@ Array [
"currentValue": "0.2.0", "currentValue": "0.2.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "amethyst_audio", "depName": "amethyst_audio",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 55, "nestedVersion": true,
"purl": "pkg:cargo/amethyst_audio", "purl": "pkg:cargo/amethyst_audio",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -89,8 +167,8 @@ Array [
"currentValue": "0.6.0", "currentValue": "0.6.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "amethyst_config", "depName": "amethyst_config",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 56, "nestedVersion": true,
"purl": "pkg:cargo/amethyst_config", "purl": "pkg:cargo/amethyst_config",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -98,8 +176,8 @@ Array [
"currentValue": "0.2.0", "currentValue": "0.2.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "amethyst_core", "depName": "amethyst_core",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 57, "nestedVersion": true,
"purl": "pkg:cargo/amethyst_core", "purl": "pkg:cargo/amethyst_core",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -107,8 +185,8 @@ Array [
"currentValue": "0.1.0", "currentValue": "0.1.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "amethyst_controls", "depName": "amethyst_controls",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 58, "nestedVersion": true,
"purl": "pkg:cargo/amethyst_controls", "purl": "pkg:cargo/amethyst_controls",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -116,8 +194,8 @@ Array [
"currentValue": "0.1.0", "currentValue": "0.1.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "amethyst_locale", "depName": "amethyst_locale",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 59, "nestedVersion": true,
"purl": "pkg:cargo/amethyst_locale", "purl": "pkg:cargo/amethyst_locale",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -125,8 +203,8 @@ Array [
"currentValue": "0.7", "currentValue": "0.7",
"datasource": "cargo", "datasource": "cargo",
"depName": "amethyst_renderer", "depName": "amethyst_renderer",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 60, "nestedVersion": true,
"purl": "pkg:cargo/amethyst_renderer", "purl": "pkg:cargo/amethyst_renderer",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -134,8 +212,8 @@ Array [
"currentValue": "0.3", "currentValue": "0.3",
"datasource": "cargo", "datasource": "cargo",
"depName": "amethyst_input", "depName": "amethyst_input",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 61, "nestedVersion": true,
"purl": "pkg:cargo/amethyst_input", "purl": "pkg:cargo/amethyst_input",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -143,8 +221,8 @@ Array [
"currentValue": "0.2", "currentValue": "0.2",
"datasource": "cargo", "datasource": "cargo",
"depName": "amethyst_ui", "depName": "amethyst_ui",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 62, "nestedVersion": true,
"purl": "pkg:cargo/amethyst_ui", "purl": "pkg:cargo/amethyst_ui",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -152,8 +230,8 @@ Array [
"currentValue": "0.2", "currentValue": "0.2",
"datasource": "cargo", "datasource": "cargo",
"depName": "amethyst_utils", "depName": "amethyst_utils",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 63, "nestedVersion": true,
"purl": "pkg:cargo/amethyst_utils", "purl": "pkg:cargo/amethyst_utils",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -161,64 +239,64 @@ Array [
"currentValue": "1.0", "currentValue": "1.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "derivative", "depName": "derivative",
"depType": "normal", "depType": "dependencies",
"lineNumber": 64, "nestedVersion": false,
"purl": "pkg:cargo/derivative", "purl": "pkg:cargo/derivative",
}, },
Object { Object {
"currentValue": "0.5", "currentValue": "0.5",
"datasource": "cargo", "datasource": "cargo",
"depName": "fern", "depName": "fern",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 65, "nestedVersion": true,
"purl": "pkg:cargo/fern", "purl": "pkg:cargo/fern",
}, },
Object { Object {
"currentValue": "0.4", "currentValue": "0.4",
"datasource": "cargo", "datasource": "cargo",
"depName": "log", "depName": "log",
"depType": "normal", "depType": "dependencies",
"lineNumber": 66, "nestedVersion": false,
"purl": "pkg:cargo/log", "purl": "pkg:cargo/log",
}, },
Object { Object {
"currentValue": "1.0.1", "currentValue": "1.0.1",
"datasource": "cargo", "datasource": "cargo",
"depName": "rayon", "depName": "rayon",
"depType": "normal", "depType": "dependencies",
"lineNumber": 67, "nestedVersion": false,
"purl": "pkg:cargo/rayon", "purl": "pkg:cargo/rayon",
}, },
Object { Object {
"currentValue": "0.1", "currentValue": "0.1",
"datasource": "cargo", "datasource": "cargo",
"depName": "rustc_version_runtime", "depName": "rustc_version_runtime",
"depType": "normal", "depType": "dependencies",
"lineNumber": 68, "nestedVersion": false,
"purl": "pkg:cargo/rustc_version_runtime", "purl": "pkg:cargo/rustc_version_runtime",
}, },
Object { Object {
"currentValue": "0.15", "currentValue": "0.15",
"datasource": "cargo", "datasource": "cargo",
"depName": "winit", "depName": "winit",
"depType": "normal", "depType": "dependencies",
"lineNumber": 69, "nestedVersion": false,
"purl": "pkg:cargo/winit", "purl": "pkg:cargo/winit",
}, },
Object { Object {
"currentValue": "0.1", "currentValue": "0.1",
"datasource": "cargo", "datasource": "cargo",
"depName": "thread_profiler", "depName": "thread_profiler",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 71, "nestedVersion": true,
"purl": "pkg:cargo/thread_profiler", "purl": "pkg:cargo/thread_profiler",
}, },
Object { Object {
"currentValue": "0.2", "currentValue": "0.2",
"datasource": "cargo", "datasource": "cargo",
"depName": "amethyst_gltf", "depName": "amethyst_gltf",
"depType": "inlineTable", "depType": "dev-dependencies",
"lineNumber": 74, "nestedVersion": true,
"purl": "pkg:cargo/amethyst_gltf", "purl": "pkg:cargo/amethyst_gltf",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -226,61 +304,103 @@ Array [
"currentValue": "0.5.10", "currentValue": "0.5.10",
"datasource": "cargo", "datasource": "cargo",
"depName": "env_logger", "depName": "env_logger",
"depType": "normal", "depType": "dev-dependencies",
"lineNumber": 75, "nestedVersion": false,
"purl": "pkg:cargo/env_logger", "purl": "pkg:cargo/env_logger",
}, },
Object { Object {
"currentValue": "0.6", "currentValue": "0.6",
"datasource": "cargo", "datasource": "cargo",
"depName": "genmesh", "depName": "genmesh",
"depType": "normal", "depType": "dev-dependencies",
"lineNumber": 76, "nestedVersion": false,
"purl": "pkg:cargo/genmesh", "purl": "pkg:cargo/genmesh",
}, },
Object { Object {
"currentValue": "0.2", "currentValue": "0.2",
"datasource": "cargo", "datasource": "cargo",
"depName": "ron", "depName": "ron",
"depType": "normal", "depType": "dev-dependencies",
"lineNumber": 77, "nestedVersion": false,
"purl": "pkg:cargo/ron", "purl": "pkg:cargo/ron",
}, },
Object { Object {
"currentValue": "1.0", "currentValue": "1.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "serde", "depName": "serde",
"depType": "normal", "depType": "dev-dependencies",
"lineNumber": 78, "nestedVersion": false,
"purl": "pkg:cargo/serde", "purl": "pkg:cargo/serde",
}, },
Object { Object {
"currentValue": "1.0", "currentValue": "1.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "serde_derive", "depName": "serde_derive",
"depType": "normal", "depType": "dev-dependencies",
"lineNumber": 79, "nestedVersion": false,
"purl": "pkg:cargo/serde_derive", "purl": "pkg:cargo/serde_derive",
}, },
Object { Object {
"currentValue": "0.1", "currentValue": "0.1",
"datasource": "cargo", "datasource": "cargo",
"depName": "vergen", "depName": "vergen",
"depType": "normal", "depType": "build-dependencies",
"lineNumber": 82, "nestedVersion": false,
"purl": "pkg:cargo/vergen", "purl": "pkg:cargo/vergen",
}, },
] ]
`; `;
exports[`lib/manager/cargo/extract extractPackageFile() extracts platform specific dependencies 1`] = `
Array [
Object {
"currentValue": "0.2.37",
"datasource": "cargo",
"depName": "wasm-bindgen",
"depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/wasm-bindgen",
"target": "cfg(target_arch = \\"wasm32\\")",
},
Object {
"currentValue": "0.3.14",
"datasource": "cargo",
"depName": "js-sys",
"depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/js-sys",
"target": "cfg(target_arch = \\"wasm32\\")",
},
Object {
"currentValue": "",
"datasource": "cargo",
"depName": "js_relative_import",
"depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/js_relative_import",
"skipReason": "path-dependency",
"target": "cfg(target_arch = \\"wasm32\\")",
},
Object {
"currentValue": "0.3.14",
"datasource": "cargo",
"depName": "web-sys",
"depType": "dependencies",
"nestedVersion": true,
"purl": "pkg:cargo/web-sys",
"target": "cfg(target_arch = \\"wasm32\\")",
},
]
`;
exports[`lib/manager/cargo/extract extractPackageFile() handles inline tables 1`] = ` exports[`lib/manager/cargo/extract extractPackageFile() handles inline tables 1`] = `
Array [ Array [
Object { Object {
"currentValue": "0.1", "currentValue": "0.1",
"datasource": "cargo", "datasource": "cargo",
"depName": "pcap-sys", "depName": "pcap-sys",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 5, "nestedVersion": true,
"purl": "pkg:cargo/pcap-sys", "purl": "pkg:cargo/pcap-sys",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -288,16 +408,16 @@ Array [
"currentValue": "0.21.0", "currentValue": "0.21.0",
"datasource": "cargo", "datasource": "cargo",
"depName": "pnet", "depName": "pnet",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 6, "nestedVersion": true,
"purl": "pkg:cargo/pnet", "purl": "pkg:cargo/pnet",
}, },
Object { Object {
"currentValue": "1.2", "currentValue": "1.2",
"datasource": "cargo", "datasource": "cargo",
"depName": "dep1", "depName": "dep1",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 7, "nestedVersion": true,
"purl": "pkg:cargo/dep1", "purl": "pkg:cargo/dep1",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -305,8 +425,8 @@ Array [
"currentValue": "3.4", "currentValue": "3.4",
"datasource": "cargo", "datasource": "cargo",
"depName": "dep2", "depName": "dep2",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 8, "nestedVersion": true,
"purl": "pkg:cargo/dep2", "purl": "pkg:cargo/dep2",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -314,8 +434,8 @@ Array [
"currentValue": "~12.3.1", "currentValue": "~12.3.1",
"datasource": "cargo", "datasource": "cargo",
"depName": "dep3", "depName": "dep3",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 9, "nestedVersion": true,
"purl": "pkg:cargo/dep3", "purl": "pkg:cargo/dep3",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
@ -323,8 +443,8 @@ Array [
"currentValue": "INVALID 3.3.1 VERSION", "currentValue": "INVALID 3.3.1 VERSION",
"datasource": "cargo", "datasource": "cargo",
"depName": "dep4", "depName": "dep4",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 10, "nestedVersion": true,
"purl": "pkg:cargo/dep4", "purl": "pkg:cargo/dep4",
"skipReason": "unknown-version", "skipReason": "unknown-version",
}, },
@ -332,61 +452,77 @@ Array [
"currentValue": "3.2.1", "currentValue": "3.2.1",
"datasource": "cargo", "datasource": "cargo",
"depName": "dep5", "depName": "dep5",
"depType": "inlineTable", "depType": "dependencies",
"lineNumber": 11, "nestedVersion": true,
"purl": "pkg:cargo/dep5", "purl": "pkg:cargo/dep5",
}, },
Object {
"currentValue": "",
"datasource": "cargo",
"depName": "dep6",
"depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/dep6",
"skipReason": "invalid-dependency-specification",
},
] ]
`; `;
exports[`lib/manager/cargo/extract extractPackageFile() handles standard tables 1`] = ` exports[`lib/manager/cargo/extract extractPackageFile() handles standard tables 1`] = `
Array [ Array [
Object { Object {
"currentValue": "INVALID 1.3.1 VERSION", "currentValue": "1.2",
"datasource": "cargo", "datasource": "cargo",
"depName": "dep1", "depName": "dep1",
"depType": "standardTable", "depType": "dependencies",
"lineNumber": 4, "nestedVersion": true,
"purl": "pkg:cargo/dep1", "purl": "pkg:cargo/dep1",
"skipReason": "path-dependency", "skipReason": "path-dependency",
"versionLineNumber": 24,
}, },
Object { Object {
"currentValue": "INVALID 1.3.1 VERSION", "currentValue": "3.4",
"datasource": "cargo", "datasource": "cargo",
"depName": "dep2", "depName": "dep2",
"depType": "standardTable", "depType": "dependencies",
"lineNumber": 13, "nestedVersion": true,
"purl": "pkg:cargo/dep2", "purl": "pkg:cargo/dep2",
"skipReason": "path-dependency", "skipReason": "path-dependency",
"versionLineNumber": 24,
}, },
Object { Object {
"currentValue": "INVALID 1.3.1 VERSION", "currentValue": "~12.3.1",
"datasource": "cargo", "datasource": "cargo",
"depName": "dep3", "depName": "dep3",
"depType": "standardTable", "depType": "dependencies",
"lineNumber": 18, "nestedVersion": true,
"purl": "pkg:cargo/dep3", "purl": "pkg:cargo/dep3",
"skipReason": "path-dependency", "skipReason": "path-dependency",
"versionLineNumber": 24,
}, },
Object { Object {
"currentValue": "INVALID 1.3.1 VERSION", "currentValue": "INVALID 1.3.1 VERSION",
"datasource": "cargo", "datasource": "cargo",
"depName": "dep4", "depName": "dep4",
"depType": "standardTable", "depType": "dependencies",
"lineNumber": 23, "nestedVersion": true,
"purl": "pkg:cargo/dep4", "purl": "pkg:cargo/dep4",
"skipReason": "path-dependency", "skipReason": "path-dependency",
"versionLineNumber": 24,
}, },
Object { Object {
"currentValue": "",
"datasource": "cargo", "datasource": "cargo",
"depName": "dep5", "depName": "dep5",
"lineNumber": 28, "depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/dep5", "purl": "pkg:cargo/dep5",
"skipReason": "path-dependency", "skipReason": "path-dependency",
}, },
Object {
"currentValue": "",
"datasource": "cargo",
"depName": "dep7",
"depType": "dependencies",
"nestedVersion": false,
"purl": "pkg:cargo/dep7",
"skipReason": "invalid-dependency-specification",
},
] ]
`; `;

View file

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`lib/manager/cargo/update updateDependency() updates inline table dependency 1`] = ` exports[`lib/manager/cargo/update updateDependency() updates nested version dependency 1`] = `
"[package] "[package]
name = \\"rustcap\\" name = \\"rustcap\\"
version = \\"0.1.2\\" version = \\"0.1.2\\"
@ -19,13 +19,33 @@ members = [\\"pcap-sys\\"]
[dependencies] [dependencies]
libc = \\"=0.2.43\\" libc = \\"=0.2.43\\"
bitflags = \\"1.0.4\\" bitflags = \\"1.0.4\\"
pcap-sys = { version = \\"=0.1\\", path = \\"pcap-sys\\" } pcap-sys = { version = \\"0.2.0\\", path = \\"pcap-sys\\" }
pnet = { version = \\"0.21.0\\", optional = true, default-features = false} pnet = { version = \\"0.21.0\\", optional = true, default-features = false}
git_dep_with_version = { version = \\"0.1.0\\", git = \\"https://github.com/foo/bar\\" }
git_dep = { git = \\"https://github.com/foo/bar\\" }
same_version_1__ = \\"0.0.0\\"
same_version_1_ = \\"0.0.0\\"
same_version_1 = \\"0.0.0\\"
[target.'cfg(windows)'.dependencies.winapi] [target.'cfg(windows)'.dependencies.winapi]
version = \\"=0.3.6\\" version = \\"=0.3.6\\"
features = [\\"ws2def\\", \\"ws2ipdef\\"] features = [\\"ws2def\\", \\"ws2ipdef\\"]
[target.'cfg(target_arch = \\"wasm32\\")'.dependencies]
wasm-bindgen = \\"0.2.37\\"
js-sys = \\"0.3.14\\"
js_relative_import = { path = \\"../../common/js_relative_import\\" }
[target.'cfg(target_arch = \\"wasm32\\")'.dependencies.web-sys]
version = \\"0.3.14\\"
features = [
\\"AudioBuffer\\",
\\"AudioBufferSourceNode\\",
\\"AudioContext\\",
\\"AudioDestinationNode\\",
\\"AudioNode\\",
]
[dependencies.dep1] [dependencies.dep1]
version = \\"0.4.2\\" version = \\"0.4.2\\"
@ -61,11 +81,31 @@ libc = \\"0.3.0\\"
bitflags = \\"1.0.4\\" bitflags = \\"1.0.4\\"
pcap-sys = { version = \\"=0.1\\", path = \\"pcap-sys\\" } pcap-sys = { version = \\"=0.1\\", path = \\"pcap-sys\\" }
pnet = { version = \\"0.21.0\\", optional = true, default-features = false} pnet = { version = \\"0.21.0\\", optional = true, default-features = false}
git_dep_with_version = { version = \\"0.1.0\\", git = \\"https://github.com/foo/bar\\" }
git_dep = { git = \\"https://github.com/foo/bar\\" }
same_version_1__ = \\"0.0.0\\"
same_version_1_ = \\"0.0.0\\"
same_version_1 = \\"0.0.0\\"
[target.'cfg(windows)'.dependencies.winapi] [target.'cfg(windows)'.dependencies.winapi]
version = \\"=0.3.6\\" version = \\"=0.3.6\\"
features = [\\"ws2def\\", \\"ws2ipdef\\"] features = [\\"ws2def\\", \\"ws2ipdef\\"]
[target.'cfg(target_arch = \\"wasm32\\")'.dependencies]
wasm-bindgen = \\"0.2.37\\"
js-sys = \\"0.3.14\\"
js_relative_import = { path = \\"../../common/js_relative_import\\" }
[target.'cfg(target_arch = \\"wasm32\\")'.dependencies.web-sys]
version = \\"0.3.14\\"
features = [
\\"AudioBuffer\\",
\\"AudioBufferSourceNode\\",
\\"AudioContext\\",
\\"AudioDestinationNode\\",
\\"AudioNode\\",
]
[dependencies.dep1] [dependencies.dep1]
version = \\"0.4.2\\" version = \\"0.4.2\\"
@ -80,7 +120,7 @@ libpnet = [\\"pnet\\"]
# features = [\\"ws2def\\", \\"ws2ipdef\\"]" # features = [\\"ws2def\\", \\"ws2ipdef\\"]"
`; `;
exports[`lib/manager/cargo/update updateDependency() updates standard table dependency 1`] = ` exports[`lib/manager/cargo/update updateDependency() updates normal dependency with mismatch on first try 1`] = `
"[package] "[package]
name = \\"rustcap\\" name = \\"rustcap\\"
version = \\"0.1.2\\" version = \\"0.1.2\\"
@ -101,13 +141,93 @@ libc = \\"=0.2.43\\"
bitflags = \\"1.0.4\\" bitflags = \\"1.0.4\\"
pcap-sys = { version = \\"=0.1\\", path = \\"pcap-sys\\" } pcap-sys = { version = \\"=0.1\\", path = \\"pcap-sys\\" }
pnet = { version = \\"0.21.0\\", optional = true, default-features = false} pnet = { version = \\"0.21.0\\", optional = true, default-features = false}
git_dep_with_version = { version = \\"0.1.0\\", git = \\"https://github.com/foo/bar\\" }
git_dep = { git = \\"https://github.com/foo/bar\\" }
same_version_1__ = \\"0.0.0\\"
same_version_1_ = \\"0.0.0\\"
same_version_1 = \\"1.2.3\\"
[target.'cfg(windows)'.dependencies.winapi] [target.'cfg(windows)'.dependencies.winapi]
version = \\"=0.3.6\\" version = \\"=0.3.6\\"
features = [\\"ws2def\\", \\"ws2ipdef\\"] features = [\\"ws2def\\", \\"ws2ipdef\\"]
[target.'cfg(target_arch = \\"wasm32\\")'.dependencies]
wasm-bindgen = \\"0.2.37\\"
js-sys = \\"0.3.14\\"
js_relative_import = { path = \\"../../common/js_relative_import\\" }
[target.'cfg(target_arch = \\"wasm32\\")'.dependencies.web-sys]
version = \\"0.3.14\\"
features = [
\\"AudioBuffer\\",
\\"AudioBufferSourceNode\\",
\\"AudioContext\\",
\\"AudioDestinationNode\\",
\\"AudioNode\\",
]
[dependencies.dep1] [dependencies.dep1]
version = \\"0.4.0\\" version = \\"0.4.2\\"
[features]
libpnet = [\\"pnet\\"]
[dev-dependencies]
# libc = \\"0.1.1\\"
# pnet = { version = \\"0.19.0\\", optional = true, default-features = false}
# [target.'cfg(windows)'.dependencies.winapi]
# version = \\"0.3.0\\"
# features = [\\"ws2def\\", \\"ws2ipdef\\"]"
`;
exports[`lib/manager/cargo/update updateDependency() updates platform specific dependency 1`] = `
"[package]
name = \\"rustcap\\"
version = \\"0.1.2\\"
description = \\"Wrapper for libpcap\\"
homepage = \\"https://github.com/jmmk/rustcap\\"
repository = \\"https://github.com/jmmk/rustcap\\"
authors = [\\"Michael McLellan <jmikem825@gmail.com>\\"]
keywords = [\\"pcap\\", \\"libpcap\\"]
license = \\"MIT\\"
readme = \\"README.md\\"
documentation = \\"https://docs.rs/rustcap\\"
[workspace]
members = [\\"pcap-sys\\"]
[dependencies]
libc = \\"=0.2.43\\"
bitflags = \\"1.0.4\\"
pcap-sys = { version = \\"=0.1\\", path = \\"pcap-sys\\" }
pnet = { version = \\"0.21.0\\", optional = true, default-features = false}
git_dep_with_version = { version = \\"0.1.0\\", git = \\"https://github.com/foo/bar\\" }
git_dep = { git = \\"https://github.com/foo/bar\\" }
same_version_1__ = \\"0.0.0\\"
same_version_1_ = \\"0.0.0\\"
same_version_1 = \\"0.0.0\\"
[target.'cfg(windows)'.dependencies.winapi]
version = \\"0.4.0\\"
features = [\\"ws2def\\", \\"ws2ipdef\\"]
[target.'cfg(target_arch = \\"wasm32\\")'.dependencies]
wasm-bindgen = \\"0.2.37\\"
js-sys = \\"0.3.14\\"
js_relative_import = { path = \\"../../common/js_relative_import\\" }
[target.'cfg(target_arch = \\"wasm32\\")'.dependencies.web-sys]
version = \\"0.3.14\\"
features = [
\\"AudioBuffer\\",
\\"AudioBufferSourceNode\\",
\\"AudioContext\\",
\\"AudioDestinationNode\\",
\\"AudioNode\\",
]
[dependencies.dep1]
version = \\"0.4.2\\"
[features] [features]
libpnet = [\\"pnet\\"] libpnet = [\\"pnet\\"]

View file

@ -18,11 +18,31 @@ libc = "=0.2.43"
bitflags = "1.0.4" bitflags = "1.0.4"
pcap-sys = { version = "=0.1", path = "pcap-sys" } pcap-sys = { version = "=0.1", path = "pcap-sys" }
pnet = { version = "0.21.0", optional = true, default-features = false} pnet = { version = "0.21.0", optional = true, default-features = false}
git_dep_with_version = { version = "0.1.0", git = "https://github.com/foo/bar" }
git_dep = { git = "https://github.com/foo/bar" }
same_version_1__ = "0.0.0"
same_version_1_ = "0.0.0"
same_version_1 = "0.0.0"
[target.'cfg(windows)'.dependencies.winapi] [target.'cfg(windows)'.dependencies.winapi]
version = "=0.3.6" version = "=0.3.6"
features = ["ws2def", "ws2ipdef"] features = ["ws2def", "ws2ipdef"]
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2.37"
js-sys = "0.3.14"
js_relative_import = { path = "../../common/js_relative_import" }
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
version = "0.3.14"
features = [
"AudioBuffer",
"AudioBufferSourceNode",
"AudioContext",
"AudioDestinationNode",
"AudioNode",
]
[dependencies.dep1] [dependencies.dep1]
version = "0.4.2" version = "0.4.2"

View file

@ -0,0 +1,19 @@
[package]
name = "platform-specific-dep-example"
version = "0.1.2"
# --- Web dependencies
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2.37"
js-sys = "0.3.14"
js_relative_import = { path = "../../common/js_relative_import" }
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
version = "0.3.14"
features = [
"AudioBuffer",
"AudioBufferSourceNode",
"AudioContext",
"AudioDestinationNode",
"AudioNode",
]

View file

@ -2,19 +2,23 @@ const fs = require('fs');
const { extractPackageFile } = require('../../../lib/manager/cargo/extract'); const { extractPackageFile } = require('../../../lib/manager/cargo/extract');
const cargo1toml = fs.readFileSync( const cargo1toml = fs.readFileSync(
'test/datasource/cargo/_fixtures/Cargo.1.toml', 'test/manager/cargo/_fixtures/Cargo.1.toml',
'utf8' 'utf8'
); );
const cargo2toml = fs.readFileSync( const cargo2toml = fs.readFileSync(
'test/datasource/cargo/_fixtures/Cargo.2.toml', 'test/manager/cargo/_fixtures/Cargo.2.toml',
'utf8' 'utf8'
); );
const cargo3toml = fs.readFileSync( const cargo3toml = fs.readFileSync(
'test/datasource/cargo/_fixtures/Cargo.3.toml', 'test/manager/cargo/_fixtures/Cargo.3.toml',
'utf8' 'utf8'
); );
const cargo4toml = fs.readFileSync( const cargo4toml = fs.readFileSync(
'test/datasource/cargo/_fixtures/Cargo.4.toml', 'test/manager/cargo/_fixtures/Cargo.4.toml',
'utf8'
);
const cargo5toml = fs.readFileSync(
'test/manager/cargo/_fixtures/Cargo.5.toml',
'utf8' 'utf8'
); );
@ -24,13 +28,25 @@ describe('lib/manager/cargo/extract', () => {
beforeEach(() => { beforeEach(() => {
config = {}; config = {};
}); });
it('returns null for invalid toml', () => {
expect(extractPackageFile('invalid toml', config)).toBeNull();
});
it('returns null for empty', () => { it('returns null for empty', () => {
expect(extractPackageFile('nothing here', config)).toBeNull(); const cargotoml = '[dependencies]\n';
expect(extractPackageFile(cargotoml, config)).toBeNull();
});
it('returns null for empty', () => {
const cargotoml = '[dev-dependencies]\n';
expect(extractPackageFile(cargotoml, config)).toBeNull();
});
it('returns null for empty', () => {
const cargotoml = '[target."foo".dependencies]\n';
expect(extractPackageFile(cargotoml, config)).toBeNull();
}); });
it('extracts multiple dependencies', () => { it('extracts multiple dependencies', () => {
const res = extractPackageFile(cargo1toml, config); const res = extractPackageFile(cargo1toml, config);
expect(res.deps).toMatchSnapshot(); expect(res.deps).toMatchSnapshot();
expect(res.deps).toHaveLength(6); expect(res.deps).toHaveLength(15);
}); });
it('extracts multiple dependencies', () => { it('extracts multiple dependencies', () => {
const res = extractPackageFile(cargo2toml, config); const res = extractPackageFile(cargo2toml, config);
@ -40,12 +56,17 @@ describe('lib/manager/cargo/extract', () => {
it('handles inline tables', () => { it('handles inline tables', () => {
const res = extractPackageFile(cargo3toml, config); const res = extractPackageFile(cargo3toml, config);
expect(res.deps).toMatchSnapshot(); expect(res.deps).toMatchSnapshot();
expect(res.deps).toHaveLength(7); expect(res.deps).toHaveLength(8);
}); });
it('handles standard tables', () => { it('handles standard tables', () => {
const res = extractPackageFile(cargo4toml, config); const res = extractPackageFile(cargo4toml, config);
expect(res.deps).toMatchSnapshot(); expect(res.deps).toMatchSnapshot();
expect(res.deps).toHaveLength(5); expect(res.deps).toHaveLength(6);
});
it('extracts platform specific dependencies', () => {
const res = extractPackageFile(cargo5toml, config);
expect(res.deps).toMatchSnapshot();
expect(res.deps).toHaveLength(4);
}); });
}); });
}); });

View file

@ -2,11 +2,15 @@ const fs = require('fs');
const { updateDependency } = require('../../../lib/manager/cargo/update'); const { updateDependency } = require('../../../lib/manager/cargo/update');
const cargo1toml = fs.readFileSync( const cargo1toml = fs.readFileSync(
'test/datasource/cargo/_fixtures/Cargo.1.toml', 'test/manager/cargo/_fixtures/Cargo.1.toml',
'utf8' 'utf8'
); );
const cargo4toml = fs.readFileSync( const cargo4toml = fs.readFileSync(
'test/datasource/cargo/_fixtures/Cargo.4.toml', 'test/manager/cargo/_fixtures/Cargo.4.toml',
'utf8'
);
const cargo5toml = fs.readFileSync(
'test/manager/cargo/_fixtures/Cargo.5.toml',
'utf8' 'utf8'
); );
@ -16,43 +20,113 @@ describe('lib/manager/cargo/update', () => {
beforeEach(() => { beforeEach(() => {
config = {}; config = {};
}); });
it('returns same', () => { it('returns same for invalid toml', () => {
expect(updateDependency('abc', config)).toEqual('abc'); const cargotoml = 'invalid toml !#$#';
expect(updateDependency(cargotoml, config)).toEqual(cargotoml);
});
it('returns same for null upgrade', () => {
const cargotoml = '[dependencies]\n';
expect(updateDependency(cargotoml, null)).toEqual(cargotoml);
});
it('returns same if version has not changed', () => {
const cargotoml = '[dependencies]\n';
expect(updateDependency(cargotoml, null)).toEqual(cargotoml);
const upgrade = {
depName: 'libc',
depType: 'dependencies',
nestedVersion: false,
newValue: '=0.2.43',
};
expect(updateDependency(cargo1toml, upgrade)).not.toBeNull();
expect(updateDependency(cargo1toml, upgrade)).toBe(cargo1toml);
});
it('returns same for invalid target', () => {
const cargotoml = '[dependencies]\n';
expect(updateDependency(cargotoml, null)).toEqual(cargotoml);
const upgrade = {
depName: 'platform-specific-dep',
depType: 'dependencies',
nestedVersion: false,
target: 'foobar',
newValue: '1.2.3',
};
expect(updateDependency(cargo1toml, upgrade)).not.toBeNull();
expect(updateDependency(cargo1toml, upgrade)).toBe(cargo1toml);
});
it('returns same for invalid depType', () => {
const cargotoml = '[dependencies]\n';
expect(updateDependency(cargotoml, null)).toEqual(cargotoml);
const upgrade = {
depName: 'libc',
depType: 'foobar',
nestedVersion: false,
newValue: '1.2.3',
};
expect(updateDependency(cargo1toml, upgrade)).not.toBeNull();
expect(updateDependency(cargo1toml, upgrade)).toBe(cargo1toml);
});
it('returns same for invalid depName', () => {
const cargotoml = '[dependencies]\n';
expect(updateDependency(cargotoml, null)).toEqual(cargotoml);
const upgrade = {
depName: 'does not exist',
depType: 'dependencies',
nestedVersion: false,
newValue: '1.2.3',
};
expect(updateDependency(cargo1toml, upgrade)).not.toBeNull();
expect(updateDependency(cargo1toml, upgrade)).toBe(cargo1toml);
}); });
it('updates normal dependency', () => { it('updates normal dependency', () => {
const upgrade = { const upgrade = {
depName: 'libc', depName: 'libc',
lineNumber: 16, depType: 'dependencies',
depType: 'normal', nestedVersion: false,
newValue: '0.3.0', newValue: '0.3.0',
}; };
expect(updateDependency(cargo1toml, upgrade)).not.toBeNull();
expect(updateDependency(cargo1toml, upgrade)).not.toBe(cargo1toml);
expect(updateDependency(cargo1toml, upgrade)).toMatchSnapshot(); expect(updateDependency(cargo1toml, upgrade)).toMatchSnapshot();
}); });
it('updates inline table dependency', () => { it('updates normal dependency with mismatch on first try', () => {
const upgrade = {
depName: 'same_version_1',
depType: 'dependencies',
nestedVersion: false,
newValue: '1.2.3',
};
expect(updateDependency(cargo1toml, upgrade)).not.toBeNull();
expect(updateDependency(cargo1toml, upgrade)).not.toBe(cargo1toml);
expect(updateDependency(cargo1toml, upgrade)).toMatchSnapshot();
});
it('updates nested version dependency', () => {
const upgrade = { const upgrade = {
depName: 'pcap-sys', depName: 'pcap-sys',
lineNumber: 18, depType: 'dependencies',
depType: 'inlineTable', nestedVersion: true,
newValue: '0.2.0', newValue: '0.2.0',
}; };
expect(updateDependency(cargo1toml, upgrade)).not.toBeNull();
expect(updateDependency(cargo1toml, upgrade)).not.toBe(cargo1toml);
expect(updateDependency(cargo1toml, upgrade)).toMatchSnapshot(); expect(updateDependency(cargo1toml, upgrade)).toMatchSnapshot();
}); });
it('updates standard table dependency', () => { it('updates platform specific dependency', () => {
const upgrade = { const upgrade = {
depName: 'winapi', depName: 'winapi',
lineNumber: 21, target: 'cfg(windows)',
versionLineNumber: 22, depType: 'dependencies',
depType: 'standardTable', nestedVersion: true,
newValue: '0.4.0', newValue: '0.4.0',
}; };
expect(updateDependency(cargo1toml, upgrade)).not.toBeNull();
expect(updateDependency(cargo1toml, upgrade)).not.toBe(cargo1toml);
expect(updateDependency(cargo1toml, upgrade)).toMatchSnapshot(); expect(updateDependency(cargo1toml, upgrade)).toMatchSnapshot();
}); });
it('handles invalid standard tables gracefully', () => { it('handles invalid standard tables gracefully', () => {
const upgrade = { const upgrade = {
depName: 'dep5', depName: 'dep5',
lineNumber: 28, nestedVersion: true,
versionLineNumber: 29, depType: 'dependencies',
depType: 'standardTable',
newValue: '2.0.0', newValue: '2.0.0',
}; };
expect(updateDependency(cargo4toml, upgrade)).toEqual(cargo4toml); expect(updateDependency(cargo4toml, upgrade)).toEqual(cargo4toml);
@ -60,21 +134,51 @@ describe('lib/manager/cargo/update', () => {
it('does not update in case of error', () => { it('does not update in case of error', () => {
const upgrade = { const upgrade = {
depName: 'libc', depName: 'libc',
lineNumber: 13, // Wrong lineNumber devType: 'dev-dependencies', // Wrong devType
depType: 'normal', nestedVersion: false,
newValue: '0.3.0', newValue: '0.3.0',
}; };
expect(updateDependency(cargo1toml, upgrade)).toEqual(cargo1toml); expect(updateDependency(cargo1toml, upgrade)).toEqual(cargo1toml);
}); });
it('does not update commented out standard table dependencies', () => { it('does not update in case of error', () => {
const upgrade = { const upgrade = {
depName: 'dep6', depName: 'libc',
lineNumber: 33, devType: 'dependencies',
versionLineNumber: 34, nestedVersion: true, // Should be false
depType: 'standardTable', newValue: '0.3.0',
newValue: '4.0.0',
}; };
expect(updateDependency(cargo4toml, upgrade)).toEqual(cargo4toml); expect(updateDependency(cargo1toml, upgrade)).toEqual(cargo1toml);
});
it('does not update in case of error', () => {
const upgrade = {
depName: 'pcap-sys',
devType: 'dependencies',
nestedVersion: false, // Should be true
newValue: '0.3.0',
};
expect(updateDependency(cargo1toml, upgrade)).toEqual(cargo1toml);
});
it('updates platform specific normal dependency', () => {
const upgrade = {
depName: 'wasm-bindgen',
depType: 'dependencies',
nestedVersion: false,
target: 'cfg(target_arch = "wasm32")',
newValue: '0.3.0',
};
expect(updateDependency(cargo5toml, upgrade)).not.toBeNull();
expect(updateDependency(cargo5toml, upgrade)).not.toBe(cargo5toml);
});
it('updates platform specific table dependency', () => {
const upgrade = {
depName: 'web-sys',
nestedVersion: true,
depType: 'dependencies',
target: 'cfg(target_arch = "wasm32")',
newValue: '0.4.0',
};
expect(updateDependency(cargo5toml, upgrade)).not.toBeNull();
expect(updateDependency(cargo5toml, upgrade)).not.toBe(cargo5toml);
}); });
}); });
}); });