Add the first version of whoisactive project (#943)

* add the first version of whoisactive

* address comments

* address comments

* fix the issues from the last commit

* clean up package.json
This commit is contained in:
Abbie Petchtes
2018-03-22 12:32:22 -07:00
committed by GitHub
parent 4cfd9bdbc0
commit 50c4fd79b7
35 changed files with 10130 additions and 0 deletions

8
samples/sp_whoIsActive/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
out
node_modules
.vscode-test/
*.vsix
.DS_Store
.idea
test-reports/**

View File

@@ -0,0 +1,28 @@
{
// 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": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}\\out\\src\\extension"
},
{
"type": "node",
"request": "attach",
"name": "Attach to Ops Studio",
"protocol": "inspector",
"port": 5870,
"restart": true,
"sourceMaps": true,
"outFiles": [
"${workspaceRoot}/out/**/*.js"
],
"preLaunchTask": "",
"timeout": 25000
},
]
}

View File

@@ -0,0 +1,29 @@
# Unwanted compiled files
out/test/**
out/**/*.map
*.vsix
# Build/Source files
src/**
tasks/**
test/**
typings/**
packages/**
samples/**
.gitignore
tsconfig.json
# IDE Settings
.vscode/**
.vscode-test/**
.idea/**
.sqlops/**
# Reference files
**/*.ts
**/*.map
.gitignore
tsconfig.json
*.exe
*.dat
gulpfile.js

View File

@@ -0,0 +1 @@
# Change Log

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2018 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,19 @@
# sp_whoisactive for SQL Operations Studio
Welcome to **sp_whoisactive** for SQL Operations Studio! Sp_whoisactive is a procedure written by Adam Machanic. It is a very useful tool for activity monitoring and troubleshooting.
To quote one of the posts about sp_whoisactive on [Adam Machanics blog]:
Here are some quick facts on Who is Active:
* Who is Active is a DMV-based monitoring stored procedure that uses **15 different views to show a large amount of data about whats running on your server**
* Who is Active was designed to be **extremely flexible**, and includes options to not only get different types of data, but also to change the output column list and sort order
* Who is Active was **designed with performance in mind** at every step; users report that under normal conditions response times are generally subsecond, with slightly longer response times on servers that are extremely taxed
* Who is Active is **compatible with all versions of SQL Server after SQL Server 2005 RTM**. It does require that the host database (generally master) is not set for SQL Server 2000 compatibility mode
If you haven't installed sp_whoisactive in your server, you can use "Install sp_whoisactive" task to create the procedure.
See [sp_whoisactive Documentation] for more infomation.
[Adam Machanics blog]:http://sqlblog.com/blogs/adam_machanic/default.aspx
[sp_whoisactive Documentation]:http://whoisactive.com/

View File

@@ -0,0 +1,14 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
// NOTE: These are es6 gulpfiles
// Basic build tasks
require('./tasks/buildtasks');
// VSIX generation tasks
require('./tasks/packagetasks');

7671
samples/sp_whoIsActive/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,230 @@
{
"name": "whoisactive",
"displayName": "whoisactive",
"description": "sp_whoisactive for SQL Operations Studio",
"version": "0.1.0",
"publisher": "Microsoft",
"engines": {
"vscode": "^1.19.0"
},
"license": "MIT",
"repository": "",
"categories": [
"Other"
],
"activationEvents": [
"*"
],
"main": "./out/src/extension",
"contributes": {
"configuration": [],
"commands": [
{
"command": "sp_whoisactive.install",
"title": "Install sp_whoisactive",
"icon": {
"light": "./out/src/media/config.svg",
"dark": "./out/src/media/config_inverse.svg"
}
},
{
"command": "sp_whoisactive.findBlockLeaders",
"title": "Find leader of block",
"icon": "./out/src/media/start.svg"
},
{
"command": "sp_whoisactive.getPlans",
"title": "Get plans",
"icon": "./out/src/media/start.svg"
}
],
"views": {},
"menus": {},
"dashboard.tabs": [
{
"id": "sp_whoisactive",
"title": "sp_whoisactive",
"description": "Extension for checking who is active.",
"container": {
"nav-section": [
{
"id": "sp_whoisactive_insights",
"title": "Insights",
"icon": {
"light": "./out/src/media/monitor.svg",
"dark": "./out/src/media/monitor_inverse.svg"
},
"container": {
"sp_whoisactive-insights": {}
}
},
{
"id": "sp_whoisactive_documentation",
"title": "Documentation",
"icon": {
"light": "./out/src/media/file.svg",
"dark": "./out/src/media/file_inverse.svg"
},
"container": {
"webview-container": null
}
}
]
}
}
],
"dashboard.insights": [
{
"id": "sp_whoisactive-CPU-usage",
"contrib": {
"type": {
"bar": {
"dataDirection": "vertical",
"dataType": "number",
"legendPosition": "none",
"labelFirstColumn": false,
"columnsAsLabels": true
}
},
"queryFile": "./out/src/sql/cpuUsage.sql"
}
},
{
"id": "sp_whoisactive-CPU-delta",
"contrib": {
"type": {
"bar": {
"dataDirection": "vertical",
"dataType": "number",
"legendPosition": "none",
"labelFirstColumn": false,
"columnsAsLabels": true
}
},
"queryFile": "./out/src/sql/cpuDelta.sql"
}
},
{
"id": "sp_whoisactive-memory-usage",
"contrib": {
"type": {
"bar": {
"dataDirection": "vertical",
"dataType": "number",
"legendPosition": "none",
"labelFirstColumn": false,
"columnsAsLabels": true
}
},
"queryFile": "./out/src/sql/memoryUsage.sql"
}
},
{
"id": "sp_whoisactive-memory-delta",
"contrib": {
"type": {
"bar": {
"dataDirection": "vertical",
"dataType": "number",
"legendPosition": "none",
"labelFirstColumn": false,
"columnsAsLabels": true
}
},
"queryFile": "./out/src/sql/memoryDelta.sql"
}
}
],
"dashboard.containers": [
{
"id": "sp_whoisactive-insights",
"container": {
"widgets-container": [
{
"name": "Tasks",
"widget": {
"tasks-widget": [
"sp_whoisactive.getPlans",
"sp_whoisactive.findBlockLeaders",
"sp_whoisactive.install"
]
}
},
{
"name": "CPU Usage",
"gridItemConfig": {
"sizex": 2,
"sizey": 1
},
"widget": {
"sp_whoisactive-CPU-usage": {}
}
},
{
"name": "CPU Delta",
"gridItemConfig": {
"sizex": 2,
"sizey": 1
},
"widget": {
"sp_whoisactive-CPU-delta": {}
}
},
{
"name": "Memory Usage",
"gridItemConfig": {
"sizex": 2,
"sizey": 1
},
"widget": {
"sp_whoisactive-memory-usage": {}
}
},
{
"name": "Memory Delta",
"gridItemConfig": {
"sizex": 2,
"sizey": 1
},
"widget": {
"sp_whoisactive-memory-delta": {}
}
}
]
}
}
],
"snippets": []
},
"scripts": {
"build": "gulp build",
"compile": "gulp compile",
"watch": "gulp watch",
"postinstall": "node ./node_modules/vscode/bin/install"
},
"dependencies": {
"fs-extra": "^5.0.0",
"handlebars": "^4.0.11",
"openurl": "^1.1.1",
"vscode-nls": "2.0.2"
},
"devDependencies": {
"@types/handlebars": "^4.0.11",
"@types/mocha": "^2.2.42",
"@types/node": "^7.0.43",
"child-process-promise": "^2.2.1",
"del": "^3.0.0",
"gulp": "^4.0.0",
"gulp-color": "0.0.1",
"gulp-sourcemaps": "^2.6.4",
"gulp-tslint": "^6.0.2",
"gulp-typescript": "^3.2.4",
"should": "^13.2.1",
"temp-write": "^3.4.0",
"tslint": "^3.14.0",
"typemoq": "^2.1.0",
"typescript": "^2.6.1",
"vscode": "^1.1.6",
"vsce": "1.36.2"
}
}

View File

@@ -0,0 +1,5 @@
'use strict';
// CONFIG VALUES ///////////////////////////////////////////////////////////
export const extensionConfigSectionName = 'extensionSamples';
export const configLogDebugInfo = 'logDebugInfo';

View File

@@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
export default abstract class ControllerBase implements vscode.Disposable {
protected _context: vscode.ExtensionContext;
public constructor(context: vscode.ExtensionContext) {
this._context = context;
}
abstract activate(): Promise<boolean>;
abstract deactivate(): void;
public dispose(): void {
this.deactivate();
}
}

View File

@@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as sqlops from 'sqlops';
import * as Utils from '../utils';
import ControllerBase from './controllerBase';
import * as fs from 'fs';
import * as path from 'path';
import * as vscode from 'vscode';
import * as openurl from 'openurl';
/**
* The main controller class that initializes the extension
*/
export default class MainController extends ControllerBase {
public apiWrapper;
// PUBLIC METHODS //////////////////////////////////////////////////////
/**
* Deactivates the extension
*/
public deactivate(): void {
Utils.logDebug('Main controller deactivated');
}
public activate(): Promise<boolean> {
sqlops.dashboard.registerWebviewProvider('sp_whoisactive_documentation', webview => {
let templateValues = {url: 'http://whoisactive.com/docs/'};
Utils.renderTemplateHtml(path.join(__dirname, '..'), 'templateTab.html', templateValues)
.then(html => {
webview.html = html;
});
});
sqlops.tasks.registerTask('sp_whoisactive.install', e => this.onInstall(e));
sqlops.tasks.registerTask('sp_whoisactive.findBlockLeaders', e => this.onExecute(e, 'findBlockLeaders.sql'));
sqlops.tasks.registerTask('sp_whoisactive.getPlans', e => this.onExecute(e, 'getPlans.sql'));
return Promise.resolve(true);
}
private onInstall(connection: sqlops.IConnectionProfile): void {
openurl.open('http://whoisactive.com/downloads/');
}
private onExecute(connection: sqlops.IConnectionProfile, fileName: string): void {
let sqlFile = fs.readFileSync(path.join(__dirname, '..', 'sql', fileName)).toString();
this.openSQLFileWithContent(sqlFile);
}
private openSQLFileWithContent(content: string): void {
vscode.workspace.openTextDocument({language: 'sql', content: content}).then(doc => {
vscode.window.showTextDocument(doc, vscode.ViewColumn.Active, false);
});
}
}

