Skip to content
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

Preview Lcov Report and general fixes #80

Merged
merged 10 commits into from
Jul 15, 2017
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- test backed code changes
- new code matches existing style (enforced via tslint)
- bug fixes always welcome :)
- new feature proposals go through a github issue
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# coverage-gutters
[![Version](https://vsmarketplacebadge.apphb.com/version/ryanluker.vscode-coverage-gutters.svg)](https://marketplace.visualstudio.com/items?itemName=ryanluker.vscode-coverage-gutters)
[![Installs](https://vsmarketplacebadge.apphb.com/installs/ryanluker.vscode-coverage-gutters.svg)](https://marketplace.visualstudio.com/items?itemName=ryanluker.vscode-coverage-gutters)
[![Ratings](https://vsmarketplacebadge.apphb.com/rating/ryanluker.vscode-coverage-gutters.svg)](https://marketplace.visualstudio.com/items?itemName=ryanluker.vscode-coverage-gutters)

[![Build Status](https://travis-ci.org/ryanluker/vscode-coverage-gutters.svg?branch=master)](https://travis-ci.org/ryanluker/vscode-coverage-gutters)
[![Build status](https://ci.appveyor.com/api/projects/status/8vb8t787frcqtrm7?svg=true)](https://ci.appveyor.com/project/ryanluker/vscode-coverage-gutters)

[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/ryanluker/vscode-coverage-gutters.svg)](https://isitmaintained.com/project/ryanluker/vscode-coverage-gutters "Average time to resolve an issue")
[![Percentage of issues still open](https://isitmaintained.com/badge/open/ryanluker/vscode-coverage-gutters.svg)](https://isitmaintained.com/project/ryanluker/vscode-coverage-gutters "Percentage of issues still open")

[![Buy me a coffee](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=XRWWCAZBYB9SG&lc=CA&item_name=vscode%2dcoverage%2dgutters&currency_code=CAD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHostedGuest)

## Features
Expand All @@ -12,12 +20,17 @@

![Coverage Gutters features options](images/coverage-gutters-features-2.PNG)

- preview overall coverage inside vscode

![Coverage Gutters preview overall coverage](images/preview-lcov-1.PNG)

- multi lcov info support via option picker
- relative lcov file resolution option for those with complex file paths
- workspace settings to customize the features to your liking
- colour compatibility with light and dark themes

## Requirements
- vscode 1.11.x and up
- vscode 1.14.x and up
- macos, linux or windows

## Extension Settings
Expand All @@ -42,10 +55,12 @@
|`coverage-gutters.showRulerCoverage`|Show or hide the ruler coverage
|`coverage-gutters.showGutterCoverage`|Show or hide the gutter coverage
|`coverage-gutters.customizable.status-bar-toggler-watchLcovAndVisibleEditors-enabled`|Setting this to false will remove the status bar item
|`coverage-gutters.customizable.menus-editor-context-previewLcovReport-enabled`|Setting this to false will remove the command from the editor context menu and vice versa
|`coverage-gutters.customizable.menus-editor-context-displayCoverage-enabled`|Setting this to false will remove the command from the editor context menu and vice versa
|`coverage-gutters.customizable.menus-editor-context-watchLcovFile-enabled`|Setting this to false will remove the command from the editor context menu and vice versa
|`coverage-gutters.customizable.menus-editor-context-watchVisibleEditors-enabled`|Setting this to false will remove the command from the editor context menu and vice versa
|`coverage-gutters.customizable.menus-editor-context-removeCoverage-enabled`|Setting this to false will remove the command from the editor context menu and vice versa
|`coverage-gutters.customizable.keybindings-previewLcovReport-enabled`|Setting this to false will remove the shortcut and vice versa
|`coverage-gutters.customizable.keybindings-displayCoverage-enabled`|Setting this to false will remove the shortcut and vice versa
|`coverage-gutters.customizable.keybindings-watchLcovFile-enabled`|Setting this to false will remove the shortcut and vice versa
|`coverage-gutters.customizable.keybindings-watchVisibleEditors-enabled`|Setting this to false will remove the shortcut and vice versa
Expand All @@ -66,10 +81,7 @@ Some examples for the highlight colour are as follows:
### [Changelog](https://github.com/ryanluker/vscode-coverage-gutters/releases)

## Contribution Guidelines
- test backed code changes
- new code matches existing style (enforced via tslint)
- bug fixes always welcome :)
- new feature proposals go through a github issue
### [Guidelines](/CONTRIBUTING.md)

-----------------------------------------------------------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "",
"main": "test-coverage.js",
"scripts": {
"test": "istanbul cover -x \"./test-coverage.js\" --report lcovonly ./node_modules/mocha/bin/_mocha -- -R spec test.js"
"test": "istanbul cover -x \"./test-coverage.js\" ./node_modules/mocha/bin/_mocha -- -R spec test.js"
},
"author": "",
"license": "ISC",
Expand Down
Binary file added images/preview-lcov-1.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 31 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "vscode-coverage-gutters",
"displayName": "Coverage Gutters",
"description": "Display test coverage generated by lcov - works with many languages",
"version": "1.0.0",
"version": "1.1.0",
"license": "MIT",
"repository": {
"type": "git",
Expand Down Expand Up @@ -123,6 +123,11 @@
"default": true,
"description": "enable or disable the status bar item"
},
"coverage-gutters.customizable.menus-editor-context-previewLcovReport-enabled": {
"type": "boolean",
"default": true,
"description": "enable or disable the previewLcovReport command in the editor/context menu"
},
"coverage-gutters.customizable.menus-editor-context-displayCoverage-enabled": {
"type": "boolean",
"default": true,
Expand All @@ -143,6 +148,11 @@
"default": true,
"description": "enable or disable the removeCoverage command in the editor/context menu"
},
"coverage-gutters.customizable.keybindings-previewLcovReport-enabled": {
"type": "boolean",
"default": true,
"description": "enable or disable the keybinding shortcut for previewing the lcov report"
},
"coverage-gutters.customizable.keybindings-displayCoverage-enabled": {
"type": "boolean",
"default": true,
Expand All @@ -166,6 +176,10 @@
}
},
"commands": [
{
"command": "extension.previewLcovReport",
"title": "Coverage Gutters: Preview Lcov Report"
},
{
"command": "extension.displayCoverage",
"title": "Coverage Gutters: Display File Coverage"
Expand All @@ -184,6 +198,12 @@
}
],
"keybindings": [
{
"command": "extension.previewLcovReport",
"key": "ctrl+shift+6",
"mac": "shift+cmd+6",
"when": "config.coverage-gutters.customizable.keybindings-previewLcovReport-enabled"
},
{
"command": "extension.displayCoverage",
"key": "ctrl+shift+7",
Expand Down Expand Up @@ -211,25 +231,30 @@
],
"menus": {
"editor/context": [
{
"when": "config.coverage-gutters.customizable.menus-editor-context-previewLcovReport-enabled",
"command": "extension.previewLcovReport",
"group": "Coverage-Gutters@1"
},
{
"when": "config.coverage-gutters.customizable.menus-editor-context-displayCoverage-enabled",
"command": "extension.displayCoverage",
"group": "Coverage-Gutters@1"
"group": "Coverage-Gutters@2"
},
{
"when": "config.coverage-gutters.customizable.menus-editor-context-watchLcovAndVisibleEditors-enabled",
"command": "extension.watchLcovAndVisibleEditors",
"group": "Coverage-Gutters@2"
"group": "Coverage-Gutters@3"
},
{
"when": "config.coverage-gutters.customizable.menus-editor-context-removeWatch-enabled",
"command": "extension.removeWatch",
"group": "Coverage-Gutters@3"
"group": "Coverage-Gutters@4"
},
{
"when": "config.coverage-gutters.customizable.menus-editor-context-removeCoverage-enabled",
"command": "extension.removeCoverage",
"group": "Coverage-Gutters@4"
"group": "Coverage-Gutters@5"
}
]
}
Expand All @@ -251,7 +276,6 @@
"@types/mocha": "2.2.41",
"@types/node": "6.0.40",
"@types/request": "0.0.43",
"@types/uuid": "3.0.0",
"mocha": "2.3.3",
"tslint": "5.4.3",
"typescript": "2.3.4",
Expand All @@ -260,7 +284,6 @@
"dependencies": {
"glob": "5.0.15",
"lcov-parse": "0.0.10",
"request": "2.81.0",
"uuid": "3.0.1"
"request": "2.81.0"
}
}
13 changes: 12 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,17 @@ export function activate(context: vscode.ExtensionContext) {
const statusBarToggler = new StatusBarToggler(configStore);
const lcov = new Lcov(configStore, globImpl, vscodeImpl, fsImpl);
const indicators = new Indicators(parseImpl, vscodeImpl, configStore);
const gutters = new Gutters(configStore, lcov, indicators, reporter, statusBarToggler);
const gutters = new Gutters(
configStore,
lcov,
indicators,
reporter,
statusBarToggler,
);

const previewLcovReport = vscode.commands.registerCommand("extension.previewLcovReport", () => {
gutters.previewLcovReport();
});

const display = vscode.commands.registerCommand("extension.displayCoverage", () => {
gutters.displayCoverageForActiveFile();
Expand All @@ -41,6 +51,7 @@ export function activate(context: vscode.ExtensionContext) {
gutters.removeCoverageForActiveFile();
});

context.subscriptions.push(previewLcovReport);
context.subscriptions.push(remove);
context.subscriptions.push(display);
context.subscriptions.push(watch);
Expand Down
71 changes: 62 additions & 9 deletions src/gutters.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import {
commands,
Disposable,
FileSystemWatcher,
StatusBarItem,
TextEditor,
Uri,
version,
ViewColumn,
window,
} from "vscode";

Expand Down Expand Up @@ -44,13 +47,52 @@ export class Gutters {
this.reporter.sendEvent("user", "vscodeVersion", version);
}

public async previewLcovReport() {
try {
const lcovReports = await this.lcov.findReports();
let pickedReport: string;
if (lcovReports.length === 1) {
pickedReport = lcovReports[0];
} else {
this.reporter.sendEvent("user", "showQuickPickReport", `${lcovReports.length}`);
pickedReport = await window.showQuickPick(
lcovReports,
{placeHolder: "Choose a Lcov Report to preview."},
);
}

if (!pickedReport) { throw new Error("Could not show Lcov Report file!"); }
const reportUri = Uri.parse(`file:///${pickedReport}`);
await commands.executeCommand(
"vscode.previewHtml",
reportUri,
ViewColumn.One,
"Preview Lcov Report",
);
this.reporter.sendEvent("user", "preview-lcov-report");
} catch (error) {
this.handleError(error);
}
}

public async displayCoverageForActiveFile() {
const textEditor = window.activeTextEditor;
try {
if (!textEditor) { return; }
const lcovPath = await this.lcov.find();
await this.loadAndRenderCoverage(textEditor, lcovPath);

const lcovPaths = await this.lcov.findLcovs();
let pickedLcov: string;
if (lcovPaths.length === 1) {
pickedLcov = lcovPaths[0];
} else {
this.reporter.sendEvent("user", "showQuickPickLcov", `${lcovPaths.length}`);
pickedLcov = await window.showQuickPick(
lcovPaths,
{placeHolder: "Choose a Lcov File to use for coverage."},
);
}
if (!pickedLcov) { throw new Error("Could not show coverage for file!"); }

await this.loadAndRenderCoverage(textEditor, pickedLcov);
this.reporter.sendEvent("user", "display-coverage");
} catch (error) {
this.handleError(error);
Expand All @@ -62,16 +104,28 @@ export class Gutters {

const textEditor = window.activeTextEditor;
try {
const lcovPath = await this.lcov.find();
const lcovPaths = await this.lcov.findLcovs();

let pickedLcov: string;
if (lcovPaths.length === 1) {
pickedLcov = lcovPaths[0];
} else {
this.reporter.sendEvent("user", "showQuickPick", `${lcovPaths.length}`);
pickedLcov = await window.showQuickPick(
lcovPaths,
{placeHolder: "Choose a Lcov to use for coverage."},
);
}
if (!pickedLcov) { throw new Error("Could not show coverage for file!"); }

// When we try to load the coverage when watch is actived we dont want to error
// if the active file has no coverage
this.loadAndRenderCoverage(textEditor, lcovPath).catch(() => {});
this.loadAndRenderCoverage(textEditor, pickedLcov).catch(() => {});

this.lcovWatcher = vscodeImpl.watchFile(lcovPath);
this.lcovWatcher.onDidChange((event) => this.renderCoverageOnVisible(lcovPath));
this.lcovWatcher = vscodeImpl.watchFile(pickedLcov);
this.lcovWatcher.onDidChange((event) => this.renderCoverageOnVisible(pickedLcov));
this.editorWatcher = window.onDidChangeVisibleTextEditors(
(event) => this.renderCoverageOnVisible(lcovPath));
(event) => this.renderCoverageOnVisible(pickedLcov));
this.statusBar.toggle();

this.reporter.sendEvent("user", "watch-lcov-editors");
Expand Down Expand Up @@ -115,7 +169,6 @@ export class Gutters {
private handleError(error: Error) {
const message = error.message ? error.message : error;
window.showWarningMessage(message.toString());

this.reporter.sendEvent("error", message.toString());
}

Expand Down
21 changes: 16 additions & 5 deletions src/lcov.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,26 @@ export class Lcov {
this.fs = fs;
}

public find(): Promise<string> {
return new Promise<string>((resolve, reject) => {
public findLcovs(): Promise<string[]> {
return new Promise<string[]>((resolve, reject) => {
this.glob.find(
`**/${this.configStore.lcovFileName}`,
{ ignore: "**/node_modules/**", cwd: this.vscode.getRootPath(), realpath: true },
(err, files) => {
if (!files || !files.length) { return reject("Could not find a lcov file!"); }
if (files.length > 1) { return reject("More then one lcov file found!"); }
return resolve(files[0]);
if (!files || !files.length) { return reject("Could not find a Lcov File!"); }
return resolve(files);
});
});
}

public findReports(): Promise<string[]> {
return new Promise<string[]>((resolve, reject) => {
this.glob.find(
`**/coverage/**/*.html`,
{ ignore: "**/node_modules/**", cwd: this.vscode.getRootPath(), realpath: true },
(err, files) => {
if (!files || !files.length) { return reject("Could not find a Lcov Report file!"); }
return resolve(files);
});
});
}
Expand Down
Loading