Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb35dae1d1 | ||
|
|
cc0a144169 | ||
|
|
b973f9e0ec | ||
|
|
d62068025c | ||
|
|
b2952d2ddf | ||
|
|
a21244816d | ||
|
|
a9aeb57dc4 | ||
|
|
00537ed199 | ||
|
|
c2df3e0e0a | ||
|
|
e3afb1cffc | ||
|
|
b475311f85 | ||
|
|
45005d61e0 | ||
|
|
adfddeae27 | ||
|
|
a7429267bb | ||
|
|
ff415d6a03 | ||
|
|
b4dc35a4de | ||
|
|
29c7ccad39 | ||
|
|
1da3635d03 | ||
|
|
1f50015ed2 | ||
|
|
01892422cb | ||
|
|
afce60b06f | ||
|
|
a2b87f6158 | ||
|
|
76a2f92daf | ||
|
|
5b09d57196 | ||
|
|
95bf18f859 | ||
|
|
1fc648ff37 | ||
|
|
37ba956bad | ||
|
|
697f887539 | ||
|
|
7b42141958 | ||
|
|
158b00f9b4 | ||
|
|
43ac8dfd20 | ||
|
|
34d8d52e7a | ||
|
|
c738b26c04 | ||
|
|
6090e7173f | ||
|
|
7ebf746584 | ||
|
|
e9d04d75ac | ||
|
|
605160a1ba | ||
|
|
82b8750b63 | ||
|
|
61f7f19d12 |
6
.vscode/launch.json
vendored
@@ -70,12 +70,10 @@
|
|||||||
"timeout": 20000
|
"timeout": 20000
|
||||||
},
|
},
|
||||||
"osx": {
|
"osx": {
|
||||||
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh",
|
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
|
||||||
"timeout": 20000
|
|
||||||
},
|
},
|
||||||
"linux": {
|
"linux": {
|
||||||
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh",
|
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
|
||||||
"timeout": 20000
|
|
||||||
},
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"VSCODE_EXTHOST_WILL_SEND_SOCKET": null
|
"VSCODE_EXTHOST_WILL_SEND_SOCKET": null
|
||||||
|
|||||||
14
.vscode/tasks.json
vendored
@@ -28,20 +28,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "npm",
|
|
||||||
"script": "strict-initialization-watch",
|
|
||||||
"label": "TS - Strict Initialization",
|
|
||||||
"isBackground": true,
|
|
||||||
"presentation": {
|
|
||||||
"reveal": "never"
|
|
||||||
},
|
|
||||||
"problemMatcher": {
|
|
||||||
"base": "$tsc-watch",
|
|
||||||
"owner": "typescript-strict-initialization",
|
|
||||||
"applyTo": "allDocuments"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "gulp",
|
"type": "gulp",
|
||||||
"task": "tslint",
|
"task": "tslint",
|
||||||
|
|||||||
2
.yarnrc
@@ -1,3 +1,3 @@
|
|||||||
disturl "https://atom.io/download/electron"
|
disturl "https://atom.io/download/electron"
|
||||||
target "3.1.8"
|
target "3.1.6"
|
||||||
runtime "electron"
|
runtime "electron"
|
||||||
|
|||||||
13
CHANGELOG.md
@@ -1,18 +1,5 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
## Version 1.6.0
|
|
||||||
* Release date: April 18, 2019
|
|
||||||
* Release status: General Availability
|
|
||||||
|
|
||||||
## What's new in this version
|
|
||||||
* Align with latest VS Code editor platform (currently 1.33.1)
|
|
||||||
* Resolved [bugs and issues](https://github.com/Microsoft/azuredatastudio/milestone/26?closed=1).
|
|
||||||
|
|
||||||
## Contributions and "thank you"
|
|
||||||
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
|
|
||||||
|
|
||||||
* yamatoya for `fix the format (#4899)`
|
|
||||||
|
|
||||||
## Version 1.5.1
|
## Version 1.5.1
|
||||||
* Release date: March 18, 2019
|
* Release date: March 18, 2019
|
||||||
* Release status: General Availability
|
* Release status: General Availability
|
||||||
|
|||||||
15
README.md
@@ -9,13 +9,13 @@ Azure Data Studio is a data management tool that enables you to work with SQL Se
|
|||||||
|
|
||||||
Platform | Link
|
Platform | Link
|
||||||
-- | --
|
-- | --
|
||||||
Windows User Installer | https://go.microsoft.com/fwlink/?linkid=2087316
|
Windows User Installer | https://go.microsoft.com/fwlink/?linkid=2083322
|
||||||
Windows System Installer | https://go.microsoft.com/fwlink/?linkid=2087317
|
Windows System Installer | https://go.microsoft.com/fwlink/?linkid=2083323
|
||||||
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=2087318
|
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=2083324
|
||||||
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=2087170
|
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=2083325
|
||||||
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=2087414
|
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=2083424
|
||||||
Linux RPM | https://go.microsoft.com/fwlink/?linkid=2087171
|
Linux RPM | https://go.microsoft.com/fwlink/?linkid=2083326
|
||||||
Linux DEB | https://go.microsoft.com/fwlink/?linkid=2087415
|
Linux DEB | https://go.microsoft.com/fwlink/?linkid=2083327
|
||||||
|
|
||||||
Go to our [download page](https://aka.ms/azuredatastudio) for more specific instructions.
|
Go to our [download page](https://aka.ms/azuredatastudio) for more specific instructions.
|
||||||
|
|
||||||
@@ -68,7 +68,6 @@ The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.micro
|
|||||||
## Contributions and "Thank You"
|
## Contributions and "Thank You"
|
||||||
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
|
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
|
||||||
|
|
||||||
* yamatoya for `fix the format (#4899)`
|
|
||||||
* GeoffYoung for `Fix sqlDropColumn description #4422`
|
* GeoffYoung for `Fix sqlDropColumn description #4422`
|
||||||
* AlexFsmn for `Added context menu for DBs in explorer view to backup & restore db. #2277`
|
* AlexFsmn for `Added context menu for DBs in explorer view to backup & restore db. #2277`
|
||||||
* sadedil for `Missing feature request: Save as XML #3729`
|
* sadedil for `Missing feature request: Save as XML #3729`
|
||||||
|
|||||||
@@ -24,15 +24,21 @@ steps:
|
|||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
yarn
|
yarn
|
||||||
displayName: 'Install'
|
displayName: 'Install'
|
||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
yarn gulp electron-x64
|
node_modules/.bin/gulp electron
|
||||||
displayName: Download Electron
|
node_modules/.bin/gulp compile --max_old_space_size=4096
|
||||||
|
displayName: 'Scripts'
|
||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
yarn gulp hygiene
|
DISPLAY=:10 ./scripts/test.sh --reporter mocha-junit-reporter
|
||||||
displayName: Run Hygiene Checks
|
displayName: 'Tests'
|
||||||
|
|
||||||
|
- task: PublishTestResults@2
|
||||||
|
inputs:
|
||||||
|
testResultsFiles: '**/test-results.xml'
|
||||||
|
condition: succeededOrFailed()
|
||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
yarn tslint
|
yarn tslint
|
||||||
@@ -41,29 +47,3 @@ steps:
|
|||||||
- script: |
|
- script: |
|
||||||
yarn strict-null-check
|
yarn strict-null-check
|
||||||
displayName: 'Run Strict Null Check'
|
displayName: 'Run Strict Null Check'
|
||||||
|
|
||||||
- script: |
|
|
||||||
yarn compile
|
|
||||||
displayName: 'Compile'
|
|
||||||
|
|
||||||
- script: |
|
|
||||||
DISPLAY=:10 ./scripts/test.sh --reporter mocha-junit-reporter
|
|
||||||
displayName: 'Tests'
|
|
||||||
condition: eq(variables['Agent.OS'], 'Linux')
|
|
||||||
|
|
||||||
- script: |
|
|
||||||
DISPLAY=:10 ./scripts/test.sh --reporter mocha-junit-reporter --coverage
|
|
||||||
displayName: 'Tests'
|
|
||||||
condition: ne(variables['Agent.OS'], 'Linux')
|
|
||||||
|
|
||||||
- task: PublishTestResults@2
|
|
||||||
inputs:
|
|
||||||
testResultsFiles: '**/test-results.xml'
|
|
||||||
condition: succeededOrFailed()
|
|
||||||
|
|
||||||
- task: PublishCodeCoverageResults@1
|
|
||||||
inputs:
|
|
||||||
codeCoverageTool: 'cobertura'
|
|
||||||
summaryFileLocation: $(System.DefaultWorkingDirectory)/.build/coverage/cobertura-coverage.xml
|
|
||||||
reportDirectory: $(System.DefaultWorkingDirectory)/.build/coverage/lcov-reports
|
|
||||||
condition: ne(variables['Agent.OS'], 'Linux')
|
|
||||||
|
|||||||
@@ -9,12 +9,21 @@ steps:
|
|||||||
displayName: 'Yarn Install'
|
displayName: 'Yarn Install'
|
||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
yarn gulp electron-x64
|
.\node_modules\.bin\gulp electron
|
||||||
displayName: 'Electron'
|
displayName: 'Electron'
|
||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
yarn gulp hygiene
|
npm run compile
|
||||||
displayName: Run Hygiene Checks
|
displayName: 'Compile'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
.\scripts\test.bat --reporter mocha-junit-reporter
|
||||||
|
displayName: 'Test'
|
||||||
|
|
||||||
|
- task: PublishTestResults@2
|
||||||
|
inputs:
|
||||||
|
testResultsFiles: 'test-results.xml'
|
||||||
|
condition: succeededOrFailed()
|
||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
yarn tslint
|
yarn tslint
|
||||||
@@ -23,22 +32,3 @@ steps:
|
|||||||
- script: |
|
- script: |
|
||||||
yarn strict-null-check
|
yarn strict-null-check
|
||||||
displayName: 'Run Strict Null Check'
|
displayName: 'Run Strict Null Check'
|
||||||
|
|
||||||
- script: |
|
|
||||||
yarn compile
|
|
||||||
displayName: 'Compile'
|
|
||||||
|
|
||||||
- script: |
|
|
||||||
.\scripts\test.bat --reporter mocha-junit-reporter --coverage
|
|
||||||
displayName: 'Test'
|
|
||||||
|
|
||||||
- task: PublishTestResults@2
|
|
||||||
inputs:
|
|
||||||
testResultsFiles: 'test-results.xml'
|
|
||||||
condition: succeededOrFailed()
|
|
||||||
|
|
||||||
- task: PublishCodeCoverageResults@1
|
|
||||||
inputs:
|
|
||||||
codeCoverageTool: 'cobertura'
|
|
||||||
summaryFileLocation: $(System.DefaultWorkingDirectory)\.build\coverage\cobertura-coverage.xml
|
|
||||||
reportDirectory: $(System.DefaultWorkingDirectory)\.build\coverage\lcov-report
|
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ interface Asset {
|
|||||||
platform: string;
|
platform: string;
|
||||||
type: string;
|
type: string;
|
||||||
url: string;
|
url: string;
|
||||||
mooncakeUrl?: string;
|
// {{SQL CARBON EDIT}}
|
||||||
|
mooncakeUrl: string | undefined;
|
||||||
hash: string;
|
hash: string;
|
||||||
sha256hash: string;
|
sha256hash: string;
|
||||||
size: number;
|
size: number;
|
||||||
@@ -188,18 +189,56 @@ async function publish(commit: string, quality: string, platform: string, type:
|
|||||||
const blobService = azure.createBlobService(storageAccount, process.env['AZURE_STORAGE_ACCESS_KEY_2']!)
|
const blobService = azure.createBlobService(storageAccount, process.env['AZURE_STORAGE_ACCESS_KEY_2']!)
|
||||||
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
|
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
|
||||||
|
|
||||||
|
// {{SQL CARBON EDIT}}
|
||||||
await assertContainer(blobService, quality);
|
await assertContainer(blobService, quality);
|
||||||
|
|
||||||
const blobExists = await doesAssetExist(blobService, quality, blobName);
|
const blobExists = await doesAssetExist(blobService, quality, blobName);
|
||||||
|
|
||||||
if (blobExists) {
|
const promises = [];
|
||||||
|
|
||||||
|
if (!blobExists) {
|
||||||
|
promises.push(uploadBlob(blobService, quality, blobName, file));
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{SQL CARBON EDIT}}
|
||||||
|
if (process.env['MOONCAKE_STORAGE_ACCESS_KEY']) {
|
||||||
|
const mooncakeBlobService = azure.createBlobService(storageAccount, process.env['MOONCAKE_STORAGE_ACCESS_KEY']!, `${storageAccount}.blob.core.chinacloudapi.cn`)
|
||||||
|
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
|
||||||
|
|
||||||
|
// mooncake is fussy and far away, this is needed!
|
||||||
|
mooncakeBlobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
assertContainer(blobService, quality),
|
||||||
|
assertContainer(mooncakeBlobService, quality)
|
||||||
|
]);
|
||||||
|
|
||||||
|
const [blobExists, moooncakeBlobExists] = await Promise.all([
|
||||||
|
doesAssetExist(blobService, quality, blobName),
|
||||||
|
doesAssetExist(mooncakeBlobService, quality, blobName)
|
||||||
|
]);
|
||||||
|
|
||||||
|
const promises: Array<Promise<void>> = [];
|
||||||
|
|
||||||
|
if (!blobExists) {
|
||||||
|
promises.push(uploadBlob(blobService, quality, blobName, file));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!moooncakeBlobExists) {
|
||||||
|
promises.push(uploadBlob(mooncakeBlobService, quality, blobName, file));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('Skipping Mooncake publishing.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (promises.length === 0) {
|
||||||
console.log(`Blob ${quality}, ${blobName} already exists, not publishing again.`);
|
console.log(`Blob ${quality}, ${blobName} already exists, not publishing again.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Uploading blobs to Azure storage...');
|
console.log('Uploading blobs to Azure storage...');
|
||||||
|
|
||||||
await uploadBlob(blobService, quality, blobName, file);
|
await Promise.all(promises);
|
||||||
|
|
||||||
console.log('Blobs successfully uploaded.');
|
console.log('Blobs successfully uploaded.');
|
||||||
|
|
||||||
@@ -211,6 +250,8 @@ async function publish(commit: string, quality: string, platform: string, type:
|
|||||||
platform: platform,
|
platform: platform,
|
||||||
type: type,
|
type: type,
|
||||||
url: `${process.env['AZURE_CDN_URL']}/${quality}/${blobName}`,
|
url: `${process.env['AZURE_CDN_URL']}/${quality}/${blobName}`,
|
||||||
|
// {{SQL CARBON EDIT}}
|
||||||
|
mooncakeUrl: process.env['MOONCAKE_CDN_URL'] ? `${process.env['MOONCAKE_CDN_URL']}/${quality}/${blobName}` : undefined,
|
||||||
hash: sha1hash,
|
hash: sha1hash,
|
||||||
sha256hash,
|
sha256hash,
|
||||||
size
|
size
|
||||||
|
|||||||
@@ -1,176 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as url from 'url';
|
|
||||||
import * as azure from 'azure-storage';
|
|
||||||
import * as mime from 'mime';
|
|
||||||
import { DocumentClient, RetrievedDocument } from 'documentdb';
|
|
||||||
|
|
||||||
function log(...args: any[]) {
|
|
||||||
console.log(...[`[${new Date().toISOString()}]`, ...args]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function error(...args: any[]) {
|
|
||||||
console.error(...[`[${new Date().toISOString()}]`, ...args]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.argv.length < 3) {
|
|
||||||
error('Usage: node sync-mooncake.js <quality>');
|
|
||||||
process.exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Build extends RetrievedDocument {
|
|
||||||
assets: Asset[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Asset {
|
|
||||||
platform: string;
|
|
||||||
type: string;
|
|
||||||
url: string;
|
|
||||||
mooncakeUrl: string;
|
|
||||||
hash: string;
|
|
||||||
sha256hash: string;
|
|
||||||
size: number;
|
|
||||||
supportsFastUpdate?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateBuild(commit: string, quality: string, platform: string, type: string, asset: Asset): Promise<void> {
|
|
||||||
const client = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT']!, { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
|
|
||||||
const collection = 'dbs/builds/colls/' + quality;
|
|
||||||
const updateQuery = {
|
|
||||||
query: 'SELECT TOP 1 * FROM c WHERE c.id = @id',
|
|
||||||
parameters: [{ name: '@id', value: commit }]
|
|
||||||
};
|
|
||||||
|
|
||||||
let updateTries = 0;
|
|
||||||
|
|
||||||
function _update(): Promise<void> {
|
|
||||||
updateTries++;
|
|
||||||
|
|
||||||
return new Promise<void>((c, e) => {
|
|
||||||
client.queryDocuments(collection, updateQuery).toArray((err, results) => {
|
|
||||||
if (err) { return e(err); }
|
|
||||||
if (results.length !== 1) { return e(new Error('No documents')); }
|
|
||||||
|
|
||||||
const release = results[0];
|
|
||||||
|
|
||||||
release.assets = [
|
|
||||||
...release.assets.filter((a: any) => !(a.platform === platform && a.type === type)),
|
|
||||||
asset
|
|
||||||
];
|
|
||||||
|
|
||||||
client.replaceDocument(release._self, release, err => {
|
|
||||||
if (err && err.code === 409 && updateTries < 5) { return c(_update()); }
|
|
||||||
if (err) { return e(err); }
|
|
||||||
|
|
||||||
log('Build successfully updated.');
|
|
||||||
c();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return _update();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function sync(commit: string, quality: string): Promise<void> {
|
|
||||||
log(`Synchronizing Mooncake assets for ${quality}, ${commit}...`);
|
|
||||||
|
|
||||||
const cosmosdb = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT']!, { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
|
|
||||||
const collection = `dbs/builds/colls/${quality}`;
|
|
||||||
const query = {
|
|
||||||
query: 'SELECT TOP 1 * FROM c WHERE c.id = @id',
|
|
||||||
parameters: [{ name: '@id', value: commit }]
|
|
||||||
};
|
|
||||||
|
|
||||||
const build = await new Promise<Build>((c, e) => {
|
|
||||||
cosmosdb.queryDocuments(collection, query).toArray((err, results) => {
|
|
||||||
if (err) { return e(err); }
|
|
||||||
if (results.length !== 1) { return e(new Error('No documents')); }
|
|
||||||
c(results[0] as Build);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
log(`Found build for ${commit}, with ${build.assets.length} assets`);
|
|
||||||
|
|
||||||
const storageAccount = process.env['AZURE_STORAGE_ACCOUNT_2']!;
|
|
||||||
|
|
||||||
const blobService = azure.createBlobService(storageAccount, process.env['AZURE_STORAGE_ACCESS_KEY_2']!)
|
|
||||||
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
|
|
||||||
|
|
||||||
const mooncakeBlobService = azure.createBlobService(storageAccount, process.env['MOONCAKE_STORAGE_ACCESS_KEY']!, `${storageAccount}.blob.core.chinacloudapi.cn`)
|
|
||||||
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
|
|
||||||
|
|
||||||
// mooncake is fussy and far away, this is needed!
|
|
||||||
blobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
|
|
||||||
mooncakeBlobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
|
|
||||||
|
|
||||||
for (const asset of build.assets) {
|
|
||||||
try {
|
|
||||||
const blobPath = url.parse(asset.url).path;
|
|
||||||
|
|
||||||
if (!blobPath) {
|
|
||||||
throw new Error(`Failed to parse URL: ${asset.url}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const blobName = blobPath.replace(/^\/\w+\//, '');
|
|
||||||
|
|
||||||
log(`Found ${blobName}`);
|
|
||||||
|
|
||||||
if (asset.mooncakeUrl) {
|
|
||||||
log(` Already in Mooncake ✔️`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const readStream = blobService.createReadStream(quality, blobName, undefined!);
|
|
||||||
const blobOptions: azure.BlobService.CreateBlockBlobRequestOptions = {
|
|
||||||
contentSettings: {
|
|
||||||
contentType: mime.lookup(blobPath),
|
|
||||||
cacheControl: 'max-age=31536000, public'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const writeStream = mooncakeBlobService.createWriteStreamToBlockBlob(quality, blobName, blobOptions, undefined);
|
|
||||||
|
|
||||||
log(` Uploading to Mooncake...`);
|
|
||||||
await new Promise((c, e) => readStream.pipe(writeStream).on('finish', c).on('error', e));
|
|
||||||
|
|
||||||
log(` Updating build in DB...`);
|
|
||||||
asset.mooncakeUrl = `${process.env['MOONCAKE_CDN_URL']}${blobPath}`;
|
|
||||||
await updateBuild(commit, quality, asset.platform, asset.type, asset);
|
|
||||||
|
|
||||||
log(` Done ✔️`);
|
|
||||||
} catch (err) {
|
|
||||||
error(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log(`All done ✔️`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function main(): void {
|
|
||||||
if (process.env['VSCODE_BUILD_SKIP_PUBLISH']) {
|
|
||||||
error('Skipping publish due to VSCODE_BUILD_SKIP_PUBLISH');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const commit = process.env['BUILD_SOURCEVERSION'];
|
|
||||||
|
|
||||||
if (!commit) {
|
|
||||||
error('Skipping publish due to missing BUILD_SOURCEVERSION');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const quality = process.argv[2];
|
|
||||||
|
|
||||||
sync(commit, quality).catch(err => {
|
|
||||||
error(err);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
yarn gulp vscode-darwin-min
|
|
||||||
yarn gulp upload-vscode-sourcemaps
|
|
||||||
@@ -18,15 +18,9 @@ steps:
|
|||||||
password $(VSCODE_MIXIN_PASSWORD)
|
password $(VSCODE_MIXIN_PASSWORD)
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git config user.email "vscode@microsoft.com"
|
|
||||||
git config user.name "VSCode"
|
|
||||||
git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git"
|
|
||||||
git fetch distro
|
|
||||||
git merge $(node -p "require('./package.json').distro")
|
|
||||||
|
|
||||||
yarn
|
yarn
|
||||||
yarn gulp mixin
|
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" yarn gulp -- mixin
|
||||||
yarn gulp hygiene
|
yarn gulp -- hygiene
|
||||||
yarn monaco-compile-check
|
yarn monaco-compile-check
|
||||||
node build/azure-pipelines/common/installDistro.js
|
node build/azure-pipelines/common/installDistro.js
|
||||||
node build/lib/builtInExtensions.js
|
node build/lib/builtInExtensions.js
|
||||||
@@ -36,7 +30,10 @@ steps:
|
|||||||
set -e
|
set -e
|
||||||
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \
|
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \
|
||||||
AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \
|
AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \
|
||||||
./build/azure-pipelines/darwin/build.sh
|
yarn gulp -- vscode-darwin-min
|
||||||
|
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \
|
||||||
|
AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \
|
||||||
|
yarn gulp -- upload-vscode-sourcemaps
|
||||||
displayName: Build
|
displayName: Build
|
||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
@@ -46,11 +43,6 @@ steps:
|
|||||||
# yarn smoketest -- --build "$(agent.builddirectory)/VSCode-darwin/$APP_NAME"
|
# yarn smoketest -- --build "$(agent.builddirectory)/VSCode-darwin/$APP_NAME"
|
||||||
displayName: Run unit tests
|
displayName: Run unit tests
|
||||||
|
|
||||||
- script: |
|
|
||||||
set -e
|
|
||||||
./scripts/test-integration.sh --build --tfs "Integration Tests"
|
|
||||||
displayName: Run integration tests
|
|
||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
set -e
|
set -e
|
||||||
pushd ../VSCode-darwin && zip -r -X -y ../VSCode-darwin.zip * && popd
|
pushd ../VSCode-darwin && zip -r -X -y ../VSCode-darwin.zip * && popd
|
||||||
@@ -77,12 +69,31 @@ steps:
|
|||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
set -e
|
set -e
|
||||||
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \
|
|
||||||
|
# remove pkg from archive
|
||||||
|
zip -d ../VSCode-darwin.zip "*.pkg"
|
||||||
|
|
||||||
|
# publish the build
|
||||||
|
PACKAGEJSON=`ls ../VSCode-darwin/*.app/Contents/Resources/app/package.json`
|
||||||
|
VERSION=`node -p "require(\"$PACKAGEJSON\").version"`
|
||||||
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
|
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
|
||||||
AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \
|
|
||||||
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
|
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
|
||||||
VSCODE_HOCKEYAPP_TOKEN="$(VSCODE_HOCKEYAPP_TOKEN)" \
|
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
|
||||||
./build/azure-pipelines/darwin/publish.sh
|
node build/azure-pipelines/common/publish.js \
|
||||||
|
"$(VSCODE_QUALITY)" \
|
||||||
|
darwin \
|
||||||
|
archive \
|
||||||
|
"VSCode-darwin-$(VSCODE_QUALITY).zip" \
|
||||||
|
$VERSION \
|
||||||
|
true \
|
||||||
|
../VSCode-darwin.zip
|
||||||
|
|
||||||
|
# publish hockeyapp symbols
|
||||||
|
node build/azure-pipelines/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" "$(VSCODE_HOCKEYAPP_ID_MACOS)"
|
||||||
|
|
||||||
|
# upload configuration
|
||||||
|
AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \
|
||||||
|
yarn gulp -- upload-vscode-configuration
|
||||||
displayName: Publish
|
displayName: Publish
|
||||||
|
|
||||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# remove pkg from archive
|
|
||||||
zip -d ../VSCode-darwin.zip "*.pkg"
|
|
||||||
|
|
||||||
# publish the build
|
|
||||||
PACKAGEJSON=`ls ../VSCode-darwin/*.app/Contents/Resources/app/package.json`
|
|
||||||
VERSION=`node -p "require(\"$PACKAGEJSON\").version"`
|
|
||||||
node build/azure-pipelines/common/publish.js \
|
|
||||||
"$VSCODE_QUALITY" \
|
|
||||||
darwin \
|
|
||||||
archive \
|
|
||||||
"VSCode-darwin-$VSCODE_QUALITY.zip" \
|
|
||||||
$VERSION \
|
|
||||||
true \
|
|
||||||
../VSCode-darwin.zip
|
|
||||||
|
|
||||||
# publish hockeyapp symbols
|
|
||||||
node build/azure-pipelines/common/symbols.js "$VSCODE_MIXIN_PASSWORD" "$VSCODE_HOCKEYAPP_TOKEN" "$VSCODE_ARCH" "$VSCODE_HOCKEYAPP_ID_MACOS"
|
|
||||||
|
|
||||||
# upload configuration
|
|
||||||
yarn gulp upload-vscode-configuration
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
trigger:
|
|
||||||
branches:
|
|
||||||
include: ['master', 'release/*']
|
|
||||||
pr:
|
|
||||||
branches:
|
|
||||||
include: ['master', 'release/*']
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- task: NodeTool@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: "10.15.1"
|
|
||||||
|
|
||||||
- script: |
|
|
||||||
set -e
|
|
||||||
|
|
||||||
cat << EOF > ~/.netrc
|
|
||||||
machine github.com
|
|
||||||
login vscode
|
|
||||||
password $(VSCODE_MIXIN_PASSWORD)
|
|
||||||
EOF
|
|
||||||
|
|
||||||
git config user.email "vscode@microsoft.com"
|
|
||||||
git config user.name "VSCode"
|
|
||||||
|
|
||||||
git remote add distro "https://github.com/$VSCODE_MIXIN_REPO.git"
|
|
||||||
git fetch distro
|
|
||||||
git push distro origin/master:refs/heads/master
|
|
||||||
git merge $(node -p "require('./package.json').distro")
|
|
||||||
|
|
||||||
displayName: Sync & Merge Distro
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
yarn gulp "vscode-linux-$VSCODE_ARCH-min"
|
|
||||||
@@ -22,45 +22,90 @@ steps:
|
|||||||
password $(VSCODE_MIXIN_PASSWORD)
|
password $(VSCODE_MIXIN_PASSWORD)
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git config user.email "vscode@microsoft.com"
|
|
||||||
git config user.name "VSCode"
|
|
||||||
git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git"
|
|
||||||
git fetch distro
|
|
||||||
git merge $(node -p "require('./package.json').distro")
|
|
||||||
|
|
||||||
CHILD_CONCURRENCY=1 yarn
|
CHILD_CONCURRENCY=1 yarn
|
||||||
yarn gulp mixin
|
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" npm run gulp -- mixin
|
||||||
yarn gulp hygiene
|
npm run gulp -- hygiene
|
||||||
yarn monaco-compile-check
|
npm run monaco-compile-check
|
||||||
node build/azure-pipelines/common/installDistro.js
|
node build/azure-pipelines/common/installDistro.js
|
||||||
node build/lib/builtInExtensions.js
|
node build/lib/builtInExtensions.js
|
||||||
displayName: Prepare build
|
|
||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
set -e
|
set -e
|
||||||
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \
|
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" npm run gulp -- vscode-linux-$(VSCODE_ARCH)-min
|
||||||
./build/azure-pipelines/linux/build.sh
|
name: build
|
||||||
displayName: Build
|
|
||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
set -e
|
set -e
|
||||||
yarn gulp "electron-$(VSCODE_ARCH)"
|
npm run gulp -- "electron-$(VSCODE_ARCH)"
|
||||||
|
|
||||||
# xvfb seems to be crashing often, let's make sure it's always up
|
# xvfb seems to be crashing often, let's make sure it's always up
|
||||||
service xvfb start
|
service xvfb start
|
||||||
|
|
||||||
DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests"
|
DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests"
|
||||||
# yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)"
|
# yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)"
|
||||||
displayName: Run unit tests
|
name: test
|
||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
set -e
|
set -e
|
||||||
|
REPO="$(pwd)"
|
||||||
|
ROOT="$REPO/.."
|
||||||
|
ARCH="$(VSCODE_ARCH)"
|
||||||
|
|
||||||
|
# Publish tarball
|
||||||
|
PLATFORM_LINUX="linux-$(VSCODE_ARCH)"
|
||||||
|
[[ "$ARCH" == "ia32" ]] && DEB_ARCH="i386" || DEB_ARCH="amd64"
|
||||||
|
[[ "$ARCH" == "ia32" ]] && RPM_ARCH="i386" || RPM_ARCH="x86_64"
|
||||||
|
BUILDNAME="VSCode-$PLATFORM_LINUX"
|
||||||
|
BUILD="$ROOT/$BUILDNAME"
|
||||||
|
BUILD_VERSION="$(date +%s)"
|
||||||
|
[ -z "$VSCODE_QUALITY" ] && TARBALL_FILENAME="code-$BUILD_VERSION.tar.gz" || TARBALL_FILENAME="code-$VSCODE_QUALITY-$BUILD_VERSION.tar.gz"
|
||||||
|
TARBALL_PATH="$ROOT/$TARBALL_FILENAME"
|
||||||
|
PACKAGEJSON="$BUILD/resources/app/package.json"
|
||||||
|
VERSION=$(node -p "require(\"$PACKAGEJSON\").version")
|
||||||
|
|
||||||
|
rm -rf $ROOT/code-*.tar.*
|
||||||
|
(cd $ROOT && tar -czf $TARBALL_PATH $BUILDNAME)
|
||||||
|
|
||||||
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
|
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
|
||||||
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
|
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
|
||||||
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \
|
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
|
||||||
VSCODE_HOCKEYAPP_TOKEN="$(VSCODE_HOCKEYAPP_TOKEN)" \
|
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_LINUX" archive-unsigned "$TARBALL_FILENAME" "$VERSION" true "$TARBALL_PATH"
|
||||||
./build/azure-pipelines/linux/publish.sh
|
|
||||||
displayName: Publish
|
# Publish hockeyapp symbols
|
||||||
|
node build/azure-pipelines/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" "$(VSCODE_HOCKEYAPP_ID_LINUX64)"
|
||||||
|
|
||||||
|
# Publish DEB
|
||||||
|
npm run gulp -- "vscode-linux-$(VSCODE_ARCH)-build-deb"
|
||||||
|
PLATFORM_DEB="linux-deb-$ARCH"
|
||||||
|
[[ "$ARCH" == "ia32" ]] && DEB_ARCH="i386" || DEB_ARCH="amd64"
|
||||||
|
DEB_FILENAME="$(ls $REPO/.build/linux/deb/$DEB_ARCH/deb/)"
|
||||||
|
DEB_PATH="$REPO/.build/linux/deb/$DEB_ARCH/deb/$DEB_FILENAME"
|
||||||
|
|
||||||
|
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
|
||||||
|
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
|
||||||
|
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
|
||||||
|
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_DEB" package "$DEB_FILENAME" "$VERSION" true "$DEB_PATH"
|
||||||
|
|
||||||
|
# Publish RPM
|
||||||
|
npm run gulp -- "vscode-linux-$(VSCODE_ARCH)-build-rpm"
|
||||||
|
PLATFORM_RPM="linux-rpm-$ARCH"
|
||||||
|
[[ "$ARCH" == "ia32" ]] && RPM_ARCH="i386" || RPM_ARCH="x86_64"
|
||||||
|
RPM_FILENAME="$(ls $REPO/.build/linux/rpm/$RPM_ARCH/ | grep .rpm)"
|
||||||
|
RPM_PATH="$REPO/.build/linux/rpm/$RPM_ARCH/$RPM_FILENAME"
|
||||||
|
|
||||||
|
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
|
||||||
|
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
|
||||||
|
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
|
||||||
|
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_RPM" package "$RPM_FILENAME" "$VERSION" true "$RPM_PATH"
|
||||||
|
|
||||||
|
# Publish Snap
|
||||||
|
npm run gulp -- "vscode-linux-$(VSCODE_ARCH)-prepare-snap"
|
||||||
|
|
||||||
|
# Pack snap tarball artifact, in order to preserve file perms
|
||||||
|
mkdir -p $REPO/.build/linux/snap-tarball
|
||||||
|
SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-$(VSCODE_ARCH).tar.gz"
|
||||||
|
rm -rf $SNAP_TARBALL_PATH
|
||||||
|
(cd .build/linux && tar -czf $SNAP_TARBALL_PATH snap)
|
||||||
|
|
||||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||||
displayName: 'Component Detection'
|
displayName: 'Component Detection'
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
REPO="$(pwd)"
|
|
||||||
ROOT="$REPO/.."
|
|
||||||
|
|
||||||
# Publish tarball
|
|
||||||
PLATFORM_LINUX="linux-$VSCODE_ARCH"
|
|
||||||
[[ "$VSCODE_ARCH" == "ia32" ]] && DEB_ARCH="i386" || DEB_ARCH="amd64"
|
|
||||||
[[ "$VSCODE_ARCH" == "ia32" ]] && RPM_ARCH="i386" || RPM_ARCH="x86_64"
|
|
||||||
BUILDNAME="VSCode-$PLATFORM_LINUX"
|
|
||||||
BUILD="$ROOT/$BUILDNAME"
|
|
||||||
BUILD_VERSION="$(date +%s)"
|
|
||||||
[ -z "$VSCODE_QUALITY" ] && TARBALL_FILENAME="code-$BUILD_VERSION.tar.gz" || TARBALL_FILENAME="code-$VSCODE_QUALITY-$BUILD_VERSION.tar.gz"
|
|
||||||
TARBALL_PATH="$ROOT/$TARBALL_FILENAME"
|
|
||||||
PACKAGEJSON="$BUILD/resources/app/package.json"
|
|
||||||
VERSION=$(node -p "require(\"$PACKAGEJSON\").version")
|
|
||||||
|
|
||||||
rm -rf $ROOT/code-*.tar.*
|
|
||||||
(cd $ROOT && tar -czf $TARBALL_PATH $BUILDNAME)
|
|
||||||
|
|
||||||
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_LINUX" archive-unsigned "$TARBALL_FILENAME" "$VERSION" true "$TARBALL_PATH"
|
|
||||||
|
|
||||||
# Publish hockeyapp symbols
|
|
||||||
node build/azure-pipelines/common/symbols.js "$VSCODE_MIXIN_PASSWORD" "$VSCODE_HOCKEYAPP_TOKEN" "$VSCODE_ARCH" "$VSCODE_HOCKEYAPP_ID_LINUX64"
|
|
||||||
|
|
||||||
# Publish DEB
|
|
||||||
yarn gulp "vscode-linux-$VSCODE_ARCH-build-deb"
|
|
||||||
PLATFORM_DEB="linux-deb-$VSCODE_ARCH"
|
|
||||||
[[ "$VSCODE_ARCH" == "ia32" ]] && DEB_ARCH="i386" || DEB_ARCH="amd64"
|
|
||||||
DEB_FILENAME="$(ls $REPO/.build/linux/deb/$DEB_ARCH/deb/)"
|
|
||||||
DEB_PATH="$REPO/.build/linux/deb/$DEB_ARCH/deb/$DEB_FILENAME"
|
|
||||||
|
|
||||||
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_DEB" package "$DEB_FILENAME" "$VERSION" true "$DEB_PATH"
|
|
||||||
|
|
||||||
# Publish RPM
|
|
||||||
yarn gulp "vscode-linux-$VSCODE_ARCH-build-rpm"
|
|
||||||
PLATFORM_RPM="linux-rpm-$VSCODE_ARCH"
|
|
||||||
[[ "$VSCODE_ARCH" == "ia32" ]] && RPM_ARCH="i386" || RPM_ARCH="x86_64"
|
|
||||||
RPM_FILENAME="$(ls $REPO/.build/linux/rpm/$RPM_ARCH/ | grep .rpm)"
|
|
||||||
RPM_PATH="$REPO/.build/linux/rpm/$RPM_ARCH/$RPM_FILENAME"
|
|
||||||
|
|
||||||
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_RPM" package "$RPM_FILENAME" "$VERSION" true "$RPM_PATH"
|
|
||||||
|
|
||||||
# Publish Snap
|
|
||||||
yarn gulp "vscode-linux-$VSCODE_ARCH-prepare-snap"
|
|
||||||
|
|
||||||
# Pack snap tarball artifact, in order to preserve file perms
|
|
||||||
mkdir -p $REPO/.build/linux/snap-tarball
|
|
||||||
SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-$VSCODE_ARCH.tar.gz"
|
|
||||||
rm -rf $SNAP_TARBALL_PATH
|
|
||||||
(cd .build/linux && tar -czf $SNAP_TARBALL_PATH snap)
|
|
||||||
@@ -46,4 +46,5 @@ steps:
|
|||||||
# Publish snap package
|
# Publish snap package
|
||||||
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
|
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
|
||||||
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
|
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
|
||||||
|
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
|
||||||
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "linux-snap-$ARCH" package "$SNAP_FILENAME" "$VERSION" true "$SNAP_PATH"
|
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "linux-snap-$ARCH" package "$SNAP_FILENAME" "$VERSION" true "$SNAP_PATH"
|
||||||
@@ -62,18 +62,4 @@ jobs:
|
|||||||
pool:
|
pool:
|
||||||
vmImage: macOS 10.13
|
vmImage: macOS 10.13
|
||||||
steps:
|
steps:
|
||||||
- template: darwin/product-build-darwin.yml
|
- template: darwin/product-build-darwin.yml
|
||||||
|
|
||||||
- job: Mooncake
|
|
||||||
pool:
|
|
||||||
vmImage: 'Ubuntu-16.04'
|
|
||||||
condition: true
|
|
||||||
dependsOn:
|
|
||||||
- Windows
|
|
||||||
- Windows32
|
|
||||||
- Linux
|
|
||||||
- LinuxSnap
|
|
||||||
- Linux32
|
|
||||||
- macOS
|
|
||||||
steps:
|
|
||||||
- template: sync-mooncake.yml
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
steps:
|
|
||||||
- task: NodeTool@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: "10.15.1"
|
|
||||||
|
|
||||||
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
|
|
||||||
inputs:
|
|
||||||
versionSpec: "1.10.1"
|
|
||||||
|
|
||||||
- script: |
|
|
||||||
set -e
|
|
||||||
|
|
||||||
(cd build ; yarn)
|
|
||||||
|
|
||||||
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
|
|
||||||
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
|
|
||||||
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
|
|
||||||
node build/azure-pipelines/common/sync-mooncake.js "$VSCODE_QUALITY"
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
. build/azure-pipelines/win32/exec.ps1
|
|
||||||
$ErrorActionPreference = "Stop"
|
|
||||||
exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-min" }
|
|
||||||
exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-inno-updater" }
|
|
||||||
@@ -18,47 +18,34 @@ steps:
|
|||||||
"machine monacotools.visualstudio.com`npassword $(VSO_PAT)`nmachine github.com`nlogin vscode`npassword $(VSCODE_MIXIN_PASSWORD)" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII
|
"machine monacotools.visualstudio.com`npassword $(VSO_PAT)`nmachine github.com`nlogin vscode`npassword $(VSCODE_MIXIN_PASSWORD)" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII
|
||||||
$env:npm_config_arch="$(VSCODE_ARCH)"
|
$env:npm_config_arch="$(VSCODE_ARCH)"
|
||||||
$env:CHILD_CONCURRENCY="1"
|
$env:CHILD_CONCURRENCY="1"
|
||||||
|
$env:VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)"
|
||||||
exec { git config user.email "vscode@microsoft.com" }
|
|
||||||
exec { git config user.name "VSCode" }
|
|
||||||
exec { git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" }
|
|
||||||
exec { git fetch distro }
|
|
||||||
exec { git merge $(node -p "require('./package.json').distro") }
|
|
||||||
|
|
||||||
exec { yarn }
|
exec { yarn }
|
||||||
exec { yarn gulp mixin }
|
exec { npm run gulp -- mixin }
|
||||||
exec { yarn gulp hygiene }
|
exec { npm run gulp -- hygiene }
|
||||||
exec { yarn monaco-compile-check }
|
exec { npm run monaco-compile-check }
|
||||||
exec { node build/azure-pipelines/common/installDistro.js }
|
exec { node build/azure-pipelines/common/installDistro.js }
|
||||||
exec { node build/lib/builtInExtensions.js }
|
exec { node build/lib/builtInExtensions.js }
|
||||||
displayName: Prepare build
|
|
||||||
|
|
||||||
- powershell: |
|
- powershell: |
|
||||||
. build/azure-pipelines/win32/exec.ps1
|
. build/azure-pipelines/win32/exec.ps1
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
$env:VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)"
|
$env:VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)"
|
||||||
.\build\azure-pipelines\win32\build.ps1
|
exec { npm run gulp -- "vscode-win32-$(VSCODE_ARCH)-min" }
|
||||||
displayName: Build
|
exec { npm run gulp -- "vscode-win32-$(VSCODE_ARCH)-inno-updater" }
|
||||||
|
name: build
|
||||||
|
|
||||||
- powershell: |
|
- powershell: |
|
||||||
. build/azure-pipelines/win32/exec.ps1
|
. build/azure-pipelines/win32/exec.ps1
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
exec { yarn gulp "electron-$(VSCODE_ARCH)" }
|
exec { npm run gulp -- "electron-$(VSCODE_ARCH)" }
|
||||||
exec { .\scripts\test.bat --build --tfs "Unit Tests" }
|
exec { .\scripts\test.bat --build --tfs "Unit Tests" }
|
||||||
# yarn smoketest -- --build "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)"
|
# yarn smoketest -- --build "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)"
|
||||||
displayName: Run unit tests
|
name: test
|
||||||
|
|
||||||
- powershell: |
|
|
||||||
. build/azure-pipelines/win32/exec.ps1
|
|
||||||
$ErrorActionPreference = "Stop"
|
|
||||||
exec { yarn gulp "electron-$(VSCODE_ARCH)" }
|
|
||||||
exec { .\scripts\test-integration.bat --build --tfs "Integration Tests" }
|
|
||||||
displayName: Run integration tests
|
|
||||||
|
|
||||||
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
|
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
|
||||||
inputs:
|
inputs:
|
||||||
ConnectedServiceName: 'ESRP CodeSign'
|
ConnectedServiceName: 'ESRP CodeSign'
|
||||||
FolderPath: '$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH),$(agent.builddirectory)/vscode-reh-win32-$(VSCODE_ARCH)'
|
FolderPath: '$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)'
|
||||||
Pattern: '*.dll,*.exe,*.node'
|
Pattern: '*.dll,*.exe,*.node'
|
||||||
signConfigType: inlineSignParams
|
signConfigType: inlineSignParams
|
||||||
inlineOperation: |
|
inlineOperation: |
|
||||||
@@ -132,11 +119,32 @@ steps:
|
|||||||
- powershell: |
|
- powershell: |
|
||||||
. build/azure-pipelines/win32/exec.ps1
|
. build/azure-pipelines/win32/exec.ps1
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
exec { npm run gulp -- "vscode-win32-$(VSCODE_ARCH)-archive" "vscode-win32-$(VSCODE_ARCH)-system-setup" "vscode-win32-$(VSCODE_ARCH)-user-setup" --sign }
|
||||||
|
|
||||||
|
$Repo = "$(pwd)"
|
||||||
|
$Root = "$Repo\.."
|
||||||
|
$SystemExe = "$Repo\.build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup.exe"
|
||||||
|
$UserExe = "$Repo\.build\win32-$(VSCODE_ARCH)\user-setup\VSCodeSetup.exe"
|
||||||
|
$Zip = "$Repo\.build\win32-$(VSCODE_ARCH)\archive\VSCode-win32-$(VSCODE_ARCH).zip"
|
||||||
|
$Build = "$Root\VSCode-win32-$(VSCODE_ARCH)"
|
||||||
|
|
||||||
|
# get version
|
||||||
|
$PackageJson = Get-Content -Raw -Path "$Build\resources\app\package.json" | ConvertFrom-Json
|
||||||
|
$Version = $PackageJson.version
|
||||||
|
$Quality = "$env:VSCODE_QUALITY"
|
||||||
$env:AZURE_STORAGE_ACCESS_KEY_2 = "$(AZURE_STORAGE_ACCESS_KEY_2)"
|
$env:AZURE_STORAGE_ACCESS_KEY_2 = "$(AZURE_STORAGE_ACCESS_KEY_2)"
|
||||||
|
$env:MOONCAKE_STORAGE_ACCESS_KEY = "$(MOONCAKE_STORAGE_ACCESS_KEY)"
|
||||||
$env:AZURE_DOCUMENTDB_MASTERKEY = "$(AZURE_DOCUMENTDB_MASTERKEY)"
|
$env:AZURE_DOCUMENTDB_MASTERKEY = "$(AZURE_DOCUMENTDB_MASTERKEY)"
|
||||||
$env:VSCODE_HOCKEYAPP_TOKEN = "$(VSCODE_HOCKEYAPP_TOKEN)"
|
|
||||||
.\build\azure-pipelines\win32\publish.ps1
|
$assetPlatform = if ("$(VSCODE_ARCH)" -eq "ia32") { "win32" } else { "win32-x64" }
|
||||||
displayName: Publish
|
|
||||||
|
exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform-archive" archive "VSCode-win32-$(VSCODE_ARCH)-$Version.zip" $Version true $Zip }
|
||||||
|
exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform" setup "VSCodeSetup-$(VSCODE_ARCH)-$Version.exe" $Version true $SystemExe }
|
||||||
|
exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform-user" setup "VSCodeUserSetup-$(VSCODE_ARCH)-$Version.exe" $Version true $UserExe }
|
||||||
|
|
||||||
|
# publish hockeyapp symbols
|
||||||
|
$hockeyAppId = if ("$(VSCODE_ARCH)" -eq "ia32") { "$(VSCODE_HOCKEYAPP_ID_WIN32)" } else { "$(VSCODE_HOCKEYAPP_ID_WIN64)" }
|
||||||
|
exec { node build/azure-pipelines/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" $hockeyAppId }
|
||||||
|
|
||||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||||
displayName: 'Component Detection'
|
displayName: 'Component Detection'
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
. build/azure-pipelines/win32/exec.ps1
|
|
||||||
$ErrorActionPreference = "Stop"
|
|
||||||
|
|
||||||
$Arch = "$env:VSCODE_ARCH"
|
|
||||||
|
|
||||||
exec { yarn gulp "vscode-win32-$Arch-archive" "vscode-win32-$Arch-system-setup" "vscode-win32-$Arch-user-setup" --sign }
|
|
||||||
|
|
||||||
$Repo = "$(pwd)"
|
|
||||||
$Root = "$Repo\.."
|
|
||||||
$SystemExe = "$Repo\.build\win32-$Arch\system-setup\VSCodeSetup.exe"
|
|
||||||
$UserExe = "$Repo\.build\win32-$Arch\user-setup\VSCodeSetup.exe"
|
|
||||||
$Zip = "$Repo\.build\win32-$Arch\archive\VSCode-win32-$Arch.zip"
|
|
||||||
$Build = "$Root\VSCode-win32-$Arch"
|
|
||||||
|
|
||||||
# get version
|
|
||||||
$PackageJson = Get-Content -Raw -Path "$Build\resources\app\package.json" | ConvertFrom-Json
|
|
||||||
$Version = $PackageJson.version
|
|
||||||
$Quality = "$env:VSCODE_QUALITY"
|
|
||||||
|
|
||||||
$AssetPlatform = if ("$Arch" -eq "ia32") { "win32" } else { "win32-x64" }
|
|
||||||
|
|
||||||
exec { node build/azure-pipelines/common/publish.js $Quality "$AssetPlatform-archive" archive "VSCode-win32-$Arch-$Version.zip" $Version true $Zip }
|
|
||||||
exec { node build/azure-pipelines/common/publish.js $Quality "$AssetPlatform" setup "VSCodeSetup-$Arch-$Version.exe" $Version true $SystemExe }
|
|
||||||
exec { node build/azure-pipelines/common/publish.js $Quality "$AssetPlatform-user" setup "VSCodeUserSetup-$Arch-$Version.exe" $Version true $UserExe }
|
|
||||||
|
|
||||||
# publish hockeyapp symbols
|
|
||||||
$hockeyAppId = if ("$Arch" -eq "ia32") { "$env:VSCODE_HOCKEYAPP_ID_WIN32" } else { "$env:VSCODE_HOCKEYAPP_ID_WIN64" }
|
|
||||||
exec { node build/azure-pipelines/common/symbols.js "$env:VSCODE_MIXIN_PASSWORD" "$env:VSCODE_HOCKEYAPP_TOKEN" "$Arch" $hockeyAppId }
|
|
||||||
@@ -87,16 +87,9 @@ const indentationFilter = [
|
|||||||
'!build/azure-pipelines/**/*.js',
|
'!build/azure-pipelines/**/*.js',
|
||||||
'!build/azure-pipelines/**/*.config',
|
'!build/azure-pipelines/**/*.config',
|
||||||
'!**/Dockerfile',
|
'!**/Dockerfile',
|
||||||
'!**/Dockerfile.*',
|
|
||||||
'!**/*.Dockerfile',
|
'!**/*.Dockerfile',
|
||||||
'!**/*.dockerfile',
|
'!**/*.dockerfile',
|
||||||
'!extensions/markdown-language-features/media/*.js',
|
'!extensions/markdown-language-features/media/*.js'
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
'!**/*.xlf',
|
|
||||||
'!**/*.docx',
|
|
||||||
'!**/*.sql',
|
|
||||||
'!extensions/mssql/sqltoolsservice/**',
|
|
||||||
'!extensions/import/flatfileimportservice/**',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const copyrightFilter = [
|
const copyrightFilter = [
|
||||||
@@ -125,37 +118,7 @@ const copyrightFilter = [
|
|||||||
'!resources/completions/**',
|
'!resources/completions/**',
|
||||||
'!extensions/markdown-language-features/media/highlight.css',
|
'!extensions/markdown-language-features/media/highlight.css',
|
||||||
'!extensions/html-language-features/server/src/modes/typescript/*',
|
'!extensions/html-language-features/server/src/modes/typescript/*',
|
||||||
'!extensions/*/server/bin/*',
|
'!extensions/*/server/bin/*'
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
'!extensions/notebook/src/intellisense/text.ts',
|
|
||||||
'!extensions/mssql/src/objectExplorerNodeProvider/webhdfs.ts',
|
|
||||||
'!src/sql/workbench/parts/notebook/outputs/tableRenderers.ts',
|
|
||||||
'!src/sql/workbench/parts/notebook/outputs/common/url.ts',
|
|
||||||
'!src/sql/workbench/parts/notebook/outputs/common/renderMimeInterfaces.ts',
|
|
||||||
'!src/sql/workbench/parts/notebook/outputs/common/outputProcessor.ts',
|
|
||||||
'!src/sql/workbench/parts/notebook/outputs/common/mimemodel.ts',
|
|
||||||
'!src/sql/workbench/parts/notebook/cellViews/media/*.css',
|
|
||||||
'!src/sql/base/browser/ui/table/plugins/rowSelectionModel.plugin.ts',
|
|
||||||
'!src/sql/base/browser/ui/table/plugins/rowDetailView.ts',
|
|
||||||
'!src/sql/base/browser/ui/table/plugins/headerFilter.plugin.ts',
|
|
||||||
'!src/sql/base/browser/ui/table/plugins/checkboxSelectColumn.plugin.ts',
|
|
||||||
'!src/sql/base/browser/ui/table/plugins/cellSelectionModel.plugin.ts',
|
|
||||||
'!src/sql/base/browser/ui/table/plugins/autoSizeColumns.plugin.ts',
|
|
||||||
'!src/sql/workbench/parts/notebook/outputs/sanitizer.ts',
|
|
||||||
'!src/sql/workbench/parts/notebook/outputs/renderers.ts',
|
|
||||||
'!src/sql/workbench/parts/notebook/outputs/registry.ts',
|
|
||||||
'!src/sql/workbench/parts/notebook/outputs/factories.ts',
|
|
||||||
'!src/sql/workbench/parts/notebook/models/nbformat.ts',
|
|
||||||
'!extensions/markdown-language-features/media/tomorrow.css',
|
|
||||||
'!src/sql/workbench/electron-browser/modelComponents/media/highlight.css',
|
|
||||||
'!src/sql/parts/modelComponents/highlight.css',
|
|
||||||
'!extensions/mssql/sqltoolsservice/**',
|
|
||||||
'!extensions/import/flatfileimportservice/**',
|
|
||||||
'!extensions/notebook/src/prompts/**',
|
|
||||||
'!extensions/mssql/src/prompts/**',
|
|
||||||
'!extensions/notebook/resources/jupyter_config/**',
|
|
||||||
'!**/*.gif',
|
|
||||||
'!**/*.xlf'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const eslintFilter = [
|
const eslintFilter = [
|
||||||
@@ -201,7 +164,8 @@ gulp.task('eslint', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('tslint', () => {
|
gulp.task('tslint', () => {
|
||||||
const options = { emitError: true };
|
// {{SQL CARBON EDIT}}
|
||||||
|
const options = { emitError: false };
|
||||||
|
|
||||||
return vfs.src(all, { base: '.', follow: true, allowEmpty: true })
|
return vfs.src(all, { base: '.', follow: true, allowEmpty: true })
|
||||||
.pipe(filter(tslintFilter))
|
.pipe(filter(tslintFilter))
|
||||||
@@ -299,8 +263,9 @@ function hygiene(some) {
|
|||||||
.pipe(filter(f => !f.stat.isDirectory()))
|
.pipe(filter(f => !f.stat.isDirectory()))
|
||||||
.pipe(filter(indentationFilter))
|
.pipe(filter(indentationFilter))
|
||||||
.pipe(indentation)
|
.pipe(indentation)
|
||||||
.pipe(filter(copyrightFilter))
|
.pipe(filter(copyrightFilter));
|
||||||
.pipe(copyrights);
|
// {{SQL CARBON EDIT}}
|
||||||
|
// .pipe(copyrights);
|
||||||
|
|
||||||
const typescript = result
|
const typescript = result
|
||||||
.pipe(filter(tslintFilter))
|
.pipe(filter(tslintFilter))
|
||||||
@@ -310,38 +275,15 @@ function hygiene(some) {
|
|||||||
const javascript = result
|
const javascript = result
|
||||||
.pipe(filter(eslintFilter))
|
.pipe(filter(eslintFilter))
|
||||||
.pipe(gulpeslint('src/.eslintrc'))
|
.pipe(gulpeslint('src/.eslintrc'))
|
||||||
.pipe(gulpeslint.formatEach('compact'))
|
.pipe(gulpeslint.formatEach('compact'));
|
||||||
.pipe(gulpeslint.failAfterError());
|
// {{SQL CARBON EDIT}}
|
||||||
|
// .pipe(gulpeslint.failAfterError());
|
||||||
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
return es.merge(typescript, javascript)
|
return es.merge(typescript, javascript)
|
||||||
.pipe(es.through(function (data) {
|
.pipe(es.through(function (data) {
|
||||||
count++;
|
// {{SQL CARBON EDIT}}
|
||||||
if (process.env['TRAVIS'] && count % 10 === 0) {
|
this.emit('end');
|
||||||
process.stdout.write('.');
|
|
||||||
}
|
|
||||||
this.emit('data', data);
|
|
||||||
}, function () {
|
|
||||||
process.stdout.write('\n');
|
|
||||||
|
|
||||||
const tslintResult = tsLinter.getResult();
|
|
||||||
if (tslintResult.failures.length > 0) {
|
|
||||||
for (const failure of tslintResult.failures) {
|
|
||||||
const name = failure.getFileName();
|
|
||||||
const position = failure.getStartPosition();
|
|
||||||
const line = position.getLineAndCharacter().line;
|
|
||||||
const character = position.getLineAndCharacter().character;
|
|
||||||
|
|
||||||
console.error(`${name}:${line + 1}:${character + 1}:${failure.getFailure()}`);
|
|
||||||
}
|
|
||||||
errorCount += tslintResult.failures.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorCount > 0) {
|
|
||||||
this.emit('error', 'Hygiene failed with ' + errorCount + ' errors. Check \'build/gulpfile.hygiene.js\'.');
|
|
||||||
} else {
|
|
||||||
this.emit('end');
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,21 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const gulp = require('gulp');
|
const gulp = require('gulp');
|
||||||
|
const json = require('gulp-json-editor');
|
||||||
|
const buffer = require('gulp-buffer');
|
||||||
|
const filter = require('gulp-filter');
|
||||||
|
const es = require('event-stream');
|
||||||
|
const vfs = require('vinyl-fs');
|
||||||
|
const pkg = require('../package.json');
|
||||||
|
const cp = require('child_process');
|
||||||
|
const fancyLog = require('fancy-log');
|
||||||
|
const ansiColors = require('ansi-colors');
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
const jeditor = require('gulp-json-editor');
|
const jeditor = require('gulp-json-editor');
|
||||||
|
|
||||||
gulp.task('mixin', function () {
|
gulp.task('mixin', function () {
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
const updateUrl = process.env['SQLOPS_UPDATEURL'];
|
const updateUrl = process.env['SQLOPS_UPDATEURL'];
|
||||||
if (!updateUrl) {
|
if (!updateUrl) {
|
||||||
console.log('Missing SQLOPS_UPDATEURL, skipping mixin');
|
console.log('Missing SQLOPS_UPDATEURL, skipping mixin');
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ const formatFiles = (some) => {
|
|||||||
console.info('ran formatting on file ' + file.path + ' result: ' + result.message);
|
console.info('ran formatting on file ' + file.path + ' result: ' + result.message);
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
console.error(result.message);
|
console.error(result.message);
|
||||||
|
errorCount++;
|
||||||
}
|
}
|
||||||
cb(null, file);
|
cb(null, file);
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ const formatFiles = (some) => {
|
|||||||
.pipe(filter(f => !f.stat.isDirectory()))
|
.pipe(filter(f => !f.stat.isDirectory()))
|
||||||
.pipe(formatting);
|
.pipe(formatting);
|
||||||
|
|
||||||
};
|
}
|
||||||
|
|
||||||
const formatStagedFiles = () => {
|
const formatStagedFiles = () => {
|
||||||
const cp = require('child_process');
|
const cp = require('child_process');
|
||||||
@@ -80,4 +81,4 @@ const formatStagedFiles = () => {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
@@ -33,10 +33,12 @@ const i18n = require('./lib/i18n');
|
|||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
const serviceDownloader = require('service-downloader').ServiceDownloadProvider;
|
const serviceDownloader = require('service-downloader').ServiceDownloadProvider;
|
||||||
const platformInfo = require('service-downloader/out/platform').PlatformInformation;
|
const platformInfo = require('service-downloader/out/platform').PlatformInformation;
|
||||||
|
const glob = require('glob');
|
||||||
// {{SQL CARBON EDIT}} - End
|
// {{SQL CARBON EDIT}} - End
|
||||||
const deps = require('./dependencies');
|
const deps = require('./dependencies');
|
||||||
const getElectronVersion = require('./lib/electron').getElectronVersion;
|
const getElectronVersion = require('./lib/electron').getElectronVersion;
|
||||||
const createAsar = require('./lib/asar').createAsar;
|
const createAsar = require('./lib/asar').createAsar;
|
||||||
|
const minimist = require('minimist');
|
||||||
const { compileBuildTask } = require('./gulpfile.compile');
|
const { compileBuildTask } = require('./gulpfile.compile');
|
||||||
|
|
||||||
const productionDependencies = deps.getProductionDependencies(path.dirname(__dirname));
|
const productionDependencies = deps.getProductionDependencies(path.dirname(__dirname));
|
||||||
@@ -52,7 +54,7 @@ const nodeModules = [
|
|||||||
'rxjs/Observable',
|
'rxjs/Observable',
|
||||||
'rxjs/Subject',
|
'rxjs/Subject',
|
||||||
'rxjs/Observer',
|
'rxjs/Observer',
|
||||||
'ng2-charts']
|
'ng2-charts/ng2-charts']
|
||||||
.concat(Object.keys(product.dependencies || {}))
|
.concat(Object.keys(product.dependencies || {}))
|
||||||
.concat(_.uniq(productionDependencies.map(d => d.name)))
|
.concat(_.uniq(productionDependencies.map(d => d.name)))
|
||||||
.concat(baseModules);
|
.concat(baseModules);
|
||||||
@@ -75,16 +77,14 @@ const vscodeResources = [
|
|||||||
'out-build/bootstrap-window.js',
|
'out-build/bootstrap-window.js',
|
||||||
'out-build/paths.js',
|
'out-build/paths.js',
|
||||||
'out-build/vs/**/*.{svg,png,cur,html}',
|
'out-build/vs/**/*.{svg,png,cur,html}',
|
||||||
'!out-build/vs/code/browser/**/*.html',
|
|
||||||
'out-build/vs/base/common/performance.js',
|
'out-build/vs/base/common/performance.js',
|
||||||
'out-build/vs/base/node/languagePacks.js',
|
'out-build/vs/base/node/languagePacks.js',
|
||||||
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh,ps.sh}',
|
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh}',
|
||||||
'out-build/vs/base/browser/ui/octiconLabel/octicons/**',
|
'out-build/vs/base/browser/ui/octiconLabel/octicons/**',
|
||||||
'out-build/vs/workbench/browser/media/*-theme.css',
|
'out-build/vs/workbench/browser/media/*-theme.css',
|
||||||
'out-build/vs/workbench/contrib/debug/**/*.json',
|
'out-build/vs/workbench/contrib/debug/**/*.json',
|
||||||
'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt',
|
'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt',
|
||||||
'out-build/vs/workbench/contrib/webview/browser/pre/*.js',
|
'out-build/vs/workbench/contrib/webview/electron-browser/webview-pre.js',
|
||||||
'out-build/vs/workbench/contrib/webview/electron-browser/pre/*.js',
|
|
||||||
'out-build/vs/**/markdown.css',
|
'out-build/vs/**/markdown.css',
|
||||||
'out-build/vs/workbench/contrib/tasks/**/*.json',
|
'out-build/vs/workbench/contrib/tasks/**/*.json',
|
||||||
'out-build/vs/workbench/contrib/welcome/walkThrough/**/*.md',
|
'out-build/vs/workbench/contrib/welcome/walkThrough/**/*.md',
|
||||||
@@ -102,11 +102,13 @@ const vscodeResources = [
|
|||||||
'out-build/sql/parts/admin/**/*.html',
|
'out-build/sql/parts/admin/**/*.html',
|
||||||
'out-build/sql/parts/connection/connectionDialog/media/*.{gif,png,svg}',
|
'out-build/sql/parts/connection/connectionDialog/media/*.{gif,png,svg}',
|
||||||
'out-build/sql/parts/common/dblist/**/*.html',
|
'out-build/sql/parts/common/dblist/**/*.html',
|
||||||
'out-build/sql/workbench/parts/dashboard/**/*.html',
|
'out-build/sql/parts/dashboard/**/*.html',
|
||||||
'out-build/sql/parts/disasterRecovery/**/*.html',
|
'out-build/sql/parts/disasterRecovery/**/*.html',
|
||||||
'out-build/sql/parts/common/modal/media/**',
|
'out-build/sql/parts/common/modal/media/**',
|
||||||
'out-build/sql/workbench/parts/grid/media/**',
|
'out-build/sql/parts/grid/load/lib/**',
|
||||||
'out-build/sql/workbench/parts/grid/views/**/*.html',
|
'out-build/sql/parts/grid/load/loadJquery.js',
|
||||||
|
'out-build/sql/parts/grid/media/**',
|
||||||
|
'out-build/sql/parts/grid/views/**/*.html',
|
||||||
'out-build/sql/parts/tasks/**/*.html',
|
'out-build/sql/parts/tasks/**/*.html',
|
||||||
'out-build/sql/parts/taskHistory/viewlet/media/**',
|
'out-build/sql/parts/taskHistory/viewlet/media/**',
|
||||||
'out-build/sql/parts/jobManagement/common/media/*.svg',
|
'out-build/sql/parts/jobManagement/common/media/*.svg',
|
||||||
@@ -357,7 +359,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
|
|||||||
.pipe(util.cleanNodeModule('core-js', ['**/**'], undefined))
|
.pipe(util.cleanNodeModule('core-js', ['**/**'], undefined))
|
||||||
.pipe(util.cleanNodeModule('slickgrid', ['node_modules/**', 'examples/**'], undefined))
|
.pipe(util.cleanNodeModule('slickgrid', ['node_modules/**', 'examples/**'], undefined))
|
||||||
.pipe(util.cleanNodeModule('nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['**/*.node', '**/*.a']))
|
.pipe(util.cleanNodeModule('nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['**/*.node', '**/*.a']))
|
||||||
.pipe(util.cleanNodeModule('vscode-nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['build/Release/*.node', '**/*.a']))
|
.pipe(util.cleanNodeModule('vscode-nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['**/*.node', '**/*.a']))
|
||||||
// {{SQL CARBON EDIT}} - End
|
// {{SQL CARBON EDIT}} - End
|
||||||
.pipe(util.cleanNodeModule('vsda', ['binding.gyp', 'README.md', 'build/**', '*.bat', '*.sh', '*.cpp', '*.h'], ['build/Release/vsda.node']))
|
.pipe(util.cleanNodeModule('vsda', ['binding.gyp', 'README.md', 'build/**', '*.bat', '*.sh', '*.cpp', '*.h'], ['build/Release/vsda.node']))
|
||||||
.pipe(util.cleanNodeModule('vscode-windows-ca-certs', ['**/*'], ['package.json', '**/*.node']))
|
.pipe(util.cleanNodeModule('vscode-windows-ca-certs', ['**/*'], ['package.json', '**/*.node']))
|
||||||
@@ -424,18 +426,14 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
|
|||||||
|
|
||||||
result = es.merge(result, gulp.src('resources/win32/bin/code.sh', { base: 'resources/win32' })
|
result = es.merge(result, gulp.src('resources/win32/bin/code.sh', { base: 'resources/win32' })
|
||||||
.pipe(replace('@@NAME@@', product.nameShort))
|
.pipe(replace('@@NAME@@', product.nameShort))
|
||||||
.pipe(replace('@@PRODNAME@@', product.nameLong))
|
|
||||||
.pipe(replace('@@VERSION@@', version))
|
|
||||||
.pipe(replace('@@COMMIT@@', commit))
|
.pipe(replace('@@COMMIT@@', commit))
|
||||||
.pipe(replace('@@APPNAME@@', product.applicationName))
|
.pipe(replace('@@APPNAME@@', product.applicationName))
|
||||||
.pipe(replace('@@QUALITY@@', quality))
|
|
||||||
.pipe(rename(function (f) { f.basename = product.applicationName; f.extname = ''; })));
|
.pipe(rename(function (f) { f.basename = product.applicationName; f.extname = ''; })));
|
||||||
|
|
||||||
result = es.merge(result, gulp.src('resources/win32/VisualElementsManifest.xml', { base: 'resources/win32' })
|
result = es.merge(result, gulp.src('resources/win32/VisualElementsManifest.xml', { base: 'resources/win32' })
|
||||||
.pipe(rename(product.nameShort + '.VisualElementsManifest.xml')));
|
.pipe(rename(product.nameShort + '.VisualElementsManifest.xml')));
|
||||||
} else if (platform === 'linux') {
|
} else if (platform === 'linux') {
|
||||||
result = es.merge(result, gulp.src('resources/linux/bin/code.sh', { base: '.' })
|
result = es.merge(result, gulp.src('resources/linux/bin/code.sh', { base: '.' })
|
||||||
.pipe(replace('@@PRODNAME@@', product.nameLong))
|
|
||||||
.pipe(replace('@@NAME@@', product.applicationName))
|
.pipe(replace('@@NAME@@', product.applicationName))
|
||||||
.pipe(rename('bin/' + product.applicationName)));
|
.pipe(rename('bin/' + product.applicationName)));
|
||||||
}
|
}
|
||||||
@@ -479,6 +477,8 @@ BUILD_TARGETS.forEach(buildTarget => {
|
|||||||
minified ? minifyVSCodeTask : optimizeVSCodeTask,
|
minified ? minifyVSCodeTask : optimizeVSCodeTask,
|
||||||
util.rimraf(path.join(buildRoot, destinationFolderName))
|
util.rimraf(path.join(buildRoot, destinationFolderName))
|
||||||
),
|
),
|
||||||
|
ext.packageExtensionTask('mssql', platform, arch),
|
||||||
|
ext.packageExtensionTask('azurecore', platform, arch),
|
||||||
packageTask(platform, arch, sourceFolderName, destinationFolderName, opts)
|
packageTask(platform, arch, sourceFolderName, destinationFolderName, opts)
|
||||||
));
|
));
|
||||||
gulp.task(vscodeTask);
|
gulp.task(vscodeTask);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ function getDebPackageArch(arch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function prepareDebPackage(arch) {
|
function prepareDebPackage(arch) {
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
const binaryDir = '../azuredatastudio-linux-' + arch;
|
const binaryDir = '../azuredatastudio-linux-' + arch;
|
||||||
const debArch = getDebPackageArch(arch);
|
const debArch = getDebPackageArch(arch);
|
||||||
const destination = '.build/linux/deb/' + debArch + '/' + product.applicationName + '-' + debArch;
|
const destination = '.build/linux/deb/' + debArch + '/' + product.applicationName + '-' + debArch;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const zipPath = arch => path.join(zipDir(arch), `VSCode-win32-${arch}.zip`);
|
|||||||
const setupDir = (arch, target) => path.join(repoPath, '.build', `win32-${arch}`, `${target}-setup`);
|
const setupDir = (arch, target) => path.join(repoPath, '.build', `win32-${arch}`, `${target}-setup`);
|
||||||
const issPath = path.join(__dirname, 'win32', 'code.iss');
|
const issPath = path.join(__dirname, 'win32', 'code.iss');
|
||||||
const innoSetupPath = path.join(path.dirname(path.dirname(require.resolve('innosetup-compiler'))), 'bin', 'ISCC.exe');
|
const innoSetupPath = path.join(path.dirname(path.dirname(require.resolve('innosetup-compiler'))), 'bin', 'ISCC.exe');
|
||||||
// const signPS1 = path.join(repoPath, 'build', 'azure-pipelines', 'win32', 'sign.ps1');
|
const signPS1 = path.join(repoPath, 'build', 'azure-pipelines', 'win32', 'sign.ps1');
|
||||||
|
|
||||||
function packageInnoSetup(iss, options, cb) {
|
function packageInnoSetup(iss, options, cb) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|||||||
@@ -237,7 +237,6 @@ exports.fromMarketplace = fromMarketplace;
|
|||||||
const excludedExtensions = [
|
const excludedExtensions = [
|
||||||
'vscode-api-tests',
|
'vscode-api-tests',
|
||||||
'vscode-colorize-tests',
|
'vscode-colorize-tests',
|
||||||
'vscode-test-resolver',
|
|
||||||
'ms-vscode.node-debug',
|
'ms-vscode.node-debug',
|
||||||
'ms-vscode.node-debug2',
|
'ms-vscode.node-debug2',
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
@@ -253,10 +252,9 @@ const sqlBuiltInExtensions = [
|
|||||||
'profiler',
|
'profiler',
|
||||||
'admin-pack',
|
'admin-pack',
|
||||||
'big-data-cluster',
|
'big-data-cluster',
|
||||||
'dacpac',
|
'dacpac'
|
||||||
'schema-compare',
|
|
||||||
'cms'
|
|
||||||
];
|
];
|
||||||
|
var azureExtensions = ['azurecore', 'mssql'];
|
||||||
const builtInExtensions = require('../builtInExtensions.json');
|
const builtInExtensions = require('../builtInExtensions.json');
|
||||||
/**
|
/**
|
||||||
* We're doing way too much stuff at once, with webpack et al. So much stuff
|
* We're doing way too much stuff at once, with webpack et al. So much stuff
|
||||||
@@ -292,7 +290,8 @@ function packageExtensionsStream(optsIn) {
|
|||||||
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
|
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
|
||||||
.filter(({ name }) => builtInExtensions.every(b => b.name !== name))
|
.filter(({ name }) => builtInExtensions.every(b => b.name !== name))
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
.filter(({ name }) => sqlBuiltInExtensions.indexOf(name) === -1);
|
.filter(({ name }) => sqlBuiltInExtensions.indexOf(name) === -1)
|
||||||
|
.filter(({ name }) => azureExtensions.indexOf(name) === -1);
|
||||||
const localExtensions = () => sequence([...localExtensionDescriptions.map(extension => () => {
|
const localExtensions = () => sequence([...localExtensionDescriptions.map(extension => () => {
|
||||||
return fromLocal(extension.path, opts.sourceMappingURLBase)
|
return fromLocal(extension.path, opts.sourceMappingURLBase)
|
||||||
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
|
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
|
||||||
|
|||||||
@@ -283,7 +283,6 @@ interface IPackageExtensionsOptions {
|
|||||||
const excludedExtensions = [
|
const excludedExtensions = [
|
||||||
'vscode-api-tests',
|
'vscode-api-tests',
|
||||||
'vscode-colorize-tests',
|
'vscode-colorize-tests',
|
||||||
'vscode-test-resolver',
|
|
||||||
'ms-vscode.node-debug',
|
'ms-vscode.node-debug',
|
||||||
'ms-vscode.node-debug2',
|
'ms-vscode.node-debug2',
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
@@ -300,10 +299,9 @@ const sqlBuiltInExtensions = [
|
|||||||
'profiler',
|
'profiler',
|
||||||
'admin-pack',
|
'admin-pack',
|
||||||
'big-data-cluster',
|
'big-data-cluster',
|
||||||
'dacpac',
|
'dacpac'
|
||||||
'schema-compare',
|
|
||||||
'cms'
|
|
||||||
];
|
];
|
||||||
|
var azureExtensions = ['azurecore', 'mssql'];
|
||||||
// {{SQL CARBON EDIT}} - End
|
// {{SQL CARBON EDIT}} - End
|
||||||
|
|
||||||
interface IBuiltInExtension {
|
interface IBuiltInExtension {
|
||||||
@@ -352,7 +350,8 @@ export function packageExtensionsStream(optsIn?: IPackageExtensionsOptions): Nod
|
|||||||
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
|
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
|
||||||
.filter(({ name }) => builtInExtensions.every(b => b.name !== name))
|
.filter(({ name }) => builtInExtensions.every(b => b.name !== name))
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
.filter(({ name }) => sqlBuiltInExtensions.indexOf(name) === -1);
|
.filter(({ name }) => sqlBuiltInExtensions.indexOf(name) === -1)
|
||||||
|
.filter(({ name }) => azureExtensions.indexOf(name) === -1);
|
||||||
|
|
||||||
const localExtensions = () => sequence([...localExtensionDescriptions.map(extension => () => {
|
const localExtensions = () => sequence([...localExtensionDescriptions.map(extension => () => {
|
||||||
return fromLocal(extension.path, opts.sourceMappingURLBase)
|
return fromLocal(extension.path, opts.sourceMappingURLBase)
|
||||||
|
|||||||
@@ -222,6 +222,10 @@
|
|||||||
"name": "vs/workbench/services/files",
|
"name": "vs/workbench/services/files",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "vs/workbench/services/files2",
|
||||||
|
"project": "vscode-workbench"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "vs/workbench/services/integrity",
|
"name": "vs/workbench/services/integrity",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ function log(message: any, ...rest: any[]): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Language {
|
export interface Language {
|
||||||
id: string; // language id, e.g. zh-tw, de
|
id: string; // laguage id, e.g. zh-tw, de
|
||||||
translationId?: string; // language id used in translation tools, e.g zh-hant, de (optional, if not set, the id is used)
|
translationId?: string; // language id used in translation tools, e.g zh-hant, de (optional, if not set, the id is used)
|
||||||
folderName?: string; // language specific folder name, e.g. cht, deu (optional, if not set, the id is used)
|
folderName?: string; // language specific folder name, e.g. cht, deu (optional, if not set, the id is used)
|
||||||
}
|
}
|
||||||
@@ -1378,4 +1378,4 @@ function decodeEntities(value: string): string {
|
|||||||
|
|
||||||
function pseudify(message: string) {
|
function pseudify(message: string) {
|
||||||
return '\uFF3B' + message.replace(/[aouei]/g, '$&$&') + '\uFF3D';
|
return '\uFF3B' + message.replace(/[aouei]/g, '$&$&') + '\uFF3D';
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ async function _doExecute(task) {
|
|||||||
// Always invoke as if it were a callback task
|
// Always invoke as if it were a callback task
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (task.length === 1) {
|
if (task.length === 1) {
|
||||||
// this is a callback task
|
// this is a calback task
|
||||||
task((err) => {
|
task((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return reject(err);
|
return reject(err);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ async function _doExecute(task: Task): Promise<void> {
|
|||||||
// Always invoke as if it were a callback task
|
// Always invoke as if it were a callback task
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (task.length === 1) {
|
if (task.length === 1) {
|
||||||
// this is a callback task
|
// this is a calback task
|
||||||
task((err) => {
|
task((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return reject(err);
|
return reject(err);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
/*---------------------------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------------------------
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const ts = require("typescript");
|
const ts = require("typescript");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------------------------
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ function update(options) {
|
|||||||
let translationPaths = [];
|
let translationPaths = [];
|
||||||
i18n.pullI18nPackFiles(server, userName, apiToken, { id: languageId }, translationPaths)
|
i18n.pullI18nPackFiles(server, userName, apiToken, { id: languageId }, translationPaths)
|
||||||
.on('error', (error) => {
|
.on('error', (error) => {
|
||||||
console.log(`Error occurred while importing translations:`);
|
console.log(`Error occured while importing translations:`);
|
||||||
translationPaths = undefined;
|
translationPaths = undefined;
|
||||||
if (Array.isArray(error)) {
|
if (Array.isArray(error)) {
|
||||||
error.forEach(console.log);
|
error.forEach(console.log);
|
||||||
@@ -100,7 +100,7 @@ function update(options) {
|
|||||||
gulp.src(path.join(location, languageId, '**', '*.xlf'))
|
gulp.src(path.join(location, languageId, '**', '*.xlf'))
|
||||||
.pipe(i18n.prepareI18nPackFiles(i18n.externalExtensionsWithTranslations, translationPaths, languageId === 'ps'))
|
.pipe(i18n.prepareI18nPackFiles(i18n.externalExtensionsWithTranslations, translationPaths, languageId === 'ps'))
|
||||||
.on('error', (error) => {
|
.on('error', (error) => {
|
||||||
console.log(`Error occurred while importing translations:`);
|
console.log(`Error occured while importing translations:`);
|
||||||
translationPaths = undefined;
|
translationPaths = undefined;
|
||||||
if (Array.isArray(error)) {
|
if (Array.isArray(error)) {
|
||||||
error.forEach(console.log);
|
error.forEach(console.log);
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
"request": "^2.85.0",
|
"request": "^2.85.0",
|
||||||
"tslint": "^5.9.1",
|
"tslint": "^5.9.1",
|
||||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||||
"typescript": "3.4.5",
|
"typescript": "3.3.1",
|
||||||
"vsce": "1.48.0",
|
"vsce": "1.48.0",
|
||||||
"xml2js": "^0.4.17"
|
"xml2js": "^0.4.17"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
// enable JavaScript type checking for the language service
|
// enable JavaScript type checking for the language service
|
||||||
// use the tsconfig.build.json for compiling which disable JavaScript
|
// use the tsconfig.build.json for compiling wich disable JavaScript
|
||||||
// type checking so that JavaScript file are not transpiled
|
// type checking so that JavaScript file are not transpiled
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"checkJs": true,
|
"checkJs": true,
|
||||||
@@ -22,4 +22,4 @@
|
|||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules/**"
|
"node_modules/**"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ Type: files; Name: "{app}\resources\app\Credits_45.0.2454.85.html"; Check: IsNot
|
|||||||
Type: filesandordirs; Name: "{app}\_"
|
Type: filesandordirs; Name: "{app}\_"
|
||||||
|
|
||||||
[Tasks]
|
[Tasks]
|
||||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked;
|
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkedonce; Check: IsNotUpdate
|
||||||
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
|
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
|
||||||
Name: "associatewithfiles"; Description: "{cm:AssociateWithFiles,{#NameLong}}"; GroupDescription: "{cm:Other}"; Flags: unchecked
|
Name: "associatewithfiles"; Description: "{cm:AssociateWithFiles,{#NameLong}}"; GroupDescription: "{cm:Other}"; Flags: unchecked
|
||||||
Name: "addtopath"; Description: "{cm:AddToPath}"; GroupDescription: "{cm:Other}"
|
Name: "addtopath"; Description: "{cm:AddToPath}"; GroupDescription: "{cm:Other}"
|
||||||
|
|||||||
@@ -3201,10 +3201,10 @@ typed-rest-client@^0.9.0:
|
|||||||
tunnel "0.0.4"
|
tunnel "0.0.4"
|
||||||
underscore "1.8.3"
|
underscore "1.8.3"
|
||||||
|
|
||||||
typescript@3.4.5:
|
typescript@3.3.1:
|
||||||
version "3.4.5"
|
version "3.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.5.tgz#2d2618d10bb566572b8d7aad5180d84257d70a99"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.1.tgz#6de14e1db4b8a006ac535e482c8ba018c55f750b"
|
||||||
integrity sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==
|
integrity sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==
|
||||||
|
|
||||||
uc.micro@^1.0.1, uc.micro@^1.0.5:
|
uc.micro@^1.0.1, uc.micro@^1.0.5:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
|
|||||||
@@ -73,12 +73,12 @@
|
|||||||
"git": {
|
"git": {
|
||||||
"name": "electron",
|
"name": "electron",
|
||||||
"repositoryUrl": "https://github.com/electron/electron",
|
"repositoryUrl": "https://github.com/electron/electron",
|
||||||
"commitHash": "e84a6860e35e14b4031b88bb9b49841cdb89a305"
|
"commitHash": "73158a6419a3e2da9e4d523e1131052abd28fbbb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"isOnlyProductionDependency": true,
|
"isOnlyProductionDependency": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"version": "3.1.8"
|
"version": "3.1.6"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"component": {
|
"component": {
|
||||||
@@ -111,11 +111,11 @@
|
|||||||
"git": {
|
"git": {
|
||||||
"name": "vscode-octicons-font",
|
"name": "vscode-octicons-font",
|
||||||
"repositoryUrl": "https://github.com/Microsoft/vscode-octicons-font",
|
"repositoryUrl": "https://github.com/Microsoft/vscode-octicons-font",
|
||||||
"commitHash": "4f69de3a233ed501c2098e33047e116ac2fbbf42"
|
"commitHash": "5095860bb929919670646e2dfa0ee47d9b93bcb9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"version": "1.1.0"
|
"version": "1.0.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"component": {
|
"component": {
|
||||||
|
|||||||
@@ -1,75 +1,61 @@
|
|||||||
{
|
{
|
||||||
"name": "admin-tool-ext-win",
|
"name": "admin-tool-ext-win",
|
||||||
"displayName": "%adminToolExtWin.displayName%",
|
"displayName": "Database Admin Tool Extensions for Windows",
|
||||||
"description": "%adminToolExtWin.description%",
|
"description": "Adds additional Windows-specific functionality to Azure Data Studio",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"publisher": "Microsoft",
|
"publisher": "Microsoft",
|
||||||
"preview": true,
|
"preview": true,
|
||||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
|
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
|
||||||
"icon": "images/sqlserver.png",
|
"icon": "images/sqlserver.png",
|
||||||
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
|
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.30.1",
|
"vscode": "^1.30.1",
|
||||||
"sqlops": "*"
|
"sqlops": "*"
|
||||||
},
|
},
|
||||||
"activationEvents": [
|
"activationEvents": [
|
||||||
"*"
|
"*"
|
||||||
],
|
],
|
||||||
"main": "./out/main",
|
"main": "./out/main",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||||
},
|
},
|
||||||
"extensionDependencies": [
|
"extensionDependencies": [
|
||||||
"Microsoft.mssql"
|
"Microsoft.mssql"
|
||||||
],
|
],
|
||||||
"contributes": {
|
"contributes": {
|
||||||
"commands": [
|
"commands": [
|
||||||
{
|
{
|
||||||
"command": "adminToolExtWin.launchSsmsMinPropertiesDialog",
|
"command": "adminToolExtWin.launchSsmsServerPropertiesDialog",
|
||||||
"title": "%adminToolExtWin.propertiesMenuItem%",
|
"title": "%adminToolExtWin.launchSsmsServerPropertiesDialog%",
|
||||||
"category": "AdminToolExtWin"
|
"category": "AdminToolExtWin"
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"command": "adminToolExtWin.launchSsmsMinGswDialog",
|
"menus": {
|
||||||
"title": "%adminToolExtWin.launchGswMenuItem%",
|
"commandPalette": [
|
||||||
"category": "AdminToolExtWin"
|
{
|
||||||
}
|
"command": "adminToolExtWin.launchSsmsServerPropertiesDialog",
|
||||||
],
|
"when": "false"
|
||||||
"menus": {
|
}
|
||||||
"commandPalette": [
|
],
|
||||||
{
|
"objectExplorer/item/context": [
|
||||||
"command": "adminToolExtWin.launchSsmsMinPropertiesDialog",
|
{
|
||||||
"when": "false"
|
"command": "adminToolExtWin.launchSsmsServerPropertiesDialog",
|
||||||
},
|
"when": "isWindows && connectionProvider == MSSQL && nodeType && nodeType == Server",
|
||||||
{
|
"group": "AdminToolExtWin"
|
||||||
"command": "adminToolExtWin.launchSsmsMinGswDialog",
|
}
|
||||||
"when": "false"
|
]
|
||||||
}
|
},
|
||||||
],
|
"outputChannels": [
|
||||||
"objectExplorer/item/context": [
|
"admin-tool-ext-win"
|
||||||
{
|
]
|
||||||
"command": "adminToolExtWin.launchSsmsMinGswDialog",
|
},
|
||||||
"when": "isWindows && connectionProvider == MSSQL && nodeType && nodeType == Database",
|
"dependencies": {
|
||||||
"group": "z-AdminToolExt@1"
|
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
||||||
},
|
"vscode-extension-telemetry": "^0.0.15",
|
||||||
{
|
"vscode-nls": "^3.2.1"
|
||||||
"command": "adminToolExtWin.launchSsmsMinPropertiesDialog",
|
},
|
||||||
"when": "isWindows && connectionProvider == MSSQL && nodeType && nodeType =~ /^(Server|Database|Table|Column|Index|Statistic|View|ServerLevelLogin|ServerLevelServerRole|ServerLevelCredential|ServerLevelServerAudit|ServerLevelServerAuditSpecification|StoredProcedure|ScalarValuedFunction|TableValuedFunction|AggregateFunction|Synonym|Assembly|UserDefinedDataType|UserDefinedType|UserDefinedTableType|Sequence|User|DatabaseRole|ApplicationRole|Schema|SecurityPolicy|ServerLevelLinkedServer)$/",
|
"devDependencies": {
|
||||||
"group": "z-AdminToolExt@2"
|
"vscode": "1.0.1"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
},
|
|
||||||
"outputChannels": [
|
|
||||||
"admin-tool-ext-win"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
|
|
||||||
"vscode-extension-telemetry": "^0.0.15",
|
|
||||||
"vscode-nls": "^3.2.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"vscode": "1.0.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
{
|
{
|
||||||
"adminToolExtWin.displayName": "Database Administration Tool Extensions for Windows",
|
"adminToolExtWin.launchSsmsServerPropertiesDialog": "Properties"
|
||||||
"adminToolExtWin.description": "Adds additional Windows-specific functionality to Azure Data Studio",
|
|
||||||
"adminToolExtWin.propertiesMenuItem": "Properties",
|
|
||||||
"adminToolExtWin.launchGswMenuItem": "Generate Scripts..."
|
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"downloadUrl": "https://sqlopsextensions.blob.core.windows.net/tools/ssmsmin/{#version#}/{#fileName#}",
|
"downloadUrl": "https://sqlopsextensions.blob.core.windows.net/tools/ssmsmin/{#version#}/{#fileName#}",
|
||||||
"version": "15.0.18120.0",
|
"version": "15.0.18092.0",
|
||||||
"downloadFileNames": {
|
"downloadFileNames": {
|
||||||
"Windows_64": "SsmsMin-15.0.18120.0-win-x64.zip",
|
"Windows_64": "SsmsMin-15.0.18092.0-win-x64.zip",
|
||||||
"Windows_86": "SsmsMin-15.0.18120.0-win-x86.zip"
|
"Windows_86": "SsmsMin-15.0.18092.0-win-x86.zip"
|
||||||
},
|
},
|
||||||
"installDirectory": "ssmsmin/{#platform#}/{#version#}",
|
"installDirectory": "ssmsmin/{#platform#}/{#version#}",
|
||||||
"executableFiles": [
|
"executableFiles": [
|
||||||
"SsmsMin.exe"
|
"SsmsMin.exe"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
///
|
||||||
|
'use strict';
|
||||||
|
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
@@ -9,51 +11,15 @@ import * as azdata from 'azdata';
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { IConfig, ServerProvider } from 'service-downloader';
|
import { IConfig, ServerProvider } from 'service-downloader';
|
||||||
import { Telemetry } from './telemetry';
|
import { Telemetry } from './telemetry';
|
||||||
import { doubleEscapeSingleQuotes, backEscapeDoubleQuotes, getConfiguration } from './utils';
|
import * as utils from './utils';
|
||||||
import { ChildProcess, exec } from 'child_process';
|
import { ChildProcess, exec, ExecException } from 'child_process';
|
||||||
|
import { stringify } from 'querystring';
|
||||||
|
|
||||||
const baseConfig = require('./config.json');
|
const baseConfig = require('./config.json');
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
let exePath: string;
|
let exePath: string;
|
||||||
let runningProcesses: Map<number, ChildProcess> = new Map<number, ChildProcess>();
|
let runningProcesses: Map<number, ChildProcess> = new Map<number, ChildProcess>();
|
||||||
|
|
||||||
|
|
||||||
interface SmoMapping {
|
|
||||||
action: string;
|
|
||||||
urnName: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nodeTypeToUrnNameMapping: { [oeNodeType: string]: SmoMapping } = {
|
|
||||||
'Database': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Database', urnName: 'Database' },
|
|
||||||
'Server': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Server', urnName: 'Server' },
|
|
||||||
'ServerLevelServerAudit': { action: 'sqla:AuditProperties', urnName: 'Audit' },
|
|
||||||
'ServerLevelCredential': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Credential', urnName: 'Credential' },
|
|
||||||
'ServerLevelServerRole': { action: 'sqla:ManageServerRole', urnName: 'Role' },
|
|
||||||
'ServerLevelServerAuditSpecification': { action: 'sqla:ServerAuditSpecificationProperties', urnName: 'ServerAuditSpecification' },
|
|
||||||
'ServerLevelLinkedServer': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.LinkedServer', urnName: 'LinkedServer' },
|
|
||||||
'Table': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Table', urnName: 'Table' },
|
|
||||||
'View': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.View', urnName: 'View' },
|
|
||||||
'Column': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Column', urnName: 'Column' },
|
|
||||||
'Index': { action: 'sqla:IndexProperties', urnName: 'Index' },
|
|
||||||
'Statistic': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Statistic', urnName: 'Statistic' },
|
|
||||||
'StoredProcedure': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.StoredProcedure', urnName: 'StoredProcedure' },
|
|
||||||
'ScalarValuedFunction': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.UserDefinedFunction', urnName: 'UserDefinedFunction' },
|
|
||||||
'TableValuedFunction': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.UserDefinedFunction', urnName: 'UserDefinedFunction' },
|
|
||||||
'AggregateFunction': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.UserDefinedFunction', urnName: 'UserDefinedFunction' },
|
|
||||||
'Synonym': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Synonym', urnName: 'Synonym' },
|
|
||||||
'Assembly': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.SqlAssembly', urnName: 'SqlAssembly' },
|
|
||||||
'UserDefinedDataType': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.UserDefinedDataType', urnName: 'UserDefinedDataType' },
|
|
||||||
'UserDefinedType': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.UserDefinedType', urnName: 'UserDefinedType' },
|
|
||||||
'UserDefinedTableType': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.UserDefinedTableType', urnName: 'UserDefinedTableType' },
|
|
||||||
'Sequence': { action: 'sqla:SequenceProperties', urnName: 'Sequence' },
|
|
||||||
'User': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.User', urnName: 'User' },
|
|
||||||
'DatabaseRole': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.DatabaseRole', urnName: 'Role' },
|
|
||||||
'ApplicationRole': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.ApplicationRole', urnName: 'ApplicationRole' },
|
|
||||||
'Schema': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Schema', urnName: 'Schema' },
|
|
||||||
'SecurityPolicy': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.SecurityPolicy', urnName: 'SecurityPolicy' },
|
|
||||||
'ServerLevelLogin': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Login', urnName: 'Login' },
|
|
||||||
};
|
|
||||||
|
|
||||||
// Params to pass to SsmsMin.exe, only an action and server are required - the rest are optional based on the
|
// Params to pass to SsmsMin.exe, only an action and server are required - the rest are optional based on the
|
||||||
// action used. Exported for use in testing.
|
// action used. Exported for use in testing.
|
||||||
export interface LaunchSsmsDialogParams {
|
export interface LaunchSsmsDialogParams {
|
||||||
@@ -61,6 +27,7 @@ export interface LaunchSsmsDialogParams {
|
|||||||
server: string;
|
server: string;
|
||||||
database?: string;
|
database?: string;
|
||||||
user?: string;
|
user?: string;
|
||||||
|
password?: string;
|
||||||
useAad?: boolean;
|
useAad?: boolean;
|
||||||
urn?: string;
|
urn?: string;
|
||||||
}
|
}
|
||||||
@@ -72,8 +39,8 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
|
|||||||
|
|
||||||
let config: IConfig = JSON.parse(JSON.stringify(baseConfig));
|
let config: IConfig = JSON.parse(JSON.stringify(baseConfig));
|
||||||
config.installDirectory = path.join(context.extensionPath, config.installDirectory);
|
config.installDirectory = path.join(context.extensionPath, config.installDirectory);
|
||||||
config.proxy = getConfiguration('http').get('proxy');
|
config.proxy = utils.getConfiguration('http').get('proxy');
|
||||||
config.strictSSL = getConfiguration('http').get('proxyStrictSSL') || true;
|
config.strictSSL = utils.getConfiguration('http').get('proxyStrictSSL') || true;
|
||||||
|
|
||||||
const serverdownloader = new ServerProvider(config);
|
const serverdownloader = new ServerProvider(config);
|
||||||
const installationStart = Date.now();
|
const installationStart = Date.now();
|
||||||
@@ -88,9 +55,9 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
|
|||||||
} else {
|
} else {
|
||||||
throw new Error('Could not find SsmsMin.exe after downloading');
|
throw new Error('Could not find SsmsMin.exe after downloading');
|
||||||
}
|
}
|
||||||
|
// Add the command now that we have the exePath to run the tool with
|
||||||
// Register the commands now that we have the exePath to run the tool with
|
context.subscriptions.push(
|
||||||
registerCommands(context);
|
vscode.commands.registerCommand('adminToolExtWin.launchSsmsServerPropertiesDialog', handleLaunchSsmsServerPropertiesDialogCommand));
|
||||||
|
|
||||||
Telemetry.sendTelemetryEvent('startup/ExtensionStarted', {
|
Telemetry.sendTelemetryEvent('startup/ExtensionStarted', {
|
||||||
installationTime: String(installationComplete - installationStart),
|
installationTime: String(installationComplete - installationStart),
|
||||||
@@ -111,56 +78,16 @@ export async function deactivate(): Promise<void> {
|
|||||||
runningProcesses.forEach(p => exec('taskkill /pid ' + p.pid + ' /T /F'));
|
runningProcesses.forEach(p => exec('taskkill /pid ' + p.pid + ' /T /F'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers extension commands with command subsystem
|
|
||||||
* @param context The context used to register the commands
|
|
||||||
*/
|
|
||||||
function registerCommands(context: vscode.ExtensionContext): void {
|
|
||||||
context.subscriptions.push(
|
|
||||||
vscode.commands.registerCommand('adminToolExtWin.launchSsmsMinPropertiesDialog', handleLaunchSsmsMinPropertiesDialogCommand));
|
|
||||||
context.subscriptions.push(
|
|
||||||
vscode.commands.registerCommand('adminToolExtWin.launchSsmsMinGswDialog', handleLaunchSsmsMinGswDialogCommand));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for command to launch SSMS Server Properties dialog
|
* Handler for command to launch SSMS Server Properties dialog
|
||||||
* @param connectionId The connection context from the command
|
* @param connectionId The connection context from the command
|
||||||
*/
|
*/
|
||||||
async function handleLaunchSsmsMinPropertiesDialogCommand(connectionContext?: azdata.ObjectExplorerContext): Promise<void> {
|
function handleLaunchSsmsServerPropertiesDialogCommand(connectionContext?: azdata.ObjectExplorerContext) {
|
||||||
if (!connectionContext) {
|
if (connectionContext && connectionContext.connectionProfile) {
|
||||||
vscode.window.showErrorMessage(localize('adminToolExtWin.noConnectionContextForProp', 'No ConnectionContext provided for handleLaunchSsmsMinPropertiesDialogCommand'));
|
launchSsmsDialog(
|
||||||
return;
|
/*action*/'sqla:Properties@Microsoft.SqlServer.Management.Smo.Server',
|
||||||
|
/*connectionProfile*/connectionContext.connectionProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
let nodeType: string;
|
|
||||||
if (connectionContext.isConnectionNode) {
|
|
||||||
nodeType = 'Server';
|
|
||||||
}
|
|
||||||
else if (connectionContext.nodeInfo) {
|
|
||||||
nodeType = connectionContext.nodeInfo.nodeType;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
vscode.window.showErrorMessage(localize('adminToolExtWin.noOeNode', 'Could not determine NodeType for handleLaunchSsmsMinPropertiesDialogCommand with context {0}', JSON.stringify(connectionContext)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
launchSsmsDialog(
|
|
||||||
nodeTypeToUrnNameMapping[nodeType].action,
|
|
||||||
connectionContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for command to launch SSMS "Generate Script Wizard" dialog
|
|
||||||
* @param connectionId The connection context from the command
|
|
||||||
*/
|
|
||||||
async function handleLaunchSsmsMinGswDialogCommand(connectionContext?: azdata.ObjectExplorerContext): Promise<void> {
|
|
||||||
if (!connectionContext) {
|
|
||||||
vscode.window.showErrorMessage(localize('adminToolExtWin.noConnectionContextForGsw', 'No ConnectionContext provided for handleLaunchSsmsMinPropertiesDialogCommand'));
|
|
||||||
}
|
|
||||||
|
|
||||||
launchSsmsDialog(
|
|
||||||
'GenerateScripts',
|
|
||||||
connectionContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,72 +96,29 @@ async function handleLaunchSsmsMinGswDialogCommand(connectionContext?: azdata.Ob
|
|||||||
* @param params The params used to construct the command
|
* @param params The params used to construct the command
|
||||||
* @param urn The URN to pass to SsmsMin
|
* @param urn The URN to pass to SsmsMin
|
||||||
*/
|
*/
|
||||||
async function launchSsmsDialog(action: string, connectionContext: azdata.ObjectExplorerContext): Promise<void> {
|
function launchSsmsDialog(action: string, connectionProfile: azdata.IConnectionProfile, urn?: string) {
|
||||||
if (!exePath) {
|
if (!exePath) {
|
||||||
vscode.window.showErrorMessage(localize('adminToolExtWin.noExeError', 'Unable to find SsmsMin.exe.'));
|
vscode.window.showErrorMessage(localize('adminToolExtWin.noExeError', 'Unable to find SsmsMin.exe.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!connectionContext.connectionProfile) {
|
Telemetry.sendTelemetryEvent('LaunchSsmsDialog', { 'action': action });
|
||||||
vscode.window.showErrorMessage(localize('adminToolExtWin.noConnectionProfile', 'No connectionProfile provided from connectionContext : {0}', JSON.stringify(connectionContext)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Currently Azure isn't supported by the SSMS server properties dialog
|
|
||||||
const serverInfo = await azdata.connection.getServerInfo(connectionContext.connectionProfile.id);
|
|
||||||
if (serverInfo && serverInfo.isCloud) {
|
|
||||||
vscode.window.showErrorMessage(localize('adminToolExtWin.invalidEngineType', 'This option is not currently available for this engine type.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note - this is a temporary fix for the issue that currently the connection API doesn't allow retrieving credentials for a disconnected
|
|
||||||
// node. So until that's fixed we'll prevent users from attempting to launch SsmsMin on a disconnected node.
|
|
||||||
// We also aren't able to hide the menu item on disconnected nodes because we currently don't have a contextKey for the connected status
|
|
||||||
// of a node.
|
|
||||||
const activeConnections = await azdata.connection.getActiveConnections();
|
|
||||||
if (!activeConnections.some(conn => conn.connectionId === connectionContext.connectionProfile.id)) {
|
|
||||||
vscode.window.showErrorMessage(localize('adminToolExtWin.notConnected', 'This option requires a connected node - please connect and try again.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let oeNode: azdata.objectexplorer.ObjectExplorerNode;
|
|
||||||
// Server node is a Connection node and so doesn't have the NodeInfo
|
|
||||||
if (connectionContext.isConnectionNode) {
|
|
||||||
oeNode = undefined;
|
|
||||||
}
|
|
||||||
else if (connectionContext.nodeInfo && connectionContext.nodeInfo.nodeType && connectionContext.connectionProfile) {
|
|
||||||
oeNode = await azdata.objectexplorer.getNode(connectionContext.connectionProfile.id, connectionContext.nodeInfo.nodePath);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
vscode.window.showErrorMessage(localize('adminToolExtWin.noOENode', 'Could not determine Object Explorer node from connectionContext : {0}', JSON.stringify(connectionContext)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let urn: string = await buildUrn(connectionContext.connectionProfile.serverName, oeNode);
|
|
||||||
let password: string = connectionContext.connectionProfile.password;
|
|
||||||
|
|
||||||
if (!password || password === '') {
|
|
||||||
let creds = await azdata.connection.getCredentials(connectionContext.connectionProfile.id);
|
|
||||||
password = creds[azdata.ConnectionOptionSpecialType.password];
|
|
||||||
}
|
|
||||||
|
|
||||||
let params: LaunchSsmsDialogParams = {
|
let params: LaunchSsmsDialogParams = {
|
||||||
action: action,
|
action: action,
|
||||||
server: connectionContext.connectionProfile.serverName,
|
server: connectionProfile.serverName,
|
||||||
database: connectionContext.connectionProfile.databaseName,
|
database: connectionProfile.databaseName,
|
||||||
user: connectionContext.connectionProfile.userName,
|
password: connectionProfile.password,
|
||||||
useAad: connectionContext.connectionProfile.authenticationType === 'AzureMFA',
|
user: connectionProfile.userName,
|
||||||
|
useAad: connectionProfile.authenticationType === 'AzureMFA',
|
||||||
urn: urn
|
urn: urn
|
||||||
};
|
};
|
||||||
|
|
||||||
let args = buildSsmsMinCommandArgs(params);
|
let args = buildSsmsMinCommandArgs(params);
|
||||||
|
|
||||||
Telemetry.sendTelemetryEvent('LaunchSsmsDialog', { 'action': action });
|
|
||||||
|
|
||||||
// This will be an async call since we pass in the callback
|
// This will be an async call since we pass in the callback
|
||||||
let proc: ChildProcess = exec(
|
var proc: ChildProcess = exec(
|
||||||
/*command*/ `"${exePath}" ${args}`,
|
/*command*/`"${exePath}" ${args}`,
|
||||||
/*options*/ undefined,
|
/*options*/undefined,
|
||||||
(execException, stdout, stderr) => {
|
(execException, stdout, stderr) => {
|
||||||
// Process has exited so remove from map of running processes
|
// Process has exited so remove from map of running processes
|
||||||
runningProcesses.delete(proc.pid);
|
runningProcesses.delete(proc.pid);
|
||||||
@@ -244,15 +128,13 @@ async function launchSsmsDialog(action: string, connectionContext: azdata.Object
|
|||||||
});
|
});
|
||||||
let err = stderr.toString();
|
let err = stderr.toString();
|
||||||
if (err !== '') {
|
if (err !== '') {
|
||||||
vscode.window.showErrorMessage(localize(
|
console.warn(`Error calling SsmsMin with args '${args}' - ${err}`);
|
||||||
'adminToolExtWin.ssmsMinError',
|
|
||||||
'Error calling SsmsMin with args \'{0}\' - {1}', args, err));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// If we're not using AAD the tool prompts for a password on stdin
|
// If we're not using AAD the tool prompts for a password on stdin
|
||||||
if (params.useAad !== true) {
|
if (params.useAad !== true) {
|
||||||
proc.stdin.end(password ? password : '');
|
proc.stdin.end(params.password ? params.password : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the process into our map so we can make sure to stop them if we exit before shutting down
|
// Save the process into our map so we can make sure to stop them if we exit before shutting down
|
||||||
@@ -266,34 +148,10 @@ async function launchSsmsDialog(action: string, connectionContext: azdata.Object
|
|||||||
* @param params The params used to build up the command parameter string
|
* @param params The params used to build up the command parameter string
|
||||||
*/
|
*/
|
||||||
export function buildSsmsMinCommandArgs(params: LaunchSsmsDialogParams): string {
|
export function buildSsmsMinCommandArgs(params: LaunchSsmsDialogParams): string {
|
||||||
return `${params.action ? '-a "' + backEscapeDoubleQuotes(params.action) + '"' : ''}\
|
return `${params.action ? '-a "' + params.action.replace(/"/g, '\\"') + '"' : ''}\
|
||||||
${params.server ? ' -S "' + backEscapeDoubleQuotes(params.server) + '"' : ''}\
|
${params.server ? ' -S "' + params.server.replace(/"/g, '\\"') + '"' : ''}\
|
||||||
${params.database ? ' -D "' + backEscapeDoubleQuotes(params.database) + '"' : ''}\
|
${params.database ? ' -D "' + params.database.replace(/"/g, '\\"') + '"' : ''}\
|
||||||
${params.useAad !== true && params.user ? ' -U "' + backEscapeDoubleQuotes(params.user) + '"' : ''}\
|
${params.useAad !== true && params.user ? ' -U "' + params.user.replace(/"/g, '\\"') + '"' : ''}\
|
||||||
${params.useAad === true ? ' -G' : ''}\
|
${params.useAad === true ? ' -G' : ''}\
|
||||||
${params.urn ? ' -u "' + backEscapeDoubleQuotes(params.urn) + '"' : ''}`;
|
${params.urn ? ' -u "' + params.urn.replace(/"/g, '\\"') + '"' : ''}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds the URN string for a given ObjectExplorerNode in the form understood by SsmsMin
|
|
||||||
* @param serverName The name of the Server to use for the Server segment
|
|
||||||
* @param node The node to get the URN of
|
|
||||||
*/
|
|
||||||
export async function buildUrn(serverName: string, node: azdata.objectexplorer.ObjectExplorerNode): Promise<string> {
|
|
||||||
let urnNodes: string[] = [];
|
|
||||||
while (node) {
|
|
||||||
// Server is special since it's a connection node - always add it as the root
|
|
||||||
if (node.nodeType === 'Server') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (node.metadata && node.nodeType !== 'Folder') {
|
|
||||||
// SFC URN expects Name and Schema to be separate properties
|
|
||||||
let urnSegment = node.metadata.schema && node.metadata.schema !== '' ?
|
|
||||||
`${nodeTypeToUrnNameMapping[node.nodeType].urnName}[@Name='${doubleEscapeSingleQuotes(node.metadata.name)}' and @Schema='${doubleEscapeSingleQuotes(node.metadata.schema)}']` :
|
|
||||||
`${nodeTypeToUrnNameMapping[node.nodeType].urnName}[@Name='${doubleEscapeSingleQuotes(node.metadata.name)}']`;
|
|
||||||
urnNodes = [urnSegment].concat(urnNodes);
|
|
||||||
}
|
|
||||||
node = await node.getParent();
|
|
||||||
}
|
|
||||||
return [`Server[@Name='${doubleEscapeSingleQuotes(serverName)}']`].concat(urnNodes).join('/');
|
|
||||||
}
|
|
||||||
@@ -13,123 +13,123 @@ import * as Utils from './utils';
|
|||||||
const packageJson = require('../package.json');
|
const packageJson = require('../package.json');
|
||||||
|
|
||||||
export interface ITelemetryEventProperties {
|
export interface ITelemetryEventProperties {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITelemetryEventMeasures {
|
export interface ITelemetryEventMeasures {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters error paths to only include source files. Exported to support testing
|
* Filters error paths to only include source files. Exported to support testing
|
||||||
*/
|
*/
|
||||||
export function filterErrorPath(line: string): string {
|
export function filterErrorPath(line: string): string {
|
||||||
if (line) {
|
if (line) {
|
||||||
let values: string[] = line.split('/out/');
|
let values: string[] = line.split('/out/');
|
||||||
if (values.length <= 1) {
|
if (values.length <= 1) {
|
||||||
// Didn't match expected format
|
// Didn't match expected format
|
||||||
return line;
|
return line;
|
||||||
} else {
|
} else {
|
||||||
return values[1];
|
return values[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Telemetry {
|
export class Telemetry {
|
||||||
private static reporter: TelemetryReporter;
|
private static reporter: TelemetryReporter;
|
||||||
private static userId: string;
|
private static userId: string;
|
||||||
private static platformInformation: PlatformInformation;
|
private static platformInformation: PlatformInformation;
|
||||||
private static disabled: boolean;
|
private static disabled: boolean;
|
||||||
|
|
||||||
public static getPlatformInformation(): Promise<PlatformInformation> {
|
public static getPlatformInformation(): Promise<PlatformInformation> {
|
||||||
if (this.platformInformation) {
|
if (this.platformInformation) {
|
||||||
return Promise.resolve(this.platformInformation);
|
return Promise.resolve(this.platformInformation);
|
||||||
} else {
|
} else {
|
||||||
return new Promise<PlatformInformation>(resolve => {
|
return new Promise<PlatformInformation>(resolve => {
|
||||||
PlatformInformation.getCurrent().then(info => {
|
PlatformInformation.getCurrent().then(info => {
|
||||||
this.platformInformation = info;
|
this.platformInformation = info;
|
||||||
resolve(this.platformInformation);
|
resolve(this.platformInformation);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable telemetry reporting
|
* Disable telemetry reporting
|
||||||
*/
|
*/
|
||||||
public static disable(): void {
|
public static disable(): void {
|
||||||
this.disabled = true;
|
this.disabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the telemetry reporter for use.
|
* Initialize the telemetry reporter for use.
|
||||||
*/
|
*/
|
||||||
public static initialize(): void {
|
public static initialize(): void {
|
||||||
if (typeof this.reporter === 'undefined') {
|
if (typeof this.reporter === 'undefined') {
|
||||||
// Check if the user has opted out of telemetry
|
// Check if the user has opted out of telemetry
|
||||||
if (!vscode.workspace.getConfiguration('telemetry').get<boolean>('enableTelemetry', true)) {
|
if (!vscode.workspace.getConfiguration('telemetry').get<boolean>('enableTelemetry', true)) {
|
||||||
this.disable();
|
this.disable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let packageInfo = Utils.getPackageInfo(packageJson);
|
let packageInfo = Utils.getPackageInfo(packageJson);
|
||||||
this.reporter = new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
|
this.reporter = new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a telemetry event for an exception
|
* Send a telemetry event for an exception
|
||||||
*/
|
*/
|
||||||
public static sendTelemetryEventForException(
|
public static sendTelemetryEventForException(
|
||||||
err: any, methodName: string, extensionConfigName: string): void {
|
err: any, methodName: string, extensionConfigName: string): void {
|
||||||
try {
|
try {
|
||||||
let stackArray: string[];
|
let stackArray: string[];
|
||||||
let firstLine: string = '';
|
let firstLine: string = '';
|
||||||
if (err !== undefined && err.stack !== undefined) {
|
if (err !== undefined && err.stack !== undefined) {
|
||||||
stackArray = err.stack.split('\n');
|
stackArray = err.stack.split('\n');
|
||||||
if (stackArray !== undefined && stackArray.length >= 2) {
|
if (stackArray !== undefined && stackArray.length >= 2) {
|
||||||
firstLine = stackArray[1]; // The first line is the error message and we don't want to send that telemetry event
|
firstLine = stackArray[1]; // The first line is the error message and we don't want to send that telemetry event
|
||||||
firstLine = filterErrorPath(firstLine);
|
firstLine = filterErrorPath(firstLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only adding the method name and the fist line of the stack trace. We don't add the error message because it might have PII
|
// Only adding the method name and the fist line of the stack trace. We don't add the error message because it might have PII
|
||||||
this.sendTelemetryEvent('Exception', { methodName: methodName, errorLine: firstLine });
|
this.sendTelemetryEvent('Exception', { methodName: methodName, errorLine: firstLine });
|
||||||
} catch (telemetryErr) {
|
} catch (telemetryErr) {
|
||||||
// If sending telemetry event fails ignore it so it won't break the extension
|
// If sending telemetry event fails ignore it so it won't break the extension
|
||||||
console.error('Failed to send telemetry event. error: ' + telemetryErr, extensionConfigName);
|
console.error('Failed to send telemetry event. error: ' + telemetryErr, extensionConfigName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a telemetry event using application insights
|
* Send a telemetry event using application insights
|
||||||
*/
|
*/
|
||||||
public static sendTelemetryEvent(
|
public static sendTelemetryEvent(
|
||||||
eventName: string,
|
eventName: string,
|
||||||
properties?: ITelemetryEventProperties,
|
properties?: ITelemetryEventProperties,
|
||||||
measures?: ITelemetryEventMeasures): void {
|
measures?: ITelemetryEventMeasures): void {
|
||||||
|
|
||||||
if (typeof this.disabled === 'undefined') {
|
if (typeof this.disabled === 'undefined') {
|
||||||
this.disabled = false;
|
this.disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.disabled || typeof (this.reporter) === 'undefined') {
|
if (this.disabled || typeof (this.reporter) === 'undefined') {
|
||||||
// Don't do anything if telemetry is disabled
|
// Don't do anything if telemetry is disabled
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!properties || typeof properties === 'undefined') {
|
if (!properties || typeof properties === 'undefined') {
|
||||||
properties = {};
|
properties = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Augment the properties structure with additional common properties before sending
|
// Augment the properties structure with additional common properties before sending
|
||||||
Promise.all([this.getPlatformInformation()]).then(() => {
|
Promise.all([this.getPlatformInformation()]).then(() => {
|
||||||
properties['distribution'] = (this.platformInformation && this.platformInformation.distribution) ?
|
properties['distribution'] = (this.platformInformation && this.platformInformation.distribution) ?
|
||||||
`${this.platformInformation.distribution.name}, ${this.platformInformation.distribution.version}` : '';
|
`${this.platformInformation.distribution.name}, ${this.platformInformation.distribution.version}` : '';
|
||||||
|
|
||||||
this.reporter.sendTelemetryEvent(eventName, properties, measures);
|
this.reporter.sendTelemetryEvent(eventName, properties, measures);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Telemetry.initialize();
|
Telemetry.initialize();
|
||||||
|
|||||||
@@ -9,20 +9,20 @@ const testRunner = require('vscode/lib/testrunner');
|
|||||||
const suite = 'Database Admin Tool Extensions for Windows';
|
const suite = 'Database Admin Tool Extensions for Windows';
|
||||||
|
|
||||||
const options: any = {
|
const options: any = {
|
||||||
ui: 'bdd',
|
ui: 'bdd',
|
||||||
useColors: true,
|
useColors: true,
|
||||||
timeout: 600000
|
timeout: 600000
|
||||||
};
|
};
|
||||||
|
|
||||||
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
|
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
|
||||||
options.reporter = 'mocha-multi-reporters';
|
options.reporter = 'mocha-multi-reporters';
|
||||||
options.reporterOptions = {
|
options.reporterOptions = {
|
||||||
reporterEnabled: 'spec, mocha-junit-reporter',
|
reporterEnabled: 'spec, mocha-junit-reporter',
|
||||||
mochaJunitReporterReporterOptions: {
|
mochaJunitReporterReporterOptions: {
|
||||||
testsuitesTitle: `${suite} ${process.platform}`,
|
testsuitesTitle: `${suite} ${process.platform}`,
|
||||||
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
|
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
testRunner.configure(options);
|
testRunner.configure(options);
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
|
||||||
import * as vscode from 'vscode';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper stub class for mocking ExtHostObjectExplorerNode
|
|
||||||
*/
|
|
||||||
export class ExtHostObjectExplorerNodeStub implements azdata.objectexplorer.ObjectExplorerNode {
|
|
||||||
// Stub properties
|
|
||||||
private parent: azdata.objectexplorer.ObjectExplorerNode;
|
|
||||||
|
|
||||||
// Base properties
|
|
||||||
public connectionId: string;
|
|
||||||
public nodePath: string;
|
|
||||||
public nodeType: string;
|
|
||||||
public nodeSubType: string;
|
|
||||||
public nodeStatus: string;
|
|
||||||
public label: string;
|
|
||||||
public isLeaf: boolean;
|
|
||||||
public metadata: azdata.ObjectMetadata;
|
|
||||||
public errorMessage: string;
|
|
||||||
|
|
||||||
constructor(nodeName: string, nodeSchema: string, nodeType, parent: azdata.objectexplorer.ObjectExplorerNode) {
|
|
||||||
this.parent = parent;
|
|
||||||
this.nodeType = nodeType;
|
|
||||||
this.metadata = { metadataType: undefined, metadataTypeName: undefined, name: nodeName, schema: nodeSchema, urn: undefined };
|
|
||||||
}
|
|
||||||
|
|
||||||
isExpanded(): Thenable<boolean> {
|
|
||||||
throw new Error('Method not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
setExpandedState(expandedState: vscode.TreeItemCollapsibleState): Thenable<void> {
|
|
||||||
throw new Error('Method not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
setSelected(selected: boolean, clearOtherSelections: boolean = undefined): Thenable<void> {
|
|
||||||
throw new Error('Method not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
getChildren(): Thenable<azdata.objectexplorer.ObjectExplorerNode[]> {
|
|
||||||
throw new Error('Method not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
getParent(): Thenable<azdata.objectexplorer.ObjectExplorerNode> {
|
|
||||||
return Promise.resolve(this.parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
refresh(): Thenable<void> {
|
|
||||||
throw new Error('Method not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param nodeName Helperfunction to create a node that is a child of this one
|
|
||||||
* @param nodeSchema The schema to give the child node
|
|
||||||
* @param nodeType The type of node this should be
|
|
||||||
*/
|
|
||||||
createChild(nodeName: string, nodeSchema: string, nodeType: string): ExtHostObjectExplorerNodeStub {
|
|
||||||
return new ExtHostObjectExplorerNodeStub(nodeName, nodeSchema, nodeType, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,128 +8,60 @@
|
|||||||
import * as should from 'should';
|
import * as should from 'should';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
|
|
||||||
import { buildSsmsMinCommandArgs, buildUrn, LaunchSsmsDialogParams } from '../main';
|
import * as extensionMain from '../main';
|
||||||
import { doubleEscapeSingleQuotes, backEscapeDoubleQuotes } from '../utils';
|
|
||||||
import { ExtHostObjectExplorerNodeStub } from './stubs';
|
|
||||||
|
|
||||||
describe('buildSsmsMinCommandArgs Method Tests', () => {
|
describe('buildSsmsMinCommandArgs Method Tests', () => {
|
||||||
it('Should be built correctly with all params and UseAAD as false', function (): void {
|
it('Should be built correctly with all params and UseAAD as false', function (): void {
|
||||||
const params: LaunchSsmsDialogParams = {
|
let params: extensionMain.LaunchSsmsDialogParams = {
|
||||||
action: 'myAction',
|
action: 'myAction',
|
||||||
server: 'myServer',
|
server: 'myServer',
|
||||||
database: 'myDatabase',
|
database: 'myDatabase',
|
||||||
user: 'user',
|
user: 'user',
|
||||||
useAad: false,
|
password: 'password',
|
||||||
urn: 'Server\\Database\\Table'
|
useAad: false,
|
||||||
};
|
urn: 'Server\\Database\\Table'
|
||||||
const args = buildSsmsMinCommandArgs(params);
|
};
|
||||||
should(args).equal('-a "myAction" -S "myServer" -D "myDatabase" -U "user" -u "Server\\Database\\Table"');
|
let args = extensionMain.buildSsmsMinCommandArgs(params);
|
||||||
});
|
should(args).equal('-a "myAction" -S "myServer" -D "myDatabase" -U "user" -u "Server\\Database\\Table"');
|
||||||
|
});
|
||||||
|
|
||||||
it('Should be built correctly with all params and UseAAD as true', function (): void {
|
it('Should be built correctly with all params and UseAAD as true', function (): void {
|
||||||
const params: LaunchSsmsDialogParams = {
|
let params: extensionMain.LaunchSsmsDialogParams = {
|
||||||
action: 'myAction',
|
action: 'myAction',
|
||||||
server: 'myServer',
|
server: 'myServer',
|
||||||
database: 'myDatabase',
|
database: 'myDatabase',
|
||||||
user: 'user',
|
user: 'user',
|
||||||
useAad: true,
|
password: 'password',
|
||||||
urn: 'Server\\Database\\Table'
|
useAad: true,
|
||||||
};
|
urn: 'Server\\Database\\Table'
|
||||||
const args = buildSsmsMinCommandArgs(params);
|
};
|
||||||
// User is omitted since UseAAD is true
|
let args = extensionMain.buildSsmsMinCommandArgs(params);
|
||||||
should(args).equal('-a "myAction" -S "myServer" -D "myDatabase" -G -u "Server\\Database\\Table"');
|
// User is omitted since UseAAD is true
|
||||||
});
|
should(args).equal('-a "myAction" -S "myServer" -D "myDatabase" -G -u "Server\\Database\\Table"');
|
||||||
|
});
|
||||||
|
|
||||||
it('Should be built correctly and names escaped correctly', function (): void {
|
it('Should be built correctly and names escaped correctly', function (): void {
|
||||||
const params: LaunchSsmsDialogParams = {
|
let params: extensionMain.LaunchSsmsDialogParams = {
|
||||||
action: 'myAction\'"/\\[]tricky',
|
action: 'myAction\'"/\\[]tricky',
|
||||||
server: 'myServer\'"/\\[]tricky',
|
server: 'myServer\'"/\\[]tricky',
|
||||||
database: 'myDatabase\'"/\\[]tricky',
|
database: 'myDatabase\'"/\\[]tricky',
|
||||||
user: 'user\'"/\\[]tricky',
|
user: 'user\'"/\\[]tricky',
|
||||||
useAad: true,
|
password: 'password',
|
||||||
urn: 'Server\\Database[\'myDatabase\'\'"/\\[]tricky\']\\Table["myTable\'""/\\[]tricky"]'
|
useAad: true,
|
||||||
};
|
urn: 'Server\\Database[\'myDatabase\'\'"/\\[]tricky\']\\Table["myTable\'""/\\[]tricky"]'
|
||||||
const args = buildSsmsMinCommandArgs(params);
|
};
|
||||||
// User is omitted since UseAAD is true
|
let args = extensionMain.buildSsmsMinCommandArgs(params);
|
||||||
should(args).equal('-a "myAction\'\\"/\\[]tricky" -S "myServer\'\\"/\\[]tricky" -D "myDatabase\'\\"/\\[]tricky" -G -u "Server\\Database[\'myDatabase\'\'\\"/\\[]tricky\']\\Table[\\"myTable\'\\"\\"/\\[]tricky\\"]"');
|
// User is omitted since UseAAD is true
|
||||||
});
|
should(args).equal('-a "myAction\'\\"/\\[]tricky" -S "myServer\'\\"/\\[]tricky" -D "myDatabase\'\\"/\\[]tricky" -G -u "Server\\Database[\'myDatabase\'\'\\"/\\[]tricky\']\\Table[\\"myTable\'\\"\\"/\\[]tricky\\"]"');
|
||||||
|
});
|
||||||
|
|
||||||
it('Should be built correctly with only action and server', function (): void {
|
it('Should be built correctly with only action and server', function (): void {
|
||||||
|
|
||||||
const params: LaunchSsmsDialogParams = {
|
let params: extensionMain.LaunchSsmsDialogParams = {
|
||||||
action: 'myAction',
|
action: 'myAction',
|
||||||
server: 'myServer'
|
server: 'myServer'
|
||||||
};
|
};
|
||||||
const args = buildSsmsMinCommandArgs(params);
|
let args = extensionMain.buildSsmsMinCommandArgs(params);
|
||||||
should(args).equal('-a "myAction" -S "myServer"');
|
should(args).equal('-a "myAction" -S "myServer"');
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
const serverName = 'My\'Server';
|
|
||||||
const escapedServerName = doubleEscapeSingleQuotes(serverName);
|
|
||||||
const dbName = 'My\'Db';
|
|
||||||
const escapedDbName = doubleEscapeSingleQuotes(dbName);
|
|
||||||
const dbSchema = 'db\'sch';
|
|
||||||
const escapedDbSchema = doubleEscapeSingleQuotes(dbSchema);
|
|
||||||
const tableName = 'My\'Table';
|
|
||||||
const escapedTableName = doubleEscapeSingleQuotes(tableName);
|
|
||||||
const tableSchema = 'tbl\'sch';
|
|
||||||
const escapedTableSchema = doubleEscapeSingleQuotes(tableSchema);
|
|
||||||
|
|
||||||
describe('buildUrn Method Tests', () => {
|
|
||||||
it('Urn should be correct with just server', async function (): Promise<void> {
|
|
||||||
should(await buildUrn(serverName, undefined)).equal(`Server[@Name=\'${escapedServerName}\']`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Urn should be correct with Server and only Databases folder', async function (): Promise<void> {
|
|
||||||
const leafNode: ExtHostObjectExplorerNodeStub =
|
|
||||||
new ExtHostObjectExplorerNodeStub('Databases', undefined, 'Folder', undefined);
|
|
||||||
should(await buildUrn(serverName, leafNode)).equal(`Server[@Name='${escapedServerName}']`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Urn should be correct with Server and Database node', async function (): Promise<void> {
|
|
||||||
const leafNode: ExtHostObjectExplorerNodeStub =
|
|
||||||
new ExtHostObjectExplorerNodeStub('Databases', undefined, 'Folder', undefined)
|
|
||||||
.createChild(dbName, dbSchema, 'Database');
|
|
||||||
should(await buildUrn(serverName, leafNode)).equal(
|
|
||||||
`Server[@Name='${escapedServerName}']/Database[@Name='${escapedDbName}' and @Schema='${escapedDbSchema}']`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Urn should be correct with Multiple levels of Nodes', async function (): Promise<void> {
|
|
||||||
const rootNode: ExtHostObjectExplorerNodeStub =
|
|
||||||
new ExtHostObjectExplorerNodeStub('Databases', undefined, 'Folder', undefined)
|
|
||||||
.createChild(dbName, dbSchema, 'Database')
|
|
||||||
.createChild('Tables', undefined, 'Folder')
|
|
||||||
.createChild(tableName, tableSchema, 'Table');
|
|
||||||
should(await buildUrn(serverName, rootNode)).equal(
|
|
||||||
`Server[@Name='${escapedServerName}']/Database[@Name='${escapedDbName}' and @Schema='${escapedDbSchema}']/Table[@Name='${escapedTableName}' and @Schema='${escapedTableSchema}']`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('doubleEscapeSingleQuotes Method Tests', () => {
|
|
||||||
it('Should return original string if no single quotes', function (): void {
|
|
||||||
const testString: string = 'MyTestString';
|
|
||||||
const ret = doubleEscapeSingleQuotes(testString);
|
|
||||||
should(ret).equal(testString);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should return escaped original string if it contains single quotes', function (): void {
|
|
||||||
const testString: string = 'MyTestString\'\'WithQuotes';
|
|
||||||
const ret = doubleEscapeSingleQuotes(testString);
|
|
||||||
should(ret).equal('MyTestString\'\'\'\'WithQuotes');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('backEscapeDoubleQuotes Method Tests', () => {
|
|
||||||
it('Should return original string if no double quotes', function (): void {
|
|
||||||
const testString: string = 'MyTestString';
|
|
||||||
const ret = backEscapeDoubleQuotes(testString);
|
|
||||||
should(ret).equal(testString);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should return escaped original string if it contains double quotes', function (): void {
|
|
||||||
const testString: string = 'MyTestString\"\"WithQuotes';
|
|
||||||
const ret = backEscapeDoubleQuotes(testString);
|
|
||||||
should(ret).equal('MyTestString\\"\\"WithQuotes');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,19 +7,19 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
|
|
||||||
export interface IPackageInfo {
|
export interface IPackageInfo {
|
||||||
name: string;
|
name: string;
|
||||||
version: string;
|
version: string;
|
||||||
aiKey: string;
|
aiKey: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPackageInfo(packageJson: any): IPackageInfo {
|
export function getPackageInfo(packageJson: any): IPackageInfo {
|
||||||
if (packageJson) {
|
if (packageJson) {
|
||||||
return {
|
return {
|
||||||
name: packageJson.name,
|
name: packageJson.name,
|
||||||
version: packageJson.version,
|
version: packageJson.version,
|
||||||
aiKey: packageJson.aiKey
|
aiKey: packageJson.aiKey
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,33 +28,15 @@ export function getPackageInfo(packageJson: any): IPackageInfo {
|
|||||||
* @param resource The optional URI, as a URI object or a string, to use to get resource-scoped configurations
|
* @param resource The optional URI, as a URI object or a string, to use to get resource-scoped configurations
|
||||||
*/
|
*/
|
||||||
export function getConfiguration(extensionName?: string, resource?: vscode.Uri | string): vscode.WorkspaceConfiguration {
|
export function getConfiguration(extensionName?: string, resource?: vscode.Uri | string): vscode.WorkspaceConfiguration {
|
||||||
if (typeof resource === 'string') {
|
if (typeof resource === 'string') {
|
||||||
try {
|
try {
|
||||||
resource = this.parseUri(resource);
|
resource = this.parseUri(resource);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
resource = undefined;
|
resource = undefined;
|
||||||
}
|
}
|
||||||
} else if (!resource) {
|
} else if (!resource) {
|
||||||
// Fix to avoid adding lots of errors to debug console. Expects a valid resource or null, not undefined
|
// Fix to avoid adding lots of errors to debug console. Expects a valid resource or null, not undefined
|
||||||
resource = null;
|
resource = null;
|
||||||
}
|
}
|
||||||
return vscode.workspace.getConfiguration(extensionName, resource as vscode.Uri);
|
return vscode.workspace.getConfiguration(extensionName, resource as vscode.Uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Escapes all single-quotes (') by prefixing them with another single quote ('')
|
|
||||||
* ' => ''
|
|
||||||
* @param value The string to escape
|
|
||||||
*/
|
|
||||||
export function doubleEscapeSingleQuotes(value: string): string {
|
|
||||||
return value.replace(/'/g, '\'\'');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Escape all double-quotes (") by prefixing them with a \
|
|
||||||
* " => \"
|
|
||||||
* @param value The string to escape
|
|
||||||
*/
|
|
||||||
export function backEscapeDoubleQuotes(value: string): string {
|
|
||||||
return value.replace(/"/g, '\\"');
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,22 @@
|
|||||||
{
|
{
|
||||||
"compileOnSave": true,
|
"compileOnSave": true,
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"outDir": "./out",
|
"outDir": "./out",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es6", "es2015.promise"
|
"es6", "es2015.promise"
|
||||||
],
|
],
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"./node_modules/@types"
|
"./node_modules/@types"
|
||||||
],
|
],
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"declaration": true
|
"declaration": true
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules"
|
"node_modules"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
2710
extensions/agent/package-lock.json
generated
@@ -2,14 +2,14 @@
|
|||||||
"name": "agent",
|
"name": "agent",
|
||||||
"displayName": "SQL Server Agent",
|
"displayName": "SQL Server Agent",
|
||||||
"description": "Manage and troubleshoot SQL Server Agent jobs",
|
"description": "Manage and troubleshoot SQL Server Agent jobs",
|
||||||
"version": "0.39.0",
|
"version": "0.37.0",
|
||||||
"publisher": "Microsoft",
|
"publisher": "Microsoft",
|
||||||
"preview": true,
|
"preview": true,
|
||||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
|
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
|
||||||
"icon": "images/sqlserver.png",
|
"icon": "images/sqlserver.png",
|
||||||
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
|
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.25.0"
|
"vscode": "0.10.x"
|
||||||
},
|
},
|
||||||
"activationEvents": [
|
"activationEvents": [
|
||||||
"*"
|
"*"
|
||||||
@@ -46,13 +46,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"mocha-junit-reporter": "^1.17.0",
|
"mocha-junit-reporter": "^1.17.0",
|
||||||
"mocha-multi-reporters": "^1.1.7",
|
"mocha-multi-reporters": "^1.1.7"
|
||||||
"@types/mocha": "^5.2.5",
|
|
||||||
"@types/node": "^8.10.25",
|
|
||||||
"mocha": "^5.2.0",
|
|
||||||
"should": "^13.2.1",
|
|
||||||
"typemoq": "^2.1.0",
|
|
||||||
"vscode": "1.1.5"
|
|
||||||
},
|
},
|
||||||
"__metadata": {
|
"__metadata": {
|
||||||
"id": "10",
|
"id": "10",
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as data from 'azdata';
|
import * as data from 'azdata';
|
||||||
|
|
||||||
@@ -11,51 +12,52 @@ import * as data from 'azdata';
|
|||||||
* this API from our code
|
* this API from our code
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
* @class ApiWrapper
|
||||||
*/
|
*/
|
||||||
export class ApiWrapper {
|
export class ApiWrapper {
|
||||||
// Data APIs
|
// Data APIs
|
||||||
|
|
||||||
public registerWebviewProvider(widgetId: string, handler: (webview: data.DashboardWebview) => void): void {
|
public registerWebviewProvider(widgetId: string, handler: (webview: data.DashboardWebview) => void): void {
|
||||||
return data.dashboard.registerWebviewProvider(widgetId, handler);
|
return data.dashboard.registerWebviewProvider(widgetId, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public registerControlHostProvider(widgetId: string, handler: (webview: data.DashboardWebview) => void): void {
|
public registerControlHostProvider(widgetId: string, handler: (webview: data.DashboardWebview) => void): void {
|
||||||
return data.dashboard.registerWebviewProvider(widgetId, handler);
|
return data.dashboard.registerWebviewProvider(widgetId, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the configuration for a extensionName
|
* Get the configuration for a extensionName
|
||||||
* @param extensionName The string name of the extension to get the configuration for
|
* @param extensionName The string name of the extension to get the configuration for
|
||||||
* @param resource The optional URI, as a URI object or a string, to use to get resource-scoped configurations
|
* @param resource The optional URI, as a URI object or a string, to use to get resource-scoped configurations
|
||||||
*/
|
*/
|
||||||
public getConfiguration(extensionName: string, resource?: vscode.Uri | string): vscode.WorkspaceConfiguration {
|
public getConfiguration(extensionName: string, resource?: vscode.Uri | string): vscode.WorkspaceConfiguration {
|
||||||
if (typeof resource === 'string') {
|
if (typeof resource === 'string') {
|
||||||
try {
|
try {
|
||||||
resource = this.parseUri(resource);
|
resource = this.parseUri(resource);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
resource = undefined;
|
resource = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return vscode.workspace.getConfiguration(extensionName, resource as vscode.Uri);
|
return vscode.workspace.getConfiguration(extensionName, resource as vscode.Uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse uri
|
* Parse uri
|
||||||
*/
|
*/
|
||||||
public parseUri(uri: string): vscode.Uri {
|
public parseUri(uri: string): vscode.Uri {
|
||||||
return vscode.Uri.parse(uri);
|
return vscode.Uri.parse(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
public showOpenDialog(options: vscode.OpenDialogOptions): Thenable<vscode.Uri[] | undefined> {
|
public showOpenDialog(options: vscode.OpenDialogOptions): Thenable<vscode.Uri[] | undefined> {
|
||||||
return vscode.window.showOpenDialog(options);
|
return vscode.window.showOpenDialog(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public showErrorMessage(message: string, ...items: string[]): Thenable<string | undefined> {
|
public showErrorMessage(message: string, ...items: string[]): Thenable<string | undefined> {
|
||||||
return vscode.window.showErrorMessage(message, ...items);
|
return vscode.window.showErrorMessage(message, ...items);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get workspaceRootPath(): string {
|
public get workspaceRootPath(): string {
|
||||||
return vscode.workspace.rootPath;
|
return vscode.workspace.rootPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export class AlertData implements IAgentDialogData {
|
|||||||
public static readonly AlertTypeSqlServerEventString: string = localize('alertData.DefaultAlertTypString', 'SQL Server event alert');
|
public static readonly AlertTypeSqlServerEventString: string = localize('alertData.DefaultAlertTypString', 'SQL Server event alert');
|
||||||
public static readonly AlertTypePerformanceConditionString: string = localize('alertDialog.PerformanceCondition', 'SQL Server performance condition alert');
|
public static readonly AlertTypePerformanceConditionString: string = localize('alertDialog.PerformanceCondition', 'SQL Server performance condition alert');
|
||||||
public static readonly AlertTypeWmiEventString: string = localize('alertDialog.WmiEvent', 'WMI event alert');
|
public static readonly AlertTypeWmiEventString: string = localize('alertDialog.WmiEvent', 'WMI event alert');
|
||||||
public static readonly DefaultAlertTypeString: string = AlertData.AlertTypeSqlServerEventString;
|
public static readonly DefaultAlertTypeString: string = AlertData.AlertTypeSqlServerEventString;
|
||||||
|
|
||||||
ownerUri: string;
|
ownerUri: string;
|
||||||
dialogMode: AgentDialogMode = AgentDialogMode.CREATE;
|
dialogMode: AgentDialogMode = AgentDialogMode.CREATE;
|
||||||
@@ -50,7 +50,7 @@ export class AlertData implements IAgentDialogData {
|
|||||||
private jobModel: JobData;
|
private jobModel: JobData;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
ownerUri: string,
|
ownerUri:string,
|
||||||
alertInfo: azdata.AgentAlertInfo,
|
alertInfo: azdata.AgentAlertInfo,
|
||||||
jobModel?: JobData,
|
jobModel?: JobData,
|
||||||
viaJobDialog: boolean = false
|
viaJobDialog: boolean = false
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const localize = nls.loadMessageBundle();
|
|||||||
|
|
||||||
export class JobData implements IAgentDialogData {
|
export class JobData implements IAgentDialogData {
|
||||||
|
|
||||||
private readonly JobCompletionActionCondition_Always: string = localize('jobData.whenJobCompletes', 'When the job completes');
|
private readonly JobCompletionActionCondition_Always: string = localize('jobData.whenJobCompletes', 'When the job completes');
|
||||||
private readonly JobCompletionActionCondition_OnFailure: string = localize('jobData.whenJobFails', 'When the job fails');
|
private readonly JobCompletionActionCondition_OnFailure: string = localize('jobData.whenJobFails', 'When the job fails');
|
||||||
private readonly JobCompletionActionCondition_OnSuccess: string = localize('jobData.whenJobSucceeds', 'When the job succeeds');
|
private readonly JobCompletionActionCondition_OnSuccess: string = localize('jobData.whenJobSucceeds', 'When the job succeeds');
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ export class JobData implements IAgentDialogData {
|
|||||||
public async save() {
|
public async save() {
|
||||||
let jobInfo: azdata.AgentJobInfo = this.toAgentJobInfo();
|
let jobInfo: azdata.AgentJobInfo = this.toAgentJobInfo();
|
||||||
let result = this.dialogMode === AgentDialogMode.CREATE
|
let result = this.dialogMode === AgentDialogMode.CREATE
|
||||||
? await this._agentService.createJob(this.ownerUri, jobInfo)
|
? await this._agentService.createJob(this.ownerUri, jobInfo)
|
||||||
: await this._agentService.updateJob(this.ownerUri, this.originalName, jobInfo);
|
: await this._agentService.updateJob(this.ownerUri, this.originalName, jobInfo);
|
||||||
if (!result || !result.success) {
|
if (!result || !result.success) {
|
||||||
if (this.dialogMode === AgentDialogMode.EDIT) {
|
if (this.dialogMode === AgentDialogMode.EDIT) {
|
||||||
@@ -142,7 +142,7 @@ export class JobData implements IAgentDialogData {
|
|||||||
localize('jobData.saveSucessMessage', "Job '{0}' updated successfully", jobInfo.name));
|
localize('jobData.saveSucessMessage', "Job '{0}' updated successfully", jobInfo.name));
|
||||||
} else {
|
} else {
|
||||||
vscode.window.showInformationMessage(
|
vscode.window.showInformationMessage(
|
||||||
localize('jobData.newJobSuccessMessage', "Job '{0}' created successfully", jobInfo.name));
|
localize('jobData.newJobSuccessMessage',"Job '{0}' created successfully", jobInfo.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export class JobStepData implements IAgentDialogData {
|
|||||||
private jobModel: JobData;
|
private jobModel: JobData;
|
||||||
private viaJobDialog: boolean;
|
private viaJobDialog: boolean;
|
||||||
|
|
||||||
constructor(ownerUri: string, jobModel?: JobData, viaJobDialog: boolean = false) {
|
constructor(ownerUri:string, jobModel?: JobData, viaJobDialog: boolean = false) {
|
||||||
this.ownerUri = ownerUri;
|
this.ownerUri = ownerUri;
|
||||||
this.jobName = jobModel.name;
|
this.jobName = jobModel.name;
|
||||||
this.jobModel = jobModel;
|
this.jobModel = jobModel;
|
||||||
@@ -102,26 +102,26 @@ export class JobStepData implements IAgentDialogData {
|
|||||||
stepData.jobName = jobStepInfo.jobName;
|
stepData.jobName = jobStepInfo.jobName;
|
||||||
stepData.script = jobStepInfo.script;
|
stepData.script = jobStepInfo.script;
|
||||||
stepData.scriptName = jobStepInfo.scriptName,
|
stepData.scriptName = jobStepInfo.scriptName,
|
||||||
stepData.stepName = jobStepInfo.stepName,
|
stepData.stepName = jobStepInfo.stepName,
|
||||||
stepData.subSystem = jobStepInfo.subSystem,
|
stepData.subSystem = jobStepInfo.subSystem,
|
||||||
stepData.id = jobStepInfo.id,
|
stepData.id = jobStepInfo.id,
|
||||||
stepData.failureAction = jobStepInfo.failureAction,
|
stepData.failureAction = jobStepInfo.failureAction,
|
||||||
stepData.successAction = jobStepInfo.successAction,
|
stepData.successAction = jobStepInfo.successAction,
|
||||||
stepData.failStepId = jobStepInfo.failStepId,
|
stepData.failStepId = jobStepInfo.failStepId,
|
||||||
stepData.successStepId = jobStepInfo.successStepId,
|
stepData.successStepId = jobStepInfo.successStepId,
|
||||||
stepData.command = jobStepInfo.command,
|
stepData.command = jobStepInfo.command,
|
||||||
stepData.commandExecutionSuccessCode = jobStepInfo.commandExecutionSuccessCode,
|
stepData.commandExecutionSuccessCode = jobStepInfo.commandExecutionSuccessCode,
|
||||||
stepData.databaseName = jobStepInfo.databaseName,
|
stepData.databaseName = jobStepInfo.databaseName,
|
||||||
stepData.databaseUserName = jobStepInfo.databaseUserName,
|
stepData.databaseUserName = jobStepInfo.databaseUserName,
|
||||||
stepData.server = jobStepInfo.server,
|
stepData.server = jobStepInfo.server,
|
||||||
stepData.outputFileName = jobStepInfo.outputFileName,
|
stepData.outputFileName = jobStepInfo.outputFileName,
|
||||||
stepData.appendToLogFile = jobStepInfo.appendToLogFile,
|
stepData.appendToLogFile = jobStepInfo.appendToLogFile,
|
||||||
stepData.appendToStepHist = jobStepInfo.appendToStepHist,
|
stepData.appendToStepHist = jobStepInfo.appendToStepHist,
|
||||||
stepData.writeLogToTable = jobStepInfo.writeLogToTable,
|
stepData.writeLogToTable = jobStepInfo.writeLogToTable,
|
||||||
stepData.appendLogToTable = jobStepInfo.appendLogToTable,
|
stepData.appendLogToTable = jobStepInfo.appendLogToTable,
|
||||||
stepData.retryAttempts = jobStepInfo.retryAttempts,
|
stepData.retryAttempts = jobStepInfo.retryAttempts,
|
||||||
stepData.retryInterval = jobStepInfo.retryInterval,
|
stepData.retryInterval = jobStepInfo.retryInterval,
|
||||||
stepData.proxyName = jobStepInfo.proxyName;
|
stepData.proxyName = jobStepInfo.proxyName;
|
||||||
stepData.dialogMode = AgentDialogMode.EDIT;
|
stepData.dialogMode = AgentDialogMode.EDIT;
|
||||||
stepData.viaJobDialog = true;
|
stepData.viaJobDialog = true;
|
||||||
return stepData;
|
return stepData;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export class OperatorData implements IAgentDialogData {
|
|||||||
weekdayPagerStartTime: string;
|
weekdayPagerStartTime: string;
|
||||||
weekdayPagerEndTime: string;
|
weekdayPagerEndTime: string;
|
||||||
|
|
||||||
constructor(ownerUri: string, operatorInfo: azdata.AgentOperatorInfo) {
|
constructor(ownerUri:string, operatorInfo: azdata.AgentOperatorInfo) {
|
||||||
this.ownerUri = ownerUri;
|
this.ownerUri = ownerUri;
|
||||||
if (operatorInfo) {
|
if (operatorInfo) {
|
||||||
this.dialogMode = AgentDialogMode.EDIT;
|
this.dialogMode = AgentDialogMode.EDIT;
|
||||||
@@ -58,7 +58,7 @@ export class OperatorData implements IAgentDialogData {
|
|||||||
|
|
||||||
public async save() {
|
public async save() {
|
||||||
let agentService = await AgentUtils.getAgentService();
|
let agentService = await AgentUtils.getAgentService();
|
||||||
let result = await agentService.createOperator(this.ownerUri, this.toAgentOperatorInfo());
|
let result = await agentService.createOperator(this.ownerUri, this.toAgentOperatorInfo());
|
||||||
if (!result || !result.success) {
|
if (!result || !result.success) {
|
||||||
// TODO handle error here
|
// TODO handle error here
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export class PickScheduleData implements IAgentDialogData {
|
|||||||
public selectedSchedule: azdata.AgentJobScheduleInfo;
|
public selectedSchedule: azdata.AgentJobScheduleInfo;
|
||||||
private jobName: string;
|
private jobName: string;
|
||||||
|
|
||||||
constructor(ownerUri: string, jobName: string) {
|
constructor(ownerUri:string, jobName: string) {
|
||||||
this.ownerUri = ownerUri;
|
this.ownerUri = ownerUri;
|
||||||
this.jobName = jobName;
|
this.jobName = jobName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export class ProxyData implements IAgentDialogData {
|
|||||||
credentialId: number;
|
credentialId: number;
|
||||||
isEnabled: boolean;
|
isEnabled: boolean;
|
||||||
|
|
||||||
constructor(ownerUri: string, proxyInfo: azdata.AgentProxyInfo) {
|
constructor(ownerUri:string, proxyInfo: azdata.AgentProxyInfo) {
|
||||||
this.ownerUri = ownerUri;
|
this.ownerUri = ownerUri;
|
||||||
|
|
||||||
if (proxyInfo) {
|
if (proxyInfo) {
|
||||||
@@ -48,7 +48,7 @@ export class ProxyData implements IAgentDialogData {
|
|||||||
localize('proxyData.saveSucessMessage', "Proxy '{0}' updated successfully", proxyInfo.accountName));
|
localize('proxyData.saveSucessMessage', "Proxy '{0}' updated successfully", proxyInfo.accountName));
|
||||||
} else {
|
} else {
|
||||||
vscode.window.showInformationMessage(
|
vscode.window.showInformationMessage(
|
||||||
localize('proxyData.newJobSuccessMessage', "Proxy '{0}' created successfully", proxyInfo.accountName));
|
localize('proxyData.newJobSuccessMessage',"Proxy '{0}' created successfully", proxyInfo.accountName));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export class ScheduleData implements IAgentDialogData {
|
|||||||
public schedules: azdata.AgentJobScheduleInfo[];
|
public schedules: azdata.AgentJobScheduleInfo[];
|
||||||
public selectedSchedule: azdata.AgentJobScheduleInfo;
|
public selectedSchedule: azdata.AgentJobScheduleInfo;
|
||||||
|
|
||||||
constructor(ownerUri: string) {
|
constructor(ownerUri:string) {
|
||||||
this.ownerUri = ownerUri;
|
this.ownerUri = ownerUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,14 +62,14 @@ export class AlertDialog extends AgentDialog<AlertData> {
|
|||||||
private static readonly AlertSeverity025Label: string = localize('alertDialog.Severity025', '025 - Fatal Error');
|
private static readonly AlertSeverity025Label: string = localize('alertDialog.Severity025', '025 - Fatal Error');
|
||||||
private static readonly AllDatabases: string = localize('alertDialog.AllDatabases', '<all databases>');
|
private static readonly AllDatabases: string = localize('alertDialog.AllDatabases', '<all databases>');
|
||||||
|
|
||||||
private static readonly AlertTypes: string[] = [
|
private static readonly AlertTypes: string[] = [
|
||||||
AlertData.AlertTypeSqlServerEventString,
|
AlertData.AlertTypeSqlServerEventString,
|
||||||
// Disabled until next release
|
// Disabled until next release
|
||||||
// AlertData.AlertTypePerformanceConditionString,
|
// AlertData.AlertTypePerformanceConditionString,
|
||||||
// AlertData.AlertTypeWmiEventString
|
// AlertData.AlertTypeWmiEventString
|
||||||
];
|
];
|
||||||
|
|
||||||
private static readonly AlertSeverities: string[] = [
|
private static readonly AlertSeverities: string[] = [
|
||||||
AlertDialog.AlertSeverity001Label,
|
AlertDialog.AlertSeverity001Label,
|
||||||
AlertDialog.AlertSeverity002Label,
|
AlertDialog.AlertSeverity002Label,
|
||||||
AlertDialog.AlertSeverity003Label,
|
AlertDialog.AlertSeverity003Label,
|
||||||
@@ -100,21 +100,21 @@ export class AlertDialog extends AgentDialog<AlertData> {
|
|||||||
// Response tab strings
|
// Response tab strings
|
||||||
private static readonly ExecuteJobCheckBoxLabel: string = localize('alertDialog.ExecuteJob', 'Execute Job');
|
private static readonly ExecuteJobCheckBoxLabel: string = localize('alertDialog.ExecuteJob', 'Execute Job');
|
||||||
private static readonly ExecuteJobTextBoxLabel: string = localize('alertDialog.ExecuteJobName', 'Job Name');
|
private static readonly ExecuteJobTextBoxLabel: string = localize('alertDialog.ExecuteJobName', 'Job Name');
|
||||||
private static readonly NotifyOperatorsTextBoxLabel: string = localize('alertDialog.NotifyOperators', 'Notify Operators');
|
private static readonly NotifyOperatorsTextBoxLabel: string = localize('alertDialog.NotifyOperators', 'Notify Operators');
|
||||||
private static readonly NewJobButtonLabel: string = localize('alertDialog.NewJob', 'New Job');
|
private static readonly NewJobButtonLabel: string = localize('alertDialog.NewJob', 'New Job');
|
||||||
private static readonly OperatorListLabel: string = localize('alertDialog.OperatorList', 'Operator List');
|
private static readonly OperatorListLabel: string = localize('alertDialog.OperatorList', 'Operator List');
|
||||||
private static readonly OperatorNameColumnLabel: string = localize('alertDialog.OperatorName', 'Operator');
|
private static readonly OperatorNameColumnLabel: string = localize('alertDialog.OperatorName', 'Operator');
|
||||||
private static readonly OperatorEmailColumnLabel: string = localize('alertDialog.OperatorEmail', 'E-mail');
|
private static readonly OperatorEmailColumnLabel: string = localize('alertDialog.OperatorEmail', 'E-mail');
|
||||||
private static readonly OperatorPagerColumnLabel: string = localize('alertDialog.OperatorPager', 'Pager');
|
private static readonly OperatorPagerColumnLabel: string = localize('alertDialog.OperatorPager', 'Pager');
|
||||||
private static readonly NewOperatorButtonLabel: string = localize('alertDialog.NewOperator', 'New Operator');
|
private static readonly NewOperatorButtonLabel: string = localize('alertDialog.NewOperator', 'New Operator');
|
||||||
|
|
||||||
// Options tab strings
|
// Options tab strings
|
||||||
private static readonly IncludeErrorInEmailCheckBoxLabel: string = localize('alertDialog.IncludeErrorInEmail', 'Include alert error text in e-mail');
|
private static readonly IncludeErrorInEmailCheckBoxLabel: string = localize('alertDialog.IncludeErrorInEmail', 'Include alert error text in e-mail');
|
||||||
private static readonly IncludeErrorInPagerCheckBoxLabel: string = localize('alertDialog.IncludeErrorInPager', 'Include alert error text in pager');
|
private static readonly IncludeErrorInPagerCheckBoxLabel: string = localize('alertDialog.IncludeErrorInPager', 'Include alert error text in pager');
|
||||||
private static readonly AdditionalMessageTextBoxLabel: string = localize('alertDialog.AdditionalNotification', 'Additional notification message to send');
|
private static readonly AdditionalMessageTextBoxLabel: string = localize('alertDialog.AdditionalNotification', 'Additional notification message to send');
|
||||||
private static readonly DelayBetweenResponsesTextBoxLabel: string = localize('alertDialog.DelayBetweenResponse', 'Delay between responses');
|
private static readonly DelayBetweenResponsesTextBoxLabel: string = localize('alertDialog.DelayBetweenResponse', 'Delay between responses');
|
||||||
private static readonly DelayMinutesTextBoxLabel: string = localize('alertDialog.DelayMinutes', 'Delay Minutes');
|
private static readonly DelayMinutesTextBoxLabel: string = localize('alertDialog.DelayMinutes', 'Delay Minutes');
|
||||||
private static readonly DelaySecondsTextBoxLabel: string = localize('alertDialog.DelaySeconds', 'Delay Seconds');
|
private static readonly DelaySecondsTextBoxLabel: string = localize('alertDialog.DelaySeconds', 'Delay Seconds');
|
||||||
|
|
||||||
// Event Name strings
|
// Event Name strings
|
||||||
private readonly NewAlertDialog = 'NewAlertDialogOpen';
|
private readonly NewAlertDialog = 'NewAlertDialogOpen';
|
||||||
@@ -315,7 +315,7 @@ export class AlertDialog extends AgentDialog<AlertData> {
|
|||||||
}],
|
}],
|
||||||
title: AlertDialog.EventAlertText
|
title: AlertDialog.EventAlertText
|
||||||
}
|
}
|
||||||
]).withLayout({ width: '100%' }).component();
|
]).withLayout({ width: '100%' }).component();
|
||||||
|
|
||||||
await view.initializeModel(formModel);
|
await view.initializeModel(formModel);
|
||||||
|
|
||||||
@@ -332,7 +332,7 @@ export class AlertDialog extends AgentDialog<AlertData> {
|
|||||||
|
|
||||||
if (this.model.severity > 0) {
|
if (this.model.severity > 0) {
|
||||||
this.severityRadioButton.checked = true;
|
this.severityRadioButton.checked = true;
|
||||||
this.severityDropDown.value = this.severityDropDown.values[this.model.severity - 1];
|
this.severityDropDown.value = this.severityDropDown.values[this.model.severity-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.model.databaseName) {
|
if (this.model.databaseName) {
|
||||||
@@ -356,9 +356,9 @@ export class AlertDialog extends AgentDialog<AlertData> {
|
|||||||
.component();
|
.component();
|
||||||
this.executeJobTextBox.enabled = false;
|
this.executeJobTextBox.enabled = false;
|
||||||
this.newJobButton = view.modelBuilder.button().withProperties({
|
this.newJobButton = view.modelBuilder.button().withProperties({
|
||||||
label: AlertDialog.NewJobButtonLabel,
|
label: AlertDialog.NewJobButtonLabel,
|
||||||
width: 80
|
width: 80
|
||||||
}).component();
|
}).component();
|
||||||
this.newJobButton.enabled = false;
|
this.newJobButton.enabled = false;
|
||||||
this.newJobButton.onDidClick(() => {
|
this.newJobButton.onDidClick(() => {
|
||||||
let jobDialog = new JobDialog(this.ownerUri);
|
let jobDialog = new JobDialog(this.ownerUri);
|
||||||
@@ -382,7 +382,7 @@ export class AlertDialog extends AgentDialog<AlertData> {
|
|||||||
}, {
|
}, {
|
||||||
component: this.newJobButton,
|
component: this.newJobButton,
|
||||||
title: AlertDialog.NewJobButtonLabel
|
title: AlertDialog.NewJobButtonLabel
|
||||||
}], { componentWidth: '100%' }).component();
|
}], { componentWidth: '100%'}).component();
|
||||||
|
|
||||||
let previewTag = view.modelBuilder.text()
|
let previewTag = view.modelBuilder.text()
|
||||||
.withProperties({
|
.withProperties({
|
||||||
@@ -409,9 +409,9 @@ export class AlertDialog extends AgentDialog<AlertData> {
|
|||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
this.newOperatorButton = view.modelBuilder.button().withProperties({
|
this.newOperatorButton = view.modelBuilder.button().withProperties({
|
||||||
label: AlertDialog.NewOperatorButtonLabel,
|
label: AlertDialog.NewOperatorButtonLabel,
|
||||||
width: 80
|
width: 80
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
this.operatorsTable.enabled = false;
|
this.operatorsTable.enabled = false;
|
||||||
this.newOperatorButton.enabled = false;
|
this.newOperatorButton.enabled = false;
|
||||||
@@ -438,7 +438,7 @@ export class AlertDialog extends AgentDialog<AlertData> {
|
|||||||
}, {
|
}, {
|
||||||
component: this.newOperatorButton,
|
component: this.newOperatorButton,
|
||||||
title: ''
|
title: ''
|
||||||
}], { componentWidth: '100%' }).component();
|
}], { componentWidth: '100%'}).component();
|
||||||
|
|
||||||
let formModel = view.modelBuilder.formContainer()
|
let formModel = view.modelBuilder.formContainer()
|
||||||
.withFormItems([{
|
.withFormItems([{
|
||||||
@@ -548,7 +548,7 @@ export class AlertDialog extends AgentDialog<AlertData> {
|
|||||||
} else {
|
} else {
|
||||||
this.model.eventDescriptionKeyword = '';
|
this.model.eventDescriptionKeyword = '';
|
||||||
}
|
}
|
||||||
let minutes = this.delayMinutesTextBox.value ? +this.delayMinutesTextBox.value : 0;
|
let minutes = this.delayMinutesTextBox.value ? +this.delayMinutesTextBox.value : 0;
|
||||||
let seconds = this.delaySecondsTextBox.value ? +this.delaySecondsTextBox : 0;
|
let seconds = this.delaySecondsTextBox.value ? +this.delaySecondsTextBox : 0;
|
||||||
this.model.delayBetweenResponses = minutes + seconds;
|
this.model.delayBetweenResponses = minutes + seconds;
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export class JobDialog extends AgentDialog<JobData> {
|
|||||||
|
|
||||||
// Event Name strings
|
// Event Name strings
|
||||||
private readonly NewJobDialogEvent: string = 'NewJobDialogOpened';
|
private readonly NewJobDialogEvent: string = 'NewJobDialogOpened';
|
||||||
private readonly EditJobDialogEvent: string = 'EditJobDialogOpened';
|
private readonly EditJobDialogEvent: string = 'EditJobDialogOpened';
|
||||||
|
|
||||||
// UI Components
|
// UI Components
|
||||||
private generalTab: azdata.window.DialogTab;
|
private generalTab: azdata.window.DialogTab;
|
||||||
@@ -259,9 +259,9 @@ export class JobDialog extends AgentDialog<JobData> {
|
|||||||
width: 140
|
width: 140
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
this.newStepButton.onDidClick((e) => {
|
this.newStepButton.onDidClick((e)=>{
|
||||||
if (this.nameTextBox.value && this.nameTextBox.value.length > 0) {
|
if (this.nameTextBox.value && this.nameTextBox.value.length > 0) {
|
||||||
let stepDialog = new JobStepDialog(this.model.ownerUri, '', this.model, null, true);
|
let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, null, true);
|
||||||
stepDialog.onSuccess((step) => {
|
stepDialog.onSuccess((step) => {
|
||||||
let stepInfo = JobStepData.convertToAgentJobStepInfo(step);
|
let stepInfo = JobStepData.convertToAgentJobStepInfo(step);
|
||||||
this.steps.push(stepInfo);
|
this.steps.push(stepInfo);
|
||||||
@@ -296,7 +296,7 @@ export class JobDialog extends AgentDialog<JobData> {
|
|||||||
this.deleteStepButton.enabled = false;
|
this.deleteStepButton.enabled = false;
|
||||||
|
|
||||||
this.moveStepUpButton.onDidClick(() => {
|
this.moveStepUpButton.onDidClick(() => {
|
||||||
let rowNumber = this.stepsTable.selectedRows[0];
|
let rowNumber = this.stepsTable.selectedRows[0];
|
||||||
let previousRow = rowNumber - 1;
|
let previousRow = rowNumber - 1;
|
||||||
let previousStep = this.steps[previousRow];
|
let previousStep = this.steps[previousRow];
|
||||||
let previousStepId = this.steps[previousRow].id;
|
let previousStepId = this.steps[previousRow].id;
|
||||||
@@ -329,7 +329,7 @@ export class JobDialog extends AgentDialog<JobData> {
|
|||||||
if (this.stepsTable.selectedRows.length === 1) {
|
if (this.stepsTable.selectedRows.length === 1) {
|
||||||
let rowNumber = this.stepsTable.selectedRows[0];
|
let rowNumber = this.stepsTable.selectedRows[0];
|
||||||
let stepData = this.model.jobSteps[rowNumber];
|
let stepData = this.model.jobSteps[rowNumber];
|
||||||
let editStepDialog = new JobStepDialog(this.model.ownerUri, '', this.model, stepData, true);
|
let editStepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, stepData, true);
|
||||||
editStepDialog.onSuccess((step) => {
|
editStepDialog.onSuccess((step) => {
|
||||||
let stepInfo = JobStepData.convertToAgentJobStepInfo(step);
|
let stepInfo = JobStepData.convertToAgentJobStepInfo(step);
|
||||||
for (let i = 0; i < this.steps.length; i++) {
|
for (let i = 0; i < this.steps.length; i++) {
|
||||||
@@ -349,7 +349,7 @@ export class JobDialog extends AgentDialog<JobData> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.deleteStepButton.onDidClick(async () => {
|
this.deleteStepButton.onDidClick(async() => {
|
||||||
if (this.stepsTable.selectedRows.length === 1) {
|
if (this.stepsTable.selectedRows.length === 1) {
|
||||||
let rowNumber = this.stepsTable.selectedRows[0];
|
let rowNumber = this.stepsTable.selectedRows[0];
|
||||||
AgentUtils.getAgentService().then(async (agentService) => {
|
AgentUtils.getAgentService().then(async (agentService) => {
|
||||||
@@ -448,7 +448,7 @@ export class JobDialog extends AgentDialog<JobData> {
|
|||||||
this.alerts.push(alertInfo);
|
this.alerts.push(alertInfo);
|
||||||
this.alertsTable.data = this.convertAlertsToData(this.alerts);
|
this.alertsTable.data = this.convertAlertsToData(this.alerts);
|
||||||
});
|
});
|
||||||
this.newAlertButton.onDidClick(() => {
|
this.newAlertButton.onDidClick(()=>{
|
||||||
if (this.nameTextBox.value && this.nameTextBox.value.length > 0) {
|
if (this.nameTextBox.value && this.nameTextBox.value.length > 0) {
|
||||||
alertDialog.jobId = this.model.jobId;
|
alertDialog.jobId = this.model.jobId;
|
||||||
alertDialog.jobName = this.model.name ? this.model.name : this.nameTextBox.value;
|
alertDialog.jobName = this.model.name ? this.model.name : this.nameTextBox.value;
|
||||||
@@ -491,7 +491,7 @@ export class JobDialog extends AgentDialog<JobData> {
|
|||||||
label: 'Remove schedule',
|
label: 'Remove schedule',
|
||||||
width: 100
|
width: 100
|
||||||
}).component();
|
}).component();
|
||||||
this.pickScheduleButton.onDidClick(() => {
|
this.pickScheduleButton.onDidClick(()=>{
|
||||||
let pickScheduleDialog = new PickScheduleDialog(this.model.ownerUri, this.model.name);
|
let pickScheduleDialog = new PickScheduleDialog(this.model.ownerUri, this.model.name);
|
||||||
pickScheduleDialog.onSuccess((dialogModel) => {
|
pickScheduleDialog.onSuccess((dialogModel) => {
|
||||||
let selectedSchedule = dialogModel.selectedSchedule;
|
let selectedSchedule = dialogModel.selectedSchedule;
|
||||||
@@ -507,8 +507,8 @@ export class JobDialog extends AgentDialog<JobData> {
|
|||||||
pickScheduleDialog.showDialog();
|
pickScheduleDialog.showDialog();
|
||||||
});
|
});
|
||||||
this.removeScheduleButton.onDidClick(() => {
|
this.removeScheduleButton.onDidClick(() => {
|
||||||
if (this.schedulesTable.selectedRows.length === 1) {
|
if (this.schedulesTable.selectedRows.length === 1) {
|
||||||
let selectedRow = this.schedulesTable.selectedRows[0];
|
let selectedRow = this.schedulesTable.selectedRows[0];
|
||||||
let selectedScheduleName = this.schedulesTable.data[selectedRow][1];
|
let selectedScheduleName = this.schedulesTable.data[selectedRow][1];
|
||||||
for (let i = 0; i < this.schedules.length; i++) {
|
for (let i = 0; i < this.schedules.length; i++) {
|
||||||
if (this.schedules[i].name === selectedScheduleName) {
|
if (this.schedules[i].name === selectedScheduleName) {
|
||||||
@@ -595,23 +595,22 @@ export class JobDialog extends AgentDialog<JobData> {
|
|||||||
let formModel = view.modelBuilder.formContainer().withFormItems([
|
let formModel = view.modelBuilder.formContainer().withFormItems([
|
||||||
{
|
{
|
||||||
components:
|
components:
|
||||||
[{
|
[{
|
||||||
component: emailContainer,
|
component: emailContainer,
|
||||||
title: ''
|
title: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: pagerContainer,
|
component: pagerContainer,
|
||||||
title: ''
|
title: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: eventLogContainer,
|
component: eventLogContainer,
|
||||||
title: ''
|
title: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: deleteJobContainer,
|
component: deleteJobContainer,
|
||||||
title: ''
|
title: ''
|
||||||
}], title: this.NotificationsTabTopLabelString
|
}], title: this.NotificationsTabTopLabelString}]).withLayout({ width: '100%' }).component();
|
||||||
}]).withLayout({ width: '100%' }).component();
|
|
||||||
|
|
||||||
await view.initializeModel(formModel);
|
await view.initializeModel(formModel);
|
||||||
this.emailConditionDropdown.values = this.model.JobCompletionActionConditions;
|
this.emailConditionDropdown.values = this.model.JobCompletionActionConditions;
|
||||||
@@ -695,7 +694,7 @@ export class JobDialog extends AgentDialog<JobData> {
|
|||||||
this.model.pageLevel = this.getActualConditionValue(this.pagerCheckBox, this.pagerConditionDropdown);
|
this.model.pageLevel = this.getActualConditionValue(this.pagerCheckBox, this.pagerConditionDropdown);
|
||||||
this.model.eventLogLevel = this.getActualConditionValue(this.eventLogCheckBox, this.eventLogConditionDropdown);
|
this.model.eventLogLevel = this.getActualConditionValue(this.eventLogCheckBox, this.eventLogConditionDropdown);
|
||||||
this.model.deleteLevel = this.getActualConditionValue(this.deleteJobCheckBox, this.deleteJobConditionDropdown);
|
this.model.deleteLevel = this.getActualConditionValue(this.deleteJobCheckBox, this.deleteJobConditionDropdown);
|
||||||
this.model.startStepId = this.startStepDropdown.enabled ? +this.getDropdownValue(this.startStepDropdown) : 1;
|
this.model.startStepId = this.startStepDropdown.enabled ? +this.getDropdownValue(this.startStepDropdown) : 1;
|
||||||
if (!this.model.jobSteps) {
|
if (!this.model.jobSteps) {
|
||||||
this.model.jobSteps = [];
|
this.model.jobSteps = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
|||||||
private readonly GeneralTabText: string = localize('jobStepDialog.general', 'General');
|
private readonly GeneralTabText: string = localize('jobStepDialog.general', 'General');
|
||||||
private readonly AdvancedTabText: string = localize('jobStepDialog.advanced', 'Advanced');
|
private readonly AdvancedTabText: string = localize('jobStepDialog.advanced', 'Advanced');
|
||||||
private readonly OpenCommandText: string = localize('jobStepDialog.open', 'Open...');
|
private readonly OpenCommandText: string = localize('jobStepDialog.open', 'Open...');
|
||||||
private readonly ParseCommandText: string = localize('jobStepDialog.parse', 'Parse');
|
private readonly ParseCommandText: string = localize('jobStepDialog.parse','Parse');
|
||||||
private readonly SuccessfulParseText: string = localize('jobStepDialog.successParse', 'The command was successfully parsed.');
|
private readonly SuccessfulParseText: string = localize('jobStepDialog.successParse', 'The command was successfully parsed.');
|
||||||
private readonly FailureParseText: string = localize('jobStepDialog.failParse', 'The command failed.');
|
private readonly FailureParseText: string = localize('jobStepDialog.failParse', 'The command failed.');
|
||||||
private readonly BlankStepNameErrorText: string = localize('jobStepDialog.blankStepName', 'The step name cannot be left blank');
|
private readonly BlankStepNameErrorText: string = localize('jobStepDialog.blankStepName', 'The step name cannot be left blank');
|
||||||
@@ -124,15 +124,15 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
|||||||
viaJobDialog: boolean = false
|
viaJobDialog: boolean = false
|
||||||
) {
|
) {
|
||||||
super(ownerUri,
|
super(ownerUri,
|
||||||
jobStepInfo ? JobStepData.convertToJobStepData(jobStepInfo, jobModel) : new JobStepData(ownerUri, jobModel, viaJobDialog),
|
jobStepInfo ? JobStepData.convertToJobStepData(jobStepInfo, jobModel) : new JobStepData(ownerUri, jobModel, viaJobDialog),
|
||||||
jobStepInfo ? JobStepDialog.EditDialogTitle : JobStepDialog.NewDialogTitle);
|
jobStepInfo ? JobStepDialog.EditDialogTitle : JobStepDialog.NewDialogTitle);
|
||||||
this.stepId = jobStepInfo ?
|
this.stepId = jobStepInfo ?
|
||||||
jobStepInfo.id : jobModel.jobSteps ?
|
jobStepInfo.id : jobModel.jobSteps ?
|
||||||
jobModel.jobSteps.length + 1 : 1;
|
jobModel.jobSteps.length + 1 : 1;
|
||||||
this.isEdit = jobStepInfo ? true : false;
|
this.isEdit = jobStepInfo ? true : false;
|
||||||
this.model.dialogMode = this.isEdit ? AgentDialogMode.EDIT : AgentDialogMode.CREATE;
|
this.model.dialogMode = this.isEdit ? AgentDialogMode.EDIT : AgentDialogMode.CREATE;
|
||||||
this.jobModel = jobModel;
|
this.jobModel = jobModel;
|
||||||
this.jobName = this.jobName ? this.jobName : this.jobModel.name;
|
this.jobName = this.jobName ? this.jobName : this.jobModel.name;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.dialogName = this.isEdit ? this.EditStepDialog : this.NewStepDialog;
|
this.dialogName = this.isEdit ? this.EditStepDialog : this.NewStepDialog;
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,7 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
|||||||
if (this.commandTextBox.value) {
|
if (this.commandTextBox.value) {
|
||||||
queryProvider.parseSyntax(this.ownerUri, this.commandTextBox.value).then(result => {
|
queryProvider.parseSyntax(this.ownerUri, this.commandTextBox.value).then(result => {
|
||||||
if (result && result.parseable) {
|
if (result && result.parseable) {
|
||||||
this.dialog.message = { text: this.SuccessfulParseText, level: 2 };
|
this.dialog.message = { text: this.SuccessfulParseText, level: 2};
|
||||||
} else if (result && !result.parseable) {
|
} else if (result && !result.parseable) {
|
||||||
this.dialog.message = { text: this.FailureParseText };
|
this.dialog.message = { text: this.FailureParseText };
|
||||||
}
|
}
|
||||||
@@ -246,7 +246,7 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
|||||||
}).component();
|
}).component();
|
||||||
this.typeDropdown.onValueChanged((type) => {
|
this.typeDropdown.onValueChanged((type) => {
|
||||||
switch (type.selected) {
|
switch (type.selected) {
|
||||||
case (this.TSQLScript):
|
case(this.TSQLScript):
|
||||||
this.runAsDropdown.value = '';
|
this.runAsDropdown.value = '';
|
||||||
this.runAsDropdown.values = [''];
|
this.runAsDropdown.values = [''];
|
||||||
this.runAsDropdown.enabled = false;
|
this.runAsDropdown.enabled = false;
|
||||||
@@ -256,7 +256,7 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
|||||||
this.processExitCodeBox.value = '';
|
this.processExitCodeBox.value = '';
|
||||||
this.processExitCodeBox.enabled = false;
|
this.processExitCodeBox.enabled = false;
|
||||||
break;
|
break;
|
||||||
case (this.Powershell):
|
case(this.Powershell):
|
||||||
this.runAsDropdown.value = this.AgentServiceAccount;
|
this.runAsDropdown.value = this.AgentServiceAccount;
|
||||||
this.runAsDropdown.values = [this.runAsDropdown.value];
|
this.runAsDropdown.values = [this.runAsDropdown.value];
|
||||||
this.runAsDropdown.enabled = true;
|
this.runAsDropdown.enabled = true;
|
||||||
@@ -266,7 +266,7 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
|||||||
this.processExitCodeBox.value = '';
|
this.processExitCodeBox.value = '';
|
||||||
this.processExitCodeBox.enabled = false;
|
this.processExitCodeBox.enabled = false;
|
||||||
break;
|
break;
|
||||||
case (this.CmdExec):
|
case(this.CmdExec):
|
||||||
this.databaseDropdown.enabled = false;
|
this.databaseDropdown.enabled = false;
|
||||||
this.databaseDropdown.values = [''];
|
this.databaseDropdown.values = [''];
|
||||||
this.databaseDropdown.value = '';
|
this.databaseDropdown.value = '';
|
||||||
@@ -397,13 +397,13 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
|||||||
|
|
||||||
let retryAttemptsContainer = view.modelBuilder.formContainer()
|
let retryAttemptsContainer = view.modelBuilder.formContainer()
|
||||||
.withFormItems(
|
.withFormItems(
|
||||||
[{
|
[{
|
||||||
component: this.retryAttemptsBox,
|
component: this.retryAttemptsBox,
|
||||||
title: this.RetryAttemptsLabel
|
title: this.RetryAttemptsLabel
|
||||||
}], {
|
}], {
|
||||||
horizontal: false,
|
horizontal: false,
|
||||||
componentWidth: '100%'
|
componentWidth: '100%'
|
||||||
})
|
})
|
||||||
.component();
|
.component();
|
||||||
|
|
||||||
let retryIntervalContainer = view.modelBuilder.formContainer()
|
let retryIntervalContainer = view.modelBuilder.formContainer()
|
||||||
@@ -411,7 +411,7 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
|||||||
[{
|
[{
|
||||||
component: this.retryIntervalBox,
|
component: this.retryIntervalBox,
|
||||||
title: this.RetryIntervalLabel
|
title: this.RetryIntervalLabel
|
||||||
}], {
|
}], {
|
||||||
horizontal: false
|
horizontal: false
|
||||||
})
|
})
|
||||||
.component();
|
.component();
|
||||||
@@ -427,13 +427,13 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
|||||||
let fileBrowserTitle = this.FileBrowserDialogTitle + `${this.server}`;
|
let fileBrowserTitle = this.FileBrowserDialogTitle + `${this.server}`;
|
||||||
this.fileBrowserDialog = azdata.window.createModelViewDialog(fileBrowserTitle);
|
this.fileBrowserDialog = azdata.window.createModelViewDialog(fileBrowserTitle);
|
||||||
let fileBrowserTab = azdata.window.createTab('File Browser');
|
let fileBrowserTab = azdata.window.createTab('File Browser');
|
||||||
this.fileBrowserDialog.content = [fileBrowserTab];
|
this.fileBrowserDialog.content = [fileBrowserTab];
|
||||||
fileBrowserTab.registerContent(async (view) => {
|
fileBrowserTab.registerContent(async (view) => {
|
||||||
this.fileBrowserTree = view.modelBuilder.fileBrowserTree()
|
this.fileBrowserTree = view.modelBuilder.fileBrowserTree()
|
||||||
.withProperties({ ownerUri: this.ownerUri, width: 420, height: 700 })
|
.withProperties({ ownerUri: this.ownerUri, width: 420, height: 700 })
|
||||||
.component();
|
.component();
|
||||||
this.selectedPathTextBox = view.modelBuilder.inputBox()
|
this.selectedPathTextBox = view.modelBuilder.inputBox()
|
||||||
.withProperties({ inputType: 'text' })
|
.withProperties({ inputType: 'text'})
|
||||||
.component();
|
.component();
|
||||||
this.fileBrowserTree.onDidChange((args) => {
|
this.fileBrowserTree.onDidChange((args) => {
|
||||||
this.selectedPathTextBox.value = args.fullPath;
|
this.selectedPathTextBox.value = args.fullPath;
|
||||||
@@ -462,7 +462,7 @@ export class JobStepDialog extends AgentDialog<JobStepData> {
|
|||||||
component: this.fileBrowserNameBox,
|
component: this.fileBrowserNameBox,
|
||||||
title: this.FileNameLabelString
|
title: this.FileNameLabelString
|
||||||
}
|
}
|
||||||
]).component();
|
]).component();
|
||||||
view.initializeModel(fileBrowserContainer);
|
view.initializeModel(fileBrowserContainer);
|
||||||
});
|
});
|
||||||
this.fileBrowserDialog.okButton.onClick(() => {
|
this.fileBrowserDialog.okButton.onClick(() => {
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ export class OperatorDialog extends AgentDialog<OperatorData> {
|
|||||||
|
|
||||||
|
|
||||||
this.pagerTuesdayCheckBox.onChanged(() => {
|
this.pagerTuesdayCheckBox.onChanged(() => {
|
||||||
if (this.pagerTuesdayCheckBox.checked) {
|
if (this.pagerTuesdayCheckBox .checked) {
|
||||||
this.weekdayPagerStartTimeInput.enabled = true;
|
this.weekdayPagerStartTimeInput.enabled = true;
|
||||||
this.weekdayPagerEndTimeInput.enabled = true;
|
this.weekdayPagerEndTimeInput.enabled = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -153,7 +153,7 @@ export class OperatorDialog extends AgentDialog<OperatorData> {
|
|||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
this.pagerWednesdayCheckBox.onChanged(() => {
|
this.pagerWednesdayCheckBox.onChanged(() => {
|
||||||
if (this.pagerWednesdayCheckBox.checked) {
|
if (this.pagerWednesdayCheckBox .checked) {
|
||||||
this.weekdayPagerStartTimeInput.enabled = true;
|
this.weekdayPagerStartTimeInput.enabled = true;
|
||||||
this.weekdayPagerEndTimeInput.enabled = true;
|
this.weekdayPagerEndTimeInput.enabled = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -171,7 +171,7 @@ export class OperatorDialog extends AgentDialog<OperatorData> {
|
|||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
this.pagerThursdayCheckBox.onChanged(() => {
|
this.pagerThursdayCheckBox.onChanged(() => {
|
||||||
if (this.pagerThursdayCheckBox.checked) {
|
if (this.pagerThursdayCheckBox .checked) {
|
||||||
this.weekdayPagerStartTimeInput.enabled = true;
|
this.weekdayPagerStartTimeInput.enabled = true;
|
||||||
this.weekdayPagerEndTimeInput.enabled = true;
|
this.weekdayPagerEndTimeInput.enabled = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -362,7 +362,7 @@ export class OperatorDialog extends AgentDialog<OperatorData> {
|
|||||||
}, {
|
}, {
|
||||||
component: pagerSundayCheckboxContainer,
|
component: pagerSundayCheckboxContainer,
|
||||||
title: ''
|
title: ''
|
||||||
}],
|
}] ,
|
||||||
title: OperatorDialog.PagerDutyScheduleLabel
|
title: OperatorDialog.PagerDutyScheduleLabel
|
||||||
}]).withLayout({ width: '100%' }).component();
|
}]).withLayout({ width: '100%' }).component();
|
||||||
await view.initializeModel(formModel);
|
await view.initializeModel(formModel);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
@@ -20,8 +20,8 @@ export class PickScheduleDialog {
|
|||||||
private readonly CancelButtonText: string = localize('pickSchedule.cancel', 'Cancel');
|
private readonly CancelButtonText: string = localize('pickSchedule.cancel', 'Cancel');
|
||||||
private readonly SchedulesLabelText: string = localize('pickSchedule.availableSchedules', 'Available Schedules:');
|
private readonly SchedulesLabelText: string = localize('pickSchedule.availableSchedules', 'Available Schedules:');
|
||||||
public static readonly ScheduleNameLabelText: string = localize('pickSchedule.scheduleName', 'Name');
|
public static readonly ScheduleNameLabelText: string = localize('pickSchedule.scheduleName', 'Name');
|
||||||
public static readonly SchedulesIDText: string = localize('pickSchedule.scheduleID', 'ID');
|
public static readonly SchedulesIDText: string = localize('pickSchedule.scheduleID','ID');
|
||||||
public static readonly ScheduleDescription: string = localize('pickSchedule.description', 'Description');
|
public static readonly ScheduleDescription: string = localize('pickSchedule.description','Description');
|
||||||
|
|
||||||
|
|
||||||
// UI Components
|
// UI Components
|
||||||
@@ -74,7 +74,7 @@ export class PickScheduleDialog {
|
|||||||
let data: any[][] = [];
|
let data: any[][] = [];
|
||||||
for (let i = 0; i < this.model.schedules.length; ++i) {
|
for (let i = 0; i < this.model.schedules.length; ++i) {
|
||||||
let schedule = this.model.schedules[i];
|
let schedule = this.model.schedules[i];
|
||||||
data[i] = [schedule.id, schedule.name, schedule.description];
|
data[i] = [ schedule.id, schedule.name, schedule.description ];
|
||||||
}
|
}
|
||||||
this.schedulesTable.data = data;
|
this.schedulesTable.data = data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export class ProxyDialog extends AgentDialog<ProxyData> {
|
|||||||
this.generalTab.registerContent(async view => {
|
this.generalTab.registerContent(async view => {
|
||||||
|
|
||||||
this.proxyNameTextBox = view.modelBuilder.inputBox()
|
this.proxyNameTextBox = view.modelBuilder.inputBox()
|
||||||
.withProperties({ width: 420 })
|
.withProperties({width: 420})
|
||||||
.component();
|
.component();
|
||||||
|
|
||||||
this.credentialNameDropDown = view.modelBuilder.dropDown()
|
this.credentialNameDropDown = view.modelBuilder.dropDown()
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export class ScheduleDialog {
|
|||||||
let data: any[][] = [];
|
let data: any[][] = [];
|
||||||
for (let i = 0; i < this.model.schedules.length; ++i) {
|
for (let i = 0; i < this.model.schedules.length; ++i) {
|
||||||
let schedule = this.model.schedules[i];
|
let schedule = this.model.schedules[i];
|
||||||
data[i] = [schedule.name];
|
data[i] = [ schedule.name ];
|
||||||
}
|
}
|
||||||
this.schedulesTable.data = data;
|
this.schedulesTable.data = data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,57 +22,57 @@ const localize = nls.loadMessageBundle();
|
|||||||
* The main controller class that initializes the extension
|
* The main controller class that initializes the extension
|
||||||
*/
|
*/
|
||||||
export class MainController {
|
export class MainController {
|
||||||
protected _context: vscode.ExtensionContext;
|
protected _context: vscode.ExtensionContext;
|
||||||
|
|
||||||
// PUBLIC METHODS //////////////////////////////////////////////////////
|
// PUBLIC METHODS //////////////////////////////////////////////////////
|
||||||
public constructor(context: vscode.ExtensionContext) {
|
public constructor(context: vscode.ExtensionContext) {
|
||||||
this._context = context;
|
this._context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static showNotYetImplemented(): void {
|
public static showNotYetImplemented(): void {
|
||||||
vscode.window.showInformationMessage(
|
vscode.window.showInformationMessage(
|
||||||
localize('mainController.notImplemented', "This feature is under development. Check-out the latest insiders build if you'd like to try out the most recent changes!"));
|
localize('mainController.notImplemented', "This feature is under development. Check-out the latest insiders build if you'd like to try out the most recent changes!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activates the extension
|
* Activates the extension
|
||||||
*/
|
*/
|
||||||
public activate(): void {
|
public activate(): void {
|
||||||
vscode.commands.registerCommand('agent.openJobDialog', async (ownerUri: string, jobInfo: azdata.AgentJobInfo) => {
|
vscode.commands.registerCommand('agent.openJobDialog', async (ownerUri: string, jobInfo: azdata.AgentJobInfo) => {
|
||||||
let dialog = new JobDialog(ownerUri, jobInfo);
|
let dialog = new JobDialog(ownerUri, jobInfo);
|
||||||
dialog.dialogName ? await dialog.openDialog(dialog.dialogName) : await dialog.openDialog();
|
dialog.dialogName ? await dialog.openDialog(dialog.dialogName) : await dialog.openDialog();
|
||||||
});
|
});
|
||||||
vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, server: string, jobInfo: azdata.AgentJobInfo, jobStepInfo: azdata.AgentJobStepInfo) => {
|
vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, server: string, jobInfo: azdata.AgentJobInfo, jobStepInfo: azdata.AgentJobStepInfo) => {
|
||||||
AgentUtils.getAgentService().then(async (agentService) => {
|
AgentUtils.getAgentService().then(async(agentService) => {
|
||||||
let jobData: JobData = new JobData(ownerUri, jobInfo, agentService);
|
let jobData: JobData = new JobData(ownerUri, jobInfo, agentService);
|
||||||
let dialog = new JobStepDialog(ownerUri, server, jobData, jobStepInfo, false);
|
let dialog = new JobStepDialog(ownerUri, server, jobData, jobStepInfo, false);
|
||||||
dialog.dialogName ? await dialog.openDialog(dialog.dialogName) : await dialog.openDialog();
|
dialog.dialogName ? await dialog.openDialog(dialog.dialogName) : await dialog.openDialog();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
vscode.commands.registerCommand('agent.openPickScheduleDialog', async (ownerUri: string, jobName: string) => {
|
vscode.commands.registerCommand('agent.openPickScheduleDialog', async (ownerUri: string, jobName: string) => {
|
||||||
let dialog = new PickScheduleDialog(ownerUri, jobName);
|
let dialog = new PickScheduleDialog(ownerUri, jobName);
|
||||||
await dialog.showDialog();
|
await dialog.showDialog();
|
||||||
});
|
});
|
||||||
vscode.commands.registerCommand('agent.openAlertDialog', (ownerUri: string, jobInfo: azdata.AgentJobInfo, alertInfo: azdata.AgentAlertInfo) => {
|
vscode.commands.registerCommand('agent.openAlertDialog', (ownerUri: string, jobInfo: azdata.AgentJobInfo, alertInfo: azdata.AgentAlertInfo) => {
|
||||||
AgentUtils.getAgentService().then(async (agentService) => {
|
AgentUtils.getAgentService().then(async (agentService) => {
|
||||||
let jobData: JobData = new JobData(ownerUri, jobInfo, agentService);
|
let jobData: JobData = new JobData(ownerUri, jobInfo, agentService);
|
||||||
let dialog = new AlertDialog(ownerUri, jobData, alertInfo, false);
|
let dialog = new AlertDialog(ownerUri, jobData, alertInfo, false);
|
||||||
dialog.dialogName ? await dialog.openDialog(dialog.dialogName) : await dialog.openDialog();
|
dialog.dialogName ? await dialog.openDialog(dialog.dialogName) : await dialog.openDialog();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
vscode.commands.registerCommand('agent.openOperatorDialog', async (ownerUri: string, operatorInfo: azdata.AgentOperatorInfo) => {
|
vscode.commands.registerCommand('agent.openOperatorDialog', async (ownerUri: string, operatorInfo: azdata.AgentOperatorInfo) => {
|
||||||
let dialog = new OperatorDialog(ownerUri, operatorInfo);
|
let dialog = new OperatorDialog(ownerUri, operatorInfo);
|
||||||
dialog.dialogName ? await dialog.openDialog(dialog.dialogName) : await dialog.openDialog();
|
dialog.dialogName ? await dialog.openDialog(dialog.dialogName) : await dialog.openDialog();
|
||||||
});
|
});
|
||||||
vscode.commands.registerCommand('agent.openProxyDialog', async (ownerUri: string, proxyInfo: azdata.AgentProxyInfo, credentials: azdata.CredentialInfo[]) => {
|
vscode.commands.registerCommand('agent.openProxyDialog', async (ownerUri: string, proxyInfo: azdata.AgentProxyInfo, credentials: azdata.CredentialInfo[]) => {
|
||||||
let dialog = new ProxyDialog(ownerUri, proxyInfo, credentials);
|
let dialog = new ProxyDialog(ownerUri, proxyInfo, credentials);
|
||||||
dialog.dialogName ? await dialog.openDialog(dialog.dialogName) : await dialog.openDialog();
|
dialog.dialogName ? await dialog.openDialog(dialog.dialogName) : await dialog.openDialog();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deactivates the extension
|
* Deactivates the extension
|
||||||
*/
|
*/
|
||||||
public deactivate(): void {
|
public deactivate(): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
extensions/agent/src/test/agent.test.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import * as assert from 'assert';
|
||||||
|
import 'mocha';
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
import * as azdata from 'azdata';
|
||||||
|
import { JobData } from '../data/jobData';
|
||||||
|
import { TestAgentService } from './testAgentService';
|
||||||
|
|
||||||
|
const testOwnerUri = 'agent://testuri';
|
||||||
|
|
||||||
|
suite('Agent extension', () => {
|
||||||
|
test('Create Job Data', async () => {
|
||||||
|
let testAgentService = new TestAgentService();
|
||||||
|
let data = new JobData(testOwnerUri, undefined, testAgentService);
|
||||||
|
data.save();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as should from 'should';
|
|
||||||
import * as TypeMoq from 'typemoq';
|
|
||||||
import 'mocha';
|
|
||||||
import * as azdata from 'azdata';
|
|
||||||
import { JobData } from '../../data/jobData';
|
|
||||||
|
|
||||||
const testOwnerUri = 'agent://testuri';
|
|
||||||
let mockJobData: TypeMoq.IMock<JobData>;
|
|
||||||
let mockAgentService: TypeMoq.IMock<azdata.AgentServicesProvider>;
|
|
||||||
|
|
||||||
describe('Agent extension create job objects', function (): void {
|
|
||||||
beforeEach(() => {
|
|
||||||
mockAgentService = TypeMoq.Mock.ofType<azdata.AgentServicesProvider>();
|
|
||||||
mockAgentService.setup(s => s.createJob(TypeMoq.It.isAnyString(), TypeMoq.It.isAny())).returns(() => TypeMoq.It.isAny());
|
|
||||||
mockAgentService.setup(s => s.createJob(undefined, TypeMoq.It.isAny())).returns(() => undefined);
|
|
||||||
mockAgentService.setup(s => s.createAlert(TypeMoq.It.isAnyString(), TypeMoq.It.isAny())).returns(() => TypeMoq.It.isAny());
|
|
||||||
mockAgentService.setup(s => s.createAlert(undefined, TypeMoq.It.isAny())).returns(() => undefined);
|
|
||||||
mockAgentService.setup(s => s.createJobSchedule(TypeMoq.It.isAnyString(), TypeMoq.It.isAny())).returns(() => TypeMoq.It.isAny());
|
|
||||||
mockAgentService.setup(s => s.createJobSchedule(undefined, TypeMoq.It.isAny())).returns(() => undefined);
|
|
||||||
mockAgentService.setup(s => s.createJobStep(TypeMoq.It.isAnyString(), TypeMoq.It.isAny())).returns(() => TypeMoq.It.isAny());
|
|
||||||
mockAgentService.setup(s => s.createJobStep(undefined, TypeMoq.It.isAny())).returns(() => undefined);
|
|
||||||
mockAgentService.setup(s => s.createOperator(TypeMoq.It.isAnyString(), TypeMoq.It.isAny())).returns(() => TypeMoq.It.isAny());
|
|
||||||
mockAgentService.setup(s => s.createOperator(undefined, TypeMoq.It.isAny())).returns(() => undefined);
|
|
||||||
mockAgentService.setup(s => s.createProxy(TypeMoq.It.isAnyString(), TypeMoq.It.isAny())).returns(() => TypeMoq.It.isAny());
|
|
||||||
mockAgentService.setup(s => s.createProxy(undefined, TypeMoq.It.isAny())).returns(() => undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Create Job Data', async () => {
|
|
||||||
// should fail when ownerUri is null
|
|
||||||
let createJobResult = mockAgentService.object.createJob(null, TypeMoq.It.isAny());
|
|
||||||
should.strictEqual(createJobResult, undefined);
|
|
||||||
createJobResult = mockAgentService.object.createJob(testOwnerUri, TypeMoq.It.isAny());
|
|
||||||
should.notEqual(createJobResult, undefined);
|
|
||||||
mockJobData = TypeMoq.Mock.ofType<JobData>(JobData, TypeMoq.MockBehavior.Loose, false, [TypeMoq.It.isAnyString(), undefined, mockAgentService]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Create Alert Data', async () => {
|
|
||||||
// should fail when ownerUri is null
|
|
||||||
let createAlertResult = mockAgentService.object.createAlert(null, TypeMoq.It.isAny());
|
|
||||||
should.strictEqual(createAlertResult, undefined);
|
|
||||||
createAlertResult = mockAgentService.object.createAlert(testOwnerUri, TypeMoq.It.isAny());
|
|
||||||
should.notEqual(createAlertResult, undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Create Job Schedule Data', async () => {
|
|
||||||
// should fail when ownerUri is null
|
|
||||||
let createJobScheduleResult = mockAgentService.object.createJobSchedule(null, TypeMoq.It.isAny());
|
|
||||||
should.strictEqual(createJobScheduleResult, undefined);
|
|
||||||
createJobScheduleResult = mockAgentService.object.createJobSchedule(testOwnerUri, TypeMoq.It.isAny());
|
|
||||||
should.notEqual(createJobScheduleResult, undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Create Job Step Data', async () => {
|
|
||||||
// should fail when ownerUri is null
|
|
||||||
let createJobStepResult = mockAgentService.object.createJobStep(null, TypeMoq.It.isAny());
|
|
||||||
should.strictEqual(createJobStepResult, undefined);
|
|
||||||
createJobStepResult = mockAgentService.object.createJobStep(testOwnerUri, TypeMoq.It.isAny());
|
|
||||||
should.notEqual(createJobStepResult, undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Create Operator Data', async () => {
|
|
||||||
// should fail when ownerUri is null
|
|
||||||
let createOperatorResult = mockAgentService.object.createOperator(null, TypeMoq.It.isAny());
|
|
||||||
should.strictEqual(createOperatorResult, undefined);
|
|
||||||
createOperatorResult = mockAgentService.object.createOperator(testOwnerUri, TypeMoq.It.isAny());
|
|
||||||
should.notEqual(createOperatorResult, undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Create Proxy Data', async () => {
|
|
||||||
// should fail when ownerUri is null
|
|
||||||
let createProxyResult = mockAgentService.object.createProxy(null, TypeMoq.It.isAny());
|
|
||||||
should.strictEqual(createProxyResult, undefined);
|
|
||||||
createProxyResult = mockAgentService.object.createProxy(testOwnerUri, TypeMoq.It.isAny());
|
|
||||||
should.notEqual(createProxyResult, undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
const path = require('path');
|
|
||||||
const testRunner = require('vscode/lib/testrunner');
|
|
||||||
|
|
||||||
const suite = 'Agent Tests';
|
|
||||||
|
|
||||||
const options: any = {
|
|
||||||
ui: 'bdd',
|
|
||||||
useColors: true,
|
|
||||||
timeout: 600000
|
|
||||||
};
|
|
||||||
|
|
||||||
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
|
|
||||||
options.reporter = 'mocha-multi-reporters';
|
|
||||||
options.reporterOptions = {
|
|
||||||
reporterEnabled: 'spec, mocha-junit-reporter',
|
|
||||||
mochaJunitReporterReporterOptions: {
|
|
||||||
testsuitesTitle: `${suite} ${process.platform}`,
|
|
||||||
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
testRunner.configure(options);
|
|
||||||
|
|
||||||
export = testRunner;
|
|
||||||
110
extensions/agent/src/test/testAgentService.ts
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
import * as azdata from 'azdata';
|
||||||
|
|
||||||
|
export class TestAgentService implements azdata.AgentServicesProvider {
|
||||||
|
handle?: number;
|
||||||
|
readonly providerId: string = 'Test Provider';
|
||||||
|
|
||||||
|
// Job management methods
|
||||||
|
getJobs(ownerUri: string): Thenable<azdata.AgentJobsResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
getJobHistory(ownerUri: string, jobId: string, jobName: string): Thenable<azdata.AgentJobHistoryResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
jobAction(ownerUri: string, jobName: string, action: string): Thenable<azdata.ResultStatus> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
createJob(ownerUri: string, jobInfo: azdata.AgentJobInfo): Thenable<azdata.CreateAgentJobResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
updateJob(ownerUri: string, originalJobName: string, jobInfo: azdata.AgentJobInfo): Thenable<azdata.UpdateAgentJobResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
deleteJob(ownerUri: string, jobInfo: azdata.AgentJobInfo): Thenable<azdata.ResultStatus> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
getJobDefaults(ownerUri: string): Thenable<azdata.AgentJobDefaultsResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Job Step management methods
|
||||||
|
createJobStep(ownerUri: string, jobInfo: azdata.AgentJobStepInfo): Thenable<azdata.CreateAgentJobStepResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
updateJobStep(ownerUri: string, originalJobStepName: string, jobInfo: azdata.AgentJobStepInfo): Thenable<azdata.UpdateAgentJobStepResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
deleteJobStep(ownerUri: string, jobInfo: azdata.AgentJobStepInfo): Thenable<azdata.ResultStatus> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alert management methods
|
||||||
|
getAlerts(ownerUri: string): Thenable<azdata.AgentAlertsResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
createAlert(ownerUri: string, alertInfo: azdata.AgentAlertInfo): Thenable<azdata.CreateAgentAlertResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
updateAlert(ownerUri: string, originalAlertName: string, alertInfo: azdata.AgentAlertInfo): Thenable<azdata.UpdateAgentAlertResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
deleteAlert(ownerUri: string, alertInfo: azdata.AgentAlertInfo): Thenable<azdata.ResultStatus> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Operator management methods
|
||||||
|
getOperators(ownerUri: string): Thenable<azdata.AgentOperatorsResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
createOperator(ownerUri: string, operatorInfo: azdata.AgentOperatorInfo): Thenable<azdata.CreateAgentOperatorResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
updateOperator(ownerUri: string, originalOperatorName: string, operatorInfo: azdata.AgentOperatorInfo): Thenable<azdata.UpdateAgentOperatorResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
deleteOperator(ownerUri: string, operatorInfo: azdata.AgentOperatorInfo): Thenable<azdata.ResultStatus> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proxy management methods
|
||||||
|
getProxies(ownerUri: string): Thenable<azdata.AgentProxiesResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
createProxy(ownerUri: string, proxyInfo: azdata.AgentProxyInfo): Thenable<azdata.CreateAgentOperatorResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
updateProxy(ownerUri: string, originalProxyName: string, proxyInfo: azdata.AgentProxyInfo): Thenable<azdata.UpdateAgentOperatorResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
deleteProxy(ownerUri: string, proxyInfo: azdata.AgentProxyInfo): Thenable<azdata.ResultStatus> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Agent Credential method
|
||||||
|
getCredentials(ownerUri: string): Thenable<azdata.GetCredentialsResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Job Schedule management methods
|
||||||
|
getJobSchedules(ownerUri: string): Thenable<azdata.AgentJobSchedulesResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
createJobSchedule(ownerUri: string, scheduleInfo: azdata.AgentJobScheduleInfo): Thenable<azdata.CreateAgentJobScheduleResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
updateJobSchedule(ownerUri: string, originalScheduleName: string, scheduleInfo: azdata.AgentJobScheduleInfo): Thenable<azdata.UpdateAgentJobScheduleResult> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
deleteJobSchedule(ownerUri: string, scheduleInfo: azdata.AgentJobScheduleInfo): Thenable<azdata.ResultStatus> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnUpdated(handler: () => any): void {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,19 @@
|
|||||||
{
|
{
|
||||||
"compileOnSave": true,
|
"compileOnSave": true,
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"outDir": "./out",
|
"outDir": "./out",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es6", "es2015.promise"
|
"es6", "es2015.promise"
|
||||||
],
|
],
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"moduleResolution": "node"
|
"moduleResolution": "node",
|
||||||
},
|
"declaration": true
|
||||||
"exclude": [
|
},
|
||||||
"node_modules"
|
"exclude": [
|
||||||
]
|
"node_modules"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
src/**
|
|
||||||
out/**
|
|
||||||
tsconfig.json
|
|
||||||
extension.webpack.config.js
|
|
||||||
yarn.lock
|
|
||||||
|
|||||||
@@ -42,15 +42,15 @@
|
|||||||
{
|
{
|
||||||
"id": "microsoft",
|
"id": "microsoft",
|
||||||
"icon": {
|
"icon": {
|
||||||
"light": "./resources/light/microsoft_account_light.svg",
|
"light": "./out/account-provider/media/microsoft_account_light.svg",
|
||||||
"dark": "./resources/dark/microsoft_account_dark.svg"
|
"dark": "./out/account-provider/media/microsoft_account_dark.svg"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "work_school",
|
"id": "work_school",
|
||||||
"icon": {
|
"icon": {
|
||||||
"light": "./resources/light/work_school_account_light.svg",
|
"light": "./out/account-provider/media/work_school_account_light.svg",
|
||||||
"dark": "./resources/dark/work_school_account_dark.svg"
|
"dark": "./out/account-provider/media/work_school_account_dark.svg"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -104,8 +104,8 @@
|
|||||||
"command": "azure.resource.connectsqldb",
|
"command": "azure.resource.connectsqldb",
|
||||||
"title": "%azure.resource.connectsqldb.title%",
|
"title": "%azure.resource.connectsqldb.title%",
|
||||||
"icon": {
|
"icon": {
|
||||||
"dark": "resources/dark/add_to_server_list_inverse.svg",
|
"dark": "resources/dark/connect_to_inverse.svg",
|
||||||
"light": "resources/light/add_to_server_list.svg"
|
"light": "resources/light/connect_to.svg"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -156,19 +156,17 @@
|
|||||||
"hasAzureResourceProviders": true
|
"hasAzureResourceProviders": true
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"adal-node": "^0.1.28",
|
|
||||||
"azure-arm-resource": "^7.0.0",
|
"azure-arm-resource": "^7.0.0",
|
||||||
"azure-arm-sql": "^5.0.1",
|
"azure-arm-sql": "^5.0.1",
|
||||||
"ms-rest": "^2.5.0",
|
|
||||||
"request": "2.88.0",
|
"request": "2.88.0",
|
||||||
"vscode-nls": "^4.0.0"
|
"vscode-nls": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/mocha": "^5.2.5",
|
"@types/mocha": "^5.2.5",
|
||||||
"@types/node": "^10.12.12",
|
"@types/node": "^8.0.24",
|
||||||
"@types/request": "^2.48.1",
|
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
"should": "^13.2.1",
|
"should": "^13.2.1",
|
||||||
"typemoq": "^2.1.0"
|
"typemoq": "^2.1.0",
|
||||||
|
"vscode": "^1.1.26"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
"azure.resource.refresh.title": "Refresh",
|
"azure.resource.refresh.title": "Refresh",
|
||||||
"azure.resource.signin.title": "Sign In",
|
"azure.resource.signin.title": "Sign In",
|
||||||
"azure.resource.selectsubscriptions.title": "Select Subscriptions",
|
"azure.resource.selectsubscriptions.title": "Select Subscriptions",
|
||||||
"azure.resource.connectsqlserver.title": "Connect",
|
"azure.resource.connectsqlserver.title": "Add to Servers",
|
||||||
"azure.resource.connectsqldb.title": "Add to Servers",
|
"azure.resource.connectsqldb.title": "Connect",
|
||||||
|
|
||||||
"accounts.clearTokenCache": "Clear Azure Account Token Cache",
|
"accounts.clearTokenCache": "Clear Azure Account Token Cache",
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M13 12H16V13H13V16H12V13H9V12H12V9H13V12ZM1 6V5H2V6H1ZM15 5V6H4V5H15ZM1 3V2H2V3H1ZM15 2V3H4V2H15Z" fill="white"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 226 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16"><defs><style>.cls-1,.cls-2{clip-rule:evenodd;}.cls-2,.cls-5,.cls-7{fill:#fff;}.cls-3,.cls-5{fill-rule:evenodd;}.cls-4{clip-path:url(#clip-path);}.cls-6{clip-path:url(#clip-path-2);}</style><clipPath id="clip-path"><path class="cls-1" d="M11.5-15.92v3.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77A3.43,3.43,0,0,1,8.5-9v6h-1V-9a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05,3.4,3.4,0,0,1-.23-1.24v-3.5h1v-3h1v3h3v-3h1v3Zm-1,1h-5v2.5a2.45,2.45,0,0,0,.2,1,2.53,2.53,0,0,0,.53.8,2.53,2.53,0,0,0,.8.53,2.45,2.45,0,0,0,1,.2,2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/></clipPath><clipPath id="clip-path-2"><path class="cls-2" d="M11.5,3V6.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77A3.43,3.43,0,0,1,8.5,10v6h-1V10a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05A3.4,3.4,0,0,1,4.5,6.5V3h1V0h1V3h3V0h1V3Zm-1,1h-5V6.5a2.45,2.45,0,0,0,.2,1A2.49,2.49,0,0,0,7,8.8,2.45,2.45,0,0,0,8,9a2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/></clipPath></defs><title>connect_to_inverse</title><path class="cls-3" d="M11.5-15.92v3.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77A3.43,3.43,0,0,1,8.5-9v6h-1V-9a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05,3.4,3.4,0,0,1-.23-1.24v-3.5h1v-3h1v3h3v-3h1v3Zm-1,1h-5v2.5a2.45,2.45,0,0,0,.2,1,2.53,2.53,0,0,0,.53.8,2.53,2.53,0,0,0,.8.53,2.45,2.45,0,0,0,1,.2,2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/><g class="cls-4"><rect x="-0.5" y="-23.92" width="17" height="26"/></g><path class="cls-5" d="M11.5,3V6.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77A3.43,3.43,0,0,1,8.5,10v6h-1V10a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05A3.4,3.4,0,0,1,4.5,6.5V3h1V0h1V3h3V0h1V3Zm-1,1h-5V6.5a2.45,2.45,0,0,0,.2,1A2.49,2.49,0,0,0,7,8.8,2.45,2.45,0,0,0,8,9a2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/><g class="cls-6"><rect class="cls-7" x="-0.5" y="-5" width="17" height="26"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -1,3 +0,0 @@
|
|||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M13 12H16V13H13V16H12V13H9V12H12V9H13V12ZM1 6V5H2V6H1ZM15 5V6H4V5H15ZM1 3V2H2V3H1ZM15 2V3H4V2H15Z" fill="#333333"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 228 B |
1
extensions/azurecore/resources/light/connect_to.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16"><defs><style>.cls-1,.cls-2{clip-rule:evenodd;}.cls-2,.cls-5,.cls-7{fill:#fff;}.cls-3,.cls-5{fill-rule:evenodd;}.cls-4{clip-path:url(#clip-path);}.cls-6{clip-path:url(#clip-path-2);}</style><clipPath id="clip-path"><path class="cls-1" d="M11.5,3V6.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77A3.43,3.43,0,0,1,8.5,10v6h-1V10a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05A3.4,3.4,0,0,1,4.5,6.5V3h1V0h1V3h3V0h1V3Zm-1,1h-5V6.5a2.45,2.45,0,0,0,.2,1A2.49,2.49,0,0,0,7,8.8,2.45,2.45,0,0,0,8,9a2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/></clipPath><clipPath id="clip-path-2"><path class="cls-2" d="M11.5,21.92v3.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77,3.43,3.43,0,0,1-1.19.4v6h-1v-6a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05,3.4,3.4,0,0,1-.23-1.24v-3.5h1v-3h1v3h3v-3h1v3Zm-1,1h-5v2.5a2.45,2.45,0,0,0,.2,1A2.49,2.49,0,0,0,7,27.72a2.45,2.45,0,0,0,1,.2,2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/></clipPath></defs><title>connect_to</title><path class="cls-3" d="M11.5,3V6.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77A3.43,3.43,0,0,1,8.5,10v6h-1V10a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05A3.4,3.4,0,0,1,4.5,6.5V3h1V0h1V3h3V0h1V3Zm-1,1h-5V6.5a2.45,2.45,0,0,0,.2,1A2.49,2.49,0,0,0,7,8.8,2.45,2.45,0,0,0,8,9a2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/><g class="cls-4"><rect x="-0.5" y="-5" width="17" height="26"/></g><path class="cls-5" d="M11.5,21.92v3.5a3.4,3.4,0,0,1-.23,1.24,3.48,3.48,0,0,1-.63,1.05,3.57,3.57,0,0,1-1,.77,3.43,3.43,0,0,1-1.19.4v6h-1v-6a3.39,3.39,0,0,1-1.2-.4,3.59,3.59,0,0,1-.95-.77,3.48,3.48,0,0,1-.63-1.05,3.4,3.4,0,0,1-.23-1.24v-3.5h1v-3h1v3h3v-3h1v3Zm-1,1h-5v2.5a2.45,2.45,0,0,0,.2,1A2.49,2.49,0,0,0,7,27.72a2.45,2.45,0,0,0,1,.2,2.42,2.42,0,0,0,1-.2,2.53,2.53,0,0,0,.79-.53,2.59,2.59,0,0,0,.54-.8,2.41,2.41,0,0,0,.2-1Z"/><g class="cls-6"><rect class="cls-7" x="-0.5" y="13.92" width="17" height="26"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -3,6 +3,8 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
import * as adal from 'adal-node';
|
import * as adal from 'adal-node';
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import * as request from 'request';
|
import * as request from 'request';
|
||||||
@@ -10,6 +12,7 @@ import * as nls from 'vscode-nls';
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as url from 'url';
|
import * as url from 'url';
|
||||||
import {
|
import {
|
||||||
|
Arguments,
|
||||||
AzureAccount,
|
AzureAccount,
|
||||||
AzureAccountProviderMetadata,
|
AzureAccountProviderMetadata,
|
||||||
AzureAccountSecurityTokenCollection,
|
AzureAccountSecurityTokenCollection,
|
||||||
@@ -26,12 +29,17 @@ export class AzureAccountProvider implements azdata.AccountProvider {
|
|||||||
private static AadCommonTenant: string = 'common';
|
private static AadCommonTenant: string = 'common';
|
||||||
|
|
||||||
// MEMBER VARIABLES ////////////////////////////////////////////////////
|
// MEMBER VARIABLES ////////////////////////////////////////////////////
|
||||||
|
private _args: Arguments;
|
||||||
private _autoOAuthCancelled: boolean;
|
private _autoOAuthCancelled: boolean;
|
||||||
private _commonAuthorityUrl: string;
|
private _commonAuthorityUrl: string;
|
||||||
private _inProgressAutoOAuth: InProgressAutoOAuth;
|
private _inProgressAutoOAuth: InProgressAutoOAuth;
|
||||||
private _isInitialized: boolean;
|
private _isInitialized: boolean;
|
||||||
|
|
||||||
constructor(private _metadata: AzureAccountProviderMetadata, private _tokenCache: TokenCache) {
|
constructor(private _metadata: AzureAccountProviderMetadata, private _tokenCache: TokenCache) {
|
||||||
|
this._args = {
|
||||||
|
host: this._metadata.settings.host,
|
||||||
|
clientId: this._metadata.settings.clientId
|
||||||
|
};
|
||||||
this._autoOAuthCancelled = false;
|
this._autoOAuthCancelled = false;
|
||||||
this._inProgressAutoOAuth = null;
|
this._inProgressAutoOAuth = null;
|
||||||
this._isInitialized = false;
|
this._isInitialized = false;
|
||||||
@@ -46,8 +54,8 @@ export class AzureAccountProvider implements azdata.AccountProvider {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears all tokens that belong to the given account from the token cache
|
* Clears all tokens that belong to the given account from the token cache
|
||||||
* @param accountKey Key identifying the account to delete tokens for
|
* @param {"data".AccountKey} accountKey Key identifying the account to delete tokens for
|
||||||
* @returns Promise to clear requested tokens from the token cache
|
* @returns {Thenable<void>} Promise to clear requested tokens from the token cache
|
||||||
*/
|
*/
|
||||||
public clear(accountKey: azdata.AccountKey): Thenable<void> {
|
public clear(accountKey: azdata.AccountKey): Thenable<void> {
|
||||||
return this.doIfInitialized(() => this.clearAccountTokens(accountKey));
|
return this.doIfInitialized(() => this.clearAccountTokens(accountKey));
|
||||||
@@ -55,7 +63,7 @@ export class AzureAccountProvider implements azdata.AccountProvider {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the entire token cache. Invoked by command palette action.
|
* Clears the entire token cache. Invoked by command palette action.
|
||||||
* @returns Promise to clear the token cache
|
* @returns {Thenable<void>} Promise to clear the token cache
|
||||||
*/
|
*/
|
||||||
public clearTokenCache(): Thenable<void> {
|
public clearTokenCache(): Thenable<void> {
|
||||||
return this._tokenCache.clear();
|
return this._tokenCache.clear();
|
||||||
@@ -84,13 +92,13 @@ export class AzureAccountProvider implements azdata.AccountProvider {
|
|||||||
// NOTE: Based on ADAL implementation, getting tokens should use the refresh token if necessary
|
// NOTE: Based on ADAL implementation, getting tokens should use the refresh token if necessary
|
||||||
let task = this.getAccessTokens(account, azdata.AzureResource.ResourceManagement)
|
let task = this.getAccessTokens(account, azdata.AzureResource.ResourceManagement)
|
||||||
.then(
|
.then(
|
||||||
() => {
|
() => {
|
||||||
return account;
|
return account;
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
account.isStale = true;
|
account.isStale = true;
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
rehydrationTasks.push(task);
|
rehydrationTasks.push(task);
|
||||||
}
|
}
|
||||||
@@ -313,10 +321,10 @@ export class AzureAccountProvider implements azdata.AccountProvider {
|
|||||||
* Retrieves a token for the given user ID for the specific tenant ID. If the token can, it
|
* Retrieves a token for the given user ID for the specific tenant ID. If the token can, it
|
||||||
* will be retrieved from the cache as per the ADAL API. AFAIK, the ADAL API will also utilize
|
* will be retrieved from the cache as per the ADAL API. AFAIK, the ADAL API will also utilize
|
||||||
* the refresh token if there aren't any unexpired tokens to use.
|
* the refresh token if there aren't any unexpired tokens to use.
|
||||||
* @param userId ID of the user to get a token for
|
* @param {string} userId ID of the user to get a token for
|
||||||
* @param tenantId Tenant to get the token for
|
* @param {string} tenantId Tenant to get the token for
|
||||||
* @param resourceId ID of the resource the token will be good for
|
* @param {string} resourceId ID of the resource the token will be good for
|
||||||
* @returns Promise to return a token. Rejected if retrieving the token fails.
|
* @returns {Thenable<TokenResponse>} Promise to return a token. Rejected if retrieving the token fails.
|
||||||
*/
|
*/
|
||||||
private getToken(userId: string, tenantId: string, resourceId: string): Thenable<adal.TokenResponse> {
|
private getToken(userId: string, tenantId: string, resourceId: string): Thenable<adal.TokenResponse> {
|
||||||
let self = this;
|
let self = this;
|
||||||
@@ -338,9 +346,9 @@ export class AzureAccountProvider implements azdata.AccountProvider {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a web request using the provided bearer token
|
* Performs a web request using the provided bearer token
|
||||||
* @param accessToken Bearer token for accessing the provided URI
|
* @param {TokenResponse} accessToken Bearer token for accessing the provided URI
|
||||||
* @param uri URI to access
|
* @param {string} uri URI to access
|
||||||
* @returns Promise to return the deserialized body of the request. Rejected if error occurred.
|
* @returns {Thenable<any>} Promise to return the deserialized body of the request. Rejected if error occurred.
|
||||||
*/
|
*/
|
||||||
private makeWebRequest(accessToken: adal.TokenResponse, uri: string): Thenable<any> {
|
private makeWebRequest(accessToken: adal.TokenResponse, uri: string): Thenable<any> {
|
||||||
return new Promise<any>((resolve, reject) => {
|
return new Promise<any>((resolve, reject) => {
|
||||||
@@ -355,7 +363,7 @@ export class AzureAccountProvider implements azdata.AccountProvider {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup the callback to resolve/reject this promise
|
// Setup the callback to resolve/reject this promise
|
||||||
const callback: request.RequestCallback = (error, response, body: { error: any; value: any; }) => {
|
let callback = (error, response, body: { error: any; value: any; }) => {
|
||||||
if (error || body.error) {
|
if (error || body.error) {
|
||||||
reject(error || JSON.stringify(body.error));
|
reject(error || JSON.stringify(body.error));
|
||||||
} else {
|
} else {
|
||||||
@@ -425,7 +433,6 @@ export class AzureAccountProvider implements azdata.AccountProvider {
|
|||||||
name: tokenResponse.userId,
|
name: tokenResponse.userId,
|
||||||
displayInfo: {
|
displayInfo: {
|
||||||
accountType: accountType,
|
accountType: accountType,
|
||||||
userId: tokenResponse.userId,
|
|
||||||
contextualDisplayName: contextualDisplayName,
|
contextualDisplayName: contextualDisplayName,
|
||||||
displayName: displayName
|
displayName: displayName
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -77,14 +77,14 @@ export class AzureAccountProviderService implements vscode.Disposable {
|
|||||||
|
|
||||||
return Promise.all(promises)
|
return Promise.all(promises)
|
||||||
.then(
|
.then(
|
||||||
() => {
|
() => {
|
||||||
let message = localize('clearTokenCacheSuccess', 'Token cache successfully cleared');
|
let message = localize('clearTokenCacheSuccess', 'Token cache successfully cleared');
|
||||||
vscode.window.showInformationMessage(`${constants.extensionName}: ${message}`);
|
vscode.window.showInformationMessage(`${constants.extensionName}: ${message}`);
|
||||||
},
|
},
|
||||||
err => {
|
err => {
|
||||||
let message = localize('clearTokenCacheFailure', 'Failed to clear token cache');
|
let message = localize('clearTokenCacheFailure', 'Failed to clear token cache');
|
||||||
vscode.window.showErrorMessage(`${constants.extensionName}: ${message}: ${err}`);
|
vscode.window.showErrorMessage(`${constants.extensionName}: ${message}: ${err}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private onDidChangeConfiguration(): void {
|
private onDidChangeConfiguration(): void {
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 442 B |
|
Before Width: | Height: | Size: 400 B After Width: | Height: | Size: 400 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -3,6 +3,8 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
import * as adal from 'adal-node';
|
import * as adal from 'adal-node';
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
@@ -32,8 +34,8 @@ export default class TokenCache implements adal.TokenCache {
|
|||||||
.then(cache => self.addToCache(cache, entries))
|
.then(cache => self.addToCache(cache, entries))
|
||||||
.then(updatedCache => self.writeCache(updatedCache))
|
.then(updatedCache => self.writeCache(updatedCache))
|
||||||
.then(
|
.then(
|
||||||
() => callback(null, false),
|
() => callback(null, false),
|
||||||
(err) => callback(err, true)
|
(err) => callback(err, true)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -68,8 +70,8 @@ export default class TokenCache implements adal.TokenCache {
|
|||||||
);
|
);
|
||||||
})
|
})
|
||||||
.then(
|
.then(
|
||||||
results => callback(null, results),
|
results => callback(null, results),
|
||||||
(err) => callback(err, null)
|
(err) => callback(err, null)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -77,7 +79,7 @@ export default class TokenCache implements adal.TokenCache {
|
|||||||
/**
|
/**
|
||||||
* Wrapper to make callback-based find method into a thenable method
|
* Wrapper to make callback-based find method into a thenable method
|
||||||
* @param query Partial object to use to look up tokens. Ideally should be partial of adal.TokenResponse
|
* @param query Partial object to use to look up tokens. Ideally should be partial of adal.TokenResponse
|
||||||
* @returns Promise to return the matching adal.TokenResponse objects.
|
* @returns {Thenable<any[]>} Promise to return the matching adal.TokenResponse objects.
|
||||||
* Rejected if an error was sent in the callback
|
* Rejected if an error was sent in the callback
|
||||||
*/
|
*/
|
||||||
public findThenable(query: any): Thenable<any[]> {
|
public findThenable(query: any): Thenable<any[]> {
|
||||||
@@ -102,16 +104,16 @@ export default class TokenCache implements adal.TokenCache {
|
|||||||
.then(cache => self.removeFromCache(cache, entries))
|
.then(cache => self.removeFromCache(cache, entries))
|
||||||
.then(updatedCache => self.writeCache(updatedCache))
|
.then(updatedCache => self.writeCache(updatedCache))
|
||||||
.then(
|
.then(
|
||||||
() => callback(null, null),
|
() => callback(null, null),
|
||||||
(err) => callback(err, null)
|
(err) => callback(err, null)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper to make callback-based remove method into a thenable method
|
* Wrapper to make callback-based remove method into a thenable method
|
||||||
* @param entries Array of entries to remove from the token cache
|
* @param {TokenResponse[]} entries Array of entries to remove from the token cache
|
||||||
* @returns Promise to remove the given tokens from the token cache
|
* @returns {Thenable<void>} Promise to remove the given tokens from the token cache
|
||||||
* Rejected if an error was sent in the callback
|
* Rejected if an error was sent in the callback
|
||||||
*/
|
*/
|
||||||
public removeThenable(entries: adal.TokenResponse[]): Thenable<void> {
|
public removeThenable(entries: adal.TokenResponse[]): Thenable<void> {
|
||||||
@@ -136,7 +138,7 @@ export default class TokenCache implements adal.TokenCache {
|
|||||||
&& entry1.resource === entry2.resource;
|
&& entry1.resource === entry2.resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static findByPartial(entry: adal.TokenResponse, query: { [key: string]: any }): boolean {
|
private static findByPartial(entry: adal.TokenResponse, query: object): boolean {
|
||||||
for (let key in query) {
|
for (let key in query) {
|
||||||
if (entry[key] === undefined || entry[key] !== query[key]) {
|
if (entry[key] === undefined || entry[key] !== query[key]) {
|
||||||
return false;
|
return false;
|
||||||
@@ -184,8 +186,8 @@ export default class TokenCache implements adal.TokenCache {
|
|||||||
if (splitValues.length === 2 && splitValues[0] && splitValues[1]) {
|
if (splitValues.length === 2 && splitValues[0] && splitValues[1]) {
|
||||||
try {
|
try {
|
||||||
return <EncryptionParams>{
|
return <EncryptionParams>{
|
||||||
key: Buffer.from(splitValues[0], 'hex'),
|
key: new Buffer(splitValues[0], 'hex'),
|
||||||
initializationVector: Buffer.from(splitValues[1], 'hex')
|
initializationVector: new Buffer(splitValues[1], 'hex')
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Swallow the error and fall through to generate new params
|
// Swallow the error and fall through to generate new params
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
|
||||||
@@ -13,6 +15,7 @@ import * as constants from './constants';
|
|||||||
* this API from our code
|
* this API from our code
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
* @class ApiWrapper
|
||||||
*/
|
*/
|
||||||
export class ApiWrapper {
|
export class ApiWrapper {
|
||||||
// Data APIs
|
// Data APIs
|
||||||
@@ -153,6 +156,12 @@ export class ApiWrapper {
|
|||||||
return vscode.window.showSaveDialog(options);
|
return vscode.window.showSaveDialog(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public openTextDocument(uri: vscode.Uri): Thenable<vscode.TextDocument>;
|
||||||
|
public openTextDocument(options: { language?: string; content?: string; }): Thenable<vscode.TextDocument>;
|
||||||
|
public openTextDocument(uriOrOptions): Thenable<vscode.TextDocument> {
|
||||||
|
return vscode.workspace.openTextDocument(uriOrOptions);
|
||||||
|
}
|
||||||
|
|
||||||
public showTextDocument(document: vscode.TextDocument, column?: vscode.ViewColumn, preserveFocus?: boolean, preview?: boolean): Thenable<vscode.TextEditor> {
|
public showTextDocument(document: vscode.TextDocument, column?: vscode.ViewColumn, preserveFocus?: boolean, preview?: boolean): Thenable<vscode.TextEditor> {
|
||||||
let options: vscode.TextDocumentShowOptions = {
|
let options: vscode.TextDocumentShowOptions = {
|
||||||
viewColumn: column,
|
viewColumn: column,
|
||||||
@@ -203,7 +212,7 @@ export class ApiWrapper {
|
|||||||
return azdata.accounts.getAllAccounts();
|
return azdata.accounts.getAllAccounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSecurityToken(account: azdata.Account, resource: azdata.AzureResource): Thenable<{ [key: string]: any }> {
|
public getSecurityToken(account: azdata.Account, resource: azdata.AzureResource): Thenable<{}> {
|
||||||
return azdata.accounts.getSecurityToken(account, resource);
|
return azdata.accounts.getSecurityToken(account, resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { ApiWrapper } from './apiWrapper';
|
import { ApiWrapper } from './apiWrapper';
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ import { AzureResourceResourceTreeNode } from '../../resourceTreeNode';
|
|||||||
|
|
||||||
export function registerAzureResourceDatabaseCommands(appContext: AppContext): void {
|
export function registerAzureResourceDatabaseCommands(appContext: AppContext): void {
|
||||||
appContext.apiWrapper.registerCommand('azure.resource.connectsqldb', async (node?: TreeNode) => {
|
appContext.apiWrapper.registerCommand('azure.resource.connectsqldb', async (node?: TreeNode) => {
|
||||||
if (!node) {
|
if (!node)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ import { AzureResourceResourceTreeNode } from '../../resourceTreeNode';
|
|||||||
|
|
||||||
export function registerAzureResourceDatabaseServerCommands(appContext: AppContext): void {
|
export function registerAzureResourceDatabaseServerCommands(appContext: AppContext): void {
|
||||||
appContext.apiWrapper.registerCommand('azure.resource.connectsqlserver', async (node?: TreeNode) => {
|
appContext.apiWrapper.registerCommand('azure.resource.connectsqlserver', async (node?: TreeNode) => {
|
||||||
if (!node) {
|
if (!node)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ export class AzureResourceDatabaseServerService implements IAzureResourceDatabas
|
|||||||
|
|
||||||
svrs.forEach((svr) => databaseServers.push({
|
svrs.forEach((svr) => databaseServers.push({
|
||||||
name: svr.name,
|
name: svr.name,
|
||||||
fullName: svr.fullyQualifiedDomainName,
|
fullName: svr.fullyQualifiedDomainName,
|
||||||
loginName: svr.administratorLogin,
|
loginName: svr.administratorLogin,
|
||||||
defaultDatabaseName: 'master'
|
defaultDatabaseName: 'master'
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return databaseServers;
|
return databaseServers;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { ServiceClientCredentials } from 'ms-rest';
|
import { ServiceClientCredentials } from 'ms-rest';
|
||||||
|
|
||||||
import { azureResource } from '../../azure-resource';
|
import { azureResource } from '../../azure-resource';
|
||||||
import { AzureResourceDatabaseServer } from './models';
|
import { AzureResourceDatabaseServer } from './models';
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ export class AzureResourceCacheService implements IAzureResourceCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public generateKey(id: string): string {
|
public generateKey(id: string): string {
|
||||||
return `${AzureResourceCacheService.cacheKeyPrefix}.${id}`;
|
return `${AzureResourceCacheService.cacheKeyPrefix}.${id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get<T>(key: string): T | undefined {
|
public get<T>(key: string): T | undefined {
|
||||||
return this._context.workspaceState.get(key);
|
return this._context.workspaceState.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { azureResource } from '../azure-resource';
|
|||||||
import { IAzureResourceSubscriptionFilterService, IAzureResourceCacheService } from '../interfaces';
|
import { IAzureResourceSubscriptionFilterService, IAzureResourceCacheService } from '../interfaces';
|
||||||
|
|
||||||
interface AzureResourceSelectedSubscriptionsCache {
|
interface AzureResourceSelectedSubscriptionsCache {
|
||||||
selectedSubscriptions: { [accountId: string]: azureResource.AzureResourceSubscription[] };
|
selectedSubscriptions: { [accountId: string]: azureResource.AzureResourceSubscription[]};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AzureResourceSubscriptionFilterService implements IAzureResourceSubscriptionFilterService {
|
export class AzureResourceSubscriptionFilterService implements IAzureResourceSubscriptionFilterService {
|
||||||
@@ -36,7 +36,7 @@ export class AzureResourceSubscriptionFilterService implements IAzureResourceSub
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async saveSelectedSubscriptions(account: Account, selectedSubscriptions: azureResource.AzureResourceSubscription[]): Promise<void> {
|
public async saveSelectedSubscriptions(account: Account, selectedSubscriptions: azureResource.AzureResourceSubscription[]): Promise<void> {
|
||||||
let selectedSubscriptionsCache: { [accountId: string]: azureResource.AzureResourceSubscription[] } = {};
|
let selectedSubscriptionsCache: { [accountId: string]: azureResource.AzureResourceSubscription[]} = {};
|
||||||
|
|
||||||
const cache = this._cacheService.get<AzureResourceSelectedSubscriptionsCache>(this._cacheKey);
|
const cache = this._cacheService.get<AzureResourceSelectedSubscriptionsCache>(this._cacheKey);
|
||||||
if (cache) {
|
if (cache) {
|
||||||
|
|||||||