View File

@@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
import ControllerBase from './controllers/controllerBase';
import MainController from './controllers/mainController';
let controllers: ControllerBase[] = [];
export function activate(context: vscode.ExtensionContext): Promise<boolean> {
let activations: Promise<boolean>[] = [];
// Start the main controller
let mainController = new MainController(context);
controllers.push(mainController);
context.subscriptions.push(mainController);
activations.push(mainController.activate());
return Promise.all(activations)
.then((results: boolean[]) => {
for (let result of results) {
if (!result) {
return false;
}
}
return true;
});
}
export function deactivate(): void {
for (let controller of controllers) {
controller.deactivate();
}
}

View File

@@ -0,0 +1,5 @@
'use strict';
// TODO: localize!
export const msgErrorLoadingTab = 'An error occurred while loading the tab.';

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><title>configure_dashboard</title><path d="M16,0V4H15V1.71L10.5,6.2l-3-3L0,10.71V9.29L7.5,1.8l3,3L14.29,1H12V0Zm-.12,10.93-1,.4a2.75,2.75,0,0,1,.06.33,3,3,0,0,1,0,.68,2.71,2.71,0,0,1-.06.33l1,.4L15.5,14l-1-.4a3,3,0,0,1-.95.95l.4,1-.92.38-.4-1-.33.06L12,15l-.34,0-.33-.06-.4,1L10,15.5l.4-1a2.93,2.93,0,0,1-.95-.95l-1,.4-.38-.92,1-.4a3.25,3.25,0,0,1,0-1.34l-1-.4L8.49,10l1,.4a2.83,2.83,0,0,1,.95-.95l-.4-1,.92-.38.4,1a3.25,3.25,0,0,1,1.34,0l.4-1,.92.38-.4,1a3,3,0,0,1,.53.42,3,3,0,0,1,.42.53l1-.4ZM12,14a1.94,1.94,0,0,0,.78-.16,2,2,0,0,0,1.07-1.07,2,2,0,0,0,0-1.55,2,2,0,0,0-1.07-1.07,2,2,0,0,0-1.55,0,2,2,0,0,0-1.07,1.07,2,2,0,0,0,0,1.55,2,2,0,0,0,1.07,1.07A1.94,1.94,0,0,0,12,14Z"/></svg>

