-
Notifications
You must be signed in to change notification settings - Fork 7
feat: add footPrint & priorityRule VS CODE extension #201
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
base: main
Are you sure you want to change the base?
Changes from all commits
cd28941
b9cb409
a4abfca
75c4adc
44baf8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // A launch configuration that compiles the extension and then opens it inside a new window | ||
| // Use IntelliSense to learn about possible attributes. | ||
| // Hover to view descriptions of existing attributes. | ||
| // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
| { | ||
| "version": "0.2.0", | ||
| "configurations": [ | ||
| { | ||
| "name": "Run Extension", | ||
| "type": "extensionHost", | ||
| "request": "launch", | ||
| "args": [ | ||
| "--extensionDevelopmentPath=${workspaceFolder}" | ||
| ], | ||
| "outFiles": [ | ||
| "${workspaceFolder}/dist/**/*.js" | ||
| ], | ||
| "preLaunchTask": "${defaultBuildTask}" | ||
| } | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,17 +1,20 @@ | ||
| // See https://go.microsoft.com/fwlink/?LinkId=733558 | ||
| // for the documentation about the tasks.json format | ||
|
Comment on lines
+1
to
+2
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue: We cannot include comments this way in a JSON File A raw option could be to add a "_comments" array property at the root of the json object with these 2 lines as string items (not recommended) A better way would be to
|
||
| { | ||
| "version": "2.0.0", | ||
| "tasks": [ | ||
| { | ||
| "label": "watch", | ||
| "type": "npm", | ||
| "script": "watch", | ||
| "presentation": { | ||
| "reveal": "never" | ||
| }, | ||
| "group": { | ||
| "kind": "build", | ||
| "isDefault": true | ||
| } | ||
| }, | ||
| ] | ||
| "version": "2.0.0", | ||
| "tasks": [ | ||
| { | ||
| "type": "npm", | ||
| "script": "watch", | ||
| "problemMatcher": "$tsc-watch", | ||
| "isBackground": true, | ||
| "presentation": { | ||
| "reveal": "never" | ||
| }, | ||
| "group": { | ||
| "kind": "build", | ||
| "isDefault": true | ||
| } | ||
| } | ||
| ] | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: as suggested by Sonar, group the subscriptions.push() subscriptions.push(
commandRegistration1,
commandRegistration2,
)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion(non-blocking): extension.mjs files should be unit tested Non blocking only because there no vscode unit tests yet |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion(non-blocking): configuration.service.mjs files should be unit tested Non blocking only because there no vscode unit tests yet |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion(non-blocking): score.script.mjs files should be unit tested Non blocking only because there no vscode unit tests yet |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,16 +11,20 @@ import { addMessageHandler } from '../../services/message.service.mjs' | |
| let errorCount = 0; | ||
|
|
||
| const scoreOutput = document.querySelector('.score'); | ||
| const priorityRuleNameElem = document.querySelector('.priority-rule'); | ||
| const footPrintElem = document.querySelector('.footprint'); | ||
| const branchFields = document.forms['branch-selection'].elements; | ||
| const branchesSelect = branchFields['branch']; | ||
|
|
||
| try { | ||
| const oldState = vscode.getState() || { score: '', branch: '' }; | ||
| let { score, branch } = oldState; | ||
| const oldState = vscode.getState() || { score: '', priorityRule: '', footPrint: '', branch: '' }; | ||
| let { score, priorityRule, footPrint, branch } = oldState; | ||
|
|
||
| const messageHandler = addMessageHandler({ | ||
| updateScore: data => updateScore(data.value), | ||
| updateBranches: data => updateBranches(data.value), | ||
| updatePriorityRule: data => updatePriorityRule(data.value), | ||
| updateFootPrint: data => updateFootPrint(data.value), | ||
| clearScore: () => updateScore(''), | ||
| }, logError) | ||
|
|
||
|
|
@@ -32,8 +36,30 @@ import { addMessageHandler } from '../../services/message.service.mjs' | |
| */ | ||
| function updateScore(newScore) { | ||
| score = newScore; | ||
| scoreOutput.textContent = `Score: ${score || 'Cleared'}`; | ||
| vscode.setState({ score, branch }); | ||
| scoreOutput.textContent = `${score || 'Cleared'}`; | ||
| vscode.setState({ score, priorityRule, footPrint, branch }); | ||
| } | ||
|
|
||
| /** | ||
| * @param {any} priorityRuleData | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue: any is not a valid JSDoc type |
||
| */ | ||
| function updatePriorityRule(priorityRuleData) { | ||
| priorityRule = priorityRuleData; | ||
| if (priorityRule) { | ||
| const link = document.createElement('a'); | ||
| link.href = priorityRule.url; | ||
| link.textContent = priorityRule.priorityRule.name; | ||
| priorityRuleNameElem.replaceChildren(link); | ||
| } else { | ||
| priorityRuleNameElem.textContent = 'None'; | ||
| } | ||
| vscode.setState({ score, priorityRule, footPrint, branch }); | ||
| } | ||
|
|
||
| function updateFootPrint(footPrintData) { | ||
| footPrint = footPrintData; | ||
| footPrintElem.textContent = footPrint ? `${footPrint} kgCO2eq` : 'None'; | ||
| vscode.setState({ score, priorityRule, footPrint, branch }); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -53,7 +79,7 @@ import { addMessageHandler } from '../../services/message.service.mjs' | |
| branches.forEach(branchData => { | ||
| const { name, isMain } = branchData; | ||
| const option = new Option(name, name); | ||
| Object.assign(option.dataset, branch); | ||
| Object.assign(option.dataset, branchData); | ||
| options.add(option); | ||
| if ((isMain && !newSelected) || (name === previousSelected)) { | ||
| newSelected = option; | ||
|
|
@@ -63,7 +89,7 @@ import { addMessageHandler } from '../../services/message.service.mjs' | |
| newSelected.selected = true; | ||
| } | ||
| branch = newSelected.dataset.name; | ||
| vscode.setState({ score, branch }); | ||
| vscode.setState({ score, priorityRule, footPrint, branch }); | ||
| vscode.postMessage({ type: 'selectBranch', message: branch }); | ||
| } | ||
|
|
||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion(non-blocking): score.view.mjs files should be unit tested Non blocking only because there no vscode unit tests yet |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,13 @@ | ||
| import vscode from '../../compat/vscode.cjs' | ||
|
|
||
| import { sync } from '../../services/configuration.service.mjs'; | ||
| import { sync, getSonarConfiguration } from '../../services/configuration.service.mjs'; | ||
| import { WebViewService } from '../../services/view.service.mjs'; | ||
| import SonarAPI from '@creedengo/sonar-services' | ||
| import core from '@creedengo/core-services'; | ||
|
|
||
| const { window, Uri } = vscode | ||
| const { getProjectBranches } = SonarAPI | ||
| const { api, calculateProjectScore } = core | ||
| const { api, calculateProjectScore, getPriorityRule, getFootprintEstimation } = core | ||
|
|
||
| api.init(SonarAPI) | ||
|
|
||
|
|
@@ -33,6 +33,8 @@ export class CreedengoScoreViewProvider { | |
| async resolveWebviewView(webviewView) { | ||
| const messageHandlers = { | ||
| updateBranches: () => this.updateScore(), | ||
| updatePriorityRule: () => this.updatePriorityRule(), | ||
| updateFootPrint: () => this.updateFootPrint(), | ||
| updateScore: () => this.updateScore(), | ||
| selectBranch: data => { | ||
| this.#currentBranch = data.message; | ||
|
|
@@ -48,8 +50,63 @@ export class CreedengoScoreViewProvider { | |
| }) | ||
|
|
||
| await this.#updateBranches(); | ||
| await this.updatePriorityRule(); | ||
| await this.updateFootPrint(); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. niptick: be consistent with the code base The
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo: Footprint is a single word |
||
|
|
||
| webviewView.onDidChangeVisibility(async () => { | ||
| if (!webviewView.visible) { | ||
| return; | ||
| } | ||
| await this.#updateBranches(); | ||
| await this.updateScore(); | ||
| await this.updatePriorityRule(); | ||
| await this.updateFootPrint(); | ||
| }) | ||
| } | ||
|
|
||
| async updatePriorityRule() { | ||
| if (!this.#service) { | ||
| return; | ||
| } | ||
| let priorityRule; | ||
| try { | ||
| const { ready, project } = await sync(); | ||
| if (!ready || !project) { | ||
| return false | ||
| } | ||
| const branch = this.#currentBranch | ||
| priorityRule = await getPriorityRule({ project, branch }); | ||
| } catch(error) { | ||
| window.showErrorMessage(error.message) | ||
| } | ||
| const { server } = await getSonarConfiguration(); | ||
| this.#service.show(true); | ||
| const url = `${server}coding_rules?languages=${priorityRule.lang}&q=${priorityRule?.name.split(' ').join('+')}&open=java%3AS2187` | ||
| this.#service.postMessage({ type: 'updatePriorityRule', value: { | ||
| priorityRule: priorityRule, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. niptick: the syntax could be simplified
|
||
| url: url, | ||
| } }); | ||
| } | ||
|
|
||
| async updateFootPrint() { | ||
| if (!this.#service) { | ||
| return; | ||
| } | ||
| let footPrint; | ||
| try { | ||
| const { ready, project } = await sync(); | ||
| if (!ready || !project) { | ||
| return false | ||
| } | ||
| const branch = this.#currentBranch | ||
| footPrint = await getFootprintEstimation({ project, branch }); | ||
| } catch(error) { | ||
| window.showErrorMessage(error.message) | ||
| } | ||
| this.#service.show(true); | ||
| this.#service.postMessage({ type: 'updateFootPrint', value: footPrint }); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue: the value is sent as a number without any formating It should indicate the unit of measurement and the number of digits should be controlled |
||
| } | ||
|
|
||
| /** | ||
| * Request data from the Sonar Server to recalculate the sustainability score | ||
| * @returns | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. praise: thank you for this fix |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,6 +30,17 @@ export async function findIssues({ project, branch }) { | |
| return issues | ||
| } | ||
|
|
||
| export async function getIssueCount({ project, branch }) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue: this function should be unit tested |
||
| const searchParams = { | ||
| ...sustainabilitySearchParams, | ||
| componentKeys: project, | ||
| branch, | ||
| ps: 1, // no issues parsing, we only want the total count | ||
| } | ||
| const page = await sonarRequestAPI.getJSON(routeUrl, searchParams) | ||
| return page.paging.total | ||
| } | ||
|
|
||
| function facetFormater(result, severity) { | ||
| const { val, count } = severity; | ||
| result[val.toLowerCase()] = count; | ||
|
|
@@ -52,7 +63,7 @@ export async function getIssuesFacet(facetName, { project, branch, severity }) { | |
| branch, | ||
| severity, | ||
| facets: facetName, | ||
| ps: 0, // no issues parsing, we only want the facets | ||
| ps: 1, // no issues parsing, we only want the facets | ||
| } | ||
| const { facets } = await sonarRequestAPI.getJSON(routeUrl, searchParams); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,7 +19,7 @@ afterEach(() => server.resetHandlers()) | |
|
|
||
| describe('getRuleDetails', () => { | ||
| test('getRuleDetails retrieve 1 rule', async () => { | ||
| const issues = await getRuleDetails({ project: 'foo', branch: 'master' }) | ||
| const issues = await getRuleDetails('project: foo', 'branch: master') | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue: this function call is wrong, it expect only 1 param The function signature is The force uppercasing part of the rule key, this behavior should be tested |
||
| expect(issues).toStrictEqual(mockRuleDetails.rule) | ||
| }) | ||
| }) | ||
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.
issue: We cannot include comments this way in a JSON File
A raw option could be to add a "_comments" array property at the root of the json object with these 2 lines as string items (not recommended)
A better way would be to
"$schema": "vscode://schemas/launch"