Skip to content

Commit

Permalink
Merge pull request snyk#2266 from snyk/feat/check-stdout-for-errors
Browse files Browse the repository at this point in the history
feat: test stdout for errors and surface
  • Loading branch information
lili2311 authored Sep 22, 2021
2 parents c8b0215 + c5536fa commit 50c67c8
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 35 deletions.
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

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

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ authors = ["ghe <lili@snyk.io>"]
[tool.poetry.dependencies]
python = "^2.7"
Django = "1.11.0"
Jinja2 = "2.11.3"

[tool.poetry.dev-dependencies]
pytest = "*"
Expand Down

0 comments on commit 50c67c8

Please sign in to comment.