After

Width:  |  Height:  |  Size: 781 B

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{font-size:12px;font-family:FullMDL2Assets, Full MDL2 Assets;}.cls-1,.cls-2{fill:#fff;}</style></defs><title>manage_inverse_16x16 </title><text class="cls-1" transform="translate(0.01 11.59)"> </text><path class="cls-2" d="M16,0V4H15V1.71L10.5,6.2l-3-3L0,10.71V9.29L7.5,1.8l3,3L14.29,1H12V0Zm-.12,10.93-1,.4a2.75,2.75,0,0,1,.06.33,3,3,0,0,1,0,.68,2.71,2.71,0,0,1-.06.33l1,.4L15.5,14l-1-.4a3,3,0,0,1-.95.95l.4,1-.92.38-.4-1-.33.06L12,15l-.34,0-.33-.06-.4,1L10,15.5l.4-1a2.93,2.93,0,0,1-.95-.95l-1,.4-.38-.92,1-.4a3.25,3.25,0,0,1,0-1.34l-1-.4L8.49,10l1,.4a2.83,2.83,0,0,1,.95-.95l-.4-1,.92-.38.4,1a3.25,3.25,0,0,1,1.34,0l.4-1,.92.38-.4,1a3,3,0,0,1,.53.42,3,3,0,0,1,.42.53l1-.4ZM12,14a1.94,1.94,0,0,0,.78-.16,2,2,0,0,0,1.07-1.07,2,2,0,0,0,0-1.55,2,2,0,0,0-1.07-1.07,2,2,0,0,0-1.55,0,2,2,0,0,0-1.07,1.07,2,2,0,0,0,0,1.55,2,2,0,0,0,1.07,1.07A1.94,1.94,0,0,0,12,14Z"/></svg>

After

Width:  |  Height:  |  Size: 980 B

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#231f20;}.cls-2{fill:#212121;}</style></defs><title>file_16x16</title><polygon class="cls-1" points="13.59 2.21 13.58 2.22 13.58 2.2 13.59 2.21"/><path class="cls-2" d="M8.71,0,14,5.29V16H2V0ZM3,15H13V6H8V1H3ZM9,1.71V5h3.29Z"/></svg>

After

Width:  |  Height:  |  Size: 351 B

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>file_inverse_16x16</title><polygon class="cls-1" points="13.59 2.21 13.58 2.22 13.58 2.2 13.59 2.21"/><path class="cls-1" d="M8.71,0,14,5.29V16H2V0ZM3,15H13V6H8V1H3ZM9,1.71V5h3.29Z"/></svg>

After

Width:  |  Height:  |  Size: 335 B

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><title>query_plan_16x16</title><path d="M13.16,10.59h1.9v5H10.32v-5h1.89v-2H3.68v2H5.58v5H.84v-5h1.9v-3H7.47v-2H5.58v-5h4.74v5H8.42v2h4.74Zm-8.53,4v-3H1.79v3Zm1.9-13v3H9.37v-3Zm7.58,13v-3H11.26v3Z"/></svg>

After

Width:  |  Height:  |  Size: 298 B

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#fff;}</style></defs><title>query_plan_inverse_16x16</title><path class="cls-1" d="M13.06,10.49H15v5H10.22v-5h1.89v-2H3.59v2H5.48v5H.75v-5h1.9v-3H7.38v-2H5.48v-5h4.74v5H8.33v2h4.74Zm-8.53,4v-3H1.69v3Zm1.9-13v3H9.27v-3Zm7.58,13v-3H11.17v3Z"/></svg>

After

Width:  |  Height:  |  Size: 365 B

View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#3bb44a;}</style></defs><title>run</title><path class="cls-1" d="M3.24,0,14.61,8,3.24,16Zm2,12.07L11.13,8,5.24,3.88Z"/><path class="cls-1" d="M3.74,1l10,7-10,7Zm1,1.92V13.07L12,8Z"/></svg>

After

Width:  |  Height:  |  Size: 306 B

View File

@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript">
window.onload = function() {
document.getElementById('frame').src = "{{{url}}}";
};
</script>
<style>
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
#frame {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
</style>
</head>
<body>
<iframe id="frame" width="100%" height="100%" frameborder="0"></iframe>
</body>
</html>

View File

@@ -0,0 +1,8 @@
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'sp_WhoIsActive')
EXEC sp_WhoIsActive
@delta_interval = 1,
@output_column_list = '[session_id][CPU_delta]',
@sort_order = '[CPU_delta] DESC'
ELSE
SELECT 0;
GO

