-
Notifications
You must be signed in to change notification settings - Fork 89
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
add dependency treeview #647
add dependency treeview #647
Conversation
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
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.
Overall it's a working, but the implemetation can be refined.
What I think of the workflow is:
- run some maven commands in background to fetch a raw data of dependencies in plaintext format.
- parse plaintext, you get a dependency tree.
- for each tree node, implement
ITreeItem
to tell vscode how to create a corresponding TreeItem for each dependency.
BTW, CI is failing, please also fix it.
src/utils/mavenUtils.ts
Outdated
@@ -83,7 +91,7 @@ async function executeInBackground(mvnArgs: string, pomfile?: string): Promise<a | |||
if (code === 0) { | |||
resolve(code); | |||
} else { | |||
reject(new Error(`Background process terminated with code ${code}.`)); | |||
reject(new Error(`Background process terminated with code ${code} and the failed command can be found in output channel.`)); |
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.
extra information/guidance should be provided outside.
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.
Let's leave it to another PR, which improves overall UX of error handling
src/explorer/model/Dependencies.ts
Outdated
const DUPLICATE_VALUE: string = "omitted for duplicate"; | ||
const CONFLICT_VALUE: string = "omitted for conflict"; | ||
|
||
export class Dependencies implements ITreeItem { |
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.
Use Dependency
or MavenDependency
instead of Dependencies
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 I imagine:
- basic properties of a Dependency should at least include groupId, artifactId, version, scope, which are parsed from plaintext from your implementation.
- in getTreeItem, you contruct an TreeItem using above props.
treeContent = treeContent.replace(/\|/g, " "); | ||
treeContent = treeContent.replace(/\\/g, "+"); | ||
treeContent = treeContent.replace(/\n/g, "\r\n"); | ||
return Promise.resolve(this.getDepsInString(treeContent)); |
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.
getDepsInString => parseDependencies
src/explorer/model/Dependencies.ts
Outdated
public dependency: string; | ||
public pomPath: string; | ||
private curDep: string; | ||
private separator: 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.
what's it for?
src/explorer/model/Dependencies.ts
Outdated
} | ||
|
||
public getTreeItem(): vscode.TreeItem | Thenable<vscode.TreeItem> { | ||
this.curDep = this.dependency.split(this.separator, 1)[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.
- parsing work should be extracted into another utility.
- during parsing with some complicated regular expression, it's better to add comments about i) a sample input and ii) the matched parts.
|
src/utils/mavenUtils.ts
Outdated
const outputDirectory: string = path.dirname(pomPath); | ||
const outputFileName: string = "dependency-graph"; | ||
await executeInBackground(`depgraph:graph -DgraphFormat=text -DshowDuplicates -DshowConflicts -DshowVersions -DshowGroupIds -DoutputDirectory="${outputDirectory}" -DoutputFileName="${outputFileName}"`, pomPath); | ||
return await readFileIfExists(`${outputDirectory}\\${outputFileName}.txt`); |
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.
\\
might not work with Unix-like systems
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.
use path.join
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.
Dependency
itself can be tree-like, I think we don't have to create an extra class TreeNode
.
Does below structure work?
Dependency {
parent: Dependency | undefined
addChild(value: string | Dependency)
// other props
....
}
} | ||
} | ||
|
||
export function parseDependency(parentNode: TreeNode): Dependency[] { |
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.
Don't export it. If you want to reuse this function, place it into utilities.
src/explorer/model/TreeNode.ts
Outdated
this.value = value; | ||
} | ||
|
||
public addChildValue(value: string): void { |
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.
addChild(value: string)
is simpler and carries enough information.
src/explorer/model/TreeNode.ts
Outdated
this.children.push(child); | ||
} | ||
|
||
public addChildNode(node: TreeNode): void { |
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.
addChild(node: TreeNode)
is enough.
See https://www.typescriptlang.org/docs/handbook/2/functions.html#function-overloads for overloads
src/explorer/model/Dependency.ts
Outdated
// Licensed under the MIT license. | ||
|
||
import * as vscode from "vscode"; | ||
import { parseDependency } from "./DependenciesMenu"; |
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 should be independent with DependenciesMenu
return rootNode; | ||
} | ||
|
||
function parseTreeNodes(parentNode: TreeNode, treecontent: string, separator: string, indent: string, starter: string, eol: string): void { |
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.
Instead of passing a parent node and modifying it, parseTreeNodes
should directly parse a raw string and return an array of TreeNode.
const indent: string = " "; // three spaces | ||
const separator: string = "\r\n"; | ||
const starter: string = "+- "; | ||
const rootNode: TreeNode = new TreeNode("Dependencies"); |
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.
The node new TreeNode("Dependencies")
is dummy.
Can you simply return an array of top level dependencies here?
To implement dependency tree requested in #161,
and the dependencies can be expanded and collapsed.
it also includes information about duplicates and conflicts: