-
Notifications
You must be signed in to change notification settings - Fork 572
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: add git metadata to monitor payload #462
Conversation
src/lib/project-metadata/git.ts
Outdated
}; | ||
} | ||
|
||
function findGitRoot(): 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.
please consider git rev-parse --show-toplevel
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.
👍
src/lib/monitor.ts
Outdated
analytics.add('packageManager', packageManager); | ||
|
||
const gitTarget = await projectMetadata.getInfo('git', root, targetFile) as GitInfo; |
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.
Can this targetfile ever be different to the https://github.com/snyk/snyk/pull/462/files#diff-e2e0f6cf5732ba336dc3ba0de17258faR88?
Will it matter? Not all plugins send targetFile and some choose what is best to process in the end
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.
@lili2311 the difference here would be that this is the relative path to the target file (relative to the git project root) and we pass it to monitor later in the chain. i think it would make more sense to present the file in this way in snyk.io. wdyt? basically meaning that if u have a monorepo for example we will save the target file as the relative path from the top level dir to the file even if ur running it inside of a sub dir
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.
What happens when a user runs a snyk test with a file ../../somefile
? After checking analytics this happens today!
54d5719
to
803a28f
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.
See inline, plus one general comment:
whatever we do here needs to be very easy to work into test
and protect
as well, as this data will be used very soon as part of the "locate the relevant project" code server-side
src/lib/project-metadata/types.ts
Outdated
@@ -0,0 +1,7 @@ | |||
export interface GitInfo { |
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.
It think this should be a GitTarget
, and should not include commitSha
or targetFile
, as those aren't part of the identify where the canonical place the source code lives.
src/lib/project-metadata/types.ts
Outdated
@@ -0,0 +1,7 @@ | |||
export interface GitInfo { | |||
repo: string; | |||
owner: 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.
owner
is a GitHub specific thing, git
itself does not have this concept.
src/lib/project-metadata/types.ts
Outdated
@@ -0,0 +1,7 @@ | |||
export interface GitInfo { | |||
repo: 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.
perhaps remoteUrl
would be better?
also, we need to normalise this, e.g. always using the ssh url, so maybe "remoteSSHUrl` or similar (depending on how we choose to normalise it)
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.
if we do a remote url (which was origin URL in michael's original PR) it means that we're leaving the parsing part to registry to build the target... or we can just use the URL somehow to represent the project at registry?
src/lib/project-metadata/index.ts
Outdated
import * as gitMetadata from './git'; | ||
import { GitInfo } from './types'; | ||
|
||
export async function getInfo(metadataSource: string, root: string, targetFile: string): Promise<GitInfo|null> { |
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 think this needs to return just the
target
, and potentially some monitor meta (although that happens elsewhere already, right?) -
Its weird that this component has to be told what the metadataSource is, surely this needs to happen before we get to the command and work out based on the CLI args, the env, the process.pwd(), etc. what the
metadataSource
andtarget
are? -
Related to 2, how would we work command-line based overrides into this structure? E.g. a git remote-url specified on the command line would still need to be normalised, which is going to end up in a completely different place to this? If the broad boundary is "CLI-args, env, process.pwd() as input -> target as output" then command line overrides would be possible too
-
We also need to decide how we cope with situations where the "root" directory here changes based on us being able to inspect the git repo metadata, right? That change (and any resulting impact on any
--file
or similar argument) needs to be propagated to the plugin somehow
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.
- yes the monitor is responsible for adding the monitor data, I wanted this factory to return only target related data
2 and 3. so would it make sense to do something like... does a git command work then it's git if not try to see if we have a docker argument etc? - if the root dir changes that's fine no since we're just using it to get the relative path to the target file?
src/lib/monitor.ts
Outdated
analytics.add('packageManager', packageManager); | ||
|
||
const gitTarget = await projectMetadata.getInfo('git', root, targetFile) as GitInfo; |
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.
see other comment, but commenting here too: how does this know already that this is git
?
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.
Interesting to put this after the plugins have done their thing, seems a better direction.
Another question: should we make sure that the targetFile
we're passing up is relative to the root directory of the git repo, if there is one?
(@lili2311 your thoughts on this seem relevant too given your familiarity with the CLI and targetFiles, etc.?).
src/lib/monitor.ts
Outdated
@@ -74,6 +81,7 @@ export function monitor(root, meta, info: SingleDepRootResult): Promise<any> { | |||
dockerImageId: pluginMeta.dockerImageId, | |||
dockerBaseImage: pkg.docker ? pkg.docker.baseImage : undefined, | |||
projectName: meta['project-name'], | |||
projectTarget, |
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 think this should be alongside targetFile
, in the top-level body, and called plain old target
(to closely match the agent-side of things)
user: string; | ||
project: string; | ||
branch: 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.
this is still too hosted-git centric. A good test case (direct from https://git-scm.com/) is user@server:path/to/repo.git
-> that should be easy to unambiguously represent in this GitTarget
type
noticed that the hosted-git-info
only supports things cloned from GitHub, GitLab, and Bitbucket so its not really appropriate here. Perhaps https://www.npmjs.com/package/git-url-parse is better? Or something else (I only searched for 2 minutes... 😂)
Maybe an https
representation generated by git-url-parse
is the most appropriate? there no perfect right answer here :'(
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.
regarding your other comment about registry needing to do processing - I don't follow? As long as the targets are both standardised and hold the git upstream repo details then we can both group by targets and support the future desire to match up CLI with hosted source code projects in some way.
what am I missing?
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.
yeah, that's a good point... I think I was overcomplicating things here because my head was too hosted solution oriented...
return null; | ||
} else if ((await subProcess.execute('git', ['remote', 'get-url', 'origin'])).trim()) { | ||
return gitMetadata.getInfo(); | ||
} |
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 crossing into the specific-code territory, but while i'm here:
const TARGET_BUILDER = [gitMetadata, dockerImageMetadata];
// ...
for (const targetBuilder in TARGET_BUILDERS) {
const target = targetBuilder.getInfo(packageInfo);
if (target) {
return target;
}
}
an implementation like that lets you add new target builders (or some other term, not precious about the name) easily.
They return a target, or undefined if they can't, and you get to keep all target-specific knowledge out of this file, its responsibility becomes simply the registration and order-of-preference for each target builder.
The plugin will always return a file that was used in the end to generate the Tree, the plugin has better understanding to do this. However not all plugins return it relevant to the git root of course. I think if we for now send what you propose we can then check the data for discrepancies. For example some users run test via Do we have a test for this? |
@lili2311 this would be translated to the relative path from the root if we chose to send that, the question here is if it's useful to send that as well. We're not in the tests stage yet, I will add tests once all the questions are answered :) |
62dc4d2
to
c7920d3
Compare
import subProcess = require('../../sub-process'); | ||
import { GitTarget } from '../types'; | ||
|
||
/* tslint:disable:no-unused-variable */ |
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.
is this necessary?
branch, | ||
}; | ||
} catch (err) { | ||
return null; |
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.
can we handle it differently? maybe log reason for erroring
ef74bd0
to
368329f
Compare
368329f
to
868a907
Compare
@@ -52,8 +56,12 @@ export function monitor(root, meta, info: SingleDepRootResult): Promise<any> { | |||
return snyk.policy.create(); | |||
} | |||
return snyk.policy.load(policyLocations, opts); | |||
}).then((policy) => { | |||
}).then(async (policy) => { |
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 add async
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 returning a promise not using async await
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.
@jonathan-fielding if you look a few lines below I'm using await there, an async function is a promise behind the scenes so this still holds true and works fine.
What does this PR do?
We are adding git metadata to monitor when sending the payload to snyk.io for grouping CLI projects