View File

@@ -0,0 +1,7 @@
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'sp_WhoIsActive')
EXEC sp_WhoIsActive
@output_column_list = '[session_id][CPU]',
@sort_order = '[CPU] DESC'
ELSE
SELECT 0;
GO

View File

@@ -0,0 +1,6 @@
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'sp_WhoIsActive')
EXEC sp_WhoIsActive
@find_block_leaders = 1,
@get_plans = 1,
@sort_order = '[blocked_session_count] DESC'
GO

View File

@@ -0,0 +1,4 @@
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'sp_WhoIsActive')
EXEC sp_WhoIsActive
@get_plans = 1
GO

View File

@@ -0,0 +1,8 @@
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'sp_WhoIsActive')
EXEC sp_WhoIsActive
@delta_interval = 1,
@output_column_list = '[session_id][used_memory_delta]',
@sort_order = '[used_memory_delta] DESC'
ELSE
SELECT 0;
GO

View File

@@ -0,0 +1,7 @@
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'sp_WhoIsActive')
EXEC sp_WhoIsActive
@output_column_list = '[session_id][used_memory]',
@sort_order = '[used_memory] DESC'
ELSE
SELECT 0;
GO

View File

@@ -0,0 +1,45 @@
'use strict';
import * as fs from 'fs-extra';
import * as handlebars from 'handlebars';
import * as path from 'path';
import * as vscode from 'vscode';
import * as Constants from './constants';
import * as LocalizedConstants from './localizedConstants';
/**
* Helper to log messages to the developer console if enabled
* @param msg Message to log to the console
*/
export function logDebug(msg: any): void {
let config = vscode.workspace.getConfiguration(Constants.extensionConfigSectionName);
let logDebugInfo = config[Constants.configLogDebugInfo];
if (logDebugInfo === true) {
let currentTime = new Date().toLocaleTimeString();
let outputMsg = '[' + currentTime + ']: ' + msg ? msg.toString() : '';
console.log(outputMsg);
}
}
export function renderTemplateHtml(extensionPath: string, templateName: string, templateValues: object): Thenable<string> {
let templatePath = path.join(extensionPath, 'resources', templateName);
// 1) Read the template from the disk
// 2) Compile it as a handlebars template and render the HTML
// 3) On failure, return a simple string as an error
return fs.readFile(templatePath, 'utf-8')
.then(templateText => {
let template = handlebars.compile(templateText);
return template(templateValues);
})
.then(
undefined,
error => {
logDebug(error);
return LocalizedConstants.msgErrorLoadingTab;
}
);
}

