-
Notifications
You must be signed in to change notification settings - Fork 582
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
feat: (experimental) show pinning remediation advice for Python #755
Conversation
@@ -0,0 +1,22 @@ | |||
import request = require('./request'); | |||
import snyk = require('.'); // TODO(kyegupov): fix import |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe time had come ? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no :( that index.js file is absolutely insane.
1963934
to
f9704b0
Compare
@@ -1,5 +1,5 @@ | |||
import * as _ from 'lodash'; | |||
import fs = require('then-fs'); | |||
import * as fs from 'fs'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😍
f9704b0
to
b680181
Compare
let wizardHintText = ''; | ||
if (WIZARD_SUPPORTED_PACKAGE_MANAGERS.includes(packageManager)) { | ||
wizardHintText = 'Run `snyk wizard` to explore remediation options.'; | ||
} | ||
|
||
if (pinningSupported | ||
&& (vuln.nearestFixedInVersion || vuln.fixedIn) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nearestFixedInVersion
is docker specific I believe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extracted the field into a Docker-specific type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean surely we should not be checking it here: if (pinningSupported && vuln.fixedIn)
is all we need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, also done that :)
screenshots please |
}; | ||
} | ||
const results = [chalk.bold.white('Remediation advice')]; | ||
|
||
const upgradeTextArray = constructUpgradesText(remediationInfo.upgrade, basicVulnInfo); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like pinning can be it's own function that generates pinning? constructPinOrUpgradesText
why not have construct pinning advice?
Is pinning not it's own section that is for packages that have no upgrade paths? It doesn't seem right to prefer pinning to upgrading? Is there some stuff to read on this feature somewhere to gain more context and what Python remediation will do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With Python, we don't have full ecosystem information, but we can perform pinning.
Thus, we chose to do pinning insteat of upgrade paths.
So, it's either-or.
.join('\n'); | ||
upgradeTextArray.push(upgradeText + thisUpgradeFixes); | ||
} | ||
return upgradeTextArray; | ||
} | ||
|
||
function constructPinOrUpgradesText( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is huge! Can it not be split up for Pin vs Upgrade, I feel like they are completely different?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was split, common formatting code was extracted.
95e250d
to
fee14ff
Compare
@@ -157,7 +170,7 @@ function createRemediationText(vuln, packageManager) { | |||
const selfUpgradeInfo = (v.upgradePath.length > 0) | |||
? ` (triggers upgrades to ${ v.upgradePath.join(' > ')})` | |||
: ''; | |||
const testedPackageName = v.upgradePath[0].split('@'); | |||
const testedPackageName = parsePackageNameVersion(v.upgradePath[0] as string); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we can have scoped packages. Splitting "@snyk/dep-graph@1.0.0" by "@" is incorrect. The "snyk-module" library, horrible as it is, should deal with that.
if (upgradeTextArray.length > 0) { | ||
results.push(upgradeTextArray.join('\n')); | ||
if (remediationInfo.pin && Object.keys(remediationInfo.pin).length) { | ||
const upgradesByCulprit: UpgradesByCulprit = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
upgradesByCulprit
is there a nicer name for this? What is it trying to name? Is it transitive
vs direct
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, will rename to "byAffectedPackage".
results.push(upgradeTextArray.join('\n')); | ||
if (remediationInfo.pin && Object.keys(remediationInfo.pin).length) { | ||
const upgradesByCulprit: UpgradesByCulprit = {}; | ||
for (const topLvlPkg of Object.keys(remediationInfo.upgrade)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
topLvlPkg
topLevelPackage
is nicer, let's avoid shortening as it is harder to read
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
decided on topLevelPkg. First, saves some characters, second, since package
is a reserved word, shortening to pkg
is a good habit anyway.
} | ||
} | ||
const upgradeTextArray = constructPinText(remediationInfo.pin, upgradesByCulprit, basicVulnInfo); | ||
if (upgradeTextArray.length > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is repeated twice, can just do it once after this whole if?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
1e2befc
to
8f441cf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
3c0ff38
to
faac0f6
Compare
7afa20d
to
6a69d1f
Compare
6a69d1f
to
d66c57c
Compare
🎉 This PR is included in version 1.226.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
What does this PR do?
Shows Python remediation advice in
snyk test
, based on pinning.Pinning means directly specifying the needed version, even for transitive dependencies.
This depends on the Registry changes: https://github.com/snyk/registry/pull/9434
The advice is calculated and shown differently, based on whether the
actionableCliRemediation
flag is set.Screenshots:
With actionableCliRemediation:

Without actionableCliRemediation:
