snyk-docker-plugin
Version:
Snyk CLI docker plugin
91 lines • 3.72 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.PythonInvalidVersionError = exports.parseDependency = exports.getPackageInfo = void 0;
const semver = require("semver");
const common_1 = require("./common");
const provides_extra_1 = require("./provides-extra");
const PACKAGE_NAME = "Name: ";
const PACKAGE_VERSION = "Version: ";
const PACKAGE_DEPS = "Requires-Dist: ";
const DEP_PARSE_REGEX = /^(?<name>[\w.-]+)((\[(?<extras>.*)\])?)(\s?\(?(?<specifier><|<=|!=|==|>=|>|~=|===)(?<version>[\w.]+)\)?)?/;
function getPackageInfo(fileContent) {
const lines = fileContent.split("\n");
const providesExtras = (0, provides_extra_1.findProvidesExtras)(lines);
let name = "";
let version = "";
const dependencies = [];
for (let line of lines) {
line = line.trim();
if (line.length === 0) {
continue;
}
if (line.startsWith(PACKAGE_NAME)) {
name = line.substring(PACKAGE_NAME.length);
}
else if (line.startsWith(PACKAGE_VERSION)) {
version = line.substring(PACKAGE_VERSION.length);
}
else if (line.startsWith(PACKAGE_DEPS)) {
const pythonPackage = parseDependency(line.substring(PACKAGE_DEPS.length), providesExtras);
if (pythonPackage) {
dependencies.push(pythonPackage);
}
}
}
const validVersion = getParseableVersion(version);
return {
name: name.toLowerCase(),
version: validVersion,
dependencies,
};
}
exports.getPackageInfo = getPackageInfo;
// parse a line containing a dependency package name & extras and (optional) specifier + version
function parseDependency(packageDependency, providesExtras) {
packageDependency = packageDependency.trim();
const parsedDep = DEP_PARSE_REGEX.exec(packageDependency);
if (!(parsedDep === null || parsedDep === void 0 ? void 0 : parsedDep.groups)) {
return null;
}
const { name, extras, version, specifier } = parsedDep.groups;
return {
name: name.toLowerCase(),
version,
specifier: (0, common_1.specifierValidRange)(specifier, version),
extras: (0, common_1.parseExtraNames)(extras),
extraEnvMarkers: parseExtraEnvMarkers(providesExtras, packageDependency),
};
}
exports.parseDependency = parseDependency;
// parse extra environment markers located after the quoted marker
// see https://peps.python.org/pep-0508
function parseExtraEnvMarkers(providesExtras, requiresDist) {
const extraNames = new Set();
// search string after quoted_marker ;
const quotedMarker = requiresDist === null || requiresDist === void 0 ? void 0 : requiresDist.split(";");
if (quotedMarker && quotedMarker.length > 1) {
for (const extra of providesExtras) {
// search for extra env markers for given provides extras
const re = new RegExp(`.*extra.*("|')(?<extra>${extra})("|').*`);
if (re.exec(quotedMarker[1])) {
extraNames.add(extra);
}
}
}
return Array.from(extraNames);
}
function getParseableVersion(versionString) {
const validVersion = semver.coerce(versionString);
if (!validVersion) {
throw new PythonInvalidVersionError(`version ${versionString} is not compatible with semver and cannot be compared`);
}
if (versionString.indexOf(validVersion.version) === 0 &&
/^\d+(\.\d+)+$/.test(versionString)) {
return versionString;
}
return validVersion.version;
}
class PythonInvalidVersionError extends Error {
}
exports.PythonInvalidVersionError = PythonInvalidVersionError;
//# sourceMappingURL=metadata-parser.js.map
;