View File

@@ -0,0 +1,118 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
"use strict";
let del = require('del');
let gulp = require('gulp');
let srcmap = require('gulp-sourcemaps');
let tslint = require('gulp-tslint');
let ts = require('gulp-typescript');
let cproc = require('child_process');
let os = require('os');
let config = require('./config');
let tsProject = ts.createProject('tsconfig.json');
// GULP TASKS //////////////////////////////////////////////////////////////
gulp.task('clean', function(done) {
return del('out', done);
});
gulp.task('lint', () => {
return gulp.src([
config.paths.project.root + '/src/**/*.ts',
config.paths.project.root + '/test/**/*.ts'
])
.pipe((tslint({
formatter: "verbose"
})))
.pipe(tslint.report());
});
gulp.task('compile:src', function(done) {
gulp.src([
config.paths.project.root + '/src/**/*.sql',
config.paths.project.root + '/src/**/*.svg',
config.paths.project.root + '/src/**/*.html'
]).pipe(gulp.dest('out/src/'));
let srcFiles = [
config.paths.project.root + '/src/**/*.ts',
config.paths.project.root + '/src/**/*.js',
config.paths.project.root + '/typings/**/*.ts'
];
return gulp.src(srcFiles)
.pipe(srcmap.init())
.pipe(tsProject())
.on('error', function() {
if(process.env.BUILDMACHINE) {
done('Failed to compile extension source, see above.');
process.exit(1);
}
})
// TODO: Reinstate localization code
// .pipe(nls.rewriteLocalizeCalls())
// .pipe(nls.createAdditionalLanguageFiles(nls.coreLanguages, config.paths.project.root + '/localization/i18n', undefined, false))
.pipe(srcmap.write('.', { sourceRoot: function(file) { return file.cwd + '/src'; }}))
.pipe(gulp.dest('out/src/'));
});
gulp.task('compile:test', function(done) {
let srcFiles = [
config.paths.project.root + '/test/**/*.ts',
config.paths.project.root + '/typings/**/*.ts'
];
return gulp.src(srcFiles)
.pipe(srcmap.init())
.pipe(tsProject())
.on('error', function() {
if(process.env.BUILDMACHINE) {
done('Failed to compile test source, see above.');
process.exit(1);
}
})
.pipe(srcmap.write('.', {sourceRoot: function(file) { return file.cwd + '/test'; }}))
.pipe(gulp.dest('out/test/'));
});
// COMPOSED GULP TASKS /////////////////////////////////////////////////////
gulp.task("compile", gulp.series("compile:src", "compile:test"));
gulp.task("build", gulp.series("clean", "lint", "compile"));
gulp.task("watch", function() {
gulp.watch([config.paths.project.root + '/src/**/*',
config.paths.project.root + '/test/**/*.ts'],
gulp.series('build'))
});
gulp.task('test', (done) => {
let workspace = process.env['WORKSPACE'];
if (!workspace) {
workspace = process.cwd();
}
process.env.JUNIT_REPORT_PATH = workspace + '/test-reports/ext_xunit.xml';
let sqlopsPath = 'sqlops';
if (process.env['SQLOPS_DEV']) {
let suffix = os.platform === 'win32' ? 'bat' : 'sh';
sqlopsPath = `${process.env['SQLOPS_DEV']}/scripts/sql-cli.${suffix}`;
}
console.log(`Using SQLOPS Path of ${sqlopsPath}`);
cproc.exec(`${sqlopsPath} --extensionDevelopmentPath="${workspace}" --extensionTestsPath="${workspace}/out/test" --verbose`, (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
process.exit(1);
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
done();
});
});

