diff --git a/tools/vscode-ext/README.md b/tools/vscode-ext/README.md index d2e1b2a..2e84ecf 100644 --- a/tools/vscode-ext/README.md +++ b/tools/vscode-ext/README.md @@ -13,6 +13,8 @@ Welcome! The [goc](https://github.com/qiniu/goc) is a coverage tool for Golang p This extension provides a frontend to show the covered lines in real time. +![demo](https://github.com/qiniu/goc/raw/master/docs/images/goc-vscode.gif) + ### Basic requirements Before you started, make sure that you have: diff --git a/tools/vscode-ext/package-lock.json b/tools/vscode-ext/package-lock.json index 69c4007..c91c452 100644 --- a/tools/vscode-ext/package-lock.json +++ b/tools/vscode-ext/package-lock.json @@ -1,6 +1,6 @@ { "name": "goc", - "version": "0.0.1", + "version": "0.0.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -40,6 +40,15 @@ "@types/node": "*" } }, + "@types/log4js": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@types/log4js/-/log4js-2.3.5.tgz", + "integrity": "sha512-SwF8LkSHqHy9A8GQ67NAYJiGl8zzP4Qtx65Wa+IOxDGdMHxKeoQZjg7m2M1erIT6VK0DYHpu2aTbdLkdkuMHjw==", + "dev": true, + "requires": { + "log4js": "*" + } + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -233,6 +242,11 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "date-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", + "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==" + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -344,6 +358,11 @@ "is-buffer": "~2.0.3" } }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" + }, "follow-redirects": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", @@ -367,6 +386,16 @@ } } }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -399,6 +428,11 @@ "path-is-absolute": "^1.0.0" } }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -549,6 +583,14 @@ "esprima": "^4.0.0" } }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -574,6 +616,28 @@ "chalk": "^2.0.1" } }, + "log4js": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz", + "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==", + "requires": { + "date-format": "^3.0.0", + "debug": "^4.1.1", + "flatted": "^2.0.1", + "rfdc": "^1.1.4", + "streamroller": "^2.2.4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -648,8 +712,7 @@ "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" }, "node-environment-flags": { "version": "1.0.5", @@ -767,6 +830,11 @@ "path-parse": "^1.0.6" } }, + "rfdc": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz", + "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==" + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -794,6 +862,31 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "streamroller": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz", + "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==", + "requires": { + "date-format": "^2.1.0", + "debug": "^4.1.1", + "fs-extra": "^8.1.0" + }, + "dependencies": { + "date-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", + "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -898,6 +991,11 @@ "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", "dev": true }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, "vscode-test": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.4.0.tgz", diff --git a/tools/vscode-ext/package.json b/tools/vscode-ext/package.json index d5b92d7..1aae77d 100644 --- a/tools/vscode-ext/package.json +++ b/tools/vscode-ext/package.json @@ -2,7 +2,7 @@ "name": "goc", "displayName": "Goc Coverage", "description": "Goc Coverage can display coverage vairation in real time. Goc is a comprehensive coverage testing system for The Go Programming Language, especially for some complex scenarios, like system testing code coverage collection and accurate testing.", - "version": "0.0.3", + "version": "0.0.4", "publisher": "lyyyuna", "repository": { "url": "https://github.com/qiniu/goc" @@ -30,10 +30,12 @@ "goc.serverUrl": { "type": "string", "default": "http://127.0.0.1:7777", - "items": { - "type": "string" - }, "description": "Specify the goc server url." + }, + "goc.debug": { + "type": "boolean", + "default": false, + "description": "Turn on debug mode to log more details." } } } @@ -47,16 +49,18 @@ }, "devDependencies": { "@types/glob": "^7.1.1", + "@types/log4js": "^2.3.5", "@types/mocha": "^5.2.7", "@types/node": "^12.11.7", "@types/vscode": "^1.43.0", "glob": "^7.1.5", "mocha": "^6.2.2", - "typescript": "^3.6.4", "tslint": "^5.20.0", + "typescript": "^3.6.4", "vscode-test": "^1.2.2" }, "dependencies": { - "axios": "^0.19.2" + "axios": "^0.19.2", + "log4js": "^6.3.0" } } diff --git a/tools/vscode-ext/src/gocserver.ts b/tools/vscode-ext/src/gocserver.ts index e57eff2..39dfe32 100644 --- a/tools/vscode-ext/src/gocserver.ts +++ b/tools/vscode-ext/src/gocserver.ts @@ -4,10 +4,13 @@ import * as vscode from 'vscode'; import { spawnSync } from 'child_process'; import * as path from 'path'; import { promisify } from 'util'; +import * as log4js from 'log4js'; const sleep = promisify(setTimeout); export class GocServer { private _serverUrl: string = ''; + private _debug: Boolean = false; + private _logger: log4js.Logger = log4js.getLogger(); private timer = true; private highlightDecorationType = vscode.window.createTextEditorDecorationType({ backgroundColor: 'green', @@ -30,6 +33,7 @@ export class GocServer { } this.getConfigurations(); + this.setDebugLogger(); let profile = await this.getLatestProfile(); this.renderFile(packages, profile); } @@ -51,6 +55,17 @@ export class GocServer { getConfigurations() { this._serverUrl = vscode.workspace.getConfiguration().get('goc.serverUrl') || ''; + this._debug = vscode.workspace.getConfiguration().get('goc.debug') || false; + } + + setDebugLogger() { + if (this._debug == false) { + this._logger.level = "info"; + } else { + this._logger.level = "debug"; + } + + this._logger.info('goc server url: ', this._serverUrl); } async getLatestProfile(): Promise { @@ -59,9 +74,10 @@ export class GocServer { try { let res = await axios.get(profileApi, ); let body: string = res.data.toString(); + this._logger.debug(body); return body; } catch(err) { - console.error(err) + this._logger.error(err.message); } return ""; @@ -70,9 +86,10 @@ export class GocServer { checkGoEnv() : Boolean { let output = spawnSync('go', ['version']); if (output.status != 0 || output.status == null) { - console.error(output.stderr.toString()) + this._logger.error(output.stderr.toString()); return true; } + this._logger.debug('go version: ', output.stdout.toString()); return false; } @@ -80,17 +97,18 @@ export class GocServer { let cwd = ""; let workspaces = vscode.workspace.workspaceFolders || []; if (workspaces.length == 0) { - console.error("no workspace found"); + this._logger.error("no workspace found"); return []; } else { cwd = workspaces[0].uri.path; } + this._logger.debug('current project root directory: ', cwd); let opts = { 'cwd': cwd }; let output = spawnSync('go', ['list', '-json', './...'], opts); if (output.status != 0 || output.status == null) { - console.error(output.stderr.toString()); + this._logger.error(output.stderr.toString()); return []; } let packages = JSON.parse('[' + output.stdout.toString().replace(/}\n{/g, '},\n{') + ']'); @@ -101,6 +119,7 @@ export class GocServer { let activeTextEditor = vscode.window.activeTextEditor; let fileNeedsRender = activeTextEditor?.document.fileName || '---'; + this._logger.debug('current active source code file: ', fileNeedsRender); // check if needs to rerender if (profile == this.lastProfile && fileNeedsRender == this.lastFileNeedsRender) { return; @@ -108,15 +127,18 @@ export class GocServer { this.lastProfile = profile; this.lastFileNeedsRender = fileNeedsRender; + this._logger.debug('go list packages length: ', packages.length); + for (let i=0; i