Compare commits

..

39 Commits
1.7.0 ... 1.6.0

Author SHA1 Message Date
Karl Burtram
eb35dae1d1 Turn off failing Insights tests 2019-04-16 22:59:03 -07:00
Karl Burtram
cc0a144169 Remove gap from bottom of Server view (#5072) 2019-04-16 19:54:30 -07:00
Anthony Dresser
b973f9e0ec changes strings for data explorer (#4946) 2019-04-16 18:49:59 -07:00
Alan Ren
d62068025c Merge fix the selectbox issue for chart 2019-04-16 13:40:24 -07:00
Aditya Bist
b2952d2ddf fix job action context (#5053) 2019-04-16 13:36:30 -07:00
Gene Lee
a21244816d Add support for new endpoint key string 'gateway' (#4954) 2019-04-16 10:45:00 -07:00
Chris LaFreniere
a9aeb57dc4 Fix to ensure that we rewrite spark ui links correctly (#4962) 2019-04-16 10:34:01 -07:00
Gene Lee
00537ed199 Fixed bug: CheckboxTreeNode label overflows, and node icon disappears (#5022) 2019-04-16 10:31:40 -07:00
Alex Ross
c2df3e0e0a Merge 51b0b28134d51361cf996d2f0a1c698247aeabd8 2019-04-15 10:15:55 -07:00
Charles Gagnon
e3afb1cffc Fix wrong release notes being loaded (#5008) 2019-04-11 20:56:19 -07:00
Kevin Cunnane
b475311f85 Fix #4500 Untitled notebook reopen doesn't show dirty (#5005)
* Fix 2 notebook issues
- Do not create notebook model twice on start
- Do not cause disposed warnings due to markdown cell deserialization

* Fix notebook dirty on open issue
Before model is resolved we weren't getting dirty events.
Solution is to use backing text model until it's ready.
Must hook to the dirty event & notify to get the dot to appear

# Conflicts:
#	src/sql/workbench/parts/notebook/cellViews/code.component.ts
2019-04-11 20:56:03 -07:00
Maddy
45005d61e0 add wrap to the <pre> tag (#5002)
* add wrap to the <pre> tag

* removed styles for browser support
2019-04-11 20:46:41 -07:00
Anthony Dresser
adfddeae27 restore line height to account list renderer (#4999) 2019-04-11 20:46:27 -07:00
Anthony Dresser
a7429267bb revert data explorer id to connections (#5003) 2019-04-11 20:46:08 -07:00
kisantia
ff415d6a03 bump SQL Tools to 1.5.0-alpha.85 to get invalid dacpac version fix (#5001) 2019-04-11 15:25:55 -07:00
udeeshagautam
b4dc35a4de Fix for 4104 : Multiple consecutive spaces in query results cells are condensed into one (#4983)
* preserving spaces in query results - all beginning, trailing and middle spaces will be shown as is

* removing the change through formatting and replacing with css change formatting was leaving special char while removing nbsp
2019-04-11 15:25:41 -07:00
Aditya Bist
29c7ccad39 Added some usage details (#4711)
* added some details

* remove unused import

* added new metrics, removed churn

* merged master and code review comments

* code review comments

* normalized days to calendar days/weeks/months

* cleaned up code

* changed comment to start required check for PR

* fix failing test

* fix test

* removed null assignment

* fix null test script
2019-04-11 15:25:24 -07:00
Yurong He
1da3635d03 Fix ##3479 ctrl+a select active cell output or preview markdown (#4981)
* Enable ctrl+a to select the output or markdown content when the cell is active

* Moved toggleUserSelect into ngOnChanges

* Resolve PR comments
2019-04-11 15:25:02 -07:00
Chris LaFreniere
1f50015ed2 Add New Notebook from Server Dashboard (#4971) 2019-04-11 15:24:47 -07:00
Aditya Bist
01892422cb Azure extension changes (#4987)
* removed search box

* removed commented code

# Conflicts:
#	src/sql/parts/objectExplorer/viewlet/serverTreeView.ts
2019-04-11 15:24:31 -07:00
Cory Rivera
afce60b06f Add additional error handling to Python installation for Notebooks (#4891)
* Also enabled integration tests for python installation.
2019-04-11 15:01:02 -07:00
Chris LaFreniere
a2b87f6158 Fix for relative markdown image paths (#4889)
* Fix for relative markdown image paths

* PR comments
2019-04-11 15:00:45 -07:00
Chris LaFreniere
76a2f92daf Notebooks: Potential Fix for "Notebook Provider does not Exist" Error (#4848)
* Fallback to SQL

* Fix providers not found issue

* await whenInstalledExtensionsRegistered

* PR comments
2019-04-11 15:00:21 -07:00
Gene Lee
5b09d57196 Fixed Broken Notebook Preview (#4895) 2019-04-11 14:59:09 -07:00
Karl Burtram
95bf18f859 Fix merge build break 2019-04-10 16:16:43 -07:00
Kevin Cunnane
1fc648ff37 Mitigate (but not fully fix) Run Cell from disconnected notebook (#4960)
This is a partial fix that lays groundwork for full "Prompt to connect" if a kernel needs a connection.
I am waiting on Yurong's refactoring of connection handling before doing any of the prompt work.

- Adds kernel metadata about whether a connection is required.
- For Jupyter, only Spark kernels are listed as requiring a connection
- If this is true and there's no active connection, will show notification and not call execute

In the future, this path will still be used if user is prompted to connect and cancels out.
The future change will be to inject a "connect" handler from notebook.component to the cell callback and use to set connection context
2019-04-10 13:50:23 -07:00
Kevin Cunnane
37ba956bad Fix #4893 New Notebook Can Open Existing Noteboon (#4959)
Add back check for textDocuments with same name, should've been there anyhow

On rehydration files show as text docs before clicking as only get
changed by customInputConverter code path.
We should look at this long term - ideally we'd update notebookDocuments
with correct values on initial start. #4958 opened to track this.
2019-04-10 13:47:49 -07:00
Kevin Cunnane
697f887539 Fix #4930 Text cells are referred to as text and markdown in commands (#4956) 2019-04-10 13:44:20 -07:00
Anthony Dresser
7b42141958 Merge 2de47c2a50 2019-04-10 13:44:11 -07:00
Chris LaFreniere
158b00f9b4 always serialize execution count (#4864) 2019-04-10 13:39:54 -07:00
Matt Bierner
43ac8dfd20 Adopt TS 3.4.3
Fixes #72005
2019-04-10 13:30:11 -07:00
Sandeep Somavarapu
34d8d52e7a Fix #71947 2019-04-09 13:09:10 -07:00
Sandeep Somavarapu
c738b26c04 Fix #71585 2019-04-09 13:09:03 -07:00
Johannes Rieken
6090e7173f properly check picked formatter, #71988 2019-04-09 13:06:45 -07:00
Johannes Rieken
7ebf746584 use editor for format on save and honor silent mode 2019-04-09 13:06:36 -07:00
Matt Bierner
e9d04d75ac Fixes #71688 2019-04-09 13:06:20 -07:00
Joao Moreno
605160a1ba Cherry pick 3773487012c98ef7974a0182771ea19178f2a525 2019-04-09 13:04:37 -07:00
Johannes Rieken
82b8750b63 show notification when formatter is disabled/uninstalled, message otherwise 2019-04-09 12:59:00 -07:00
Rob Lourens
61f7f19d12 Fix #71465 - "find in files shortcut broken" 2019-04-09 12:58:48 -07:00
2108 changed files with 84071 additions and 122579 deletions

6
.vscode/launch.json vendored
View File

@@ -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
View File

@@ -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",

View File

@@ -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"

View File

@@ -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

View File

@@ -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`

View File

@@ -27,12 +27,18 @@ steps:
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')

View File

@@ -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

View File

@@ -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

View File

@@ -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();

View File

@@ -1,4 +0,0 @@
#!/usr/bin/env bash
set -e
yarn gulp vscode-darwin-min
yarn gulp upload-vscode-sourcemaps

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,3 +0,0 @@
#!/usr/bin/env bash
set -e
yarn gulp "vscode-linux-$VSCODE_ARCH-min"

View File

@@ -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'

View File

@@ -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)

View File

@@ -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"

View File

@@ -63,17 +63,3 @@ jobs:
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

View File

@@ -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"

View File

@@ -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" }

View File

@@ -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'

View File

@@ -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 }

View File

@@ -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) {
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'); this.emit('end');
}
})); }));
} }

View File

@@ -6,6 +6,15 @@
'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');

View File

@@ -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);
}); });
}); });
}; }

View File

@@ -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);

View File

@@ -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 || {};

View File

@@ -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}`));

View File

@@ -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)

View File

@@ -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"

View File

@@ -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)
} }

View File

@@ -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);

View File

@@ -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);

View File

@@ -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");

View File

@@ -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';

View File

@@ -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);

View File

@@ -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"
}, },

View File

@@ -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,

View File

@@ -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}"

View File

@@ -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"

View File

@@ -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": {

View File

@@ -1,7 +1,7 @@
{ {
"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,
@@ -26,37 +26,23 @@
"contributes": { "contributes": {
"commands": [ "commands": [
{ {
"command": "adminToolExtWin.launchSsmsMinPropertiesDialog", "command": "adminToolExtWin.launchSsmsServerPropertiesDialog",
"title": "%adminToolExtWin.propertiesMenuItem%", "title": "%adminToolExtWin.launchSsmsServerPropertiesDialog%",
"category": "AdminToolExtWin"
},
{
"command": "adminToolExtWin.launchSsmsMinGswDialog",
"title": "%adminToolExtWin.launchGswMenuItem%",
"category": "AdminToolExtWin" "category": "AdminToolExtWin"
} }
], ],
"menus": { "menus": {
"commandPalette": [ "commandPalette": [
{ {
"command": "adminToolExtWin.launchSsmsMinPropertiesDialog", "command": "adminToolExtWin.launchSsmsServerPropertiesDialog",
"when": "false"
},
{
"command": "adminToolExtWin.launchSsmsMinGswDialog",
"when": "false" "when": "false"
} }
], ],
"objectExplorer/item/context": [ "objectExplorer/item/context": [
{ {
"command": "adminToolExtWin.launchSsmsMinGswDialog", "command": "adminToolExtWin.launchSsmsServerPropertiesDialog",
"when": "isWindows && connectionProvider == MSSQL && nodeType && nodeType == Database", "when": "isWindows && connectionProvider == MSSQL && nodeType && nodeType == Server",
"group": "z-AdminToolExt@1" "group": "AdminToolExtWin"
},
{
"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)$/",
"group": "z-AdminToolExt@2"
} }
] ]
}, },

View File

@@ -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..."
} }

View File

@@ -1,9 +1,9 @@
{ {
"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": [

View File

@@ -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'));
return;
}
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( launchSsmsDialog(
nodeTypeToUrnNameMapping[nodeType].action, /*action*/'sqla:Properties@Microsoft.SqlServer.Management.Smo.Server',
connectionContext); /*connectionProfile*/connectionContext.connectionProfile);
} }
/**
* 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,70 +96,27 @@ 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) => {
@@ -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('/');
} }

View File

@@ -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);
}
}

View File

@@ -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',
password: 'password',
useAad: false, useAad: false,
urn: 'Server\\Database\\Table' urn: 'Server\\Database\\Table'
}; };
const args = buildSsmsMinCommandArgs(params); let args = extensionMain.buildSsmsMinCommandArgs(params);
should(args).equal('-a "myAction" -S "myServer" -D "myDatabase" -U "user" -u "Server\\Database\\Table"'); 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',
password: 'password',
useAad: true, useAad: true,
urn: 'Server\\Database\\Table' urn: 'Server\\Database\\Table'
}; };
const args = buildSsmsMinCommandArgs(params); let args = extensionMain.buildSsmsMinCommandArgs(params);
// User is omitted since UseAAD is true // User is omitted since UseAAD is true
should(args).equal('-a "myAction" -S "myServer" -D "myDatabase" -G -u "Server\\Database\\Table"'); 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',
password: 'password',
useAad: true, useAad: true,
urn: 'Server\\Database[\'myDatabase\'\'"/\\[]tricky\']\\Table["myTable\'""/\\[]tricky"]' urn: 'Server\\Database[\'myDatabase\'\'"/\\[]tricky\']\\Table["myTable\'""/\\[]tricky"]'
}; };
const args = buildSsmsMinCommandArgs(params); let args = extensionMain.buildSsmsMinCommandArgs(params);
// User is omitted since UseAAD is true // 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\\"]"'); 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');
});
});

View File

@@ -40,21 +40,3 @@ export function getConfiguration(extensionName?: string, resource?: vscode.Uri |
} }
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, '\\"');
}

File diff suppressed because it is too large Load Diff

View File

@@ -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",

View File

@@ -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';

View File

@@ -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,6 +12,7 @@ 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

View File

@@ -610,8 +610,7 @@ export class JobDialog extends AgentDialog<JobData> {
{ {
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;

View 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();
});
});

View File

@@ -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);
});
});

View File

@@ -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;

View 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 {
}
}

View File

@@ -10,7 +10,8 @@
"sourceMap": true, "sourceMap": true,
"emitDecoratorMetadata": true, "emitDecoratorMetadata": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"moduleResolution": "node" "moduleResolution": "node",
"declaration": true
}, },
"exclude": [ "exclude": [
"node_modules" "node_modules"

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +0,0 @@
src/**
out/**
tsconfig.json
extension.webpack.config.js
yarn.lock

View File

@@ -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"
} }
} }

View File

@@ -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",

View File

@@ -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

View 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-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

View File

@@ -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

View 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

View File

@@ -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();
@@ -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
}, },

View File

@@ -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';

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -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';
@@ -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[]> {
@@ -110,8 +112,8 @@ export default class TokenCache implements adal.TokenCache {
/** /**
* 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

View File

@@ -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);
} }

View File

@@ -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';

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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 { TreeItem, TreeItemCollapsibleState } from 'vscode'; import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { Account, NodeInfo, AzureResource } from 'azdata'; import { Account, NodeInfo, AzureResource } from 'azdata';
import { TokenCredentials } from 'ms-rest'; import { TokenCredentials } from 'ms-rest';

View File

@@ -1,7 +1,4 @@
/*--------------------------------------------------------------------------------------------- 'use strict';
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vscode-nls'; import * as nls from 'vscode-nls';

View File

@@ -3,16 +3,17 @@
* 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 ControllerBase from './controllerBase'; import ControllerBase from './controllerBase';
import { DidChangeAccountsParams, Account } from 'azdata'; import { DidChangeAccountsParams } from 'azdata';
import { import {
IAzureResourceCacheService, IAzureResourceCacheService,
IAzureResourceAccountService, IAzureResourceAccountService,
IAzureResourceSubscriptionService, IAzureResourceSubscriptionService,
IAzureResourceSubscriptionFilterService, IAzureResourceSubscriptionFilterService,
IAzureResourceTenantService IAzureResourceTenantService } from '../azureResource/interfaces';
} from '../azureResource/interfaces';
import { AzureResourceServiceNames } from '../azureResource/constants'; import { AzureResourceServiceNames } from '../azureResource/constants';
import { AzureResourceTreeProvider } from '../azureResource/tree/treeProvider'; import { AzureResourceTreeProvider } from '../azureResource/tree/treeProvider';
import { registerAzureResourceCommands } from '../azureResource/commands'; import { registerAzureResourceCommands } from '../azureResource/commands';
@@ -37,7 +38,7 @@ export default class AzureResourceController extends ControllerBase {
const azureResourceTree = new AzureResourceTreeProvider(this.appContext); const azureResourceTree = new AzureResourceTreeProvider(this.appContext);
this.extensionContext.subscriptions.push(this.apiWrapper.registerTreeDataProvider('azureResourceExplorer', azureResourceTree)); this.extensionContext.subscriptions.push(this.apiWrapper.registerTreeDataProvider('azureResourceExplorer', azureResourceTree));
let previousAccounts: Array<Account> = undefined; let previousAccounts = undefined;
this.appContext.getService<IAzureResourceAccountService>(AzureResourceServiceNames.accountService).onDidChangeAccounts((e: DidChangeAccountsParams) => { this.appContext.getService<IAzureResourceAccountService>(AzureResourceServiceNames.accountService).onDidChangeAccounts((e: DidChangeAccountsParams) => {
// the onDidChangeAccounts event will trigger in many cases where the accounts didn't actually change // the onDidChangeAccounts event will trigger in many cases where the accounts didn't actually change
// the notifyNodeChanged event triggers a refresh which triggers a getChildren which can trigger this callback // the notifyNodeChanged event triggers a refresh which triggers a getChildren which can trigger this callback

View File

@@ -1,7 +1,4 @@
/*--------------------------------------------------------------------------------------------- 'use strict';
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as fs from 'fs'; import * as fs from 'fs';
@@ -26,7 +23,7 @@ let controllers: ControllerBase[] = [];
// The function is a duplicate of \src\paths.js. IT would be better to import path.js but it doesn't // The function is a duplicate of \src\paths.js. IT would be better to import path.js but it doesn't
// work for now because the extension is running in different process. // work for now because the extension is running in different process.
export function getAppDataPath() { export function getAppDataPath() {
let platform = process.platform; var platform = process.platform;
switch (platform) { switch (platform) {
case 'win32': return process.env['APPDATA'] || path.join(process.env['USERPROFILE'], 'AppData', 'Roaming'); case 'win32': return process.env['APPDATA'] || path.join(process.env['USERPROFILE'], 'AppData', 'Roaming');
case 'darwin': return path.join(os.homedir(), 'Library', 'Application Support'); case 'darwin': return path.join(os.homedir(), 'Library', 'Application Support');
@@ -57,7 +54,7 @@ export function activate(extensionContext: vscode.ExtensionContext) {
} catch (e) { } catch (e) {
console.error(`Initialization of Azure account extension storage failed: ${e}`); console.error(`Initialization of Azure account extension storage failed: ${e}`);
console.error('Azure accounts will not be available'); console.error('Azure accounts will not be available');
return undefined; return;
} }
// Create the provider service and activate // Create the provider service and activate

View File

@@ -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 should from 'should'; import * as should from 'should';
import * as TypeMoq from 'typemoq'; import * as TypeMoq from 'typemoq';
import * as azdata from 'azdata'; import * as azdata from 'azdata';
@@ -30,8 +32,7 @@ const mockAccount: azdata.Account = {
displayInfo: { displayInfo: {
displayName: 'mock_account@test.com', displayName: 'mock_account@test.com',
accountType: 'Microsoft', accountType: 'Microsoft',
contextualDisplayName: 'test', contextualDisplayName: 'test'
userId: 'test@email.com'
}, },
properties: undefined, properties: undefined,
isStale: false isStale: false
@@ -57,7 +58,7 @@ const mockResourceRootNode: azureResource.IAzureResourceNode = {
} }
}; };
const mockTokens: { [key: string]: any } = {}; const mockTokens = {};
mockTokens[mockTenantId] = { mockTokens[mockTenantId] = {
token: 'mock_token', token: 'mock_token',
tokenType: 'Bearer' tokenType: 'Bearer'

View File

@@ -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 should from 'should'; import * as should from 'should';
import * as TypeMoq from 'typemoq'; import * as TypeMoq from 'typemoq';
import * as azdata from 'azdata'; import * as azdata from 'azdata';
@@ -30,8 +32,7 @@ const mockAccount: azdata.Account = {
displayInfo: { displayInfo: {
displayName: 'mock_account@test.com', displayName: 'mock_account@test.com',
accountType: 'Microsoft', accountType: 'Microsoft',
contextualDisplayName: 'test', contextualDisplayName: 'test'
userId: 'test@email.com'
}, },
properties: undefined, properties: undefined,
isStale: false isStale: false
@@ -57,7 +58,7 @@ const mockResourceRootNode: azureResource.IAzureResourceNode = {
} }
}; };
const mockTokens: { [key: string]: any } = {}; const mockTokens = {};
mockTokens[mockTenantId] = { mockTokens[mockTenantId] = {
token: 'mock_token', token: 'mock_token',
tokenType: 'Bearer' tokenType: 'Bearer'

View File

@@ -23,8 +23,7 @@ const mockAccount: azdata.Account = {
displayInfo: { displayInfo: {
displayName: 'mock_account@test.com', displayName: 'mock_account@test.com',
accountType: 'Microsoft', accountType: 'Microsoft',
contextualDisplayName: 'test', contextualDisplayName: 'test'
userId: 'test@email.com'
}, },
properties: undefined, properties: undefined,
isStale: false isStale: false

View File

@@ -26,8 +26,7 @@ const mockAccount: azdata.Account = {
displayInfo: { displayInfo: {
displayName: 'mock_account@test.com', displayName: 'mock_account@test.com',
accountType: 'Microsoft', accountType: 'Microsoft',
contextualDisplayName: 'test', contextualDisplayName: 'test'
userId: 'test@email.com'
}, },
properties: undefined, properties: undefined,
isStale: false isStale: false

View File

@@ -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 should from 'should'; import * as should from 'should';
import * as TypeMoq from 'typemoq'; import * as TypeMoq from 'typemoq';
import * as azdata from 'azdata'; import * as azdata from 'azdata';
@@ -48,8 +50,7 @@ const mockAccount: azdata.Account = {
displayInfo: { displayInfo: {
displayName: 'mock_account@test.com', displayName: 'mock_account@test.com',
accountType: 'Microsoft', accountType: 'Microsoft',
contextualDisplayName: 'test', contextualDisplayName: 'test'
userId: 'test@email.com'
}, },
properties: { properties: {
tenants: [ tenants: [
@@ -75,7 +76,7 @@ const mockSubscriptions = [mockSubscription1, mockSubscription2];
const mockFilteredSubscriptions = [mockSubscription1]; const mockFilteredSubscriptions = [mockSubscription1];
const mockTokens: { [key: string]: any } = {}; const mockTokens = {};
mockTokens[mockTenantId] = { mockTokens[mockTenantId] = {
token: 'mock_token', token: 'mock_token',
tokenType: 'Bearer' tokenType: 'Bearer'

View File

@@ -40,8 +40,7 @@ const mockAccount: azdata.Account = {
displayInfo: { displayInfo: {
displayName: 'mock_account@test.com', displayName: 'mock_account@test.com',
accountType: 'Microsoft', accountType: 'Microsoft',
contextualDisplayName: 'test', contextualDisplayName: 'test'
userId: 'test@email.com'
}, },
properties: undefined, properties: undefined,
isStale: false isStale: false

View File

@@ -38,8 +38,7 @@ const mockAccount1: azdata.Account = {
displayInfo: { displayInfo: {
displayName: 'mock_account_1@test.com', displayName: 'mock_account_1@test.com',
accountType: 'Microsoft', accountType: 'Microsoft',
contextualDisplayName: 'test', contextualDisplayName: 'test'
userId: 'test@email.com'
}, },
properties: undefined, properties: undefined,
isStale: false isStale: false
@@ -52,8 +51,7 @@ const mockAccount2: azdata.Account = {
displayInfo: { displayInfo: {
displayName: 'mock_account_2@test.com', displayName: 'mock_account_2@test.com',
accountType: 'Microsoft', accountType: 'Microsoft',
contextualDisplayName: 'test', contextualDisplayName: 'test'
userId: 'test@email.com'
}, },
properties: undefined, properties: undefined,
isStale: false isStale: false

View File

@@ -1,14 +1,22 @@
{ {
"extends": "../shared.tsconfig.json", "compileOnSave": true,
"compilerOptions": { "compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "./out", "outDir": "./out",
"strict": false, "lib": [
"noUnusedParameters": false, "es6", "es2015.promise"
],
"typeRoots": [ "typeRoots": [
"./node_modules/@types" "./node_modules/@types"
] ],
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"declaration": false
}, },
"include": [ "exclude": [
"src/**/*" "node_modules"
] ]
} }

File diff suppressed because it is too large Load Diff

View File

@@ -2,8 +2,10 @@
* 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 azdata from 'azdata'; import * as azdata from 'azdata';
import * as vscode from 'vscode';
import { WizardPageBase } from '../../wizardPageBase'; import { WizardPageBase } from '../../wizardPageBase';
import { CreateClusterWizard } from '../createClusterWizard'; import { CreateClusterWizard } from '../createClusterWizard';
import * as nls from 'vscode-nls'; import * as nls from 'vscode-nls';
@@ -345,7 +347,7 @@ export class ClusterProfilePage extends WizardPageBase<CreateClusterWizard> {
case ClusterPoolType.Spark: case ClusterPoolType.Spark:
return localize('bdc-create.SparkPoolDisplayName', 'Spark pool'); return localize('bdc-create.SparkPoolDisplayName', 'Spark pool');
default: default:
throw new Error('unknown pool type'); throw 'unknown pool type';
} }
} }
@@ -362,7 +364,7 @@ export class ClusterProfilePage extends WizardPageBase<CreateClusterWizard> {
case ClusterPoolType.Spark: case ClusterPoolType.Spark:
return localize('bdc-create.SparkPoolDescription', 'TODO: Add description'); return localize('bdc-create.SparkPoolDescription', 'TODO: Add description');
default: default:
throw new Error('unknown pool type'); throw 'unknown pool type';
} }
} }

View File

@@ -2,6 +2,7 @@
* 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 azdata from 'azdata'; import * as azdata from 'azdata';
import { WizardPageBase } from '../../wizardPageBase'; import { WizardPageBase } from '../../wizardPageBase';

View File

@@ -1,28 +0,0 @@
# Microsoft Central Management Servers for Azure Data Studio
## Central Management Servers *(preview)*
The Central Management Servers extension allows users to store a list of instances of SQL Server that is organized into one or more groups. Actions that are taken using a CMS group act on all servers in the server group.
This experience is currently in its initial preview. Please report issues and feature requests [here.](https://github.com/microsoft/azuredatastudio/issues)
<img src="https://user-images.githubusercontent.com/30873802/57338070-eba5af00-70e0-11e9-911c-ddaa166b59b8.png" width="800px" />
### How do I start Central Management Servers?
Central Management Servers can be viewed by clicking on the Connections icon (Ctrl/Cmd + G). The first time you download the extension, the CMS view will be minimized, and you can open it by click on **Central Management Servers**
### Where can I learn more about Central Management Servers
To learn more conceptually about Central Management Servers, [you can read more here.](https://docs.microsoft.com/sql/ssms/register-servers/create-a-central-management-server-and-server-group)
## Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Privacy Statement
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/en-us/privacystatement) describes the privacy statement of this software.
## License
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the [Source EULA](https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt).

View File

@@ -1,644 +0,0 @@
{
"name": "cms",
"displayName": "%cms.displayName%",
"description": "%cms.description%",
"version": "0.1.0",
"publisher": "Microsoft",
"preview": true,
"engines": {
"vscode": "^1.25.0",
"sqlops": "*"
},
"activationEvents": [
"*"
],
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"main": "./out/extension",
"contributes": {
"configuration": {
"type": "object",
"title": "%cms.title%",
"properties": {
"cms.cmsServers": {
"type": "object"
}
}
},
"connectionProvider": {
"providerId": "MSSQL-CMS",
"displayName": "%cms.connectionProvider.displayName%",
"connectionOptions": [
{
"specialValueType": "connectionName",
"isIdentity": true,
"name": "connectionName",
"displayName": "%cms.connectionOptions.connectionName.displayName%",
"description": "%cms.connectionOptions.connectionName.description%",
"groupName": "Source",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": "serverName",
"isIdentity": true,
"name": "server",
"displayName": "%cms.connectionOptions.serverName.displayName%",
"description": "%cms.connectionOptions.serverName.description%",
"groupName": "Source",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": true,
"isArray": false
},
{
"specialValueType": "serverDescription",
"isIdentity": true,
"name": "serverDescription",
"displayName": "%cms.connectionOptions.serverDescription.displayName%",
"description": "%cms.connectionOptions.serverDescription.description%",
"groupName": "Source",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": "authType",
"isIdentity": true,
"name": "authenticationType",
"displayName": "%cms.connectionOptions.authType.displayName%",
"description": "%cms.connectionOptions.authType.description%",
"groupName": "Security",
"valueType": "category",
"defaultValue": null,
"objectType": null,
"categoryValues": [
{
"displayName": "%cms.connectionOptions.authType.categoryValues.sqlLogin%",
"name": "SqlLogin"
},
{
"displayName": "%cms.connectionOptions.authType.categoryValues.integrated%",
"name": "Integrated"
},
{
"displayName": "%cms.connectionOptions.authType.categoryValues.azureMFA%",
"name": "AzureMFA"
}
],
"isRequired": true,
"isArray": false
},
{
"specialValueType": "userName",
"isIdentity": true,
"name": "user",
"displayName": "%cms.connectionOptions.userName.displayName%",
"description": "%cms.connectionOptions.userName.description%",
"groupName": "Security",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": true,
"isArray": false
},
{
"specialValueType": "password",
"isIdentity": true,
"name": "password",
"displayName": "%cms.connectionOptions.password.displayName%",
"description": "%cms.connectionOptions.password.description%",
"groupName": "Security",
"valueType": "password",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": true,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "applicationIntent",
"displayName": "%cms.connectionOptions.applicationIntent.displayName%",
"description": "%cms.connectionOptions.applicationIntent.description%",
"groupName": "Initialization",
"valueType": "category",
"defaultValue": null,
"objectType": null,
"categoryValues": [
{
"displayName": "ReadWrite",
"name": "ReadWrite"
},
{
"displayName": "ReadOnly",
"name": "ReadOnly"
}
],
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "asynchronousProcessing",
"displayName": "%cms.connectionOptions.asynchronousProcessing.displayName%",
"description": "%cms.connectionOptions.asynchronousProcessing.description%",
"groupName": "Initialization",
"valueType": "boolean",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "connectTimeout",
"displayName": "%cms.connectionOptions.connectTimeout.displayName%",
"description": "%cms.connectionOptions.connectTimeout.description%",
"groupName": "Initialization",
"valueType": "number",
"defaultValue": "15",
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "currentLanguage",
"displayName": "%cms.connectionOptions.currentLanguage.displayName%",
"description": "%cms.connectionOptions.currentLanguage.description%",
"groupName": "Initialization",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "columnEncryptionSetting",
"displayName": "%cms.connectionOptions.columnEncryptionSetting.displayName%",
"description": "%cms.connectionOptions.columnEncryptionSetting.description%",
"groupName": "Security",
"valueType": "category",
"defaultValue": null,
"objectType": null,
"categoryValues": [
{
"displayName": null,
"name": "Disabled"
},
{
"displayName": null,
"name": "Enabled"
}
],
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "encrypt",
"displayName": "%cms.connectionOptions.encrypt.displayName%",
"description": "%cms.connectionOptions.encrypt.description%",
"groupName": "Security",
"valueType": "boolean",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "persistSecurityInfo",
"displayName": "%cms.connectionOptions.persistSecurityInfo.displayName%",
"description": "%cms.connectionOptions.persistSecurityInfo.description%",
"groupName": "Security",
"valueType": "boolean",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "trustServerCertificate",
"displayName": "%cms.connectionOptions.trustServerCertificate.displayName%",
"description": "%cms.connectionOptions.trustServerCertificate.description%",
"groupName": "Security",
"valueType": "boolean",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "attachedDBFileName",
"displayName": "%cms.connectionOptions.attachedDBFileName.displayName%",
"description": "%cms.connectionOptions.attachedDBFileName.description%",
"groupName": "Source",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "contextConnection",
"displayName": "%cms.connectionOptions.contextConnection.displayName%",
"description": "%cms.connectionOptions.contextConnection.description%",
"groupName": "Source",
"valueType": "boolean",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "port",
"displayName": "%cms.connectionOptions.port.displayName%",
"description": null,
"groupName": null,
"valueType": "number",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "connectRetryCount",
"displayName": "%cms.connectionOptions.connectRetryCount.displayName%",
"description": "%cms.connectionOptions.connectRetryCount.description%",
"groupName": "Connection Resiliency",
"valueType": "number",
"defaultValue": "1",
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "connectRetryInterval",
"displayName": "%cms.connectionOptions.connectRetryInterval.displayName%",
"description": "%cms.connectionOptions.connectRetryInterval.description%",
"groupName": "Connection Resiliency",
"valueType": "number",
"defaultValue": "10",
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": "appName",
"isIdentity": false,
"name": "applicationName",
"displayName": "%cms.connectionOptions.applicationName.displayName%",
"description": "%cms.connectionOptions.applicationName.description%",
"groupName": "Context",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "workstationId",
"displayName": "%cms.connectionOptions.workstationId.displayName%",
"description": "%cms.connectionOptions.workstationId.description%",
"groupName": "Context",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "pooling",
"displayName": "%cms.connectionOptions.pooling.displayName%",
"description": "%cms.connectionOptions.pooling.description%",
"groupName": "Pooling",
"valueType": "boolean",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "maxPoolSize",
"displayName": "%cms.connectionOptions.maxPoolSize.displayName%",
"description": "%cms.connectionOptions.maxPoolSize.description%",
"groupName": "Pooling",
"valueType": "number",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "minPoolSize",
"displayName": "%cms.connectionOptions.minPoolSize.displayName%",
"description": "%cms.connectionOptions.minPoolSize.description%",
"groupName": "Pooling",
"valueType": "number",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "loadBalanceTimeout",
"displayName": "%cms.connectionOptions.loadBalanceTimeout.displayName%",
"description": "%cms.connectionOptions.loadBalanceTimeout.description%",
"groupName": "Pooling",
"valueType": "number",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "replication",
"displayName": "%cms.connectionOptions.replication.displayName%",
"description": "%cms.connectionOptions.replication.description%",
"groupName": "Replication",
"valueType": "boolean",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "attachDbFilename",
"displayName": "%cms.connectionOptions.attachDbFilename.displayName%",
"description": null,
"groupName": null,
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "failoverPartner",
"displayName": "%cms.connectionOptions.failoverPartner.displayName%",
"description": "%cms.connectionOptions.failoverPartner.description%",
"groupName": " Source",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "multiSubnetFailover",
"displayName": "%cms.connectionOptions.multiSubnetFailover.displayName%",
"description": null,
"groupName": null,
"valueType": "boolean",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "multipleActiveResultSets",
"displayName": "%cms.connectionOptions.multipleActiveResultSets.displayName%",
"description": "%cms.connectionOptions.multipleActiveResultSets.description%",
"groupName": "Advanced",
"valueType": "boolean",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "packetSize",
"displayName": "%cms.connectionOptions.packetSize.displayName%",
"description": "%cms.connectionOptions.packetSize.description%",
"groupName": "Advanced",
"valueType": "number",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
},
{
"specialValueType": null,
"isIdentity": false,
"name": "typeSystemVersion",
"displayName": "%cms.connectionOptions.typeSystemVersion.displayName%",
"description": "%cms.connectionOptions.typeSystemVersion.description%",
"groupName": "Advanced",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
}
]
},
"commands": [
{
"command": "cms.resource.deleteRegisteredServer",
"title": "%cms.resource.deleteRegisteredServer.title%",
"when": "viewItem == cms.resource.itemType.registeredServer"
},
{
"command": "cms.resource.addRegisteredServer",
"title": "%cms.resource.addRegisteredServer.title%",
"when": "viewItem == cms.resource.itemType.serverGroup"
},
{
"command": "cms.resource.addServerGroup",
"title": "%cms.resource.addServerGroup.title%",
"when": "viewItem == cms.resource.itemType.serverGroup"
},
{
"command": "cms.resource.deleteServerGroup",
"title": "%cms.resource.deleteServerGroup.title%",
"when": "viewItem == cms.resource.itemType.serverGroup"
},
{
"command": "cms.resource.refreshServerGroup",
"title": "%cms.resource.refreshServerGroup.title%",
"when": "viewItem == cms.resource.itemType.serverGroup",
"icon": {
"light": "resources/light/refresh.svg",
"dark": "resources/dark/refresh_inverse.svg"
}
},
{
"command": "cms.resource.refreshCmsServer",
"title": "%cms.resource.refreshCmsServer.title%",
"when": "viewItem == cms.resource.itemType.cmsNodeContainer",
"icon": {
"light": "resources/light/refresh.svg",
"dark": "resources/dark/refresh_inverse.svg"
}
},
{
"command": "cms.resource.registerCmsServer",
"title": "%cms.resource.registerCmsServer.title%",
"icon": {
"light": "resources/light/add.svg",
"dark": "resources/dark/add_inverse.svg"
}
},
{
"command": "cms.resource.deleteCmsServer",
"title": "%cms.resource.deleteCmsServer.title%"
}
],
"dataExplorer": {
"cmsResource": [
{
"id": "cmsResourceExplorer",
"name": "%cms.resource.explorer.title%"
}
]
},
"menus": {
"view/title": [
{
"command": "cms.resource.registerCmsServer",
"when": "view == cmsResourceExplorer",
"group": "navigation"
}
],
"view/item/context": [
{
"command": "cms.resource.deleteRegisteredServer",
"when": "viewItem == cms.resource.itemType.registeredServer",
"group": "navigation@2"
},
{
"command": "cms.resource.deleteServerGroup",
"when": "viewItem == cms.resource.itemType.serverGroup",
"group": "navigation@10"
},
{
"command": "cms.resource.addRegisteredServer",
"when": "viewItem == cms.resource.itemType.serverGroup",
"group": "navigation@10"
},
{
"command": "cms.resource.addRegisteredServer",
"when": "viewItem == cms.resource.itemType.cmsNodeContainer",
"group": "navigation@10"
},
{
"command": "cms.resource.addServerGroup",
"when": "viewItem == cms.resource.itemType.serverGroup",
"group": "navigation@10"
},
{
"command": "cms.resource.addServerGroup",
"when": "viewItem == cms.resource.itemType.cmsNodeContainer",
"group": "navigation@10"
},
{
"command": "cms.resource.refreshServerGroup",
"when": "viewItem == cms.resource.itemType.serverGroup",
"group": "navigation@10"
},
{
"command": "cms.resource.refreshCmsServer",
"when": "viewItem == cms.resource.itemType.cmsNodeContainer",
"group": "navigation@10"
},
{
"command": "cms.resource.deleteCmsServer",
"when": "viewItem == cms.resource.itemType.cmsNodeContainer",
"group": "navigation@10"
}
]
}
},
"dependencies": {
"request": "2.88.0",
"vscode-nls": "^4.0.0"
},
"devDependencies": {
"@types/mocha": "^5.2.5",
"@types/node": "^8.0.24",
"mocha": "^5.2.0",
"should": "^13.2.1",
"vscode": "^1.1.26",
"typemoq": "^2.1.0"
}
}

View File

@@ -1,111 +0,0 @@
{
"cms.displayName": "CMS",
"cms.description": "Central Management Servers",
"cms.title": "Central Management Servers",
"cms.connectionProvider.displayName": "Microsoft SQL Server - CMS",
"cms.resource.explorer.title": "Central Management Servers",
"cms.resource.refreshServerGroup.title": "Refresh Server Group",
"cms.resource.refreshCmsServer.title": "Refresh Central Management Server",
"cms.resource.deleteRegisteredServer.title": "Delete Registered Server",
"cms.resource.addRegisteredServer.title": "Add Registered Server",
"cms.resource.deleteServerGroup.title": "Delete Server Group",
"cms.resource.addServerGroup.title": "Add Server Group",
"cms.resource.registerCmsServer.title": "Add Central Management Server",
"cms.resource.deleteCmsServer.title": "Delete Central Management Server",
"cms.configuration.title": "MSSQL configuration",
"cms.query.displayBitAsNumber": "Should BIT columns be displayed as numbers (1 or 0)? If false, BIT columns will be displayed as 'true' or 'false'",
"cms.format.alignColumnDefinitionsInColumns": "Should column definitions be aligned?",
"cms.format.datatypeCasing": "Should data types be formatted as UPPERCASE, lowercase, or none (not formatted)",
"cms.format.keywordCasing": "Should keywords be formatted as UPPERCASE, lowercase, or none (not formatted)",
"cms.format.placeCommasBeforeNextStatement": "should commas be placed at the beginning of each statement in a list e.g. ', mycolumn2' instead of at the end e.g. 'mycolumn1,'",
"cms.format.placeSelectStatementReferencesOnNewLine": "Should references to objects in a select statements be split into separate lines? E.g. for 'SELECT C1, C2 FROM T1' both C1 and C2 will be on separate lines",
"cms.logDebugInfo": "[Optional] Log debug output to the console (View -> Output) and then select appropriate output channel from the dropdown",
"cms.tracingLevel": "[Optional] Log level for backend services. Azure Data Studio generates a file name every time it starts and if the file already exists the logs entries are appended to that file. For cleanup of old log files see logRetentionMinutes and logFilesRemovalLimit settings. The default tracingLevel does not log much. Changing verbosity could lead to extensive logging and disk space requirements for the logs. Error includes Critical, Warning includes Error, Information includes Warning and Verbose includes Information",
"cms.logRetentionMinutes": "Number of minutes to retain log files for backend services. Default is 1 week.",
"cms.logFilesRemovalLimit": "Maximum number of old files to remove upon startup that have expired mssql.logRetentionMinutes. Files that do not get cleaned up due to this limitation get cleaned up next time Azure Data Studio starts up.",
"ignorePlatformWarning": "[Optional] Do not show unsupported platform warnings",
"onprem.databaseProperties.recoveryModel": "Recovery Model",
"onprem.databaseProperties.lastBackupDate": "Last Database Backup",
"onprem.databaseProperties.lastLogBackupDate": "Last Log Backup",
"onprem.databaseProperties.compatibilityLevel": "Compatibility Level",
"onprem.databaseProperties.owner": "Owner",
"onprem.serverProperties.serverVersion": "Version",
"onprem.serverProperties.serverEdition": "Edition",
"onprem.serverProperties.machineName": "Computer Name",
"onprem.serverProperties.osVersion": "OS Version",
"cloud.databaseProperties.azureEdition": "Edition",
"cloud.databaseProperties.serviceLevelObjective": "Pricing Tier",
"cloud.databaseProperties.compatibilityLevel": "Compatibility Level",
"cloud.databaseProperties.owner": "Owner",
"cloud.serverProperties.serverVersion": "Version",
"cloud.serverProperties.serverEdition": "Type",
"cms.provider.displayName": "Microsoft SQL Server",
"cms.connectionOptions.connectionName.displayName": "Name (optional)",
"cms.connectionOptions.connectionName.description": "Custom name of the connection",
"cms.connectionOptions.serverName.displayName": "Server",
"cms.connectionOptions.serverName.description": "Name of the SQL Server instance",
"cms.connectionOptions.serverDescription.displayName": "Server Description",
"cms.connectionOptions.serverDescription.description": "Description of the SQL Server instance",
"cms.connectionOptions.authType.displayName": "Authentication type",
"cms.connectionOptions.authType.description": "Specifies the method of authenticating with SQL Server",
"cms.connectionOptions.authType.categoryValues.sqlLogin": "SQL Login",
"cms.connectionOptions.authType.categoryValues.integrated": "Windows Authentication",
"cms.connectionOptions.authType.categoryValues.azureMFA": "Azure Active Directory - Universal with MFA support",
"cms.connectionOptions.userName.displayName": "User name",
"cms.connectionOptions.userName.description": "Indicates the user ID to be used when connecting to the data source",
"cms.connectionOptions.password.displayName": "Password",
"cms.connectionOptions.password.description": "Indicates the password to be used when connecting to the data source",
"cms.connectionOptions.applicationIntent.displayName": "Application intent",
"cms.connectionOptions.applicationIntent.description": "Declares the application workload type when connecting to a server",
"cms.connectionOptions.asynchronousProcessing.displayName": "Asynchronous processing",
"cms.connectionOptions.asynchronousProcessing.description": "When true, enables usage of the Asynchronous functionality in the .Net Framework Data Provider",
"cms.connectionOptions.connectTimeout.displayName": "Connect timeout",
"cms.connectionOptions.connectTimeout.description": "The length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error",
"cms.connectionOptions.currentLanguage.displayName": "Current language",
"cms.connectionOptions.currentLanguage.description": "The SQL Server language record name",
"cms.connectionOptions.columnEncryptionSetting.displayName": "Column encryption",
"cms.connectionOptions.columnEncryptionSetting.description": "Default column encryption setting for all the commands on the connection",
"cms.connectionOptions.encrypt.displayName": "Encrypt",
"cms.connectionOptions.encrypt.description": "When true, SQL Server uses SSL encryption for all data sent between the client and server if the servers has a certificate installed",
"cms.connectionOptions.persistSecurityInfo.displayName": "Persist security info",
"cms.connectionOptions.persistSecurityInfo.description": "When false, security-sensitive information, such as the password, is not returned as part of the connection",
"cms.connectionOptions.trustServerCertificate.displayName": "Trust server certificate",
"cms.connectionOptions.trustServerCertificate.description": "When true (and encrypt=true), SQL Server uses SSL encryption for all data sent between the client and server without validating the server certificate",
"cms.connectionOptions.attachedDBFileName.displayName": "Attached DB file name",
"cms.connectionOptions.attachedDBFileName.description": "The name of the primary file, including the full path name, of an attachable database",
"cms.connectionOptions.contextConnection.displayName": "Context connection",
"cms.connectionOptions.contextConnection.description": "When true, indicates the connection should be from the SQL server context. Available only when running in the SQL Server process",
"cms.connectionOptions.port.displayName": "Port",
"cms.connectionOptions.connectRetryCount.displayName": "Connect retry count",
"cms.connectionOptions.connectRetryCount.description": "Number of attempts to restore connection",
"cms.connectionOptions.connectRetryInterval.displayName": "Connect retry interval",
"cms.connectionOptions.connectRetryInterval.description": "Delay between attempts to restore connection",
"cms.connectionOptions.applicationName.displayName": "Application name",
"cms.connectionOptions.applicationName.description": "The name of the application",
"cms.connectionOptions.workstationId.displayName": "Workstation Id",
"cms.connectionOptions.workstationId.description": "The name of the workstation connecting to SQL Server",
"cms.connectionOptions.pooling.displayName": "Pooling",
"cms.connectionOptions.pooling.description": "When true, the connection object is drawn from the appropriate pool, or if necessary, is created and added to the appropriate pool",
"cms.connectionOptions.maxPoolSize.displayName": "Max pool size",
"cms.connectionOptions.maxPoolSize.description": "The maximum number of connections allowed in the pool",
"cms.connectionOptions.minPoolSize.displayName": "Min pool size",
"cms.connectionOptions.minPoolSize.description": "The minimum number of connections allowed in the pool",
"cms.connectionOptions.loadBalanceTimeout.displayName": "Load balance timeout",
"cms.connectionOptions.loadBalanceTimeout.description": "The minimum amount of time (in seconds) for this connection to live in the pool before being destroyed",
"cms.connectionOptions.replication.displayName": "Replication",
"cms.connectionOptions.replication.description": "Used by SQL Server in Replication",
"cms.connectionOptions.attachDbFilename.displayName": "Attach DB filename",
"cms.connectionOptions.failoverPartner.displayName": "Failover partner",
"cms.connectionOptions.failoverPartner.description": "The name or network address of the instance of SQL Server that acts as a failover partner",
"cms.connectionOptions.multiSubnetFailover.displayName": "Multi subnet failover",
"cms.connectionOptions.multipleActiveResultSets.displayName": "Multiple active result sets",
"cms.connectionOptions.multipleActiveResultSets.description": "When true, multiple result sets can be returned and read from one connection",
"cms.connectionOptions.packetSize.displayName": "Packet size",
"cms.connectionOptions.packetSize.description": "Size in bytes of the network packets used to communicate with an instance of SQL Server",
"cms.connectionOptions.typeSystemVersion.displayName": "Type system version",
"cms.connectionOptions.typeSystemVersion.description": "Indicates which server type system then provider will expose through the DataReader"
}

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#252526;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#c5c5c5;}</style></defs><title>add</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,16H0V0H16Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M14,6v4H10v4H6V10H2V6H6V2h4V6Z"/></g><g id="iconBg"><path class="icon-vs-bg" d="M13,7V9H9v4H7V9H3V7H7V3H9V7Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 486 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3-.795 0-1.545-.311-2.107-.868-.563-.567-.873-1.317-.873-2.111 0-1.431 1.007-2.632 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012l3.061-2.582-4.919-4.1h-1.137v2.404c-3.429.318-6.121 3.211-6.121 6.721 0 1.809.707 3.508 1.986 4.782 1.277 1.282 2.976 1.988 4.784 1.988 3.722 0 6.75-3.028 6.75-6.75 0-1.245-.349-2.468-1.007-3.536z" fill="#2D2D30"/><path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4-1.098 0-2.093-.445-2.817-1.164-.718-.724-1.163-1.718-1.163-2.815 0-2.206 1.794-4 4-4l.351.025v1.85s1.626-1.342 1.631-1.339l1.869-1.577-3.5-2.917v2.218l-.371-.03c-3.176 0-5.75 2.574-5.75 5.75 0 1.593.648 3.034 1.695 4.076 1.042 1.046 2.482 1.694 4.076 1.694 3.176 0 5.75-2.574 5.75-5.75-.001-1.106-.318-2.135-.859-3.012z" fill="#C5C5C5"/></svg>

Before

Width:  |  Height:  |  Size: 986 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.icon-canvas-transparent,.icon-vs-out{fill:#f6f6f6;}.icon-canvas-transparent{opacity:0;}.icon-vs-bg{fill:#424242;}</style></defs><title>add</title><g id="canvas"><path class="icon-canvas-transparent" d="M16,16H0V0H16Z"/></g><g id="outline" style="display: none;"><path class="icon-vs-out" d="M14,6v4H10v4H6V10H2V6H6V2h4V6Z"/></g><g id="iconBg"><path class="icon-vs-bg" d="M13,7V9H9v4H7V9H3V7H7V3H9V7Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 486 B

View File

@@ -1 +0,0 @@
<svg id="Icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><defs><style>.cls-1{opacity:0;}.cls-2{fill:#f6f6f6;}.cls-3{fill:#424242;}.cls-4{fill:#f0eff1;}</style></defs><title>centralmanagement_server_16x</title><g id="canvas" class="cls-1"><rect class="cls-2" width="16" height="16"/></g><path id="outline" class="cls-2" d="M16,0H7V1H3V5H0V16H8V13h8ZM6,4H7V5H6Z"/><g id="iconBG"><path class="cls-3" d="M8,1V12h7V1Zm6,10H13V10h1Zm0-6H9V4h5Zm0-2H9V2h5Z"/><path class="cls-3" d="M1,6v9H7V6Zm5,8H5V13H6Zm0-4H2V9H6ZM6,8H2V7H6Z"/><rect class="cls-3" x="6" y="2" width="1" height="1"/><rect class="cls-3" x="4" y="4" width="1" height="1"/><rect class="cls-3" x="4" y="2" width="1" height="1"/></g><g id="iconFG"><path class="cls-4" d="M14,3H9V2h5Zm0,1H9V5h5Zm0,6H13v1h1Z"/><path class="cls-4" d="M6,8H2V7H6ZM6,9H2v1H6Zm0,4H5v1H6Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 869 B

Some files were not shown because too many files have changed in this diff Show More