View File

@@ -0,0 +1,19 @@
var path = require('path');
var projectRoot = path.resolve(path.dirname(__dirname));
var srcRoot = path.resolve(projectRoot, 'src');
var localization = path.resolve(projectRoot, 'localization');
var config = {
paths: {
project: {
root: projectRoot,
localization: localization
},
extension: {
root: srcRoot
}
}
};
module.exports = config;

View File

@@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
let gulp = require('gulp');
let exec = require('child-process-promise').exec;
let color = require('gulp-color');
// CONSTANTS ///////////////////////////////////////////////////////////////
let packageVals = require('../package');
// HELPER FUNCTIONS ////////////////////////////////////////////////////////
let buildPackage = function(packageName) {
// Make sure there are
if (!packageVals.repository) {
return Promise.reject("Repository field is not defined in package.json");
}
// Initialize the package command with program and command
let vsceArgs = [];
vsceArgs.push('./node_modules/vsce/out/vsce');
vsceArgs.push('package'); // package command
// Add the package name
vsceArgs.push('-o');
vsceArgs.push(packageName);
// Put it all together and execute the command
let command = vsceArgs.join(' ');
console.log(command);
return exec(command);
};
function getOnlinePackageName() {
return packageVals.name + "-" + packageVals.version + ".vsix";
}
function getOnlinePackagePath() {
return './' + getOnlinePackageName();
}

View File

@@ -0,0 +1,16 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "out",
"lib": [
"es6"
],
"sourceMap": true,
"rootDir": "."
},
"exclude": [
"node_modules",
".vscode-test"
]
}

View File

@@ -0,0 +1,123 @@
{
"rules": {
"align": [
true,
"parameters",
"statements"
],
"ban": false,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"curly": true,
"eofline": true,
"forin": true,
"indent": [
true,
"spaces"
],
"interface-name": true,
"jsdoc-format": true,
"label-position": true,
"label-undefined": true,
"max-line-length": [
true,
160
],
"member-access": false,
"member-ordering": false,
"no-any": false,
"no-arg": true,
"no-bitwise": true,
"no-conditional-assignment": true,
"no-consecutive-blank-lines": false,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-constructor-vars": false,
"no-debugger": true,
"no-duplicate-key": true,
"no-duplicate-variable": true,
"no-empty": true,
"no-eval": true,
"no-inferrable-types": false,
"no-internal-module": true,
"no-null-keyword": true,
"no-require-imports": false,
"no-shadowed-variable": true,
"no-string-literal": false,
"no-switch-case-fall-through": false,
"no-trailing-whitespace": true,
"no-unreachable": true,
"no-unused-expression": false,
"no-unused-variable": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"no-var-requires": false,
"object-literal-sort-keys": false,
"one-line": [
true,
"check-open-brace",
"check-catch",
"check-else",
"check-finally",
"check-whitespace"
],
"quotemark": [
true,
"single",
"avoid-escape"
],
"radix": true,
"semicolon": true,
"switch-default": true,
"trailing-comma": [
true,
{
"multiline": "never",
"singleline": "never"
}
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef": [
true,
"call-signature",
"property-declaration"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"use-strict": false,
"variable-name": [
true,
"allow-leading-underscore",
"ban-keywords"
],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
]
}
}

1530
samples/sp_whoIsActive/typings/sqlops.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff