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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] master from snyk:master #40

Merged
merged 6 commits into from
Sep 22, 2021
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
31 changes: 16 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"dependencies": {
"@open-policy-agent/opa-wasm": "^1.2.0",
"@snyk/cli-interface": "2.11.0",
"@snyk/cloud-config-parser": "^1.10.2",
"@snyk/cloud-config-parser": "^1.11.1",
"@snyk/code-client": "^4.2.3",
"@snyk/dep-graph": "^1.27.1",
"@snyk/fix": "file:packages/snyk-fix",
Expand Down Expand Up @@ -137,8 +137,7 @@
"tar": "^6.1.2",
"tempy": "^1.0.1",
"uuid": "^8.3.2",
"wrap-ansi": "^5.1.0",
"yaml": "^1.10.2"
"wrap-ansi": "^5.1.0"
},
"devDependencies": {
"@types/cross-spawn": "^6.0.2",
Expand Down
2 changes: 2 additions & 0 deletions packages/snyk-fix/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export async function fix(
meta: FixedMeta;
fixSummary: string;
}> {
debug('Running snyk fix with options:', options);

const spinner = ora({ isSilent: options.quiet, stream: process.stdout });

let resultsByPlugin: FixHandlerResultByPlugin = {};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as pathLib from 'path';
import * as pipenvPipfileFix from '@snyk/fix-pipenv-pipfile';
import * as debugLib from 'debug';

import {
EntityToFix,
Expand All @@ -15,6 +16,8 @@ import {
import { CommandFailedError } from '../../../../../lib/errors/command-failed-to-run-error';
import { NoFixesCouldBeAppliedError } from '../../../../../lib/errors/no-fixes-applied';

const debug = debugLib('snyk-fix:python:pipenvAdd');

export async function pipenvAdd(
entity: EntityToFix,
options: FixOptions,
Expand All @@ -27,12 +30,18 @@ export async function pipenvAdd(
const targetFilePath = pathLib.resolve(entity.workspace.path, targetFile);
const { dir } = pathLib.parse(targetFilePath);
if (!options.dryRun && upgrades.length) {
const res = await pipenvPipfileFix.pipenvInstall(dir, upgrades, {
const {
stderr,
stdout,
command,
exitCode,
} = await pipenvPipfileFix.pipenvInstall(dir, upgrades, {
python: entity.options.command,
});
if (res.exitCode !== 0) {
pipenvCommand = res.command;
throwPipenvError(res.stderr ? res.stderr : res.stdout, res.command);
debug('`pipenv add` returned:', { stderr, stdout, command });
if (exitCode !== 0) {
pipenvCommand = command;
throwPipenvError(stderr, stdout, command);
}
}
changes.push(...generateSuccessfulChanges(upgrades, remediation.pin));
Expand All @@ -44,8 +53,7 @@ export async function pipenvAdd(
return changes;
}

function throwPipenvError(stderr: string, command?: string) {
const errorStr = stderr.toLowerCase();
function throwPipenvError(stderr: string, stdout: string, command?: string) {
const incompatibleDeps =
'There are incompatible versions in the resolved dependencies';
const lockingFailed = 'Locking failed';
Expand All @@ -54,13 +62,17 @@ function throwPipenvError(stderr: string, command?: string) {
const errorsToBubbleUp = [incompatibleDeps, lockingFailed, versionNotFound];

for (const error of errorsToBubbleUp) {
if (errorStr.includes(error.toLowerCase())) {
if (
stderr.toLowerCase().includes(error.toLowerCase()) ||
stdout.toLowerCase().includes(error.toLowerCase())
) {
throw new CommandFailedError(error, command);
}
}

const SOLVER_PROBLEM = /SolverProblemError(.* version solving failed)/gms;
const solverProblemError = SOLVER_PROBLEM.exec(stderr);
const solverProblemError =
SOLVER_PROBLEM.exec(stderr) || SOLVER_PROBLEM.exec(stdout);
if (solverProblemError) {
throw new CommandFailedError(solverProblemError[0].trim(), command);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as pathLib from 'path';
import * as debugLib from 'debug';

import * as poetryFix from '@snyk/fix-poetry';

Expand All @@ -14,6 +15,7 @@ import {
} from '../../attempted-changes-summary';
import { CommandFailedError } from '../../../../../lib/errors/command-failed-to-run-error';
import { NoFixesCouldBeAppliedError } from '../../../../../lib/errors/no-fixes-applied';
const debug = debugLib('snyk-fix:python:poetryAdd');

export async function poetryAdd(
entity: EntityToFix,
Expand All @@ -28,13 +30,19 @@ export async function poetryAdd(
const targetFilePath = pathLib.resolve(entity.workspace.path, targetFile);
const { dir } = pathLib.parse(targetFilePath);
if (!options.dryRun && upgrades.length) {
const res = await poetryFix.poetryAdd(dir, upgrades, {
dev,
python: entity.options.command ?? undefined,
});
if (res.exitCode !== 0) {
poetryCommand = res.command;
throwPoetryError(res.stderr ? res.stderr : res.stdout, res.command);
const { stderr, stdout, command, exitCode } = await poetryFix.poetryAdd(
dir,
upgrades,
{
dev,
python: entity.options.command ?? undefined,
},
);
debug('`poetry add` returned:', { stderr, stdout, command });

if (exitCode !== 0) {
poetryCommand = command;
throwPoetryError(stderr, stdout, command);
}
}
changes.push(...generateSuccessfulChanges(upgrades, remediation.pin));
Expand All @@ -46,27 +54,32 @@ export async function poetryAdd(
return changes;
}

function throwPoetryError(stderr: string, command?: string) {
function throwPoetryError(stderr: string, stdout: string, command?: string) {
const ALREADY_UP_TO_DATE = 'No dependencies to install or update';
const INCOMPATIBLE_PYTHON = new RegExp(
/Python requirement (.*) is not compatible/g,
'gm',
);
const SOLVER_PROBLEM = /SolverProblemError(.* version solving failed)/gms;

const incompatiblePythonError = INCOMPATIBLE_PYTHON.exec(stderr);
const incompatiblePythonError =
INCOMPATIBLE_PYTHON.exec(stderr) || SOLVER_PROBLEM.exec(stdout);
if (incompatiblePythonError) {
throw new CommandFailedError(
`The current project's Python requirement ${incompatiblePythonError[1]} is not compatible with some of the required packages`,
command,
);
}
const solverProblemError = SOLVER_PROBLEM.exec(stderr);
const solverProblemError =
SOLVER_PROBLEM.exec(stderr) || SOLVER_PROBLEM.exec(stdout);
if (solverProblemError) {
throw new CommandFailedError(solverProblemError[0].trim(), command);
}

if (stderr.includes(ALREADY_UP_TO_DATE)) {
if (
stderr.includes(ALREADY_UP_TO_DATE) ||
stdout.includes(ALREADY_UP_TO_DATE)
) {
throw new CommandFailedError(
'No dependencies could be updated as they seem to be at the correct versions. Make sure installed dependencies in the environment match those in the lockfile by running `poetry update`',
command,
Expand Down
Loading