Refresh master with initial release/0.24 snapshot (#332)

* Initial port of release/0.24 source code

* Fix additional headers

* Fix a typo in launch.json
This commit is contained in:
Karl Burtram
2017-12-15 15:38:57 -08:00
committed by GitHub
parent 271b3a0b82
commit 6ad0df0e3e
7118 changed files with 107999 additions and 56466 deletions
+1 -1
View File
@@ -11,6 +11,6 @@ trim_trailing_whitespace = true
# The indent size used in the `package.json` file cannot be changed # The indent size used in the `package.json` file cannot be changed
# https://github.com/npm/npm/pull/3180#issuecomment-16336516 # https://github.com/npm/npm/pull/3180#issuecomment-16336516
[{.travis.yml,npm-shrinkwrap.json,package.json}] [{*.yml,*.yaml,npm-shrinkwrap.json,package.json}]
indent_style = space indent_style = space
indent_size = 2 indent_size = 2
+6 -2
View File
@@ -5,6 +5,10 @@ os:
- linux - linux
- osx - osx
cache:
directories:
- $HOME/.npm
notifications: notifications:
email: false email: false
@@ -27,8 +31,8 @@ before_install:
- git submodule update --init --recursive - git submodule update --init --recursive
- git clone --depth 1 https://github.com/creationix/nvm.git ./.nvm - git clone --depth 1 https://github.com/creationix/nvm.git ./.nvm
- source ./.nvm/nvm.sh - source ./.nvm/nvm.sh
- nvm install 7.4.0 - nvm install 7.9.0
- nvm use 7.4.0 - nvm use 7.9.0
- npm config set python `which python` - npm config set python `which python`
- npm install -g gulp - npm install -g gulp
- if [ $TRAVIS_OS_NAME == "linux" ]; then - if [ $TRAVIS_OS_NAME == "linux" ]; then
+26 -19
View File
@@ -6,12 +6,12 @@
"type": "node", "type": "node",
"request": "launch", "request": "launch",
"name": "Gulp Build", "name": "Gulp Build",
"program": "${workspaceRoot}/node_modules/gulp/bin/gulp.js", "program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
"stopOnEntry": true, "stopOnEntry": true,
"args": [ "args": [
"watch-extension:json-client" "watch-extension:json-client"
], ],
"cwd": "${workspaceRoot}" "cwd": "${workspaceFolder}"
}, },
{ {
"type": "node", "type": "node",
@@ -21,7 +21,7 @@
"port": 5870, "port": 5870,
"restart": true, "restart": true,
"outFiles": [ "outFiles": [
"${workspaceRoot}/out/**/*.js" "${workspaceFolder}/out/**/*.js"
] ]
}, },
{ {
@@ -31,17 +31,17 @@
"protocol": "inspector", "protocol": "inspector",
"port": 5871, "port": 5871,
"outFiles": [ "outFiles": [
"${workspaceRoot}/out/**/*.js" "${workspaceFolder}/out/**/*.js"
] ]
}, },
{ {
"type": "node", "type": "node",
"request": "attach", "request": "attach",
"protocol": "inspector", "protocol": "inspector",
"name": "Attach to Search process", "name": "Attach to Search Process",
"port": 7890, "port": 5876,
"outFiles": [ "outFiles": [
"${workspaceRoot}/out/**/*.js" "${workspaceFolder}/out/**/*.js"
] ]
}, },
{ {
@@ -51,7 +51,7 @@
"protocol": "inspector", "protocol": "inspector",
"port": 5874, "port": 5874,
"outFiles": [ "outFiles": [
"${workspaceRoot}/out/**/*.js" "${workspaceFolder}/out/**/*.js"
] ]
}, },
{ {
@@ -61,7 +61,7 @@
"protocol": "inspector", "protocol": "inspector",
"port": 5875, "port": 5875,
"outFiles": [ "outFiles": [
"${workspaceRoot}/out/**/*.js" "${workspaceFolder}/out/**/*.js"
] ]
}, },
{ {
@@ -75,44 +75,44 @@
"request": "launch", "request": "launch",
"name": "Launch sqlops", "name": "Launch sqlops",
"windows": { "windows": {
"runtimeExecutable": "${workspaceRoot}/scripts/sql.bat" "runtimeExecutable": "${workspaceFolder}/scripts/sql.bat"
}, },
"osx": { "osx": {
"runtimeExecutable": "${workspaceRoot}/scripts/sql.sh" "runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
}, },
"linux": { "linux": {
"runtimeExecutable": "${workspaceRoot}/scripts/sql.sh" "runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
}, },
"urlFilter": "*index.html*", "urlFilter": "*index.html*",
"runtimeArgs": [ "runtimeArgs": [
"--inspect=5875" "--inspect=5875"
], ],
"webRoot": "${workspaceRoot}" "webRoot": "${workspaceFolder}"
}, },
{ {
"type": "node", "type": "node",
"request": "launch", "request": "launch",
"name": "Unit Tests", "name": "Unit Tests",
"protocol": "inspector", "protocol": "inspector",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"runtimeExecutable": "${workspaceRoot}/.build/electron/sqlops.app/Contents/MacOS/Electron", "runtimeExecutable": "${workspaceFolder}/.build/electron/sqlops.app/Contents/MacOS/Electron",
"windows": { "windows": {
"runtimeExecutable": "${workspaceRoot}/.build/electron/sqlops.exe" "runtimeExecutable": "${workspaceFolder}/.build/electron/sqlops.exe"
}, },
"linux": { "linux": {
"runtimeExecutable": "${workspaceRoot}/.build/electron/sqlops" "runtimeExecutable": "${workspaceFolder}/.build/electron/sqlops"
}, },
"stopOnEntry": false, "stopOnEntry": false,
"args": [ "args": [
"--timeout", "--timeout",
"2000" "2000"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceFolder}",
"env": { "env": {
"ELECTRON_RUN_AS_NODE": "true" "ELECTRON_RUN_AS_NODE": "true"
}, },
"outFiles": [ "outFiles": [
"${workspaceRoot}/out/**/*.js" "${workspaceFolder}/out/**/*.js"
] ]
} }
], ],
@@ -123,6 +123,13 @@
"Launch sqlops", "Launch sqlops",
"Attach to Main Process" "Attach to Main Process"
] ]
},
{
"name": "Search and Renderer processes",
"configurations": [
"Launch sqlops",
"Attach to Search Process"
]
} }
] ]
} }
+7 -4
View File
@@ -14,9 +14,12 @@
"**/node_modules": true, "**/node_modules": true,
"**/bower_components": true, "**/bower_components": true,
".build/**": true, ".build/**": true,
"out*/**": true, "out/**": true,
"out-build/**": true,
"out-vscode/**": true,
"i18n/**": true, "i18n/**": true,
"extensions/**/out/**": true "extensions/**/out/**": true,
"test/smoke/out/**": true
}, },
"tslint.enable": true, "tslint.enable": true,
"lcov.path": [ "lcov.path": [
@@ -26,9 +29,9 @@
"lcov.watch": [ "lcov.watch": [
{ {
"pattern": "**/*.test.js", "pattern": "**/*.test.js",
"command": "${workspaceRoot}/scripts/test.sh --coverage --run ${file}", "command": "${workspaceFolder}/scripts/test.sh --coverage --run ${file}",
"windows": { "windows": {
"command": "${workspaceRoot}\\scripts\\test.bat --coverage --run ${file}" "command": "${workspaceFolder}\\scripts\\test.bat --coverage --run ${file}"
} }
} }
] ]
+5 -5
View File
@@ -2,16 +2,16 @@ MICROSOFT SOFTWARE LICENSE TERMS
MICROSOFT SQL OPERATIONS STUDIO MICROSOFT SQL OPERATIONS STUDIO
Microsoft Corporation (“Microsoft”) grants you a nonexclusive, perpetual, Microsoft Corporation (“Microsoft”) grants you a nonexclusive, perpetual,
royalty-free right to use, copy, and modify the software code provided by us royalty-free right to use, copy, and modify the software code provided by us
("Software Code"). You may not sublicense the Software Code or any use of it ("Software Code"). You may not sublicense the Software Code or any use of it
(except to your affiliates and to vendors to perform work on your behalf) (except to your affiliates and to vendors to perform work on your behalf)
through distribution, network access, service agreement, lease, rental, or through distribution, network access, service agreement, lease, rental, or
otherwise. Unless applicable law gives you more rights, Microsoft reserves all otherwise. Unless applicable law gives you more rights, Microsoft reserves all
other rights not expressly granted herein, whether by implication, estoppel or other rights not expressly granted herein, whether by implication, estoppel or
otherwise.  otherwise. 
   
THE SOFTWARE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL MICROSOFT OR ITS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL MICROSOFT OR ITS
LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-27
View File
@@ -44,7 +44,6 @@ expressly granted herein, whether by implication, estoppel or otherwise.
pretty-data: https://github.com/vkiryukhin/pretty-data pretty-data: https://github.com/vkiryukhin/pretty-data
primeng: https://github.com/primefaces/primeng primeng: https://github.com/primefaces/primeng
pty.js: https://github.com/chjj/pty.js pty.js: https://github.com/chjj/pty.js
rangy: https://github.com/timdown/rangy
reflect-metadata: https://github.com/rbuckton/reflect-metadata reflect-metadata: https://github.com/rbuckton/reflect-metadata
rxjs: https://github.com/ReactiveX/RxJS rxjs: https://github.com/ReactiveX/RxJS
semver: https://github.com/npm/node-semver semver: https://github.com/npm/node-semver
@@ -1395,32 +1394,6 @@ THE SOFTWARE.
========================================= =========================================
END OF pty.js NOTICES AND INFORMATION END OF pty.js NOTICES AND INFORMATION
%% rangy NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
Copyright (c) 2014 Tim Down
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
=========================================
END OF rangy NOTICES AND INFORMATION
%% reflect-metadata NOTICES AND INFORMATION BEGIN HERE %% reflect-metadata NOTICES AND INFORMATION BEGIN HERE
========================================= =========================================
Apache License Apache License
+5 -3
View File
@@ -2,14 +2,16 @@ environment:
ELECTRON_RUN_AS_NODE: 1 ELECTRON_RUN_AS_NODE: 1
VSCODE_BUILD_VERBOSE: true VSCODE_BUILD_VERBOSE: true
cache:
- '%APPDATA%\npm-cache'
install: install:
- ps: Install-Product node 7.4.0 x64 - ps: Install-Product node 7.9.0 x64
- npm install -g npm@4 --silent - npm install -g npm@4 --silent
- npm install -g gulp mocha --silent
build_script: build_script:
- .\scripts\npm.bat install - .\scripts\npm.bat install
- gulp electron - .\node_modules\.bin\gulp electron
- npm run compile - npm run compile
test_script: test_script:
+7 -4
View File
@@ -12,6 +12,7 @@ const gulptslint = require('gulp-tslint');
const gulpeslint = require('gulp-eslint'); const gulpeslint = require('gulp-eslint');
const tsfmt = require('typescript-formatter'); const tsfmt = require('typescript-formatter');
const tslint = require('tslint'); const tslint = require('tslint');
const vfs = require('vinyl-fs');
/** /**
* Hygiene works by creating cascading subsets of all our files and * Hygiene works by creating cascading subsets of all our files and
@@ -53,6 +54,7 @@ const indentationFilter = [
'!**/*.md', '!**/*.md',
'!**/*.ps1', '!**/*.ps1',
'!**/*.template', '!**/*.template',
'!**/*.yaml',
'!**/*.yml', '!**/*.yml',
'!**/lib/**', '!**/lib/**',
'!extensions/**/*.d.ts', '!extensions/**/*.d.ts',
@@ -92,6 +94,7 @@ const copyrightFilter = [
'!**/*.opts', '!**/*.opts',
'!**/*.disabled', '!**/*.disabled',
'!build/**/*.init', '!build/**/*.init',
'!resources/linux/snap/snapcraft.yaml',
'!resources/win32/bin/code.js', '!resources/win32/bin/code.js',
'!extensions/markdown/media/tomorrow.css', '!extensions/markdown/media/tomorrow.css',
'!extensions/html/server/src/modes/typescript/*' '!extensions/html/server/src/modes/typescript/*'
@@ -141,7 +144,7 @@ function reportFailures(failures) {
} }
gulp.task('eslint', () => { gulp.task('eslint', () => {
return gulp.src(all, { base: '.' }) return vfs.src(all, { base: '.', follow: true, allowEmpty: true })
.pipe(filter(eslintFilter)) .pipe(filter(eslintFilter))
.pipe(gulpeslint('src/.eslintrc')) .pipe(gulpeslint('src/.eslintrc'))
.pipe(gulpeslint.formatEach('compact')) .pipe(gulpeslint.formatEach('compact'))
@@ -151,7 +154,7 @@ gulp.task('eslint', () => {
gulp.task('tslint', () => { gulp.task('tslint', () => {
const options = { summarizeFailureOutput: true }; const options = { summarizeFailureOutput: true };
return gulp.src(all, { base: '.' }) return vfs.src(all, { base: '.', follow: true, allowEmpty: true })
.pipe(filter(tslintFilter)) .pipe(filter(tslintFilter))
.pipe(gulptslint({ rulesDirectory: 'build/lib/tslint' })) .pipe(gulptslint({ rulesDirectory: 'build/lib/tslint' }))
.pipe(gulptslint.report(reportFailures, options)); .pipe(gulptslint.report(reportFailures, options));
@@ -232,7 +235,7 @@ const hygiene = exports.hygiene = (some, options) => {
this.emit('data', file); this.emit('data', file);
}); });
const result = gulp.src(some || all, { base: '.' }) const result = vfs.src(some || all, { base: '.', follow: true, allowEmpty: true })
.pipe(filter(f => !f.stat.isDirectory())) .pipe(filter(f => !f.stat.isDirectory()))
.pipe(filter(eolFilter)) .pipe(filter(eolFilter))
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
@@ -267,7 +270,7 @@ const hygiene = exports.hygiene = (some, options) => {
})); }));
}; };
gulp.task('hygiene', () => hygiene()); gulp.task('hygiene', () => hygiene(''));
// this allows us to run hygiene as a git pre-commit hook // this allows us to run hygiene as a git pre-commit hook
if (require.main === module) { if (require.main === module) {
-1
View File
@@ -17,7 +17,6 @@ gulp.task('clean-client', util.rimraf('dataprotocol-node/client/node_modules'));
gulp.task('clean-jsonrpc', util.rimraf('dataprotocol-node/jsonrpc/node_modules')); gulp.task('clean-jsonrpc', util.rimraf('dataprotocol-node/jsonrpc/node_modules'));
gulp.task('clean-server', util.rimraf('dataprotocol-node/server/node_modules')); gulp.task('clean-server', util.rimraf('dataprotocol-node/server/node_modules'));
gulp.task('clean-types', util.rimraf('dataprotocol-node/types/node_modules')); gulp.task('clean-types', util.rimraf('dataprotocol-node/types/node_modules'));
// {{SQL CARBON EDIT}}
gulp.task('clean-extensions-modules', util.rimraf('extensions-modules/node_modules')); gulp.task('clean-extensions-modules', util.rimraf('extensions-modules/node_modules'));
gulp.task('clean-protocol', ['clean-extensions-modules', 'clean-mssql-extension', 'clean-credentials-extension', 'clean-client', 'clean-jsonrpc', 'clean-server', 'clean-types']); gulp.task('clean-protocol', ['clean-extensions-modules', 'clean-mssql-extension', 'clean-credentials-extension', 'clean-client', 'clean-jsonrpc', 'clean-server', 'clean-types']);
+150 -13
View File
@@ -7,6 +7,8 @@
const gulp = require('gulp'); const gulp = require('gulp');
const fs = require('fs'); const fs = require('fs');
const os = require('os');
const cp = require('child_process');
const path = require('path'); const path = require('path');
const es = require('event-stream'); const es = require('event-stream');
const azure = require('gulp-azure-storage'); const azure = require('gulp-azure-storage');
@@ -47,17 +49,15 @@ const nodeModules = [
'rxjs/Observable', 'rxjs/Observable',
'rxjs/Subject', 'rxjs/Subject',
'rxjs/Observer', 'rxjs/Observer',
'ng2-charts/ng2-charts', 'ng2-charts/ng2-charts']
'rangy/lib/rangy-textrange']
.concat(dependencies) .concat(dependencies)
.concat(baseModules); .concat(baseModules);
// Build // Build
const builtInExtensions = [ const builtInExtensions = [
{ name: 'ms-vscode.node-debug', version: '1.16.10' }, { name: 'ms-vscode.node-debug', version: '1.18.3' },
{ name: 'ms-vscode.node-debug2', version: '1.16.9' } { name: 'ms-vscode.node-debug2', version: '1.18.5' }
]; ];
const excludedExtensions = [ const excludedExtensions = [
@@ -168,7 +168,7 @@ const config = {
role: 'Editor', role: 'Editor',
ostypes: ["TEXT", "utxt", "TUTX", "****"], ostypes: ["TEXT", "utxt", "TUTX", "****"],
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
extensions: ["csv", "json", "showplan", "sql", "xml"], extensions: ["csv", "json", "sqlplan", "sql", "xml"],
iconFile: 'resources/darwin/code_file.icns' iconFile: 'resources/darwin/code_file.icns'
}], }],
darwinBundleURLTypes: [{ darwinBundleURLTypes: [{
@@ -304,9 +304,10 @@ function packageTask(platform, arch, opts) {
const packageJsonStream = gulp.src(['package.json'], { base: '.' }) const packageJsonStream = gulp.src(['package.json'], { base: '.' })
.pipe(json({ name, version })); .pipe(json({ name, version }));
const settingsSearchBuildId = getBuildNumber();
const date = new Date().toISOString(); const date = new Date().toISOString();
const productJsonStream = gulp.src(['product.json'], { base: '.' }) const productJsonStream = gulp.src(['product.json'], { base: '.' })
.pipe(json({ commit, date, checksums })); .pipe(json({ commit, date, checksums, settingsSearchBuildId }));
const license = gulp.src(['LICENSES.chromium.html', 'LICENSE.txt', 'ThirdPartyNotices.txt', 'licenses/**'], { base: '.' }); const license = gulp.src(['LICENSES.chromium.html', 'LICENSE.txt', 'ThirdPartyNotices.txt', 'licenses/**'], { base: '.' });
@@ -315,13 +316,10 @@ function packageTask(platform, arch, opts) {
// TODO the API should be copied to `out` during compile, not here // TODO the API should be copied to `out` during compile, not here
const api = gulp.src('src/vs/vscode.d.ts').pipe(rename('out/vs/vscode.d.ts')); const api = gulp.src('src/vs/vscode.d.ts').pipe(rename('out/vs/vscode.d.ts'));
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
const dataApi = gulp.src('src/vs/data.d.ts').pipe(rename('out/sql/data.d.ts')); const dataApi = gulp.src('src/vs/data.d.ts').pipe(rename('out/sql/data.d.ts'));
const depsSrc = _.flatten(dependencies const depsSrc = _.flatten(dependencies
.map(function (d) { return ['node_modules/' + d + '/**', .map(function (d) { return ['node_modules/' + d + '/**', '!node_modules/' + d + '/**/{test,tests}/**']; }));
'!node_modules/' + d + '/**/{test,tests}/**',
'!node_modules/' + d + '/**/test.*',
'!node_modules/' + d + '/**/*.test.*']; }));
const deps = gulp.src(depsSrc, { base: '.', dot: true }) const deps = gulp.src(depsSrc, { base: '.', dot: true })
.pipe(filter(['**', '!**/package-lock.json'])) .pipe(filter(['**', '!**/package-lock.json']))
@@ -335,6 +333,7 @@ function packageTask(platform, arch, opts) {
.pipe(util.cleanNodeModule('windows-process-tree', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node'])) .pipe(util.cleanNodeModule('windows-process-tree', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('gc-signals', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js'])) .pipe(util.cleanNodeModule('gc-signals', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js']))
.pipe(util.cleanNodeModule('v8-profiler', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js'])) .pipe(util.cleanNodeModule('v8-profiler', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js']))
.pipe(util.cleanNodeModule('keytar', ['binding.gyp', 'build/**', 'src/**', 'script/**', 'node_modules/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('node-pty', ['binding.gyp', 'build/**', 'src/**', 'tools/**'], ['build/Release/**'])) .pipe(util.cleanNodeModule('node-pty', ['binding.gyp', 'build/**', 'src/**', 'tools/**'], ['build/Release/**']))
.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('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']));
@@ -352,7 +351,7 @@ function packageTask(platform, arch, opts) {
); );
if (platform === 'win32') { if (platform === 'win32') {
all = es.merge(all, gulp.src('resources/win32/code_file.ico', { base: '.' })); all = es.merge(all, gulp.src(['resources/win32/code_file.ico', 'resources/win32/code_70x70.png', 'resources/win32/code_150x150.png'], { base: '.' }));
} else if (platform === 'linux') { } else if (platform === 'linux') {
all = es.merge(all, gulp.src('resources/linux/code.png', { base: '.' })); all = es.merge(all, gulp.src('resources/linux/code.png', { base: '.' }));
} else if (platform === 'darwin') { } else if (platform === 'darwin') {
@@ -378,6 +377,9 @@ function packageTask(platform, arch, opts) {
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(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' })
.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('@@NAME@@', product.applicationName)) .pipe(replace('@@NAME@@', product.applicationName))
@@ -482,6 +484,139 @@ gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => {
})); }));
}); });
const allConfigDetailsPath = path.join(os.tmpdir(), 'configuration.json');
gulp.task('upload-vscode-configuration', ['generate-vscode-configuration'], () => {
const branch = process.env.BUILD_SOURCEBRANCH;
if (!branch.endsWith('/master') && !branch.indexOf('/release/') >= 0) {
console.log(`Only runs on master and release branches, not ${branch}`);
return;
}
if (!fs.existsSync(allConfigDetailsPath)) {
console.error(`configuration file at ${allConfigDetailsPath} does not exist`);
return;
}
const settingsSearchBuildId = getBuildNumber();
if (!settingsSearchBuildId) {
console.error('Failed to compute build number');
return;
}
return gulp.src(allConfigDetailsPath)
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
key: process.env.AZURE_STORAGE_ACCESS_KEY,
container: 'configuration',
prefix: `${settingsSearchBuildId}/${commit}/`
}));
});
function getBuildNumber() {
const previous = getPreviousVersion(packageJson.version);
if (!previous) {
return 0;
}
try {
const out = cp.execSync(`git rev-list ${previous}..HEAD --count`);
const count = parseInt(out.toString());
return versionStringToNumber(packageJson.version) * 1e4 + count;
} catch (e) {
console.error('Could not determine build number: ' + e.toString());
return 0;
}
}
/**
* Given 1.17.2, return 1.17.1
* 1.18.0 => 1.17.2.
* 2.0.0 => 1.18.0 (or the highest 1.x)
*/
function getPreviousVersion(versionStr) {
function tagExists(tagName) {
try {
cp.execSync(`git rev-parse ${tagName}`, { stdio: 'ignore' });
return true;
} catch (e) {
return false;
}
}
function getLastTagFromBase(semverArr, componentToTest) {
const baseVersion = semverArr.join('.');
if (!tagExists(baseVersion)) {
console.error('Failed to find tag for base version, ' + baseVersion);
return null;
}
let goodTag;
do {
goodTag = semverArr.join('.');
semverArr[componentToTest]++;
} while (tagExists(semverArr.join('.')));
return goodTag;
}
const semverArr = versionStr.split('.');
if (semverArr[2] > 0) {
semverArr[2]--;
return semverArr.join('.');
} else if (semverArr[1] > 0) {
semverArr[1]--;
return getLastTagFromBase(semverArr, 2);
} else {
semverArr[0]--;
return getLastTagFromBase(semverArr, 1);
}
}
function versionStringToNumber(versionStr) {
const semverRegex = /(\d+)\.(\d+)\.(\d+)/;
const match = versionStr.match(semverRegex);
if (!match) {
return 0;
}
return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10);
}
gulp.task('generate-vscode-configuration', () => {
return new Promise((resolve, reject) => {
const buildDir = process.env['AGENT_BUILDDIRECTORY'];
if (!buildDir) {
return reject(new Error('$AGENT_BUILDDIRECTORY not set'));
}
const userDataDir = path.join(os.tmpdir(), 'tmpuserdata');
const extensionsDir = path.join(os.tmpdir(), 'tmpextdir');
const appPath = path.join(buildDir, 'VSCode-darwin/Visual\\ Studio\\ Code\\ -\\ Insiders.app/Contents/Resources/app/bin/code');
const codeProc = cp.exec(`${appPath} --export-default-configuration='${allConfigDetailsPath}' --wait --user-data-dir='${userDataDir}' --extensions-dir='${extensionsDir}'`);
const timer = setTimeout(() => {
codeProc.kill();
reject(new Error('export-default-configuration process timed out'));
}, 10 * 1000);
codeProc.stdout.on('data', d => console.log(d.toString()));
codeProc.stderr.on('data', d => console.log(d.toString()));
codeProc.on('exit', () => {
clearTimeout(timer);
resolve();
});
codeProc.on('error', err => {
clearTimeout(timer);
reject(err);
});
}).catch(e => {
// Don't fail the build
console.error(e.toString());
});
});
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
// Install service locally before building carbon // Install service locally before building carbon
@@ -506,3 +641,5 @@ gulp.task('install-sqltoolsservice', () => {
var extObj = new mssqlExt.Constants(); var extObj = new mssqlExt.Constants();
return installService(extObj); return installService(extObj);
}); });
+58 -4
View File
@@ -56,6 +56,7 @@ function prepareDebPackage(arch) {
.pipe(replace('@@NAME_LONG@@', product.nameLong)) .pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort)) .pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName)) .pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ICON@@', product.applicationName))
.pipe(rename('usr/share/applications/' + product.applicationName + '.desktop')); .pipe(rename('usr/share/applications/' + product.applicationName + '.desktop'));
const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' }) const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' })
@@ -133,6 +134,7 @@ function prepareRpmPackage(arch) {
.pipe(replace('@@NAME_LONG@@', product.nameLong)) .pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort)) .pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName)) .pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ICON@@', product.applicationName))
.pipe(rename('BUILD/usr/share/applications/' + product.applicationName + '.desktop')); .pipe(rename('BUILD/usr/share/applications/' + product.applicationName + '.desktop'));
const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' }) const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' })
@@ -180,6 +182,50 @@ function buildRpmPackage(arch) {
'cp "' + rpmOut + '/$(ls ' + rpmOut + ')" ' + destination + '/' 'cp "' + rpmOut + '/$(ls ' + rpmOut + ')" ' + destination + '/'
]); ]);
} }
function getSnapBuildPath(arch) {
return `.build/linux/snap/${arch}/${product.applicationName}-${arch}`;
}
function prepareSnapPackage(arch) {
const binaryDir = '../VSCode-linux-' + arch;
const destination = getSnapBuildPath(arch);
return function () {
const desktop = gulp.src('resources/linux/code.desktop', { base: '.' })
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ICON@@', `/usr/share/pixmaps/${product.applicationName}.png`))
.pipe(rename(`usr/share/applications/${product.applicationName}.desktop`));
const icon = gulp.src('resources/linux/code.png', { base: '.' })
.pipe(rename(`usr/share/pixmaps/${product.applicationName}.png`));
const code = gulp.src(binaryDir + '/**/*', { base: binaryDir })
.pipe(rename(function (p) { p.dirname = 'usr/share/' + product.applicationName + '/' + p.dirname; }));
const snapcraft = gulp.src('resources/linux/snap/snapcraft.yaml', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@VERSION@@', packageJson.version))
.pipe(rename('snap/snapcraft.yaml'));
const electronLaunch = gulp.src('resources/linux/snap/electron-launch', { base: '.' })
.pipe(rename('electron-launch'));
const all = es.merge(desktop, icon, code, snapcraft, electronLaunch);
return all.pipe(vfs.dest(destination));
};
}
function buildSnapPackage(arch) {
const snapBuildPath = getSnapBuildPath(arch);
return shell.task([
`chmod +x ${snapBuildPath}/electron-launch`,
`cd ${snapBuildPath} && snapcraft snap`
]);
}
function getFlatpakArch(arch) { function getFlatpakArch(arch) {
return { x64: 'x86_64', ia32: 'i386', arm: 'arm' }[arch]; return { x64: 'x86_64', ia32: 'i386', arm: 'arm' }[arch];
@@ -261,6 +307,12 @@ gulp.task('clean-vscode-linux-arm-deb', util.rimraf('.build/linux/deb/armhf'));
gulp.task('clean-vscode-linux-ia32-rpm', util.rimraf('.build/linux/rpm/i386')); gulp.task('clean-vscode-linux-ia32-rpm', util.rimraf('.build/linux/rpm/i386'));
gulp.task('clean-vscode-linux-x64-rpm', util.rimraf('.build/linux/rpm/x86_64')); gulp.task('clean-vscode-linux-x64-rpm', util.rimraf('.build/linux/rpm/x86_64'));
gulp.task('clean-vscode-linux-arm-rpm', util.rimraf('.build/linux/rpm/armhf')); gulp.task('clean-vscode-linux-arm-rpm', util.rimraf('.build/linux/rpm/armhf'));
gulp.task('clean-vscode-linux-ia32-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('clean-vscode-linux-x64-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('clean-vscode-linux-arm-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('clean-vscode-linux-ia32-flatpak', util.rimraf('.build/linux/flatpak/i386'));
gulp.task('clean-vscode-linux-x64-flatpak', util.rimraf('.build/linux/flatpak/x86_64'));
gulp.task('clean-vscode-linux-arm-flatpak', util.rimraf('.build/linux/flatpak/arm'));
gulp.task('vscode-linux-ia32-prepare-deb', ['clean-vscode-linux-ia32-deb'], prepareDebPackage('ia32')); gulp.task('vscode-linux-ia32-prepare-deb', ['clean-vscode-linux-ia32-deb'], prepareDebPackage('ia32'));
gulp.task('vscode-linux-x64-prepare-deb', ['clean-vscode-linux-x64-deb'], prepareDebPackage('x64')); gulp.task('vscode-linux-x64-prepare-deb', ['clean-vscode-linux-x64-deb'], prepareDebPackage('x64'));
@@ -276,14 +328,16 @@ gulp.task('vscode-linux-ia32-build-rpm', ['vscode-linux-ia32-prepare-rpm'], buil
gulp.task('vscode-linux-x64-build-rpm', ['vscode-linux-x64-prepare-rpm'], buildRpmPackage('x64')); gulp.task('vscode-linux-x64-build-rpm', ['vscode-linux-x64-prepare-rpm'], buildRpmPackage('x64'));
gulp.task('vscode-linux-arm-build-rpm', ['vscode-linux-arm-prepare-rpm'], buildRpmPackage('arm')); gulp.task('vscode-linux-arm-build-rpm', ['vscode-linux-arm-prepare-rpm'], buildRpmPackage('arm'));
gulp.task('clean-vscode-linux-ia32-flatpak', util.rimraf('.build/linux/flatpak/i386')); gulp.task('vscode-linux-ia32-prepare-snap', ['clean-vscode-linux-ia32-snap'], prepareSnapPackage('ia32'));
gulp.task('clean-vscode-linux-x64-flatpak', util.rimraf('.build/linux/flatpak/x86_64')); gulp.task('vscode-linux-x64-prepare-snap', ['clean-vscode-linux-x64-snap'], prepareSnapPackage('x64'));
gulp.task('clean-vscode-linux-arm-flatpak', util.rimraf('.build/linux/flatpak/arm')); gulp.task('vscode-linux-arm-prepare-snap', ['clean-vscode-linux-arm-snap'], prepareSnapPackage('arm'));
gulp.task('vscode-linux-ia32-build-snap', ['vscode-linux-ia32-prepare-snap'], buildSnapPackage('ia32'));
gulp.task('vscode-linux-x64-build-snap', ['vscode-linux-x64-prepare-snap'], buildSnapPackage('x64'));
gulp.task('vscode-linux-arm-build-snap', ['vscode-linux-arm-prepare-snap'], buildSnapPackage('arm'));
gulp.task('vscode-linux-ia32-prepare-flatpak', ['clean-vscode-linux-ia32-flatpak'], prepareFlatpak('ia32')); gulp.task('vscode-linux-ia32-prepare-flatpak', ['clean-vscode-linux-ia32-flatpak'], prepareFlatpak('ia32'));
gulp.task('vscode-linux-x64-prepare-flatpak', ['clean-vscode-linux-x64-flatpak'], prepareFlatpak('x64')); gulp.task('vscode-linux-x64-prepare-flatpak', ['clean-vscode-linux-x64-flatpak'], prepareFlatpak('x64'));
gulp.task('vscode-linux-arm-prepare-flatpak', ['clean-vscode-linux-arm-flatpak'], prepareFlatpak('arm')); gulp.task('vscode-linux-arm-prepare-flatpak', ['clean-vscode-linux-arm-flatpak'], prepareFlatpak('arm'));
gulp.task('vscode-linux-ia32-flatpak', ['vscode-linux-ia32-prepare-flatpak'], buildFlatpak('ia32')); gulp.task('vscode-linux-ia32-flatpak', ['vscode-linux-ia32-prepare-flatpak'], buildFlatpak('ia32'));
gulp.task('vscode-linux-x64-flatpak', ['vscode-linux-x64-prepare-flatpak'], buildFlatpak('x64')); gulp.task('vscode-linux-x64-flatpak', ['vscode-linux-x64-prepare-flatpak'], buildFlatpak('x64'));
gulp.task('vscode-linux-arm-flatpak', ['vscode-linux-arm-prepare-flatpak'], buildFlatpak('arm')); gulp.task('vscode-linux-arm-flatpak', ['vscode-linux-arm-prepare-flatpak'], buildFlatpak('arm'));
+3 -3
View File
@@ -64,7 +64,7 @@ var ModuleJsonFormat;
} }
ModuleJsonFormat.is = is; ModuleJsonFormat.is = is;
})(ModuleJsonFormat || (ModuleJsonFormat = {})); })(ModuleJsonFormat || (ModuleJsonFormat = {}));
var Line = (function () { var Line = /** @class */ (function () {
function Line(indent) { function Line(indent) {
if (indent === void 0) { indent = 0; } if (indent === void 0) { indent = 0; }
this.indent = indent; this.indent = indent;
@@ -83,7 +83,7 @@ var Line = (function () {
return Line; return Line;
}()); }());
exports.Line = Line; exports.Line = Line;
var TextModel = (function () { var TextModel = /** @class */ (function () {
function TextModel(contents) { function TextModel(contents) {
this._lines = contents.split(/\r\n|\r|\n/); this._lines = contents.split(/\r\n|\r|\n/);
} }
@@ -96,7 +96,7 @@ var TextModel = (function () {
}); });
return TextModel; return TextModel;
}()); }());
var XLF = (function () { var XLF = /** @class */ (function () {
function XLF(project) { function XLF(project) {
this.project = project; this.project = project;
this.buffer = []; this.buffer = [];
+8 -4
View File
@@ -130,10 +130,6 @@
"name": "vs/workbench/parts/update", "name": "vs/workbench/parts/update",
"project": "vscode-workbench" "project": "vscode-workbench"
}, },
{
"name": "vs/workbench/parts/views",
"project": "vscode-workbench"
},
{ {
"name": "vs/workbench/parts/watermark", "name": "vs/workbench/parts/watermark",
"project": "vscode-workbench" "project": "vscode-workbench"
@@ -190,6 +186,14 @@
"name": "vs/workbench/services/textMate", "name": "vs/workbench/services/textMate",
"project": "vscode-workbench" "project": "vscode-workbench"
}, },
{
"name": "vs/workbench/services/workspace",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/services/decorations",
"project": "vscode-workbench"
},
{ {
"name": "setup_messages", "name": "setup_messages",
"project": "vscode-workbench" "project": "vscode-workbench"
+3 -3
View File
@@ -94,7 +94,7 @@ function isImportNode(node) {
return { line: position.line - 1, character: position.column }; return { line: position.line - 1, character: position.column };
} }
nls_1.lcFrom = lcFrom; nls_1.lcFrom = lcFrom;
var SingleFileServiceHost = (function () { var SingleFileServiceHost = /** @class */ (function () {
function SingleFileServiceHost(options, filename, contents) { function SingleFileServiceHost(options, filename, contents) {
var _this = this; var _this = this;
this.options = options; this.options = options;
@@ -161,7 +161,7 @@ function isImportNode(node) {
// `localize` named imports // `localize` named imports
var allLocalizeImportDeclarations = importDeclarations var allLocalizeImportDeclarations = importDeclarations
.filter(function (d) { return d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports; }) .filter(function (d) { return d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports; })
.map(function (d) { return d.importClause.namedBindings.elements; }) .map(function (d) { return [].concat(d.importClause.namedBindings.elements); })
.flatten(); .flatten();
// `localize` read-only references // `localize` read-only references
var localizeReferences = allLocalizeImportDeclarations var localizeReferences = allLocalizeImportDeclarations
@@ -200,7 +200,7 @@ function isImportNode(node) {
}; };
} }
nls_1.analyze = analyze; nls_1.analyze = analyze;
var TextModel = (function () { var TextModel = /** @class */ (function () {
function TextModel(contents) { function TextModel(contents) {
var regex = /\r\n|\r|\n/g; var regex = /\r\n|\r|\n/g;
var index = 0; var index = 0;
+1 -1
View File
@@ -227,7 +227,7 @@ module nls {
// `localize` named imports // `localize` named imports
const allLocalizeImportDeclarations = importDeclarations const allLocalizeImportDeclarations = importDeclarations
.filter(d => d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports) .filter(d => d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports)
.map(d => (<ts.NamedImports>d.importClause.namedBindings).elements) .map(d => [].concat((<ts.NamedImports>d.importClause.namedBindings).elements))
.flatten(); .flatten();
// `localize` read-only references // `localize` read-only references
+1 -1
View File
@@ -54,7 +54,7 @@ function log() {
function createReporter() { function createReporter() {
var errors = []; var errors = [];
allErrors.push(errors); allErrors.push(errors);
var ReportFunc = (function () { var ReportFunc = /** @class */ (function () {
function ReportFunc(err) { function ReportFunc(err) {
errors.push(err); errors.push(err);
} }
-59
View File
@@ -1,59 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var allowed = this.getOptions().ruleArguments[0];
return this.applyWithWalker(new AsyncRuleWalker(sourceFile, this.getOptions(), allowed));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var AsyncRuleWalker = (function (_super) {
__extends(AsyncRuleWalker, _super);
function AsyncRuleWalker(file, opts, allowed) {
var _this = _super.call(this, file, opts) || this;
_this.allowed = allowed;
return _this;
}
AsyncRuleWalker.prototype.visitMethodDeclaration = function (node) {
this.visitFunctionLikeDeclaration(node);
};
AsyncRuleWalker.prototype.visitFunctionDeclaration = function (node) {
this.visitFunctionLikeDeclaration(node);
};
AsyncRuleWalker.prototype.visitFunctionLikeDeclaration = function (node) {
var _this = this;
var flags = ts.getCombinedModifierFlags(node);
if (!(flags & ts.ModifierFlags.Async)) {
return;
}
var path = node.getSourceFile().path;
var pathParts = path.split(/\\|\//);
if (pathParts.some(function (part) { return _this.allowed.some(function (allowed) { return part === allowed; }); })) {
return;
}
var message = "You are not allowed to use async function in this layer. Allowed layers are: [" + this.allowed + "]";
this.addFailureAtNode(node, message);
};
return AsyncRuleWalker;
}(Lint.RuleWalker));
-47
View File
@@ -1,47 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as ts from 'typescript';
import * as Lint from 'tslint';
export class Rule extends Lint.Rules.AbstractRule {
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
const allowed = this.getOptions().ruleArguments[0] as string[];
return this.applyWithWalker(new AsyncRuleWalker(sourceFile, this.getOptions(), allowed));
}
}
class AsyncRuleWalker extends Lint.RuleWalker {
constructor(file: ts.SourceFile, opts: Lint.IOptions, private allowed: string[]) {
super(file, opts);
}
protected visitMethodDeclaration(node: ts.MethodDeclaration): void {
this.visitFunctionLikeDeclaration(node);
}
protected visitFunctionDeclaration(node: ts.FunctionDeclaration): void {
this.visitFunctionLikeDeclaration(node);
}
private visitFunctionLikeDeclaration(node: ts.FunctionLikeDeclaration) {
const flags = ts.getCombinedModifierFlags(node);
if (!(flags & ts.ModifierFlags.Async)) {
return;
}
const path = (node.getSourceFile() as any).path;
const pathParts = path.split(/\\|\//);
if (pathParts.some(part => this.allowed.some(allowed => part === allowed))) {
return;
}
const message = `You are not allowed to use async function in this layer. Allowed layers are: [${this.allowed}]`;
this.addFailureAtNode(node, message);
}
}
+2 -2
View File
@@ -16,7 +16,7 @@ var __extends = (this && this.__extends) || (function () {
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
var path_1 = require("path"); var path_1 = require("path");
var Lint = require("tslint"); var Lint = require("tslint");
var Rule = (function (_super) { var Rule = /** @class */ (function (_super) {
__extends(Rule, _super); __extends(Rule, _super);
function Rule() { function Rule() {
return _super !== null && _super.apply(this, arguments) || this; return _super !== null && _super.apply(this, arguments) || this;
@@ -27,7 +27,7 @@ var Rule = (function (_super) {
return Rule; return Rule;
}(Lint.Rules.AbstractRule)); }(Lint.Rules.AbstractRule));
exports.Rule = Rule; exports.Rule = Rule;
var ImportPatterns = (function (_super) { var ImportPatterns = /** @class */ (function (_super) {
__extends(ImportPatterns, _super); __extends(ImportPatterns, _super);
function ImportPatterns(file, opts) { function ImportPatterns(file, opts) {
var _this = _super.call(this, file, opts) || this; var _this = _super.call(this, file, opts) || this;
+2 -2
View File
@@ -18,7 +18,7 @@ var ts = require("typescript");
var Lint = require("tslint"); var Lint = require("tslint");
var minimatch = require("minimatch"); var minimatch = require("minimatch");
var path_1 = require("path"); var path_1 = require("path");
var Rule = (function (_super) { var Rule = /** @class */ (function (_super) {
__extends(Rule, _super); __extends(Rule, _super);
function Rule() { function Rule() {
return _super !== null && _super.apply(this, arguments) || this; return _super !== null && _super.apply(this, arguments) || this;
@@ -36,7 +36,7 @@ var Rule = (function (_super) {
return Rule; return Rule;
}(Lint.Rules.AbstractRule)); }(Lint.Rules.AbstractRule));
exports.Rule = Rule; exports.Rule = Rule;
var ImportPatterns = (function (_super) { var ImportPatterns = /** @class */ (function (_super) {
__extends(ImportPatterns, _super); __extends(ImportPatterns, _super);
function ImportPatterns(file, opts, _config) { function ImportPatterns(file, opts, _config) {
var _this = _super.call(this, file, opts) || this; var _this = _super.call(this, file, opts) || this;
+2 -2
View File
@@ -17,7 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript"); var ts = require("typescript");
var Lint = require("tslint"); var Lint = require("tslint");
var path_1 = require("path"); var path_1 = require("path");
var Rule = (function (_super) { var Rule = /** @class */ (function (_super) {
__extends(Rule, _super); __extends(Rule, _super);
function Rule() { function Rule() {
return _super !== null && _super.apply(this, arguments) || this; return _super !== null && _super.apply(this, arguments) || this;
@@ -48,7 +48,7 @@ var Rule = (function (_super) {
return Rule; return Rule;
}(Lint.Rules.AbstractRule)); }(Lint.Rules.AbstractRule));
exports.Rule = Rule; exports.Rule = Rule;
var LayeringRule = (function (_super) { var LayeringRule = /** @class */ (function (_super) {
__extends(LayeringRule, _super); __extends(LayeringRule, _super);
function LayeringRule(file, config, opts) { function LayeringRule(file, config, opts) {
var _this = _super.call(this, file, opts) || this; var _this = _super.call(this, file, opts) || this;
@@ -19,7 +19,7 @@ var Lint = require("tslint");
/** /**
* Implementation of the no-unexternalized-strings rule. * Implementation of the no-unexternalized-strings rule.
*/ */
var Rule = (function (_super) { var Rule = /** @class */ (function (_super) {
__extends(Rule, _super); __extends(Rule, _super);
function Rule() { function Rule() {
return _super !== null && _super.apply(this, arguments) || this; return _super !== null && _super.apply(this, arguments) || this;
@@ -39,7 +39,7 @@ function isObjectLiteral(node) {
function isPropertyAssignment(node) { function isPropertyAssignment(node) {
return node && node.kind === ts.SyntaxKind.PropertyAssignment; return node && node.kind === ts.SyntaxKind.PropertyAssignment;
} }
var NoUnexternalizedStringsRuleWalker = (function (_super) { var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
__extends(NoUnexternalizedStringsRuleWalker, _super); __extends(NoUnexternalizedStringsRuleWalker, _super);
function NoUnexternalizedStringsRuleWalker(file, opts) { function NoUnexternalizedStringsRuleWalker(file, opts) {
var _this = _super.call(this, file, opts) || this; var _this = _super.call(this, file, opts) || this;
+2 -2
View File
@@ -16,7 +16,7 @@ var __extends = (this && this.__extends) || (function () {
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
var Lint = require("tslint"); var Lint = require("tslint");
var fs = require("fs"); var fs = require("fs");
var Rule = (function (_super) { var Rule = /** @class */ (function (_super) {
__extends(Rule, _super); __extends(Rule, _super);
function Rule() { function Rule() {
return _super !== null && _super.apply(this, arguments) || this; return _super !== null && _super.apply(this, arguments) || this;
@@ -27,7 +27,7 @@ var Rule = (function (_super) {
return Rule; return Rule;
}(Lint.Rules.AbstractRule)); }(Lint.Rules.AbstractRule));
exports.Rule = Rule; exports.Rule = Rule;
var TranslationRemindRuleWalker = (function (_super) { var TranslationRemindRuleWalker = /** @class */ (function (_super) {
__extends(TranslationRemindRuleWalker, _super); __extends(TranslationRemindRuleWalker, _super);
function TranslationRemindRuleWalker(file, opts) { function TranslationRemindRuleWalker(file, opts) {
return _super.call(this, file, opts) || this; return _super.call(this, file, opts) || this;
+1 -1
View File
@@ -67,7 +67,7 @@ function fixWin32DirectoryPermissions() {
exports.fixWin32DirectoryPermissions = fixWin32DirectoryPermissions; exports.fixWin32DirectoryPermissions = fixWin32DirectoryPermissions;
function setExecutableBit(pattern) { function setExecutableBit(pattern) {
var setBit = es.mapSync(function (f) { var setBit = es.mapSync(function (f) {
f.stat.mode = 33261; f.stat.mode = /* 100755 */ 33261;
return f; return f;
}); });
if (!pattern) { if (!pattern) {
+9 -8
View File
@@ -19,14 +19,15 @@ function handleDeletions() {
let watch = void 0; let watch = void 0;
if (!process.env['VSCODE_USE_LEGACY_WATCH']) { // Disabled due to https://github.com/Microsoft/vscode/issues/36214
try { // if (!process.env['VSCODE_USE_LEGACY_WATCH']) {
watch = require('./watch-nsfw'); // try {
} catch (err) { // watch = require('./watch-nsfw');
console.warn('Could not load our cross platform file watcher: ' + err.toString()); // } catch (err) {
console.warn('Falling back to our platform specific watcher...'); // console.warn('Could not load our cross platform file watcher: ' + err.toString());
} // console.warn('Falling back to our platform specific watcher...');
} // }
// }
if (!watch) { if (!watch) {
watch = process.platform === 'win32' ? require('./watch-win32') : require('gulp-watch'); watch = process.platform === 'win32' ? require('./watch-win32') : require('gulp-watch');
+1 -1
View File
@@ -11,4 +11,4 @@ a good page describing the code editor's features is [here](https://code.visuals
This npm module contains the core editor functionality, as it comes from the [vscode repository](https://github.com/Microsoft/vscode). This npm module contains the core editor functionality, as it comes from the [vscode repository](https://github.com/Microsoft/vscode).
## License ## License
[Source EULA](https://github.com/Microsoft/sqlopsstudio/blob/master/LICENSE.txt) [MIT](https://github.com/Microsoft/vscode/blob/master/LICENSE.txt)
+3 -3
View File
@@ -16,7 +16,7 @@ Copyright (c) Microsoft Corporation
All rights reserved. All rights reserved.
Source EULA MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
@@ -32,7 +32,7 @@ END OF winjs NOTICES AND INFORMATION
%% string_scorer version 0.1.20 (https://github.com/joshaven/string_score) %% string_scorer version 0.1.20 (https://github.com/joshaven/string_score)
========================================= =========================================
This software is released under the Source EULA: This software is released under the MIT license:
Copyright (c) Joshaven Potter Copyright (c) Joshaven Potter
@@ -60,7 +60,7 @@ END OF string_scorer NOTICES AND INFORMATION
%% chjj-marked NOTICES AND INFORMATION BEGIN HERE %% chjj-marked NOTICES AND INFORMATION BEGIN HERE
========================================= =========================================
The Source EULA License The MIT License (MIT)
Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/) Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
+1 -1
View File
@@ -34,7 +34,7 @@ declare module monaco {
#include(vs/base/common/winjs.base.d.ts): TValueCallback, ProgressCallback, Promise #include(vs/base/common/winjs.base.d.ts): TValueCallback, ProgressCallback, Promise
#include(vs/base/common/cancellation): CancellationTokenSource, CancellationToken #include(vs/base/common/cancellation): CancellationTokenSource, CancellationToken
#include(vs/base/common/uri): URI #include(vs/base/common/uri): URI, UriComponents
#include(vs/editor/common/standalone/standaloneBase): KeyCode, KeyMod #include(vs/editor/common/standalone/standaloneBase): KeyCode, KeyMod
#include(vs/base/common/htmlContent): IMarkdownString #include(vs/base/common/htmlContent): IMarkdownString
#include(vs/base/browser/keyboardEvent): IKeyboardEvent #include(vs/base/browser/keyboardEvent): IKeyboardEvent
+5 -5
View File
@@ -13,10 +13,10 @@
"url": "https://github.com/Microsoft/vscode/issues" "url": "https://github.com/Microsoft/vscode/issues"
}, },
"devDependencies": { "devDependencies": {
"@types/minimist": "^1.2.0", "@types/minimist": "1.2.0",
"@types/mocha": "^2.2.39", "@types/mocha": "2.2.39",
"@types/semver": "^5.3.30", "@types/semver": "5.3.30",
"@types/sinon": "^1.16.34", "@types/sinon": "1.16.34",
"debounce": "^1.0.0", "debounce": "^1.0.0",
"eslint": "^3.4.0", "eslint": "^3.4.0",
"event-stream": "^3.1.7", "event-stream": "^3.1.7",
@@ -48,7 +48,7 @@
"sinon": "^1.17.2", "sinon": "^1.17.2",
"source-map": "^0.4.4", "source-map": "^0.4.4",
"tslint": "^4.3.1", "tslint": "^4.3.1",
"typescript": "2.4.1", "typescript": "2.5.2",
"typescript-formatter": "4.0.1", "typescript-formatter": "4.0.1",
"underscore": "^1.8.2", "underscore": "^1.8.2",
"vinyl": "^0.4.5", "vinyl": "^0.4.5",
+1
View File
@@ -19,6 +19,7 @@ function npmInstall(location, opts) {
} }
} }
// {{SQL CARBON EDIT}}
const protocol = [ const protocol = [
'jsonrpc', 'jsonrpc',
'types', 'types',
+1 -1
View File
@@ -54,7 +54,7 @@ const extensions = [
'scss', 'scss',
'shaderlab', 'shaderlab',
'shellscript', 'shellscript',
// 'sql', customized, PRs pending 'sql',
'swift', 'swift',
'typescript', 'typescript',
'vb', 'vb',
+5 -3
View File
@@ -22,7 +22,7 @@ function getOptions(urlString) {
headers: { headers: {
'User-Agent': 'NodeJS' 'User-Agent': 'NodeJS'
} }
} };
} }
function download(url, redirectCount) { function download(url, redirectCount) {
@@ -100,7 +100,9 @@ exports.update = function (repoId, repoPath, dest, modifyGrammar) {
result.version = 'https://github.com/' + repoId + '/commit/' + info.commitSha; result.version = 'https://github.com/' + repoId + '/commit/' + info.commitSha;
} }
for (let key in grammar) { for (let key in grammar) {
result[key] = grammar[key]; if (!result.hasOwnProperty(key)) {
result[key] = grammar[key];
}
} }
try { try {
@@ -116,7 +118,7 @@ exports.update = function (repoId, repoPath, dest, modifyGrammar) {
}); });
}, console.error); }, console.error);
} };
if (path.basename(process.argv[1]) === 'update-grammar.js') { if (path.basename(process.argv[1]) === 'update-grammar.js') {
for (var i = 3; i < process.argv.length; i += 2) { for (var i = 3; i < process.argv.length; i += 2) {
+8 -8
View File
@@ -1,14 +1,14 @@
{ {
"name": "code-oss-dev-build", "name": "sqlops-oss-dev-build",
"version": "1.0.0", "version": "1.0.0",
"devDependencies": { "devDependencies": {
"@types/azure": "^0.9.18", "@types/azure": "0.9.19",
"@types/documentdb": "^1.10.1", "@types/documentdb": "1.10.2",
"@types/es6-collections": "^0.5.30", "@types/es6-collections": "0.5.31",
"@types/es6-promise": "0.0.32", "@types/es6-promise": "0.0.33",
"@types/mime": "0.0.29", "@types/mime": "0.0.29",
"@types/node": "^7.0.13", "@types/node": "8.0.33",
"@types/xml2js": "^0.0.33", "@types/xml2js": "0.0.33",
"azure-storage": "^2.1.0", "azure-storage": "^2.1.0",
"decompress": "^4.2.0", "decompress": "^4.2.0",
"documentdb": "^1.11.0", "documentdb": "^1.11.0",
@@ -16,7 +16,7 @@
"fs-extra-promise": "^1.0.1", "fs-extra-promise": "^1.0.1",
"mime": "^1.3.4", "mime": "^1.3.4",
"minimist": "^1.2.0", "minimist": "^1.2.0",
"typescript": "2.4.1", "typescript": "2.5.2",
"vscode": "^1.0.1", "vscode": "^1.0.1",
"xml2js": "^0.4.17" "xml2js": "^0.4.17"
}, },
+14 -14
View File
@@ -52,20 +52,20 @@ function isBuildSigned(quality: string, commit: string): Promise<boolean> {
}); });
} }
async function waitForSignedBuild(quality: string, commit: string): Promise<void> { // async function waitForSignedBuild(quality: string, commit: string): Promise<void> {
let retries = 0; // let retries = 0;
while (retries < 180) { // while (retries < 180) {
if (await isBuildSigned(quality, commit)) { // if (await isBuildSigned(quality, commit)) {
return; // return;
} // }
await new Promise<void>(c => setTimeout(c, 10000)); // await new Promise<void>(c => setTimeout(c, 10000));
retries++; // retries++;
} // }
throw new Error('Timed out waiting for signed build'); // throw new Error('Timed out waiting for signed build');
} // }
async function main(quality: string): Promise<void> { async function main(quality: string): Promise<void> {
const commit = execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim(); const commit = execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
@@ -73,10 +73,10 @@ async function main(quality: string): Promise<void> {
console.log(`Queueing signing request for '${quality}/${commit}'...`); console.log(`Queueing signing request for '${quality}/${commit}'...`);
await queueSigningRequest(quality, commit); await queueSigningRequest(quality, commit);
console.log('Waiting on signed build...'); // console.log('Waiting on signed build...');
await waitForSignedBuild(quality, commit); // await waitForSignedBuild(quality, commit);
console.log('Found signed build!'); // console.log('Found signed build!');
} }
main(process.argv[2]).catch(err => { main(process.argv[2]).catch(err => {
+9 -2
View File
@@ -68,6 +68,7 @@ interface Asset {
mooncakeUrl: string; mooncakeUrl: string;
hash: string; hash: string;
sha256hash: string; sha256hash: string;
size: number;
} }
function createOrUpdate(commit: string, quality: string, platform: string, type: string, release: NewDocument, asset: Asset, isUpdate: boolean): Promise<void> { function createOrUpdate(commit: string, quality: string, platform: string, type: string, release: NewDocument, asset: Asset, isUpdate: boolean): Promise<void> {
@@ -156,7 +157,7 @@ async function publish(commit: string, quality: string, platform: string, type:
console.log('Publishing...'); console.log('Publishing...');
console.log('Quality:', quality); console.log('Quality:', quality);
console.log('Platforn:', platform); console.log('Platform:', platform);
console.log('Type:', type); console.log('Type:', type);
console.log('Name:', name); console.log('Name:', name);
console.log('Version:', version); console.log('Version:', version);
@@ -165,6 +166,11 @@ async function publish(commit: string, quality: string, platform: string, type:
console.log('Is Released:', isReleased); console.log('Is Released:', isReleased);
console.log('File:', file); console.log('File:', file);
const stat = await new Promise<fs.Stats>((c, e) => fs.stat(file, (err, stat) => err ? e(err) : c(stat)));
const size = stat.size;
console.log('Size:', size);
const stream = fs.createReadStream(file); const stream = fs.createReadStream(file);
const [sha1hash, sha256hash] = await Promise.all([hashStream('sha1', stream), hashStream('sha256', stream)]); const [sha1hash, sha256hash] = await Promise.all([hashStream('sha1', stream), hashStream('sha256', stream)]);
@@ -224,7 +230,8 @@ async function publish(commit: string, quality: string, platform: string, type:
url: `${process.env['AZURE_CDN_URL']}/${quality}/${blobName}`, url: `${process.env['AZURE_CDN_URL']}/${quality}/${blobName}`,
mooncakeUrl: `${process.env['MOONCAKE_CDN_URL']}/${quality}/${blobName}`, mooncakeUrl: `${process.env['MOONCAKE_CDN_URL']}/${quality}/${blobName}`,
hash: sha1hash, hash: sha1hash,
sha256hash sha256hash,
size
}; };
const release = { const release = {
+14
View File
@@ -37,5 +37,19 @@ step "Run unit tests" \
step "Run integration tests" \ step "Run integration tests" \
./scripts/test-integration.sh ./scripts/test-integration.sh
# function smoketest {
# ARTIFACTS="$AGENT_BUILDDIRECTORY/smoketest-artifacts"
# rm -rf $ARTIFACTS
# [[ "$VSCODE_QUALITY" == "insider" ]] && VSCODE_APPNAME="Visual Studio Code - Insiders" || VSCODE_APPNAME="Visual Studio Code"
# npm run smoketest -- --build "$AGENT_BUILDDIRECTORY/VSCode-darwin/$VSCODE_APPNAME.app" --log $ARTIFACTS
# }
# step "Run smoke test" \
# smoketest
step "Publish release" \ step "Publish release" \
./build/tfs/darwin/release.sh ./build/tfs/darwin/release.sh
step "Generate and upload configuration.json" \
npm run gulp -- upload-vscode-configuration
+1 -1
View File
@@ -20,7 +20,7 @@ rm -rf $UNSIGNEDZIP
zip -r -X -y $UNSIGNEDZIP *) zip -r -X -y $UNSIGNEDZIP *)
step "Upload unsigned archive" \ step "Upload unsigned archive" \
node build/tfs/common/publish.js --upload-only $VSCODE_QUALITY darwin archive-unsigned VSCode-darwin-$VSCODE_QUALITY-unsigned.zip $VERSION false $UNSIGNEDZIP node build/tfs/common/publish.js $VSCODE_QUALITY darwin archive-unsigned VSCode-darwin-$VSCODE_QUALITY-unsigned.zip $VERSION false $UNSIGNEDZIP
step "Sign build" \ step "Sign build" \
node build/tfs/common/enqueue.js $VSCODE_QUALITY node build/tfs/common/enqueue.js $VSCODE_QUALITY
-28
View File
@@ -1,28 +0,0 @@
#!/bin/sh
. ./build/tfs/common/node.sh
. ./scripts/env.sh
. ./build/tfs/common/common.sh
export VSCODE_MIXIN_PASSWORD="$1"
VSO_PAT="$2"
echo "machine monacotools.visualstudio.com password $VSO_PAT" > ~/.netrc
step "Install dependencies" \
npm install
step "Mix in repository from vscode-distro" \
npm run gulp -- mixin
step "Install distro dependencies" \
node build/tfs/common/installDistro.js
step "Build minified & upload source maps" \
npm run gulp -- vscode-darwin-min
step "Run smoke test" \
pushd test/smoke
npm install
npm test -- --latest "$AGENT_BUILDDIRECTORY/VSCode-darwin/Visual Studio Code - Insiders.app/Contents/MacOS/Electron"
popd
+17
View File
@@ -39,5 +39,22 @@ step "Build minified" \
step "Run unit tests" \ step "Run unit tests" \
./scripts/test.sh --build --reporter dot ./scripts/test.sh --build --reporter dot
# function smoketest {
# id -u testuser &>/dev/null || (useradd -m testuser; chpasswd <<< testuser:testpassword)
# sudo -i -u testuser -- sh -c 'git config --global user.name "VS Code Agent" && git config --global user.email "monacotools@microsoft.com"'
# ARTIFACTS="$AGENT_BUILDDIRECTORY/smoketest-artifacts"
# rm -rf $ARTIFACTS
# mkdir -p $ARTIFACTS
# chown -R testuser $ARTIFACTS
# ps -o pid= -u testuser | xargs sudo kill -9
# DISPLAY=:10 sudo -i -u testuser -- sh -c "cd $BUILD_SOURCESDIRECTORY/test/smoke && ./node_modules/.bin/mocha --build $AGENT_BUILDDIRECTORY/VSCode-linux-$ARCH --log $ARTIFACTS"
# # DISPLAY=:10 sudo -i -u testuser -- sh -c "cd /vso/work/1/s/test/smoke && ./node_modules/.bin/mocha --build /vso/work/1/VSCode-linux-ia32"
# }
# step "Run smoke test" \
# smoketest
step "Publish release" \ step "Publish release" \
./build/tfs/linux/release.sh ./build/tfs/linux/release.sh
+4 -1
View File
@@ -40,6 +40,9 @@ ADD xvfb.init /etc/init.d/xvfb
RUN chmod +x /etc/init.d/xvfb RUN chmod +x /etc/init.d/xvfb
RUN update-rc.d xvfb defaults RUN update-rc.d xvfb defaults
# dbus
RUN ln -sf /bin/dbus-daemon /usr/bin/dbus-daemon
# nvm # nvm
ENV NVM_DIR /usr/local/nvm ENV NVM_DIR /usr/local/nvm
RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
@@ -47,4 +50,4 @@ RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | b
# for libsecret # for libsecret
ENV PKG_CONFIG_PATH /usr/lib/i386-linux-gnu/pkgconfig ENV PKG_CONFIG_PATH /usr/lib/i386-linux-gnu/pkgconfig
CMD (service xvfb start; export DISPLAY=:10; ./start.sh) CMD (service xvfb start; service dbus start; export DISPLAY=:10; ./start.sh)
+6
View File
@@ -9,6 +9,9 @@ step "Build Debian package" \
step "Build RPM package" \ step "Build RPM package" \
npm run gulp -- "vscode-linux-$ARCH-build-rpm" npm run gulp -- "vscode-linux-$ARCH-build-rpm"
# step "Build snap package" \
# npm run gulp -- "vscode-linux-$ARCH-build-snap"
(cd $BUILD_SOURCESDIRECTORY/build/tfs/common && \ (cd $BUILD_SOURCESDIRECTORY/build/tfs/common && \
step "Install build dependencies" \ step "Install build dependencies" \
npm install --unsafe-perm) npm install --unsafe-perm)
@@ -49,6 +52,9 @@ RPM_PATH="$REPO/.build/linux/rpm/$RPM_ARCH/$RPM_FILENAME"
step "Publish RPM package" \ step "Publish RPM package" \
node build/tfs/common/publish.js $VSCODE_QUALITY $PLATFORM_RPM package $RPM_FILENAME $VERSION true $RPM_PATH node build/tfs/common/publish.js $VSCODE_QUALITY $PLATFORM_RPM package $RPM_FILENAME $VERSION true $RPM_PATH
# SNAP_FILENAME="$(ls $REPO/.build/linux/snap/$ARCH/ | grep .snap)"
# SNAP_PATH="$REPO/.build/linux/snap/$ARCH/$SNAP_FILENAME"
if [ -z "$VSCODE_QUALITY" ]; then if [ -z "$VSCODE_QUALITY" ]; then
echo "VSCODE_QUALITY is not set, skipping repo package publish" echo "VSCODE_QUALITY is not set, skipping repo package publish"
else else
-46
View File
@@ -1,46 +0,0 @@
#!/bin/bash
set -e
. ./build/tfs/common/node.sh
. ./scripts/env.sh
. ./build/tfs/common/common.sh
export ARCH="$1"
export VSCODE_MIXIN_PASSWORD="$2"
VSO_PAT="$3"
echo "machine monacotools.visualstudio.com password $VSO_PAT" > ~/.netrc
step "Install dependencies" \
npm install --arch=$ARCH --unsafe-perm
step "Mix in repository from vscode-distro" \
npm run gulp -- mixin
step "Get Electron" \
npm run gulp -- "electron-$ARCH"
step "Install distro dependencies" \
node build/tfs/common/installDistro.js --arch=$ARCH
step "Build minified" \
npm run gulp -- "vscode-linux-$ARCH-min"
function configureEnvironment {
id -u testuser &>/dev/null || (useradd -m testuser; chpasswd <<< testuser:testpassword)
sudo -i -u testuser git config --global user.name "VS Code Agent"
sudo -i -u testuser git config --global user.email "monacotools@microsoft.com"
chown -R testuser $AGENT_BUILDDIRECTORY
}
function runTest {
pushd test/smoke
npm install
sudo -u testuser -H xvfb-run -a -s "-screen 0 1024x768x8" npm test -- --latest "$AGENT_BUILDDIRECTORY/VSCode-linux-ia32/code-insiders"
popd
}
step "Configure environment" configureEnvironment
step "Run smoke test" runTest
+4 -1
View File
@@ -36,8 +36,11 @@ ADD xvfb.init /etc/init.d/xvfb
RUN chmod +x /etc/init.d/xvfb RUN chmod +x /etc/init.d/xvfb
RUN update-rc.d xvfb defaults RUN update-rc.d xvfb defaults
# dbus
RUN ln -sf /bin/dbus-daemon /usr/bin/dbus-daemon
# nvm # nvm
ENV NVM_DIR /usr/local/nvm ENV NVM_DIR /usr/local/nvm
RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
CMD (service xvfb start; export DISPLAY=:10; ./start.sh) CMD (service xvfb start; service dbus start; export DISPLAY=:10; ./start.sh)
+7
View File
@@ -52,4 +52,11 @@ step "Run unit tests" {
# exec { & .\scripts\test-integration.bat } # exec { & .\scripts\test-integration.bat }
# } # }
# step "Run smoke test" {
# $Artifacts = "$env:AGENT_BUILDDIRECTORY\smoketest-artifacts"
# Remove-Item -Recurse -Force -ErrorAction Ignore $Artifacts
# exec { & npm run smoketest -- --build "$env:AGENT_BUILDDIRECTORY\VSCode-win32-$global:arch" --log "$Artifacts" }
# }
done done
+85
View File
@@ -0,0 +1,85 @@
Param(
[string]$arch,
[string]$mixinPassword,
[string]$vsoPAT,
[string]$storageKey,
[string]$mooncakeStorageKey,
[string]$documentDbKey
)
. .\build\tfs\win32\node.ps1
. .\scripts\env.ps1
. .\build\tfs\win32\lib.ps1
# Create a _netrc file to download distro dependencies
# In order to get _netrc to work, we need a HOME variable setup
"machine monacotools.visualstudio.com password ${vsoPAT}" | Out-File "$env:HOME\_netrc" -Encoding ASCII
# Set the right architecture
$env:npm_config_arch="$arch"
step "Install dependencies" {
exec { & npm install }
}
step "Hygiene" {
exec { & npm run gulp -- hygiene }
}
$env:VSCODE_MIXIN_PASSWORD = $mixinPassword
step "Mix in repository from vscode-distro" {
exec { & npm run gulp -- mixin }
}
step "Get Electron" {
exec { & npm run gulp -- "electron-$global:arch" }
}
step "Install distro dependencies" {
exec { & node build\tfs\common\installDistro.js }
}
step "Build minified" {
exec { & npm run gulp -- "vscode-win32-$global:arch-min" }
}
step "Run unit tests" {
exec { & .\scripts\test.bat --build --reporter dot }
}
step "Run smoke test" {
$Artifacts = "$env:AGENT_BUILDDIRECTORY\smoketest-artifacts"
Remove-Item -Recurse -Force -ErrorAction Ignore $Artifacts
exec { & npm run smoketest -- --build "$env:AGENT_BUILDDIRECTORY\VSCode-win32-$global:arch" --log "$Artifacts" }
}
step "Create archive and setup package" {
exec { & npm run gulp -- "vscode-win32-$global:arch-archive" "vscode-win32-$global:arch-setup" }
}
$Repo = "$(pwd)"
$Root = "$Repo\.."
$Exe = "$Repo\.build\win32-$arch\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"
$env:AZURE_STORAGE_ACCESS_KEY_2 = $storageKey
$env:MOONCAKE_STORAGE_ACCESS_KEY = $mooncakeStorageKey
$env:AZURE_DOCUMENTDB_MASTERKEY = $documentDbKey
$assetPlatform = if ($arch -eq "ia32") { "win32" } else { "win32-x64" }
step "Publish UNSIGNED archive" {
exec { & node build/tfs/common/publish.js $Quality "$global:assetPlatform-archive" archive-unsigned "VSCode-win32-$global:arch-$Version-unsigned.zip" $Version false $Zip }
}
step "Publish UNSIGNED setup package" {
exec { & node build/tfs/common/publish.js $Quality "$global:assetPlatform" setup-unsigned "VSCodeSetup-$global:arch-$Version-unsigned.exe" $Version false $Exe }
}
done
-47
View File
@@ -1,47 +0,0 @@
Param(
[string]$arch,
[string]$mixinPassword,
[string]$vsoPAT
)
. .\build\tfs\win32\node.ps1
. .\scripts\env.ps1
. .\build\tfs\win32\lib.ps1
# Create a _netrc file to download distro dependencies
# In order to get _netrc to work, we need a HOME variable setup
$env:HOME = $env:USERPROFILE
"machine monacotools.visualstudio.com password ${vsoPAT}" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII
# Set the right architecture
$env:npm_config_arch = "$arch"
step "Install dependencies" {
exec { & npm install }
}
$env:VSCODE_MIXIN_PASSWORD = $mixinPassword
step "Mix in repository from vscode-distro" {
exec { & npm run gulp -- mixin }
}
step "Get Electron" {
exec { & npm run gulp -- "electron-$global:arch" }
}
step "Install distro dependencies" {
exec { & node build\tfs\common\installDistro.js }
}
step "Build minified" {
exec { & npm run gulp -- "vscode-win32-$global:arch-min" }
}
step "Run smoke test" {
exec { & Push-Location test\smoke }
exec { & npm install }
exec { & npm test -- --latest "$env:AGENT_BUILDDIRECTORY\VSCode-win32-$global:arch\Code - Insiders.exe" }
exec { & Pop-Location }
}
done
+1
View File
@@ -20,6 +20,7 @@ OutputBaseFilename=SqlOpsStudioSetup
Compression=lzma Compression=lzma
SolidCompression=yes SolidCompression=yes
AppMutex={#AppMutex} AppMutex={#AppMutex}
SetupMutex={#AppMutex}setup
WizardImageFile={#RepoDir}\resources\win32\inno-big.bmp WizardImageFile={#RepoDir}\resources\win32\inno-big.bmp
WizardSmallImageFile={#RepoDir}\resources\win32\inno-small.bmp WizardSmallImageFile={#RepoDir}\resources\win32\inno-small.bmp
SetupIconFile={#RepoDir}\resources\win32\code.ico SetupIconFile={#RepoDir}\resources\win32\code.ico
-13
View File
@@ -1,13 +0,0 @@
language: node_js
sudo: false
node_js:
- "0.12"
install:
- cd jsonrpc && npm install && cd ../client && mkdir node_modules && cd node_modules && ln -s ../../jsonrpc vscode-jsonrpc && cd .. && npm install && cd ../server && mkdir node_modules && cd node_modules && ln -s ../../jsonrpc vscode-jsonrpc && cd .. && npm install && cd ..
- cd types && npm install && cd ../client && cd node_modules && ln -s ../../types vscode-languageserver-types && cd .. && npm install && cd ../server && cd node_modules && ln -s ../../types vscode-languageserver-types && cd .. && npm install && cd ..
script:
- cd jsonrpc && npm run compile && cd ../types && npm run compile && cd ../client && npm run compile && cd ../server && npm run compile && cd ..
- cd jsonrpc && npm test && cd ../types && npm test && cd ..
+18
View File
@@ -0,0 +1,18 @@
Copyright (c) Microsoft Corporation
All rights reserved.
Source EULA
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+1 -1
View File
@@ -1,4 +1,4 @@
# Microsoft Data Management Protocol - Node # Microsoft Data Management Protocol - Node
## License ## License
[Source EULA](https://github.com/Microsoft/sqlopsstudio/blob/dev/license.txt) [MIT](https://github.com/Microsoft/carbon/blob/dev/license.txt)
+1 -1
View File
@@ -1,4 +1,4 @@
# Microsoft Data Management Protocol - Node # Microsoft Data Management Protocol - Node
## License ## License
[Source EULA](https://github.com/Microsoft/sqlopsstudio/blob/dev/license.txt) [MIT](https://github.com/Microsoft/carbon/blob/dev/license.txt)
+67 -54
View File
@@ -30,7 +30,8 @@ import {
ExpandNodeInfo, ObjectExplorerCloseSessionInfo, ObjectExplorerSession, ObjectExplorerExpandInfo, ExpandNodeInfo, ObjectExplorerCloseSessionInfo, ObjectExplorerSession, ObjectExplorerExpandInfo,
TaskServicesProvider, ListTasksParams, ListTasksResponse, CancelTaskParams, TaskProgressInfo, TaskInfo, TaskServicesProvider, ListTasksParams, ListTasksResponse, CancelTaskParams, TaskProgressInfo, TaskInfo,
AdminServicesProvider, DisasterRecoveryProvider, RestoreInfo, ExecutionPlanOptions, AdminServicesProvider, DisasterRecoveryProvider, RestoreInfo, ExecutionPlanOptions,
RestoreConfigInfo, SerializationProvider, FileBrowserProvider, FileBrowserOpenedParams, FileBrowserExpandedParams, FileBrowserValidatedParams SerializationProvider, FileBrowserProvider, FileBrowserOpenedParams, FileBrowserExpandedParams, FileBrowserValidatedParams,
RestoreConfigInfo, ProfilerProvider, ProfilerSessionEvents
} from 'data'; } from 'data';
import { import {
@@ -63,7 +64,9 @@ import {
DefaultDatabaseInfoResponse, DefaultDatabaseInfoParams, DefaultDatabaseInfoResponse, DefaultDatabaseInfoParams,
GetDatabaseInfoResponse, GetDatabaseInfoParams, GetDatabaseInfoResponse, GetDatabaseInfoParams,
BackupConfigInfoResponse, FileBrowserOpenParams, FileBrowserCloseResponse, BackupConfigInfoResponse, FileBrowserOpenParams, FileBrowserCloseResponse,
FileBrowserCloseParams, FileBrowserExpandParams, FileBrowserValidateParams FileBrowserCloseParams, FileBrowserExpandParams, FileBrowserValidateParams,
StartProfilingParams, StartProfilingResponse, StopProfilingParams, StopProfilingResponse,
ProfilerEventsAvailableParams
} from 'dataprotocol-languageserver-types'; } from 'dataprotocol-languageserver-types';
@@ -126,7 +129,8 @@ import {
RestoreRequest, RestorePlanRequest, CancelRestorePlanRequest, RestoreConfigInfoRequest, RestoreRequest, RestorePlanRequest, CancelRestorePlanRequest, RestoreConfigInfoRequest,
ListTasksRequest, CancelTaskRequest, TaskStatusChangedNotification, TaskCreatedNotification, ListTasksRequest, CancelTaskRequest, TaskStatusChangedNotification, TaskCreatedNotification,
LanguageFlavorChangedNotification, DidChangeLanguageFlavorParams, FileBrowserOpenRequest, FileBrowserOpenedNotification, LanguageFlavorChangedNotification, DidChangeLanguageFlavorParams, FileBrowserOpenRequest, FileBrowserOpenedNotification,
FileBrowserValidateRequest, FileBrowserValidatedNotification, FileBrowserExpandRequest, FileBrowserExpandedNotification, FileBrowserCloseRequest FileBrowserValidateRequest, FileBrowserValidatedNotification, FileBrowserExpandRequest, FileBrowserExpandedNotification, FileBrowserCloseRequest,
StartProfilingRequest, StopProfilingRequest, ProfilerEventsAvailableNotification
} from './protocol'; } from './protocol';
import * as c2p from './codeConverter'; import * as c2p from './codeConverter';
@@ -835,6 +839,7 @@ export class LanguageClient {
this.state = ClientState.StartFailed; this.state = ClientState.StartFailed;
this._onReadyCallbacks.reject(error); this._onReadyCallbacks.reject(error);
this.error('Starting client failed', error); this.error('Starting client failed', error);
Window.showErrorMessage(`Couldn't start client ${this._name}`);
}); });
return new Disposable(() => { return new Disposable(() => {
if (this.needsStop()) { if (this.needsStop()) {
@@ -2026,53 +2031,10 @@ export class LanguageClient {
let scriptingProvider: ScriptingProvider = { let scriptingProvider: ScriptingProvider = {
scriptAsSelect(connectionUri: string, metadata: ObjectMetadata, paramDetails: ScriptingParamDetails): Thenable<ScriptingResult> {
return self.sendRequest(ScriptingRequest.type,
self._c2p.asScriptingParams(connectionUri, ScriptOperation.Select, metadata, paramDetails), undefined).then(
self._p2c.asScriptingResult,
(error) => {
self.logFailedRequest(ScriptingRequest.type, error);
return Promise.resolve(undefined);
}
);
},
scriptAsCreate(connectionUri: string, metadata: ObjectMetadata, paramDetails: ScriptingParamDetails): Thenable<ScriptingResult> { scriptAsOperation(connectionUri: string, operation: ScriptOperation, metadata: ObjectMetadata, paramDetails: ScriptingParamDetails): Thenable<ScriptingResult> {
return self.sendRequest(ScriptingRequest.type, return self.sendRequest(ScriptingRequest.type,
self._c2p.asScriptingParams(connectionUri, ScriptOperation.Create, metadata, paramDetails), undefined).then( self._c2p.asScriptingParams(connectionUri, operation, metadata, paramDetails), undefined).then(
self._p2c.asScriptingResult,
(error) => {
self.logFailedRequest(ScriptingRequest.type, error);
return Promise.resolve(undefined);
}
);
},
scriptAsInsert(connectionUri: string, metadata: ObjectMetadata, paramDetails: ScriptingParamDetails): Thenable<ScriptingResult> {
return self.sendRequest(ScriptingRequest.type,
self._c2p.asScriptingParams(connectionUri, ScriptOperation.Insert, metadata, paramDetails), undefined).then(
self._p2c.asScriptingResult,
(error) => {
self.logFailedRequest(ScriptingRequest.type, error);
return Promise.resolve(undefined);
}
);
},
scriptAsUpdate(connectionUri: string, metadata: ObjectMetadata, paramDetails: ScriptingParamDetails): Thenable<ScriptingResult> {
return self.sendRequest(ScriptingRequest.type,
self._c2p.asScriptingParams(connectionUri, ScriptOperation.Update, metadata, paramDetails), undefined).then(
self._p2c.asScriptingResult,
(error) => {
self.logFailedRequest(ScriptingRequest.type, error);
return Promise.resolve(undefined);
}
);
},
scriptAsDelete(connectionUri: string, metadata: ObjectMetadata, paramDetails: ScriptingParamDetails): Thenable<ScriptingResult> {
return self.sendRequest(ScriptingRequest.type,
self._c2p.asScriptingParams(connectionUri, ScriptOperation.Delete, metadata, paramDetails), undefined).then(
self._p2c.asScriptingResult, self._p2c.asScriptingResult,
(error) => { (error) => {
self.logFailedRequest(ScriptingRequest.type, error); self.logFailedRequest(ScriptingRequest.type, error);
@@ -2211,12 +2173,61 @@ export class LanguageClient {
} }
}; };
let serializationProvider: SerializationProvider = { let profilerProvider: ProfilerProvider = {
handle: 0, startSession(sessionId: string): Thenable<boolean> {
saveAs(saveFormat: string, savePath: string, results: string, appendToFile: boolean): Thenable<SaveResultRequestResult> { let params: StartProfilingParams = {
throw new Error('NotImplemented'); ownerUri: sessionId,
options: { }
};
return self.sendRequest(StartProfilingRequest.type, params, undefined).then(
(result) => {
return result;
},
(error) => {
self.logFailedRequest(StartProfilingRequest.type, error);
return Promise.reject(error);
}
);
},
stopSession(sessionId: string): Thenable<boolean> {
let params: StopProfilingParams = {
ownerUri: sessionId
};
return self.sendRequest(StopProfilingRequest.type, params, undefined).then(
(result) => {
return result;
},
(error) => {
self.logFailedRequest(StopProfilingRequest.type, error);
return Promise.reject(error);
}
);
},
pauseSession(sessionId: string): Thenable<boolean> {
return undefined;
},
connectSession(sessionId: string): Thenable<boolean> {
return undefined;
},
disconnectSession(sessionId: string): Thenable<boolean> {
return undefined;
},
registerOnSessionEventsAvailable(handler: (response: ProfilerSessionEvents) => any) {
self.onNotification(ProfilerEventsAvailableNotification.type, (params: ProfilerEventsAvailableParams) => {
handler(<ProfilerSessionEvents>{
sessionId: params.ownerUri,
events: params.events
});
});
} }
} };
this._providers.push(dataprotocol.registerProvider({ this._providers.push(dataprotocol.registerProvider({
handle: -1, handle: -1,
@@ -2241,7 +2252,9 @@ export class LanguageClient {
taskServicesProvider: taskServicesProvider, taskServicesProvider: taskServicesProvider,
fileBrowserProvider: fileBrowserProvider fileBrowserProvider: fileBrowserProvider,
profilerProvider: profilerProvider
})); }));
// Hook to the workspace-wide notifications that aren't routed to a specific provider // Hook to the workspace-wide notifications that aren't routed to a specific provider
+17 -1
View File
@@ -34,7 +34,9 @@ import {
TaskInfo, ListTasksParams, ListTasksResponse, CancelTaskParams, TaskProgressInfo, TaskInfo, ListTasksParams, ListTasksResponse, CancelTaskParams, TaskProgressInfo,
DefaultDatabaseInfoParams, DefaultDatabaseInfoResponse, BackupConfigInfoResponse, FileBrowserOpenParams, FileBrowserOpenedParams, DefaultDatabaseInfoParams, DefaultDatabaseInfoResponse, BackupConfigInfoResponse, FileBrowserOpenParams, FileBrowserOpenedParams,
FileBrowserCloseParams, FileBrowserExpandParams, FileBrowserValidateParams, FileBrowserCloseParams, FileBrowserExpandParams, FileBrowserValidateParams,
FileBrowserCloseResponse, FileBrowserExpandedParams, FileBrowserValidatedParams FileBrowserCloseResponse, FileBrowserExpandedParams, FileBrowserValidatedParams,
StartProfilingParams, StartProfilingResponse, StopProfilingParams, StopProfilingResponse,
ProfilerEventsAvailableParams
} from 'dataprotocol-languageserver-types'; } from 'dataprotocol-languageserver-types';
@@ -1583,3 +1585,17 @@ export namespace FileBrowserValidatedNotification {
export namespace FileBrowserCloseRequest { export namespace FileBrowserCloseRequest {
export const type: RequestType<FileBrowserCloseParams, FileBrowserCloseResponse, void> = { get method(): string { return 'filebrowser/close'; } }; export const type: RequestType<FileBrowserCloseParams, FileBrowserCloseResponse, void> = { get method(): string { return 'filebrowser/close'; } };
} }
// ------------------------------- < Profiler Events > ------------------------------------
export namespace StartProfilingRequest {
export const type: RequestType<StartProfilingParams, StartProfilingResponse, void> = { get method(): string { return 'profiler/start'; } };
}
export namespace StopProfilingRequest {
export const type: RequestType<StopProfilingParams, StopProfilingResponse, void> = { get method(): string { return 'profiler/stop'; } };
}
export namespace ProfilerEventsAvailableNotification {
export const type: NotificationType<ProfilerEventsAvailableParams> = { get method(): string { return 'profiler/eventsavailable'; } };
}
@@ -9,7 +9,7 @@ granted, whether by implication, estoppel or otherwise.
1. DefinitelyTyped version 0.0.1 (https://github.com/borisyankov/DefinitelyTyped) 1. DefinitelyTyped version 0.0.1 (https://github.com/borisyankov/DefinitelyTyped)
This project is licensed under the Source EULA license. This project is licensed under the MIT license.
Copyrights are respective of each contributor listed at the beginning of each definition file. Copyrights are respective of each contributor listed at the beginning of each definition file.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
+1 -1
View File
@@ -1,4 +1,4 @@
# Microsoft Data Management Protocol - Node # Microsoft Data Management Protocol - Node
## License ## License
[Source EULA](https://github.com/Microsoft/sqlopsstudio/blob/dev/license.txt) [MIT](https://github.com/Microsoft/carbon/blob/dev/license.txt)
+1 -1
View File
@@ -467,7 +467,7 @@ function createMessageConnection<T extends MessageConnection>(messageReader: Mes
eventHandlers[type.method] = handler; eventHandlers[type.method] = handler;
}, },
sendRequest: <P, R, E>(type: RequestType<P, R, E>, params: P, token?: CancellationToken): any => { sendRequest: <P, R, E>(type: RequestType<P, R, E>, params: P, token?: CancellationToken) => {
throwIfClosedOrDisposed(); throwIfClosedOrDisposed();
let id = sequenceNumber++; let id = sequenceNumber++;
@@ -108,7 +108,7 @@ export class IPCMessageWriter extends AbstractMessageWriter implements MessageWr
public write(msg: Message): void { public write(msg: Message): void {
try { try {
(<any>this.process).send(<any>msg); (this.process.send as Function)(msg);
this.errorCount = 0; this.errorCount = 0;
} catch (error) { } catch (error) {
this.errorCount++; this.errorCount++;
@@ -9,7 +9,7 @@ granted, whether by implication, estoppel or otherwise.
1. DefinitelyTyped version 0.0.1 (https://github.com/borisyankov/DefinitelyTyped) 1. DefinitelyTyped version 0.0.1 (https://github.com/borisyankov/DefinitelyTyped)
This project is licensed under the Source EULA. This project is licensed under the MIT license.
Copyrights are respective of each contributor listed at the beginning of each definition file. Copyrights are respective of each contributor listed at the beginning of each definition file.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
+1 -1
View File
@@ -1,4 +1,4 @@
# Microsoft Data Management Protocol - Node # Microsoft Data Management Protocol - Node
## License ## License
[Source EULA](https://github.com/Microsoft/sqlopsstudio/blob/dev/license.txt) [MIT](https://github.com/Microsoft/carbon/blob/dev/license.txt)
+82 -9
View File
@@ -480,8 +480,8 @@ export interface RestoreDatabaseFileInfo {
} }
export interface FileBrowserOpenParams { export interface FileBrowserOpenParams {
ownerUri: string; ownerUri: string;
expandPath: string; expandPath: string;
fileFilters: string[]; fileFilters: string[];
changeFilter: boolean; changeFilter: boolean;
} }
@@ -507,8 +507,8 @@ export interface FileBrowserOpenedParams {
} }
export interface FileBrowserExpandParams { export interface FileBrowserExpandParams {
ownerUri: string; ownerUri: string;
expandPath: string; expandPath: string;
} }
export interface FileBrowserExpandedParams { export interface FileBrowserExpandedParams {
@@ -520,9 +520,9 @@ export interface FileBrowserExpandedParams {
} }
export interface FileBrowserValidateParams { export interface FileBrowserValidateParams {
ownerUri: string; ownerUri: string;
serviceType: string; serviceType: string;
selectedFiles: string[]; selectedFiles: string[];
} }
export interface FileBrowserValidatedParams { export interface FileBrowserValidatedParams {
@@ -531,7 +531,7 @@ export interface FileBrowserValidatedParams {
} }
export interface FileBrowserCloseParams { export interface FileBrowserCloseParams {
ownerUri: string; ownerUri: string;
} }
export interface FileBrowserCloseResponse { export interface FileBrowserCloseResponse {
@@ -721,7 +721,9 @@ export enum ScriptOperation {
Create = 1, Create = 1,
Insert = 2, Insert = 2,
Update = 3, Update = 3,
Delete = 4 Delete = 4,
Execute = 5,
Alter = 6
} }
export interface ScriptOptions { export interface ScriptOptions {
@@ -1079,6 +1081,77 @@ export class TableMetadata {
} }
/**
* Parameters to start a profiler session
*/
export interface StartProfilingParams {
/**
* Session Owner URI
*/
ownerUri: string;
/**
* Session options
*/
options: {};
}
export interface StartProfilingResponse {
succeeded: string;
errorMessage: string;
}
/**
* Parameters to start a profiler session
*/
export interface StopProfilingParams {
/**
* Session Owner URI
*/
ownerUri: string;
}
export interface StopProfilingResponse {
succeeded: string;
errorMessage: string;
}
/**
* Profiler Event
*/
export interface ProfilerEvent {
/**
* Event class name
*/
name: string;
/**
* Event timestamp
*/
timestamp: string;
/**
* Event values
*/
values: {};
}
/**
* Profiler events available notification parameters
*/
export interface ProfilerEventsAvailableParams
{
/**
* Session owner URI
*/
ownerUri: string;
/**
* New profiler events available
*/
events: ProfilerEvent[];
}
/** /**
* Position in a text document expressed as zero-based line and character offset. * Position in a text document expressed as zero-based line and character offset.
*/ */
+2 -8
View File
@@ -248,7 +248,7 @@ export function parseNumAsTimeString(value: number): string {
} }
// The function is a duplicate of carbon\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() {
var platform = process.platform; var platform = process.platform;
@@ -260,11 +260,5 @@ export function getAppDataPath() {
} }
} }
export function getDefaultLogLocation() { export function getDefaultLogLocation() {
var platform = process.platform; return path.join(getAppDataPath(), 'sqlops');
let rootFolderName: string = '.sqlops';
if (platform === 'win32') {
rootFolderName = 'sqlops';
}
return path.join(getAppDataPath(), rootFolderName);
} }
+7 -1
View File
@@ -18,5 +18,11 @@
["[", "]"], ["[", "]"],
["(", ")"], ["(", ")"],
["\"", "\""] ["\"", "\""]
] ],
"folding": {
"markers": {
"start": "^\\s*(::\\s*|REM\\s+)#region",
"end": "^\\s*(::\\s*|REM\\s+)#endregion"
}
}
} }
+7 -15
View File
@@ -33,19 +33,11 @@
}, },
{ {
"fileMatch": "vscode://defaultsettings/settings.json", "fileMatch": "vscode://defaultsettings/settings.json",
"url": "vscode://schemas/settings" "url": "vscode://schemas/settings/default"
},
{
"fileMatch": "vscode://defaultsettings/resourceSettings.json",
"url": "vscode://schemas/settings/resource"
},
{
"fileMatch": "vscode://settings/workspaceSettings.json",
"url": "vscode://schemas/settings"
}, },
{ {
"fileMatch": "%APP_SETTINGS_HOME%/settings.json", "fileMatch": "%APP_SETTINGS_HOME%/settings.json",
"url": "vscode://schemas/settings" "url": "vscode://schemas/settings/user"
}, },
{ {
"fileMatch": "%APP_WORKSPACES_HOME%/*/workspace.json", "fileMatch": "%APP_WORKSPACES_HOME%/*/workspace.json",
@@ -60,15 +52,15 @@
"url": "vscode://schemas/locale" "url": "vscode://schemas/locale"
}, },
{ {
"fileMatch": "/.sqlops/settings.json", "fileMatch": "/.vscode/settings.json",
"url": "vscode://schemas/settings" "url": "vscode://schemas/settings/folder"
}, },
{ {
"fileMatch": "/.sqlops/launch.json", "fileMatch": "/.vscode/launch.json",
"url": "vscode://schemas/launch" "url": "vscode://schemas/launch"
}, },
{ {
"fileMatch": "/.sqlops/tasks.json", "fileMatch": "/.vscode/tasks.json",
"url": "vscode://schemas/tasks" "url": "vscode://schemas/tasks"
}, },
{ {
@@ -82,6 +74,6 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^7.0.4" "@types/node": "7.0.4"
} }
} }
@@ -27,8 +27,8 @@ export function activate(context): void {
//settings.json suggestions //settings.json suggestions
context.subscriptions.push(registerSettingsCompletions()); context.subscriptions.push(registerSettingsCompletions());
//extensions.json suggestions //extensions suggestions
context.subscriptions.push(registerExtensionsCompletions()); context.subscriptions.push(...registerExtensionsCompletions());
// launch.json decorations // launch.json decorations
context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(editor => updateLaunchJsonDecorations(editor), null, context.subscriptions)); context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(editor => updateLaunchJsonDecorations(editor), null, context.subscriptions));
@@ -67,43 +67,69 @@ function registerSettingsCompletions(): vscode.Disposable {
}); });
} }
function registerExtensionsCompletions(): vscode.Disposable { interface IExtensionsContent {
recommendations: string[];
}
function registerExtensionsCompletions(): vscode.Disposable[] {
return [registerExtensionsCompletionsInExtensionsDocument(), registerExtensionsCompletionsInWorkspaceConfigurationDocument()];
}
function registerExtensionsCompletionsInExtensionsDocument(): vscode.Disposable {
return vscode.languages.registerCompletionItemProvider({ pattern: '**/extensions.json' }, { return vscode.languages.registerCompletionItemProvider({ pattern: '**/extensions.json' }, {
provideCompletionItems(document, position, token) { provideCompletionItems(document, position, token) {
const location = getLocation(document.getText(), document.offsetAt(position)); const location = getLocation(document.getText(), document.offsetAt(position));
const range = document.getWordRangeAtPosition(position) || new vscode.Range(position, position); const range = document.getWordRangeAtPosition(position) || new vscode.Range(position, position);
if (location.path[0] === 'recommendations') { if (location.path[0] === 'recommendations') {
const config = parse(document.getText()); const extensionsContent = <IExtensionsContent>parse(document.getText());
const alreadyEnteredExtensions = config && config.recommendations || []; return provideInstalledExtensionProposals(extensionsContent, range);
if (Array.isArray(alreadyEnteredExtensions)) {
const knownExtensionProposals = vscode.extensions.all.filter(e =>
!(e.id.startsWith('vscode.')
|| e.id === 'Microsoft.vscode-markdown'
|| alreadyEnteredExtensions.indexOf(e.id) > -1));
if (knownExtensionProposals.length) {
return knownExtensionProposals.map(e => {
const item = new vscode.CompletionItem(e.id);
const insertText = `"${e.id}"`;
item.kind = vscode.CompletionItemKind.Value;
item.insertText = insertText;
item.range = range;
item.filterText = insertText;
return item;
});
} else {
const example = new vscode.CompletionItem(localize('exampleExtension', "Example"));
example.insertText = '"vscode.csharp"';
example.kind = vscode.CompletionItemKind.Value;
example.range = range;
return [example];
}
}
} }
return []; return [];
} }
}); });
} }
function registerExtensionsCompletionsInWorkspaceConfigurationDocument(): vscode.Disposable {
return vscode.languages.registerCompletionItemProvider({ pattern: '**/*.code-workspace' }, {
provideCompletionItems(document, position, token) {
const location = getLocation(document.getText(), document.offsetAt(position));
const range = document.getWordRangeAtPosition(position) || new vscode.Range(position, position);
if (location.path[0] === 'extensions' && location.path[1] === 'recommendations') {
const extensionsContent = <IExtensionsContent>parse(document.getText())['extensions'];
return provideInstalledExtensionProposals(extensionsContent, range);
}
return [];
}
});
}
function provideInstalledExtensionProposals(extensionsContent: IExtensionsContent, range: vscode.Range): vscode.ProviderResult<vscode.CompletionItem[] | vscode.CompletionList> {
const alreadyEnteredExtensions = extensionsContent && extensionsContent.recommendations || [];
if (Array.isArray(alreadyEnteredExtensions)) {
const knownExtensionProposals = vscode.extensions.all.filter(e =>
!(e.id.startsWith('vscode.')
|| e.id === 'Microsoft.vscode-markdown'
|| alreadyEnteredExtensions.indexOf(e.id) > -1));
if (knownExtensionProposals.length) {
return knownExtensionProposals.map(e => {
const item = new vscode.CompletionItem(e.id);
const insertText = `"${e.id}"`;
item.kind = vscode.CompletionItemKind.Value;
item.insertText = insertText;
item.range = range;
item.filterText = insertText;
return item;
});
} else {
const example = new vscode.CompletionItem(localize('exampleExtension', "Example"));
example.insertText = '"vscode.csharp"';
example.kind = vscode.CompletionItemKind.Value;
example.range = range;
return [example];
}
}
}
function newSimpleCompletionItem(label: string, range: vscode.Range, description?: string, insertText?: string): vscode.CompletionItem { function newSimpleCompletionItem(label: string, range: vscode.Range, description?: string, insertText?: string): vscode.CompletionItem {
const item = new vscode.CompletionItem(label); const item = new vscode.CompletionItem(label);
item.kind = vscode.CompletionItemKind.Value; item.kind = vscode.CompletionItemKind.Value;
@@ -43,13 +43,13 @@ export class SettingsDocument {
private provideWindowTitleCompletionItems(location: Location, range: vscode.Range): vscode.ProviderResult<vscode.CompletionItem[]> { private provideWindowTitleCompletionItems(location: Location, range: vscode.Range): vscode.ProviderResult<vscode.CompletionItem[]> {
const completions: vscode.CompletionItem[] = []; const completions: vscode.CompletionItem[] = [];
completions.push(this.newSimpleCompletionItem('${activeEditorShort}', range, localize('activeEditorShort', "e.g. myFile.txt"))); completions.push(this.newSimpleCompletionItem('${activeEditorShort}', range, localize('activeEditorShort', "the file name (e.g. myFile.txt)")));
completions.push(this.newSimpleCompletionItem('${activeEditorMedium}', range, localize('activeEditorMedium', "e.g. myFolder/myFile.txt"))); completions.push(this.newSimpleCompletionItem('${activeEditorMedium}', range, localize('activeEditorMedium', "the path of the file relative to the workspace folder (e.g. myFolder/myFile.txt)")));
completions.push(this.newSimpleCompletionItem('${activeEditorLong}', range, localize('activeEditorLong', "e.g. /Users/Development/myProject/myFolder/myFile.txt"))); completions.push(this.newSimpleCompletionItem('${activeEditorLong}', range, localize('activeEditorLong', "the full path of the file (e.g. /Users/Development/myProject/myFolder/myFile.txt)")));
completions.push(this.newSimpleCompletionItem('${rootName}', range, localize('rootName', "e.g. myFolder1, myFolder2, myFolder3"))); completions.push(this.newSimpleCompletionItem('${rootName}', range, localize('rootName', "name of the workspace (e.g. myFolder or myWorkspace)")));
completions.push(this.newSimpleCompletionItem('${rootPath}', range, localize('rootPath', "e.g. /Users/Development/myProject"))); completions.push(this.newSimpleCompletionItem('${rootPath}', range, localize('rootPath', "file path of the workspace (e.g. /Users/Development/myWorkspace)")));
completions.push(this.newSimpleCompletionItem('${folderName}', range, localize('folderName', "e.g. myFolder"))); completions.push(this.newSimpleCompletionItem('${folderName}', range, localize('folderName', "name of the workspace folder the file is contained in (e.g. myFolder)")));
completions.push(this.newSimpleCompletionItem('${folderPath}', range, localize('folderPath', "e.g. /Users/Development/myFolder"))); completions.push(this.newSimpleCompletionItem('${folderPath}', range, localize('folderPath', "file path of the workspace folder the file is contained in (e.g. /Users/Development/myFolder)")));
completions.push(this.newSimpleCompletionItem('${appName}', range, localize('appName', "e.g. VS Code"))); completions.push(this.newSimpleCompletionItem('${appName}', range, localize('appName', "e.g. VS Code")));
completions.push(this.newSimpleCompletionItem('${dirty}', range, localize('dirty', "a dirty indicator if the active editor is dirty"))); completions.push(this.newSimpleCompletionItem('${dirty}', range, localize('dirty', "a dirty indicator if the active editor is dirty")));
completions.push(this.newSimpleCompletionItem('${separator}', range, localize('separator', "a conditional separator (' - ') that only shows when surrounded by variables with values"))); completions.push(this.newSimpleCompletionItem('${separator}', range, localize('separator', "a conditional separator (' - ') that only shows when surrounded by variables with values")));
+2 -1
View File
@@ -5,7 +5,8 @@
"@types/node": { "@types/node": {
"version": "6.0.78", "version": "6.0.78",
"from": "@types/node@>=6.0.46 <7.0.0", "from": "@types/node@>=6.0.46 <7.0.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.78.tgz" "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.78.tgz",
"dev": true
}, },
"argparse": { "argparse": {
"version": "1.0.9", "version": "1.0.9",
+1 -1
View File
@@ -47,6 +47,6 @@
}, },
"devDependencies": { "devDependencies": {
"@types/markdown-it": "0.0.2", "@types/markdown-it": "0.0.2",
"@types/node": "^7.0.4" "@types/node": "7.0.43"
} }
} }
@@ -46,7 +46,7 @@ const _linkProvider = new class implements vscode.DocumentLinkProvider {
const offset = lookUp(match[1]); const offset = lookUp(match[1]);
if (offset === -1) { if (offset === -1) {
console.warn(match[1]); console.warn(`Could not find symbol for link ${match[1]}`);
continue; continue;
} }
@@ -8,8 +8,7 @@ import * as path from 'path';
import { parseTree, findNodeAtLocation, Node as JsonNode } from 'jsonc-parser'; import { parseTree, findNodeAtLocation, Node as JsonNode } from 'jsonc-parser';
import * as nls from 'vscode-nls'; import * as nls from 'vscode-nls';
import * as MarkdownIt from 'markdown-it'; import * as MarkdownItType from 'markdown-it';
import * as parse5 from 'parse5';
import { languages, workspace, Disposable, ExtensionContext, TextDocument, Uri, Diagnostic, Range, DiagnosticSeverity, Position } from 'vscode'; import { languages, workspace, Disposable, ExtensionContext, TextDocument, Uri, Diagnostic, Range, DiagnosticSeverity, Position } from 'vscode';
@@ -33,7 +32,7 @@ enum Context {
} }
interface TokenAndPosition { interface TokenAndPosition {
token: MarkdownIt.Token; token: MarkdownItType.Token;
begin: number; begin: number;
end: number; end: number;
} }
@@ -53,7 +52,7 @@ export class ExtensionLinter {
private packageJsonQ = new Set<TextDocument>(); private packageJsonQ = new Set<TextDocument>();
private readmeQ = new Set<TextDocument>(); private readmeQ = new Set<TextDocument>();
private timer: NodeJS.Timer; private timer: NodeJS.Timer;
private markdownIt = new MarkdownIt(); private markdownIt: MarkdownItType.MarkdownIt;
constructor(private context: ExtensionContext) { constructor(private context: ExtensionContext) {
this.disposables.push( this.disposables.push(
@@ -148,8 +147,11 @@ export class ExtensionLinter {
} }
const text = document.getText(); const text = document.getText();
if (!this.markdownIt) {
this.markdownIt = new (await import('markdown-it'));
}
const tokens = this.markdownIt.parse(text, {}); const tokens = this.markdownIt.parse(text, {});
const tokensAndPositions = (function toTokensAndPositions(this: ExtensionLinter, tokens: MarkdownIt.Token[], begin = 0, end = text.length): TokenAndPosition[] { const tokensAndPositions = (function toTokensAndPositions(this: ExtensionLinter, tokens: MarkdownItType.Token[], begin = 0, end = text.length): TokenAndPosition[] {
const tokensAndPositions = tokens.map<TokenAndPosition>(token => { const tokensAndPositions = tokens.map<TokenAndPosition>(token => {
if (token.map) { if (token.map) {
const tokenBegin = document.offsetAt(new Position(token.map[0], 0)); const tokenBegin = document.offsetAt(new Position(token.map[0], 0));
@@ -192,8 +194,9 @@ export class ExtensionLinter {
}); });
let svgStart: Diagnostic; let svgStart: Diagnostic;
tokensAndPositions.filter(tnp => tnp.token.type === 'text' && tnp.token.content) for (const tnp of tokensAndPositions) {
.map(tnp => { if (tnp.token.type === 'text' && tnp.token.content) {
const parse5 = await import('parse5');
const parser = new parse5.SAXParser({ locationInfo: true }); const parser = new parse5.SAXParser({ locationInfo: true });
parser.on('startTag', (name, attrs, selfClosing, location) => { parser.on('startTag', (name, attrs, selfClosing, location) => {
if (name === 'img') { if (name === 'img') {
@@ -220,13 +223,14 @@ export class ExtensionLinter {
}); });
parser.write(tnp.token.content); parser.write(tnp.token.content);
parser.end(); parser.end();
}); }
}
this.diagnosticsCollection.set(document.uri, diagnostics); this.diagnosticsCollection.set(document.uri, diagnostics);
}; };
} }
private locateToken(text: string, begin: number, end: number, token: MarkdownIt.Token, content: string) { private locateToken(text: string, begin: number, end: number, token: MarkdownItType.Token, content: string) {
if (content) { if (content) {
const tokenBegin = text.indexOf(content, begin); const tokenBegin = text.indexOf(content, begin);
if (tokenBegin !== -1) { if (tokenBegin !== -1) {
+6 -1
View File
@@ -7,13 +7,18 @@
"from": "applicationinsights@0.18.0", "from": "applicationinsights@0.18.0",
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz" "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz"
}, },
"byline": {
"version": "5.0.0",
"from": "byline@latest",
"resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz"
},
"iconv-lite": { "iconv-lite": {
"version": "0.4.15", "version": "0.4.15",
"from": "iconv-lite@0.4.15", "from": "iconv-lite@0.4.15",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz" "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz"
}, },
"vscode-extension-telemetry": { "vscode-extension-telemetry": {
"version": "0.0.7", "version": "0.0.8",
"from": "vscode-extension-telemetry@>=0.0.8 <0.0.9", "from": "vscode-extension-telemetry@>=0.0.8 <0.0.9",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz" "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz"
}, },
+110 -4
View File
@@ -36,6 +36,11 @@
"dark": "resources/icons/dark/git.svg" "dark": "resources/icons/dark/git.svg"
} }
}, },
{
"command": "git.close",
"title": "%command.close%",
"category": "Git"
},
{ {
"command": "git.refresh", "command": "git.refresh",
"title": "%command.refresh%", "title": "%command.refresh%",
@@ -96,6 +101,24 @@
"title": "%command.revertSelectedRanges%", "title": "%command.revertSelectedRanges%",
"category": "Git" "category": "Git"
}, },
{
"command": "git.stageChange",
"title": "%command.stageChange%",
"category": "Git",
"icon": {
"light": "resources/icons/light/stage.svg",
"dark": "resources/icons/dark/stage.svg"
}
},
{
"command": "git.revertChange",
"title": "%command.revertChange%",
"category": "Git",
"icon": {
"light": "resources/icons/light/clean.svg",
"dark": "resources/icons/dark/clean.svg"
}
},
{ {
"command": "git.unstage", "command": "git.unstage",
"title": "%command.unstage%", "title": "%command.unstage%",
@@ -310,10 +333,18 @@
"command": "git.stageSelectedRanges", "command": "git.stageSelectedRanges",
"when": "config.git.enabled && gitOpenRepositoryCount != 0" "when": "config.git.enabled && gitOpenRepositoryCount != 0"
}, },
{
"command": "git.stageChange",
"when": "false"
},
{ {
"command": "git.revertSelectedRanges", "command": "git.revertSelectedRanges",
"when": "config.git.enabled && gitOpenRepositoryCount != 0" "when": "config.git.enabled && gitOpenRepositoryCount != 0"
}, },
{
"command": "git.revertChange",
"when": "false"
},
{ {
"command": "git.unstage", "command": "git.unstage",
"when": "config.git.enabled && gitOpenRepositoryCount != 0" "when": "config.git.enabled && gitOpenRepositoryCount != 0"
@@ -529,6 +560,11 @@
"group": "3_commit", "group": "3_commit",
"when": "config.git.enabled && scmProvider == git" "when": "config.git.enabled && scmProvider == git"
}, },
{
"command": "git.stageAll",
"group": "4_stage",
"when": "config.git.enabled && scmProvider == git"
},
{ {
"command": "git.unstageAll", "command": "git.unstageAll",
"group": "4_stage", "group": "4_stage",
@@ -560,6 +596,13 @@
"when": "config.git.enabled && scmProvider == git" "when": "config.git.enabled && scmProvider == git"
} }
], ],
"scm/sourceControl": [
{
"command": "git.close",
"group": "navigation",
"when": "config.git.enabled && scmProvider == git"
}
],
"scm/resourceGroup/context": [ "scm/resourceGroup/context": [
{ {
"command": "git.stageAll", "command": "git.stageAll",
@@ -688,7 +731,7 @@
{ {
"command": "git.openChange", "command": "git.openChange",
"group": "navigation", "group": "navigation",
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && !isInDiffEditor && resourceScheme != extension" "when": "config.git.enabled && gitOpenRepositoryCount != 0 && !isInDiffEditor && resourceScheme == file"
}, },
{ {
"command": "git.stageSelectedRanges", "command": "git.stageSelectedRanges",
@@ -705,6 +748,16 @@
"group": "2_git@3", "group": "2_git@3",
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff" "when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff"
} }
],
"scm/change/title": [
{
"command": "git.stageChange",
"when": "config.git.enabled && originalResourceScheme == git"
},
{
"command": "git.revertChange",
"when": "config.git.enabled && originalResourceScheme == git"
}
] ]
}, },
"configuration": { "configuration": {
@@ -784,18 +837,71 @@
"type": "boolean", "type": "boolean",
"description": "%config.enableCommitSigning%", "description": "%config.enableCommitSigning%",
"default": false "default": false
},
"git.decorations.enabled": {
"type": "boolean",
"default": true,
"description": "%config.decorations.enabled%"
} }
} }
} },
"colors": [
{
"id": "gitDecoration.modifiedResourceForeground",
"description": "%colors.modified%",
"defaults": {
"light": "#a76e12",
"dark": "#E2C08D",
"highContrast": "#E2C08D"
}
},
{
"id": "gitDecoration.deletedResourceForeground",
"description": "%colors.deleted%",
"defaults": {
"light": "#ad0707",
"dark": "#c74e39",
"highContrast": "#c74e39"
}
},
{
"id": "gitDecoration.untrackedResourceForeground",
"description": "%colors.untracked%",
"defaults": {
"light": "#019001",
"dark": "#73C991",
"highContrast": "#73C991"
}
},
{
"id": "gitDecoration.ignoredResourceForeground",
"description": "%colors.ignored%",
"defaults": {
"light": "#8E8E90",
"dark": "#A7A8A9",
"highContrast": "#A7A8A9"
}
},
{
"id": "gitDecoration.conflictingResourceForeground",
"description": "%colors.conflict%",
"defaults": {
"light": "#6c6cc4",
"dark": "#6c6cc4",
"highContrast": "#6c6cc4"
}
}
]
}, },
"dependencies": { "dependencies": {
"byline": "^5.0.0",
"iconv-lite": "0.4.15", "iconv-lite": "0.4.15",
"vscode-extension-telemetry": "0.0.8", "vscode-extension-telemetry": "0.0.8",
"vscode-nls": "2.0.2" "vscode-nls": "2.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/mocha": "^2.2.41", "@types/mocha": "2.2.43",
"@types/node": "^7.0.4", "@types/node": "7.0.43",
"mocha": "^3.2.0" "mocha": "^3.2.0"
} }
} }
+9 -1
View File
@@ -10,6 +10,8 @@
"command.stageAll": "Stage All Changes", "command.stageAll": "Stage All Changes",
"command.stageSelectedRanges": "Stage Selected Ranges", "command.stageSelectedRanges": "Stage Selected Ranges",
"command.revertSelectedRanges": "Revert Selected Ranges", "command.revertSelectedRanges": "Revert Selected Ranges",
"command.stageChange": "Stage Change",
"command.revertChange": "Revert Change",
"command.unstage": "Unstage Changes", "command.unstage": "Unstage Changes",
"command.unstageAll": "Unstage All Changes", "command.unstageAll": "Unstage All Changes",
"command.unstageSelectedRanges": "Unstage Selected Ranges", "command.unstageSelectedRanges": "Unstage Selected Ranges",
@@ -54,5 +56,11 @@
"config.defaultCloneDirectory": "The default location where to clone a git repository", "config.defaultCloneDirectory": "The default location where to clone a git repository",
"config.enableSmartCommit": "Commit all changes when there are no staged changes.", "config.enableSmartCommit": "Commit all changes when there are no staged changes.",
"config.enableCommitSigning": "Enables commit signing with GPG.", "config.enableCommitSigning": "Enables commit signing with GPG.",
"config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run." "config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run.",
"config.decorations.enabled": "Controls if Git contributes colors and badges to the explorer and the open editors view.",
"colors.modified": "Color for modified resources.",
"colors.deleted": "Color for deleted resources.",
"colors.untracked": "Color for untracked resources.",
"colors.ignored": "Color for ignored resources.",
"colors.conflict": "Color for resources with conflicts."
} }
+36 -14
View File
@@ -5,16 +5,23 @@
'use strict'; 'use strict';
import { workspace, Disposable } from 'vscode'; import { workspace, Disposable, EventEmitter } from 'vscode';
import { GitErrorCodes } from './git'; import { GitErrorCodes } from './git';
import { Repository } from './repository'; import { Repository } from './repository';
import { throttle } from './decorators'; import { eventToPromise, filterEvent } from './util';
export class AutoFetcher { export class AutoFetcher {
private static Period = 3 * 60 * 1000 /* three minutes */; private static Period = 3 * 60 * 1000 /* three minutes */;
private _onDidChange = new EventEmitter<boolean>();
private onDidChange = this._onDidChange.event;
private _enabled: boolean = false;
get enabled(): boolean { return this._enabled; }
set enabled(enabled: boolean) { this._enabled = enabled; this._onDidChange.fire(enabled); }
private disposables: Disposable[] = []; private disposables: Disposable[] = [];
private timer: NodeJS.Timer;
constructor(private repository: Repository) { constructor(private repository: Repository) {
workspace.onDidChangeConfiguration(this.onConfiguration, this, this.disposables); workspace.onDidChangeConfiguration(this.onConfiguration, this, this.disposables);
@@ -32,26 +39,41 @@ export class AutoFetcher {
} }
enable(): void { enable(): void {
if (this.timer) { if (this.enabled) {
return; return;
} }
this.fetch(); this.enabled = true;
this.timer = setInterval(() => this.fetch(), AutoFetcher.Period); this.run();
} }
disable(): void { disable(): void {
clearInterval(this.timer); this.enabled = false;
} }
@throttle private async run(): Promise<void> {
private async fetch(): Promise<void> { while (this.enabled) {
try { await this.repository.whenIdleAndFocused();
await this.repository.fetch();
} catch (err) { if (!this.enabled) {
if (err.gitErrorCode === GitErrorCodes.AuthenticationFailed) { return;
this.disable();
} }
try {
await this.repository.fetch();
} catch (err) {
if (err.gitErrorCode === GitErrorCodes.AuthenticationFailed) {
this.disable();
}
}
if (!this.enabled) {
return;
}
const timeout = new Promise(c => setTimeout(c, AutoFetcher.Period));
const whenDisabled = eventToPromise(filterEvent(this.onDidChange, enabled => !enabled));
await Promise.race([timeout, whenDisabled]);
} }
} }
+183 -69
View File
@@ -5,11 +5,12 @@
'use strict'; 'use strict';
import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation } from 'vscode'; import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor } from 'vscode';
import { Ref, RefType, Git, GitErrorCodes, Branch } from './git'; import { Ref, RefType, Git, GitErrorCodes, Branch } from './git';
import { Repository, Resource, Status, CommitOptions, ResourceGroupType } from './repository'; import { Repository, Resource, Status, CommitOptions, ResourceGroupType } from './repository';
import { Model } from './model'; import { Model } from './model';
import { toGitUri, fromGitUri } from './uri'; import { toGitUri, fromGitUri } from './uri';
import { grep } from './util';
import { applyLineChanges, intersectDiffWithRange, toLineRanges, invertLineChange } from './staging'; import { applyLineChanges, intersectDiffWithRange, toLineRanges, invertLineChange } from './staging';
import * as path from 'path'; import * as path from 'path';
import * as os from 'os'; import * as os from 'os';
@@ -92,11 +93,13 @@ class MergeItem implements QuickPickItem {
class CreateBranchItem implements QuickPickItem { class CreateBranchItem implements QuickPickItem {
constructor(private cc: CommandCenter) { }
get label(): string { return localize('create branch', '$(plus) Create new branch'); } get label(): string { return localize('create branch', '$(plus) Create new branch'); }
get description(): string { return ''; } get description(): string { return ''; }
async run(repository: Repository): Promise<void> { async run(repository: Repository): Promise<void> {
await commands.executeCommand('git.branch'); await this.cc.branch(repository);
} }
} }
@@ -169,12 +172,14 @@ export class CommandCenter {
const opts: TextDocumentShowOptions = { const opts: TextDocumentShowOptions = {
preserveFocus, preserveFocus,
preview, preview,
viewColumn: window.activeTextEditor && window.activeTextEditor.viewColumn || ViewColumn.One viewColumn: ViewColumn.Active
}; };
const activeTextEditor = window.activeTextEditor; const activeTextEditor = window.activeTextEditor;
if (preserveSelection && activeTextEditor && activeTextEditor.document.uri.fsPath === right.fsPath) { // Check if active text editor has same path as other editor. we cannot compare via
// URI.toString() here because the schemas can be different. Instead we just go by path.
if (preserveSelection && activeTextEditor && activeTextEditor.document.uri.path === right.path) {
opts.selection = activeTextEditor.selection; opts.selection = activeTextEditor.selection;
} }
@@ -257,13 +262,20 @@ export class CommandCenter {
} }
@command('git.clone') @command('git.clone')
async clone(): Promise<void> { async clone(url?: string): Promise<void> {
const url = await window.showInputBox({ if (!url) {
prompt: localize('repourl', "Repository URL"), url = await window.showInputBox({
ignoreFocusOut: true prompt: localize('repourl', "Repository URL"),
}); ignoreFocusOut: true
});
}
if (!url) { if (!url) {
/* __GDPR__
"clone" : {
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'no_URL' }); this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'no_URL' });
return; return;
} }
@@ -278,6 +290,11 @@ export class CommandCenter {
}); });
if (!parentPath) { if (!parentPath) {
/* __GDPR__
"clone" : {
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'no_directory' }); this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'no_directory' });
return; return;
} }
@@ -295,14 +312,30 @@ export class CommandCenter {
const result = await window.showInformationMessage(localize('proposeopen', "Would you like to open the cloned repository?"), open); const result = await window.showInformationMessage(localize('proposeopen', "Would you like to open the cloned repository?"), open);
const openFolder = result === open; const openFolder = result === open;
/* __GDPR__
"clone" : {
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"openFolder": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
}
*/
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'success' }, { openFolder: openFolder ? 1 : 0 }); this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'success' }, { openFolder: openFolder ? 1 : 0 });
if (openFolder) { if (openFolder) {
commands.executeCommand('vscode.openFolder', Uri.file(repositoryPath)); commands.executeCommand('vscode.openFolder', Uri.file(repositoryPath));
} }
} catch (err) { } catch (err) {
if (/already exists and is not an empty directory/.test(err && err.stderr || '')) { if (/already exists and is not an empty directory/.test(err && err.stderr || '')) {
/* __GDPR__
"clone" : {
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'directory_not_empty' }); this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'directory_not_empty' });
} else { } else {
/* __GDPR__
"clone" : {
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'error' }); this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'error' });
} }
throw err; throw err;
@@ -311,25 +344,44 @@ export class CommandCenter {
@command('git.init') @command('git.init')
async init(): Promise<void> { async init(): Promise<void> {
const value = workspace.workspaceFolders && workspace.workspaceFolders.length > 0 const homeUri = Uri.file(os.homedir());
? workspace.workspaceFolders[0].uri.fsPath const defaultUri = workspace.workspaceFolders && workspace.workspaceFolders.length > 0
: os.homedir(); ? Uri.file(workspace.workspaceFolders[0].uri.fsPath)
: homeUri;
const path = await window.showInputBox({ const result = await window.showOpenDialog({
placeHolder: localize('path to init', "Folder path"), canSelectFiles: false,
prompt: localize('provide path', "Please provide a folder path to initialize a Git repository"), canSelectFolders: true,
value, canSelectMany: false,
ignoreFocusOut: true defaultUri,
openLabel: localize('init repo', "Initialize Repository")
}); });
if (!path) { if (!result || result.length === 0) {
return; return;
} }
const uri = result[0];
if (homeUri.toString().startsWith(uri.toString())) {
const yes = localize('create repo', "Initialize Repository");
const answer = await window.showWarningMessage(localize('are you sure', "This will create a Git repository in '{0}'. Are you sure you want to continue?", uri.fsPath), yes);
if (answer !== yes) {
return;
}
}
const path = uri.fsPath;
await this.git.init(path); await this.git.init(path);
await this.model.tryOpenRepository(path); await this.model.tryOpenRepository(path);
} }
@command('git.close', { repository: true })
async close(repository: Repository): Promise<void> {
this.model.close(repository);
}
@command('git.openFile') @command('git.openFile')
async openFile(arg?: Resource | Uri, ...resourceStates: SourceControlResourceState[]): Promise<void> { async openFile(arg?: Resource | Uri, ...resourceStates: SourceControlResourceState[]): Promise<void> {
const preserveFocus = arg instanceof Resource; const preserveFocus = arg instanceof Resource;
@@ -364,11 +416,13 @@ export class CommandCenter {
for (const uri of uris) { for (const uri of uris) {
const opts: TextDocumentShowOptions = { const opts: TextDocumentShowOptions = {
preserveFocus, preserveFocus,
preview: preview, preview,
viewColumn: activeTextEditor && activeTextEditor.viewColumn || ViewColumn.One viewColumn: ViewColumn.Active
}; };
if (activeTextEditor && activeTextEditor.document.uri.fsPath === uri.fsPath) { // Check if active text editor has same path as other editor. we cannot compare via
// URI.toString() here because the schemas can be different. Instead we just go by path.
if (activeTextEditor && activeTextEditor.document.uri.path === uri.path) {
opts.selection = activeTextEditor.selection; opts.selection = activeTextEditor.selection;
} }
@@ -451,12 +505,20 @@ export class CommandCenter {
} }
const selection = resourceStates.filter(s => s instanceof Resource) as Resource[]; const selection = resourceStates.filter(s => s instanceof Resource) as Resource[];
const mergeConflicts = selection.filter(s => s.resourceGroupType === ResourceGroupType.Merge); const merge = selection.filter(s => s.resourceGroupType === ResourceGroupType.Merge);
const bothModified = merge.filter(s => s.type === Status.BOTH_MODIFIED);
const promises = bothModified.map(s => grep(s.resourceUri.fsPath, /^<{7}|^={7}|^>{7}/));
const unresolvedBothModified = await Promise.all<boolean>(promises);
const resolvedConflicts = bothModified.filter((s, i) => !unresolvedBothModified[i]);
const unresolvedConflicts = [
...merge.filter(s => s.type !== Status.BOTH_MODIFIED),
...bothModified.filter((s, i) => unresolvedBothModified[i])
];
if (mergeConflicts.length > 0) { if (unresolvedConflicts.length > 0) {
const message = mergeConflicts.length > 1 const message = unresolvedConflicts.length > 1
? localize('confirm stage files with merge conflicts', "Are you sure you want to stage {0} files with merge conflicts?", mergeConflicts.length) ? localize('confirm stage files with merge conflicts', "Are you sure you want to stage {0} files with merge conflicts?", unresolvedConflicts.length)
: localize('confirm stage file with merge conflicts', "Are you sure you want to stage {0} with merge conflicts?", path.basename(mergeConflicts[0].resourceUri.fsPath)); : localize('confirm stage file with merge conflicts', "Are you sure you want to stage {0} with merge conflicts?", path.basename(unresolvedConflicts[0].resourceUri.fsPath));
const yes = localize('yes', "Yes"); const yes = localize('yes', "Yes");
const pick = await window.showWarningMessage(message, { modal: true }, yes); const pick = await window.showWarningMessage(message, { modal: true }, yes);
@@ -466,10 +528,8 @@ export class CommandCenter {
} }
} }
const workingTree = selection const workingTree = selection.filter(s => s.resourceGroupType === ResourceGroupType.WorkingTree);
.filter(s => s.resourceGroupType === ResourceGroupType.WorkingTree); const scmResources = [...workingTree, ...resolvedConflicts, ...unresolvedConflicts];
const scmResources = [...workingTree, ...mergeConflicts];
if (!scmResources.length) { if (!scmResources.length) {
return; return;
@@ -500,14 +560,39 @@ export class CommandCenter {
await repository.add([]); await repository.add([]);
} }
@command('git.stageChange')
async stageChange(uri: Uri, changes: LineChange[], index: number): Promise<void> {
const textEditor = window.visibleTextEditors.filter(e => e.document.uri.toString() === uri.toString())[0];
if (!textEditor) {
return;
}
await this._stageChanges(textEditor, [changes[index]]);
}
@command('git.stageSelectedRanges', { diff: true }) @command('git.stageSelectedRanges', { diff: true })
async stageSelectedRanges(diffs: LineChange[]): Promise<void> { async stageSelectedChanges(changes: LineChange[]): Promise<void> {
const textEditor = window.activeTextEditor; const textEditor = window.activeTextEditor;
if (!textEditor) { if (!textEditor) {
return; return;
} }
const modifiedDocument = textEditor.document;
const selectedLines = toLineRanges(textEditor.selections, modifiedDocument);
const selectedChanges = changes
.map(diff => selectedLines.reduce<LineChange | null>((result, range) => result || intersectDiffWithRange(modifiedDocument, diff, range), null))
.filter(d => !!d) as LineChange[];
if (!selectedChanges.length) {
return;
}
await this._stageChanges(textEditor, selectedChanges);
}
private async _stageChanges(textEditor: TextEditor, changes: LineChange[]): Promise<void> {
const modifiedDocument = textEditor.document; const modifiedDocument = textEditor.document;
const modifiedUri = modifiedDocument.uri; const modifiedUri = modifiedDocument.uri;
@@ -517,28 +602,48 @@ export class CommandCenter {
const originalUri = toGitUri(modifiedUri, '~'); const originalUri = toGitUri(modifiedUri, '~');
const originalDocument = await workspace.openTextDocument(originalUri); const originalDocument = await workspace.openTextDocument(originalUri);
const selectedLines = toLineRanges(textEditor.selections, modifiedDocument); const result = applyLineChanges(originalDocument, modifiedDocument, changes);
const selectedDiffs = diffs
.map(diff => selectedLines.reduce<LineChange | null>((result, range) => result || intersectDiffWithRange(modifiedDocument, diff, range), null))
.filter(d => !!d) as LineChange[];
if (!selectedDiffs.length) {
return;
}
const result = applyLineChanges(originalDocument, modifiedDocument, selectedDiffs);
await this.runByRepository(modifiedUri, async (repository, resource) => await repository.stage(resource, result)); await this.runByRepository(modifiedUri, async (repository, resource) => await repository.stage(resource, result));
} }
@command('git.revertChange')
async revertChange(uri: Uri, changes: LineChange[], index: number): Promise<void> {
const textEditor = window.visibleTextEditors.filter(e => e.document.uri.toString() === uri.toString())[0];
if (!textEditor) {
return;
}
await this._revertChanges(textEditor, [...changes.slice(0, index), ...changes.slice(index + 1)]);
}
@command('git.revertSelectedRanges', { diff: true }) @command('git.revertSelectedRanges', { diff: true })
async revertSelectedRanges(diffs: LineChange[]): Promise<void> { async revertSelectedRanges(changes: LineChange[]): Promise<void> {
const textEditor = window.activeTextEditor; const textEditor = window.activeTextEditor;
if (!textEditor) { if (!textEditor) {
return; return;
} }
const modifiedDocument = textEditor.document;
const selections = textEditor.selections;
const selectedChanges = changes.filter(change => {
const modifiedRange = change.modifiedEndLineNumber === 0
? new Range(modifiedDocument.lineAt(change.modifiedStartLineNumber - 1).range.end, modifiedDocument.lineAt(change.modifiedStartLineNumber).range.start)
: new Range(modifiedDocument.lineAt(change.modifiedStartLineNumber - 1).range.start, modifiedDocument.lineAt(change.modifiedEndLineNumber - 1).range.end);
return selections.every(selection => !selection.intersection(modifiedRange));
});
if (selectedChanges.length === changes.length) {
return;
}
await this._revertChanges(textEditor, selectedChanges);
}
private async _revertChanges(textEditor: TextEditor, changes: LineChange[]): Promise<void> {
const modifiedDocument = textEditor.document; const modifiedDocument = textEditor.document;
const modifiedUri = modifiedDocument.uri; const modifiedUri = modifiedDocument.uri;
@@ -548,19 +653,6 @@ export class CommandCenter {
const originalUri = toGitUri(modifiedUri, '~'); const originalUri = toGitUri(modifiedUri, '~');
const originalDocument = await workspace.openTextDocument(originalUri); const originalDocument = await workspace.openTextDocument(originalUri);
const selections = textEditor.selections;
const selectedDiffs = diffs.filter(diff => {
const modifiedRange = diff.modifiedEndLineNumber === 0
? new Range(modifiedDocument.lineAt(diff.modifiedStartLineNumber - 1).range.end, modifiedDocument.lineAt(diff.modifiedStartLineNumber).range.start)
: new Range(modifiedDocument.lineAt(diff.modifiedStartLineNumber - 1).range.start, modifiedDocument.lineAt(diff.modifiedEndLineNumber - 1).range.end);
return selections.every(selection => !selection.intersection(modifiedRange));
});
if (selectedDiffs.length === diffs.length) {
return;
}
const basename = path.basename(modifiedUri.fsPath); const basename = path.basename(modifiedUri.fsPath);
const message = localize('confirm revert', "Are you sure you want to revert the selected changes in {0}?", basename); const message = localize('confirm revert', "Are you sure you want to revert the selected changes in {0}?", basename);
const yes = localize('revert', "Revert Changes"); const yes = localize('revert', "Revert Changes");
@@ -570,10 +662,11 @@ export class CommandCenter {
return; return;
} }
const result = applyLineChanges(originalDocument, modifiedDocument, selectedDiffs); const result = applyLineChanges(originalDocument, modifiedDocument, changes);
const edit = new WorkspaceEdit(); const edit = new WorkspaceEdit();
edit.replace(modifiedUri, new Range(new Position(0, 0), modifiedDocument.lineAt(modifiedDocument.lineCount - 1).range.end), result); edit.replace(modifiedUri, new Range(new Position(0, 0), modifiedDocument.lineAt(modifiedDocument.lineCount - 1).range.end), result);
workspace.applyEdit(edit); workspace.applyEdit(edit);
await modifiedDocument.save();
} }
@command('git.unstage') @command('git.unstage')
@@ -909,7 +1002,7 @@ export class CommandCenter {
const includeTags = checkoutType === 'all' || checkoutType === 'tags'; const includeTags = checkoutType === 'all' || checkoutType === 'tags';
const includeRemotes = checkoutType === 'all' || checkoutType === 'remote'; const includeRemotes = checkoutType === 'all' || checkoutType === 'remote';
const createBranch = new CreateBranchItem(); const createBranch = new CreateBranchItem(this);
const heads = repository.refs.filter(ref => ref.type === RefType.Head) const heads = repository.refs.filter(ref => ref.type === RefType.Head)
.map(ref => new CheckoutItem(ref)); .map(ref => new CheckoutItem(ref));
@@ -1174,6 +1267,19 @@ export class CommandCenter {
await repository.sync(); await repository.sync();
} }
@command('git._syncAll')
async syncAll(): Promise<void> {
await Promise.all(this.model.repositories.map(async repository => {
const HEAD = repository.HEAD;
if (!HEAD || !HEAD.upstream) {
return;
}
await repository.sync();
}));
}
@command('git.publish', { repository: true }) @command('git.publish', { repository: true })
async publish(repository: Repository): Promise<void> { async publish(repository: Repository): Promise<void> {
const remotes = repository.remotes; const remotes = repository.remotes;
@@ -1184,9 +1290,12 @@ export class CommandCenter {
} }
const branchName = repository.HEAD && repository.HEAD.name || ''; const branchName = repository.HEAD && repository.HEAD.name || '';
const picks = repository.remotes.map(r => r.name); const selectRemote = async () => {
const placeHolder = localize('pick remote', "Pick a remote to publish the branch '{0}' to:", branchName); const picks = repository.remotes.map(r => r.name);
const choice = await window.showQuickPick(picks, { placeHolder }); const placeHolder = localize('pick remote', "Pick a remote to publish the branch '{0}' to:", branchName);
return await window.showQuickPick(picks, { placeHolder });
};
const choice = remotes.length === 1 ? remotes[0].name : await selectRemote();
if (!choice) { if (!choice) {
return; return;
@@ -1200,27 +1309,27 @@ export class CommandCenter {
this.outputChannel.show(); this.outputChannel.show();
} }
@command('git.ignore', { repository: true }) @command('git.ignore')
async ignore(repository: Repository, ...resourceStates: SourceControlResourceState[]): Promise<void> { async ignore(...resourceStates: SourceControlResourceState[]): Promise<void> {
if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) { if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) {
const uri = window.activeTextEditor && window.activeTextEditor.document.uri; const resource = this.getSCMResource();
if (!uri) { if (!resource) {
return; return;
} }
return await repository.ignore([uri]); resourceStates = [resource];
} }
const uris = resourceStates const resources = resourceStates
.filter(s => s instanceof Resource) .filter(s => s instanceof Resource)
.map(r => r.resourceUri); .map(r => r.resourceUri);
if (!uris.length) { if (!resources.length) {
return; return;
} }
await repository.ignore(uris); await this.runByRepository(resources, async (repository, resources) => repository.ignore(resources));
} }
@command('git.stash', { repository: true }) @command('git.stash', { repository: true })
@@ -1302,6 +1411,11 @@ export class CommandCenter {
}); });
} }
/* __GDPR__
"git.command" : {
"command" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryReporter.sendTelemetryEvent('git.command', { command: id }); this.telemetryReporter.sendTelemetryEvent('git.command', { command: id });
return result.catch(async err => { return result.catch(async err => {
@@ -1389,7 +1503,7 @@ export class CommandCenter {
return result; return result;
} }
const tuple = result.filter(p => p[0] === repository)[0]; const tuple = result.filter(p => p.repository === repository)[0];
if (tuple) { if (tuple) {
tuple.resources.push(resource); tuple.resources.push(resource);
+28 -9
View File
@@ -6,9 +6,10 @@
'use strict'; 'use strict';
import { workspace, Uri, Disposable, Event, EventEmitter, window } from 'vscode'; import { workspace, Uri, Disposable, Event, EventEmitter, window } from 'vscode';
import { debounce } from './decorators'; import { debounce, throttle } from './decorators';
import { fromGitUri } from './uri'; import { fromGitUri, toGitUri } from './uri';
import { Model, ModelChangeEvent } from './model'; import { Model, ModelChangeEvent, OriginalResourceChangeEvent } from './model';
import { filterEvent, eventToPromise } from './util';
interface CacheRow { interface CacheRow {
uri: Uri; uri: Uri;
@@ -24,8 +25,8 @@ const FIVE_MINUTES = 1000 * 60 * 5;
export class GitContentProvider { export class GitContentProvider {
private onDidChangeEmitter = new EventEmitter<Uri>(); private _onDidChange = new EventEmitter<Uri>();
get onDidChange(): Event<Uri> { return this.onDidChangeEmitter.event; } get onDidChange(): Event<Uri> { return this._onDidChange.event; }
private changedRepositoryRoots = new Set<string>(); private changedRepositoryRoots = new Set<string>();
private cache: Cache = Object.create(null); private cache: Cache = Object.create(null);
@@ -34,6 +35,7 @@ export class GitContentProvider {
constructor(private model: Model) { constructor(private model: Model) {
this.disposables.push( this.disposables.push(
model.onDidChangeRepository(this.onDidChangeRepository, this), model.onDidChangeRepository(this.onDidChangeRepository, this),
model.onDidChangeOriginalResource(this.onDidChangeOriginalResource, this),
workspace.registerTextDocumentContentProvider('git', this) workspace.registerTextDocumentContentProvider('git', this)
); );
@@ -45,19 +47,33 @@ export class GitContentProvider {
this.eventuallyFireChangeEvents(); this.eventuallyFireChangeEvents();
} }
private onDidChangeOriginalResource({ uri }: OriginalResourceChangeEvent): void {
if (uri.scheme !== 'file') {
return;
}
this._onDidChange.fire(toGitUri(uri, '', true));
}
@debounce(1100) @debounce(1100)
private eventuallyFireChangeEvents(): void { private eventuallyFireChangeEvents(): void {
this.fireChangeEvents(); this.fireChangeEvents();
} }
private fireChangeEvents(): void { @throttle
private async fireChangeEvents(): Promise<void> {
if (!window.state.focused) {
const onDidFocusWindow = filterEvent(window.onDidChangeWindowState, e => e.focused);
await eventToPromise(onDidFocusWindow);
}
Object.keys(this.cache).forEach(key => { Object.keys(this.cache).forEach(key => {
const uri = this.cache[key].uri; const uri = this.cache[key].uri;
const fsPath = uri.fsPath; const fsPath = uri.fsPath;
for (const root of this.changedRepositoryRoots) { for (const root of this.changedRepositoryRoots) {
if (fsPath.startsWith(root)) { if (fsPath.startsWith(root)) {
this.onDidChangeEmitter.fire(uri); this._onDidChange.fire(uri);
return; return;
} }
} }
@@ -75,7 +91,7 @@ export class GitContentProvider {
const cacheKey = uri.toString(); const cacheKey = uri.toString();
const timestamp = new Date().getTime(); const timestamp = new Date().getTime();
const cacheValue = { uri, timestamp }; const cacheValue: CacheRow = { uri, timestamp };
this.cache[cacheKey] = cacheValue; this.cache[cacheKey] = cacheValue;
@@ -101,7 +117,10 @@ export class GitContentProvider {
Object.keys(this.cache).forEach(key => { Object.keys(this.cache).forEach(key => {
const row = this.cache[key]; const row = this.cache[key];
const isOpen = window.visibleTextEditors.some(e => e.document.uri.fsPath === row.uri.fsPath); const { path } = fromGitUri(row.uri);
const isOpen = workspace.textDocuments
.filter(d => d.uri.scheme === 'file')
.some(d => d.uri.fsPath === path);
if (isOpen || now - row.timestamp < THREE_MINUTES) { if (isOpen || now - row.timestamp < THREE_MINUTES) {
cache[row.uri.toString()] = row; cache[row.uri.toString()] = row;
+173
View File
@@ -0,0 +1,173 @@
/*---------------------------------------------------------------------------------------------
* 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 { window, workspace, Uri, Disposable, Event, EventEmitter, DecorationData, DecorationProvider, ThemeColor } from 'vscode';
import { Repository, GitResourceGroup } from './repository';
import { Model } from './model';
import { debounce } from './decorators';
import { filterEvent } from './util';
class GitIgnoreDecorationProvider implements DecorationProvider {
private readonly _onDidChangeDecorations = new EventEmitter<Uri[]>();
readonly onDidChangeDecorations: Event<Uri[]> = this._onDidChangeDecorations.event;
private checkIgnoreQueue = new Map<string, { resolve: (status: boolean) => void, reject: (err: any) => void }>();
private disposables: Disposable[] = [];
constructor(private repository: Repository) {
this.disposables.push(
window.registerDecorationProvider(this),
filterEvent(workspace.onDidSaveTextDocument, e => e.fileName.endsWith('.gitignore'))(_ => this._onDidChangeDecorations.fire())
//todo@joh -> events when the ignore status actually changes, not only when the file changes
);
}
dispose(): void {
this.disposables.forEach(d => d.dispose());
this.checkIgnoreQueue.clear();
}
provideDecoration(uri: Uri): Promise<DecorationData | undefined> {
return new Promise<boolean>((resolve, reject) => {
this.checkIgnoreQueue.set(uri.fsPath, { resolve, reject });
this.checkIgnoreSoon();
}).then(ignored => {
if (ignored) {
return <DecorationData>{
priority: 3,
color: new ThemeColor('gitDecoration.ignoredResourceForeground')
};
}
});
}
@debounce(500)
private checkIgnoreSoon(): void {
const queue = new Map(this.checkIgnoreQueue.entries());
this.checkIgnoreQueue.clear();
this.repository.checkIgnore([...queue.keys()]).then(ignoreSet => {
for (const [key, value] of queue.entries()) {
value.resolve(ignoreSet.has(key));
}
}, err => {
console.error(err);
for (const [, value] of queue.entries()) {
value.reject(err);
}
});
}
}
class GitDecorationProvider implements DecorationProvider {
private readonly _onDidChangeDecorations = new EventEmitter<Uri[]>();
readonly onDidChangeDecorations: Event<Uri[]> = this._onDidChangeDecorations.event;
private disposables: Disposable[] = [];
private decorations = new Map<string, DecorationData>();
constructor(private repository: Repository) {
this.disposables.push(
window.registerDecorationProvider(this),
repository.onDidRunOperation(this.onDidRunOperation, this)
);
}
private onDidRunOperation(): void {
let newDecorations = new Map<string, DecorationData>();
this.collectDecorationData(this.repository.indexGroup, newDecorations);
this.collectDecorationData(this.repository.workingTreeGroup, newDecorations);
this.collectDecorationData(this.repository.mergeGroup, newDecorations);
let uris: Uri[] = [];
newDecorations.forEach((value, uriString) => {
if (this.decorations.has(uriString)) {
this.decorations.delete(uriString);
} else {
uris.push(Uri.parse(uriString));
}
});
this.decorations.forEach((value, uriString) => {
uris.push(Uri.parse(uriString));
});
this.decorations = newDecorations;
this._onDidChangeDecorations.fire(uris);
}
private collectDecorationData(group: GitResourceGroup, bucket: Map<string, DecorationData>): void {
group.resourceStates.forEach(r => {
if (r.resourceDecoration) {
bucket.set(r.original.toString(), r.resourceDecoration);
}
});
}
provideDecoration(uri: Uri): DecorationData | undefined {
return this.decorations.get(uri.toString());
}
dispose(): void {
this.disposables.forEach(d => d.dispose());
}
}
export class GitDecorations {
private configListener: Disposable;
private modelListener: Disposable[] = [];
private providers = new Map<Repository, Disposable>();
constructor(private model: Model) {
this.configListener = workspace.onDidChangeConfiguration(e => e.affectsConfiguration('git.decorations.enabled') && this.update());
this.update();
}
private update(): void {
const enabled = workspace.getConfiguration('git').get('decorations.enabled');
if (enabled) {
this.enable();
} else {
this.disable();
}
}
private enable(): void {
this.modelListener = [];
this.model.onDidOpenRepository(this.onDidOpenRepository, this, this.modelListener);
this.model.onDidCloseRepository(this.onDidCloseRepository, this, this.modelListener);
this.model.repositories.forEach(this.onDidOpenRepository, this);
}
private disable(): void {
this.modelListener.forEach(d => d.dispose());
this.providers.forEach(value => value.dispose());
this.providers.clear();
}
private onDidOpenRepository(repository: Repository): void {
const provider = new GitDecorationProvider(repository);
const ignoreProvider = new GitIgnoreDecorationProvider(repository);
this.providers.set(repository, Disposable.from(provider, ignoreProvider));
}
private onDidCloseRepository(repository: Repository): void {
const provider = this.providers.get(repository);
if (provider) {
provider.dispose();
this.providers.delete(repository);
}
}
dispose(): void {
this.configListener.dispose();
this.modelListener.forEach(d => d.dispose());
this.providers.forEach(value => value.dispose);
this.providers.clear();
}
}
+47 -41
View File
@@ -13,7 +13,6 @@ import { EventEmitter } from 'events';
import iconv = require('iconv-lite'); import iconv = require('iconv-lite');
import { assign, uniqBy, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp } from './util'; import { assign, uniqBy, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp } from './util';
const readdir = denodeify<string[]>(fs.readdir);
const readfile = denodeify<string>(fs.readFile); const readfile = denodeify<string>(fs.readFile);
export interface IGit { export interface IGit {
@@ -66,7 +65,7 @@ function findSpecificGit(path: string): Promise<IGit> {
const buffers: Buffer[] = []; const buffers: Buffer[] = [];
const child = cp.spawn(path, ['--version']); const child = cp.spawn(path, ['--version']);
child.stdout.on('data', (b: Buffer) => buffers.push(b)); child.stdout.on('data', (b: Buffer) => buffers.push(b));
child.on('error', e); child.on('error', cpErrorHandler(e));
child.on('exit', code => code ? e(new Error('Not found')) : c({ path, version: parseVersion(Buffer.concat(buffers).toString('utf8').trim()) })); child.on('exit', code => code ? e(new Error('Not found')) : c({ path, version: parseVersion(Buffer.concat(buffers).toString('utf8').trim()) }));
}); });
} }
@@ -82,12 +81,12 @@ function findGitDarwin(): Promise<IGit> {
function getVersion(path: string) { function getVersion(path: string) {
// make sure git executes // make sure git executes
cp.exec('git --version', (err, stdout: Buffer) => { cp.exec('git --version', (err, stdout) => {
if (err) { if (err) {
return e('git not found'); return e('git not found');
} }
return c({ path, version: parseVersion(stdout.toString('utf8').trim()) }); return c({ path, version: parseVersion(stdout.trim()) });
}); });
} }
@@ -118,48 +117,54 @@ function findSystemGitWin32(base: string): Promise<IGit> {
return findSpecificGit(path.join(base, 'Git', 'cmd', 'git.exe')); return findSpecificGit(path.join(base, 'Git', 'cmd', 'git.exe'));
} }
function findGitHubGitWin32(): Promise<IGit> {
const github = path.join(process.env['LOCALAPPDATA'], 'GitHub');
return readdir(github).then(children => {
const git = children.filter(child => /^PortableGit/.test(child))[0];
if (!git) {
return Promise.reject<IGit>('Not found');
}
return findSpecificGit(path.join(github, git, 'cmd', 'git.exe'));
});
}
function findGitWin32(): Promise<IGit> { function findGitWin32(): Promise<IGit> {
return findSystemGitWin32(process.env['ProgramW6432']) return findSystemGitWin32(process.env['ProgramW6432'])
.then(void 0, () => findSystemGitWin32(process.env['ProgramFiles(x86)'])) .then(void 0, () => findSystemGitWin32(process.env['ProgramFiles(x86)']))
.then(void 0, () => findSystemGitWin32(process.env['ProgramFiles'])) .then(void 0, () => findSystemGitWin32(process.env['ProgramFiles']))
.then(void 0, () => findSpecificGit('git')) .then(void 0, () => findSpecificGit('git'));
.then(void 0, () => findGitHubGitWin32());
} }
export function findGit(hint: string | undefined): Promise<IGit> { export function findGit(hint: string | undefined): Promise<IGit> {
var first = hint ? findSpecificGit(hint) : Promise.reject<IGit>(null); var first = hint ? findSpecificGit(hint) : Promise.reject<IGit>(null);
return first.then(void 0, () => { return first
switch (process.platform) { .then(void 0, () => {
case 'darwin': return findGitDarwin(); switch (process.platform) {
case 'win32': return findGitWin32(); case 'darwin': return findGitDarwin();
default: return findSpecificGit('git'); case 'win32': return findGitWin32();
} default: return findSpecificGit('git');
}); }
})
.then(null, () => Promise.reject(new Error('Git installation not found.')));
} }
export interface IExecutionResult { export interface IExecutionResult {
exitCode: number; exitCode: number;
stdout: string; stdout: string;
stderr: string; stderr: string;
} }
async function exec(child: cp.ChildProcess, options: any = {}): Promise<IExecutionResult> { function cpErrorHandler(cb: (reason?: any) => void): (reason?: any) => void {
return err => {
if (/ENOENT/.test(err.message)) {
err = new GitError({
error: err,
message: 'Failed to execute git (ENOENT)',
gitErrorCode: GitErrorCodes.NotAGitRepository
});
}
cb(err);
};
}
export interface SpawnOptions extends cp.SpawnOptions {
input?: string;
encoding?: string;
log?: boolean;
}
async function exec(child: cp.ChildProcess, options: SpawnOptions = {}): Promise<IExecutionResult> {
if (!child.stdout || !child.stderr) { if (!child.stdout || !child.stderr) {
throw new GitError({ throw new GitError({
message: 'Failed to get stdout or stderr from git process.' message: 'Failed to get stdout or stderr from git process.'
@@ -183,7 +188,7 @@ async function exec(child: cp.ChildProcess, options: any = {}): Promise<IExecuti
const [exitCode, stdout, stderr] = await Promise.all<any>([ const [exitCode, stdout, stderr] = await Promise.all<any>([
new Promise<number>((c, e) => { new Promise<number>((c, e) => {
once(child, 'error', e); once(child, 'error', cpErrorHandler(e));
once(child, 'exit', c); once(child, 'exit', c);
}), }),
new Promise<string>(c => { new Promise<string>(c => {
@@ -246,7 +251,7 @@ export class GitError {
gitCommand: this.gitCommand, gitCommand: this.gitCommand,
stdout: this.stdout, stdout: this.stdout,
stderr: this.stderr stderr: this.stderr
}, [], 2); }, null, 2);
if (this.error) { if (this.error) {
result += (<any>this.error).stack; result += (<any>this.error).stack;
@@ -350,17 +355,17 @@ export class Git {
return path.normalize(result.stdout.trim()); return path.normalize(result.stdout.trim());
} }
async exec(cwd: string, args: string[], options: any = {}): Promise<IExecutionResult> { async exec(cwd: string, args: string[], options: SpawnOptions = {}): Promise<IExecutionResult> {
options = assign({ cwd }, options || {}); options = assign({ cwd }, options || {});
return await this._exec(args, options); return await this._exec(args, options);
} }
stream(cwd: string, args: string[], options: any = {}): cp.ChildProcess { stream(cwd: string, args: string[], options: SpawnOptions = {}): cp.ChildProcess {
options = assign({ cwd }, options || {}); options = assign({ cwd }, options || {});
return this.spawn(args, options); return this.spawn(args, options);
} }
private async _exec(args: string[], options: any = {}): Promise<IExecutionResult> { private async _exec(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult> {
const child = this.spawn(args, options); const child = this.spawn(args, options);
if (options.input) { if (options.input) {
@@ -387,7 +392,7 @@ export class Git {
return result; return result;
} }
spawn(args: string[], options: any = {}): cp.ChildProcess { spawn(args: string[], options: SpawnOptions = {}): cp.ChildProcess {
if (!this.gitPath) { if (!this.gitPath) {
throw new Error('git could not be found in the system.'); throw new Error('git could not be found in the system.');
} }
@@ -505,19 +510,19 @@ export class Repository {
} }
// TODO@Joao: rename to exec // TODO@Joao: rename to exec
async run(args: string[], options: any = {}): Promise<IExecutionResult> { async run(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult> {
return await this.git.exec(this.repositoryRoot, args, options); return await this.git.exec(this.repositoryRoot, args, options);
} }
stream(args: string[], options: any = {}): cp.ChildProcess { stream(args: string[], options: SpawnOptions = {}): cp.ChildProcess {
return this.git.stream(this.repositoryRoot, args, options); return this.git.stream(this.repositoryRoot, args, options);
} }
spawn(args: string[], options: any = {}): cp.ChildProcess { spawn(args: string[], options: SpawnOptions = {}): cp.ChildProcess {
return this.git.spawn(args, options); return this.git.spawn(args, options);
} }
async config(scope: string, key: string, value: any, options: any): Promise<string> { async config(scope: string, key: string, value: any, options: SpawnOptions): Promise<string> {
const args = ['config']; const args = ['config'];
if (scope) { if (scope) {
@@ -883,7 +888,8 @@ export class Repository {
getStatus(limit = 5000): Promise<{ status: IFileStatus[]; didHitLimit: boolean; }> { getStatus(limit = 5000): Promise<{ status: IFileStatus[]; didHitLimit: boolean; }> {
return new Promise<{ status: IFileStatus[]; didHitLimit: boolean; }>((c, e) => { return new Promise<{ status: IFileStatus[]; didHitLimit: boolean; }>((c, e) => {
const parser = new GitStatusParser(); const parser = new GitStatusParser();
const child = this.stream(['status', '-z', '-u']); const env = { GIT_OPTIONAL_LOCKS: '0' };
const child = this.stream(['status', '-z', '-u'], { env });
const onExit = exitCode => { const onExit = exitCode => {
if (exitCode !== 0) { if (exitCode !== 0) {
@@ -919,7 +925,7 @@ export class Repository {
child.stderr.setEncoding('utf8'); child.stderr.setEncoding('utf8');
child.stderr.on('data', raw => stderrData.push(raw as string)); child.stderr.on('data', raw => stderrData.push(raw as string));
child.on('error', e); child.on('error', cpErrorHandler(e));
child.on('exit', onExit); child.on('exit', onExit);
}); });
} }
+3 -1
View File
@@ -12,6 +12,7 @@ import { findGit, Git, IGit } from './git';
import { Model } from './model'; import { Model } from './model';
import { CommandCenter } from './commands'; import { CommandCenter } from './commands';
import { GitContentProvider } from './contentProvider'; import { GitContentProvider } from './contentProvider';
import { GitDecorations } from './decorationProvider';
import { Askpass } from './askpass'; import { Askpass } from './askpass';
import { toDisposable } from './util'; import { toDisposable } from './util';
import TelemetryReporter from 'vscode-extension-telemetry'; import TelemetryReporter from 'vscode-extension-telemetry';
@@ -54,6 +55,7 @@ async function init(context: ExtensionContext, disposables: Disposable[]): Promi
disposables.push( disposables.push(
new CommandCenter(git, model, outputChannel, telemetryReporter), new CommandCenter(git, model, outputChannel, telemetryReporter),
new GitContentProvider(model), new GitContentProvider(model),
new GitDecorations(model)
); );
await checkGitVersion(info); await checkGitVersion(info);
@@ -70,7 +72,7 @@ export function activate(context: ExtensionContext): any {
async function checkGitVersion(info: IGit): Promise<void> { async function checkGitVersion(info: IGit): Promise<void> {
// {{SQL CARBON EDIT}} // {{SQL CARBON EDIT}}
// remove Git version check on since for Carbon // remove Git version check for sqlops
return; return;
+39 -3
View File
@@ -17,8 +17,16 @@ import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle(); const localize = nls.loadMessageBundle();
class RepositoryPick implements QuickPickItem { class RepositoryPick implements QuickPickItem {
@memoize get label(): string { return path.basename(this.repository.root); } @memoize get label(): string {
@memoize get description(): string { return path.dirname(this.repository.root); } return path.basename(this.repository.root);
}
@memoize get description(): string {
return [this.repository.headLabel, this.repository.syncLabel]
.filter(l => !!l)
.join(' ');
}
constructor(public readonly repository: Repository) { } constructor(public readonly repository: Repository) { }
} }
@@ -27,10 +35,19 @@ export interface ModelChangeEvent {
uri: Uri; uri: Uri;
} }
export interface OriginalResourceChangeEvent {
repository: Repository;
uri: Uri;
}
interface OpenRepository extends Disposable { interface OpenRepository extends Disposable {
repository: Repository; repository: Repository;
} }
function isParent(parent: string, child: string): boolean {
return child.startsWith(parent);
}
export class Model { export class Model {
private _onDidOpenRepository = new EventEmitter<Repository>(); private _onDidOpenRepository = new EventEmitter<Repository>();
@@ -42,6 +59,9 @@ export class Model {
private _onDidChangeRepository = new EventEmitter<ModelChangeEvent>(); private _onDidChangeRepository = new EventEmitter<ModelChangeEvent>();
readonly onDidChangeRepository: Event<ModelChangeEvent> = this._onDidChangeRepository.event; readonly onDidChangeRepository: Event<ModelChangeEvent> = this._onDidChangeRepository.event;
private _onDidChangeOriginalResource = new EventEmitter<OriginalResourceChangeEvent>();
readonly onDidChangeOriginalResource: Event<OriginalResourceChangeEvent> = this._onDidChangeOriginalResource.event;
private openRepositories: OpenRepository[] = []; private openRepositories: OpenRepository[] = [];
get repositories(): Repository[] { return this.openRepositories.map(r => r.repository); } get repositories(): Repository[] { return this.openRepositories.map(r => r.repository); }
@@ -147,7 +167,9 @@ export class Model {
const activeRepositories = new Set<Repository>(activeRepositoriesList); const activeRepositories = new Set<Repository>(activeRepositoriesList);
const openRepositoriesToDispose = removed const openRepositoriesToDispose = removed
.map(folder => this.getOpenRepository(folder.uri)) .map(folder => this.getOpenRepository(folder.uri))
.filter(r => !!r && !activeRepositories.has(r.repository)) as OpenRepository[]; .filter(r => !!r)
.filter(r => !activeRepositories.has(r!.repository))
.filter(r => !(workspace.workspaceFolders || []).some(f => isParent(f.uri.fsPath, r!.repository.root))) as OpenRepository[];
possibleRepositoryFolders.forEach(p => this.tryOpenRepository(p.uri.fsPath)); possibleRepositoryFolders.forEach(p => this.tryOpenRepository(p.uri.fsPath));
openRepositoriesToDispose.forEach(r => r.dispose()); openRepositoriesToDispose.forEach(r => r.dispose());
@@ -203,10 +225,14 @@ export class Model {
const onDidDisappearRepository = filterEvent(repository.onDidChangeState, state => state === RepositoryState.Disposed); const onDidDisappearRepository = filterEvent(repository.onDidChangeState, state => state === RepositoryState.Disposed);
const disappearListener = onDidDisappearRepository(() => dispose()); const disappearListener = onDidDisappearRepository(() => dispose());
const changeListener = repository.onDidChangeRepository(uri => this._onDidChangeRepository.fire({ repository, uri })); const changeListener = repository.onDidChangeRepository(uri => this._onDidChangeRepository.fire({ repository, uri }));
const originalResourceChangeListener = repository.onDidChangeOriginalResource(uri => this._onDidChangeOriginalResource.fire({ repository, uri }));
const dispose = () => { const dispose = () => {
disappearListener.dispose(); disappearListener.dispose();
changeListener.dispose(); changeListener.dispose();
originalResourceChangeListener.dispose();
repository.dispose(); repository.dispose();
this.openRepositories = this.openRepositories.filter(e => e !== openRepository); this.openRepositories = this.openRepositories.filter(e => e !== openRepository);
this._onDidCloseRepository.fire(repository); this._onDidCloseRepository.fire(repository);
}; };
@@ -216,6 +242,16 @@ export class Model {
this._onDidOpenRepository.fire(repository); this._onDidOpenRepository.fire(repository);
} }
close(repository: Repository): void {
const openRepository = this.getOpenRepository(repository);
if (!openRepository) {
return;
}
openRepository.dispose();
}
async pickRepository(): Promise<Repository | undefined> { async pickRepository(): Promise<Repository | undefined> {
if (this.openRepositories.length === 0) { if (this.openRepositories.length === 0) {
throw new Error(localize('no repositories', "There are no available repositories")); throw new Error(localize('no repositories', "There are no available repositories"));
+225 -68
View File
@@ -5,8 +5,8 @@
'use strict'; 'use strict';
import { Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, Disposable, ProgressLocation, window, workspace, WorkspaceEdit } from 'vscode'; import { Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData } from 'vscode';
import { Repository as BaseRepository, Ref, Branch, Remote, Commit, GitErrorCodes, Stash } from './git'; import { Repository as BaseRepository, Ref, Branch, Remote, Commit, GitErrorCodes, Stash, RefType, GitError } from './git';
import { anyEvent, filterEvent, eventToPromise, dispose, find } from './util'; import { anyEvent, filterEvent, eventToPromise, dispose, find } from './util';
import { memoize, throttle, debounce } from './decorators'; import { memoize, throttle, debounce } from './decorators';
import { toGitUri } from './uri'; import { toGitUri } from './uri';
@@ -171,13 +171,104 @@ export class Resource implements SourceControlResourceState {
} }
get decorations(): SourceControlResourceDecorations { get decorations(): SourceControlResourceDecorations {
const light = { iconPath: this.getIconPath('light') }; // TODO@joh, still requires restart/redraw in the SCM viewlet
const dark = { iconPath: this.getIconPath('dark') }; const decorations = workspace.getConfiguration().get<boolean>('git.decorations.enabled');
const light = !decorations ? { iconPath: this.getIconPath('light') } : undefined;
const dark = !decorations ? { iconPath: this.getIconPath('dark') } : undefined;
const tooltip = this.tooltip; const tooltip = this.tooltip;
const strikeThrough = this.strikeThrough; const strikeThrough = this.strikeThrough;
const faded = this.faded; const faded = this.faded;
const letter = this.letter;
const color = this.color;
return { strikeThrough, faded, tooltip, light, dark }; return { strikeThrough, faded, tooltip, light, dark, letter, color, source: 'git.resource' /*todo@joh*/ };
}
get letter(): string | undefined {
switch (this.type) {
case Status.INDEX_MODIFIED:
case Status.MODIFIED:
return 'M';
case Status.INDEX_ADDED:
return 'A';
case Status.INDEX_DELETED:
case Status.DELETED:
return 'D';
case Status.INDEX_RENAMED:
return 'R';
case Status.UNTRACKED:
return 'U';
case Status.IGNORED:
return 'I';
case Status.INDEX_COPIED:
case Status.BOTH_DELETED:
case Status.ADDED_BY_US:
case Status.DELETED_BY_THEM:
case Status.ADDED_BY_THEM:
case Status.DELETED_BY_US:
case Status.BOTH_ADDED:
case Status.BOTH_MODIFIED:
return 'C';
default:
return undefined;
}
}
get color(): ThemeColor | undefined {
switch (this.type) {
case Status.INDEX_MODIFIED:
case Status.MODIFIED:
return new ThemeColor('gitDecoration.modifiedResourceForeground');
case Status.INDEX_DELETED:
case Status.DELETED:
return new ThemeColor('gitDecoration.deletedResourceForeground');
case Status.INDEX_ADDED: // todo@joh - special color?
case Status.INDEX_RENAMED: // todo@joh - special color?
case Status.UNTRACKED:
return new ThemeColor('gitDecoration.untrackedResourceForeground');
case Status.IGNORED:
return new ThemeColor('gitDecoration.ignoredResourceForeground');
case Status.INDEX_COPIED:
case Status.BOTH_DELETED:
case Status.ADDED_BY_US:
case Status.DELETED_BY_THEM:
case Status.ADDED_BY_THEM:
case Status.DELETED_BY_US:
case Status.BOTH_ADDED:
case Status.BOTH_MODIFIED:
return new ThemeColor('gitDecoration.conflictingResourceForeground');
default:
return undefined;
}
}
get priority(): number {
switch (this.type) {
case Status.INDEX_MODIFIED:
case Status.MODIFIED:
return 2;
case Status.IGNORED:
return 3;
case Status.INDEX_COPIED:
case Status.BOTH_DELETED:
case Status.ADDED_BY_US:
case Status.DELETED_BY_THEM:
case Status.ADDED_BY_THEM:
case Status.DELETED_BY_US:
case Status.BOTH_ADDED:
case Status.BOTH_MODIFIED:
return 4;
default:
return 1;
}
}
get resourceDecoration(): DecorationData | undefined {
const title = this.tooltip;
const abbreviation = this.letter;
const color = this.color;
const priority = this.priority;
return { bubble: true, source: 'git.resource', title, abbreviation, color, priority };
} }
constructor( constructor(
@@ -189,54 +280,34 @@ export class Resource implements SourceControlResourceState {
} }
export enum Operation { export enum Operation {
Status = 1 << 0, Status = 'Status',
Add = 1 << 1, Add = 'Add',
RevertFiles = 1 << 2, RevertFiles = 'RevertFiles',
Commit = 1 << 3, Commit = 'Commit',
Clean = 1 << 4, Clean = 'Clean',
Branch = 1 << 5, Branch = 'Branch',
Checkout = 1 << 6, Checkout = 'Checkout',
Reset = 1 << 7, Reset = 'Reset',
Fetch = 1 << 8, Fetch = 'Fetch',
Pull = 1 << 9, Pull = 'Pull',
Push = 1 << 10, Push = 'Push',
Sync = 1 << 11, Sync = 'Sync',
Show = 1 << 12, Show = 'Show',
Stage = 1 << 13, Stage = 'Stage',
GetCommitTemplate = 1 << 14, GetCommitTemplate = 'GetCommitTemplate',
DeleteBranch = 1 << 15, DeleteBranch = 'DeleteBranch',
Merge = 1 << 16, Merge = 'Merge',
Ignore = 1 << 17, Ignore = 'Ignore',
Tag = 1 << 18, Tag = 'Tag',
Stash = 1 << 19 Stash = 'Stash',
CheckIgnore = 'CheckIgnore'
} }
// function getOperationName(operation: Operation): string {
// switch (operation) {
// case Operation.Status: return 'Status';
// case Operation.Add: return 'Add';
// case Operation.RevertFiles: return 'RevertFiles';
// case Operation.Commit: return 'Commit';
// case Operation.Clean: return 'Clean';
// case Operation.Branch: return 'Branch';
// case Operation.Checkout: return 'Checkout';
// case Operation.Reset: return 'Reset';
// case Operation.Fetch: return 'Fetch';
// case Operation.Pull: return 'Pull';
// case Operation.Push: return 'Push';
// case Operation.Sync: return 'Sync';
// case Operation.Init: return 'Init';
// case Operation.Show: return 'Show';
// case Operation.Stage: return 'Stage';
// case Operation.GetCommitTemplate: return 'GetCommitTemplate';
// default: return 'unknown';
// }
// }
function isReadOnly(operation: Operation): boolean { function isReadOnly(operation: Operation): boolean {
switch (operation) { switch (operation) {
case Operation.Show: case Operation.Show:
case Operation.GetCommitTemplate: case Operation.GetCommitTemplate:
case Operation.CheckIgnore:
return true; return true;
default: default:
return false; return false;
@@ -246,6 +317,7 @@ function isReadOnly(operation: Operation): boolean {
function shouldShowProgress(operation: Operation): boolean { function shouldShowProgress(operation: Operation): boolean {
switch (operation) { switch (operation) {
case Operation.Fetch: case Operation.Fetch:
case Operation.CheckIgnore:
return false; return false;
default: default:
return true; return true;
@@ -259,24 +331,36 @@ export interface Operations {
class OperationsImpl implements Operations { class OperationsImpl implements Operations {
constructor(private readonly operations: number = 0) { private operations = new Map<Operation, number>();
// noop
start(operation: Operation): void {
this.operations.set(operation, (this.operations.get(operation) || 0) + 1);
} }
start(operation: Operation): OperationsImpl { end(operation: Operation): void {
return new OperationsImpl(this.operations | operation); const count = (this.operations.get(operation) || 0) - 1;
}
end(operation: Operation): OperationsImpl { if (count <= 0) {
return new OperationsImpl(this.operations & ~operation); this.operations.delete(operation);
} else {
this.operations.set(operation, count);
}
} }
isRunning(operation: Operation): boolean { isRunning(operation: Operation): boolean {
return (this.operations & operation) !== 0; return this.operations.has(operation);
} }
isIdle(): boolean { isIdle(): boolean {
return this.operations === 0; const operations = this.operations.keys();
for (const operation of operations) {
if (!isReadOnly(operation)) {
return false;
}
}
return true;
} }
} }
@@ -302,6 +386,9 @@ export class Repository implements Disposable {
private _onDidChangeStatus = new EventEmitter<void>(); private _onDidChangeStatus = new EventEmitter<void>();
readonly onDidChangeStatus: Event<void> = this._onDidChangeStatus.event; readonly onDidChangeStatus: Event<void> = this._onDidChangeStatus.event;
private _onDidChangeOriginalResource = new EventEmitter<Uri>();
readonly onDidChangeOriginalResource: Event<Uri> = this._onDidChangeOriginalResource.event;
private _onRunOperation = new EventEmitter<Operation>(); private _onRunOperation = new EventEmitter<Operation>();
readonly onRunOperation: Event<Operation> = this._onRunOperation.event; readonly onRunOperation: Event<Operation> = this._onRunOperation.event;
@@ -382,9 +469,7 @@ export class Repository implements Disposable {
const onRelevantGitChange = filterEvent(onRelevantRepositoryChange, uri => /\/\.git\//.test(uri.path)); const onRelevantGitChange = filterEvent(onRelevantRepositoryChange, uri => /\/\.git\//.test(uri.path));
onRelevantGitChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables); onRelevantGitChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables);
const label = `${path.basename(repository.root)} (Git)`; this._sourceControl = scm.createSourceControl('git', 'Git', Uri.file(repository.root));
this._sourceControl = scm.createSourceControl('git', label);
this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit"), arguments: [this._sourceControl] }; this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit"), arguments: [this._sourceControl] };
this._sourceControl.quickDiffProvider = this; this._sourceControl.quickDiffProvider = this;
this.disposables.push(this._sourceControl); this.disposables.push(this._sourceControl);
@@ -449,6 +534,7 @@ export class Repository implements Disposable {
async stage(resource: Uri, contents: string): Promise<void> { async stage(resource: Uri, contents: string): Promise<void> {
const relativePath = path.relative(this.repository.root, resource.fsPath).replace(/\\/g, '/'); const relativePath = path.relative(this.repository.root, resource.fsPath).replace(/\\/g, '/');
await this.run(Operation.Stage, () => this.repository.stage(relativePath, contents)); await this.run(Operation.Stage, () => this.repository.stage(relativePath, contents));
this._onDidChangeOriginalResource.fire(resource);
} }
async revert(resources: Uri[]): Promise<void> { async revert(resources: Uri[]): Promise<void> {
@@ -534,11 +620,7 @@ export class Repository implements Disposable {
@throttle @throttle
async fetch(): Promise<void> { async fetch(): Promise<void> {
try { await this.run(Operation.Fetch, () => this.repository.fetch());
await this.run(Operation.Fetch, () => this.repository.fetch());
} catch (err) {
// noop
}
} }
@throttle @throttle
@@ -584,7 +666,7 @@ export class Repository implements Disposable {
async show(ref: string, filePath: string): Promise<string> { async show(ref: string, filePath: string): Promise<string> {
return await this.run(Operation.Show, async () => { return await this.run(Operation.Show, async () => {
const relativePath = path.relative(this.repository.root, filePath).replace(/\\/g, '/'); const relativePath = path.relative(this.repository.root, filePath).replace(/\\/g, '/');
const configFiles = workspace.getConfiguration('files'); const configFiles = workspace.getConfiguration('files', Uri.file(filePath));
const encoding = configFiles.get<string>('encoding'); const encoding = configFiles.get<string>('encoding');
return await this.repository.buffer(`${ref}:${relativePath}`, encoding); return await this.repository.buffer(`${ref}:${relativePath}`, encoding);
@@ -629,13 +711,58 @@ export class Repository implements Disposable {
}); });
} }
checkIgnore(filePaths: string[]): Promise<Set<string>> {
return this.run(Operation.CheckIgnore, () => {
return new Promise<Set<string>>((resolve, reject) => {
filePaths = filePaths.filter(filePath => !path.relative(this.root, filePath).startsWith('..'));
if (filePaths.length === 0) {
// nothing left
return resolve(new Set<string>());
}
// https://git-scm.com/docs/git-check-ignore#git-check-ignore--z
const child = this.repository.stream(['check-ignore', '-z', '--stdin'], { stdio: [null, null, null] });
child.stdin.end(filePaths.join('\0'), 'utf8');
const onExit = exitCode => {
if (exitCode === 1) {
// nothing ignored
resolve(new Set<string>());
} else if (exitCode === 0) {
// paths are separated by the null-character
resolve(new Set<string>(data.split('\0')));
} else {
reject(new GitError({ stdout: data, stderr, exitCode }));
}
};
let data = '';
const onStdoutData = (raw: string) => {
data += raw;
};
child.stdout.setEncoding('utf8');
child.stdout.on('data', onStdoutData);
let stderr: string = '';
child.stderr.setEncoding('utf8');
child.stderr.on('data', raw => stderr += raw);
child.on('error', reject);
child.on('exit', onExit);
});
});
}
private async run<T>(operation: Operation, runOperation: () => Promise<T> = () => Promise.resolve<any>(null)): Promise<T> { private async run<T>(operation: Operation, runOperation: () => Promise<T> = () => Promise.resolve<any>(null)): Promise<T> {
if (this.state !== RepositoryState.Idle) { if (this.state !== RepositoryState.Idle) {
throw new Error('Repository not initialized'); throw new Error('Repository not initialized');
} }
const run = async () => { const run = async () => {
this._operations = this._operations.start(operation); this._operations.start(operation);
this._onRunOperation.fire(operation); this._onRunOperation.fire(operation);
try { try {
@@ -653,7 +780,7 @@ export class Repository implements Disposable {
throw err; throw err;
} finally { } finally {
this._operations = this._operations.end(operation); this._operations.end(operation);
this._onDidRunOperation.fire(operation); this._onDidRunOperation.fire(operation);
} }
}; };
@@ -818,7 +945,7 @@ export class Repository implements Disposable {
await timeout(5000); await timeout(5000);
} }
private async whenIdleAndFocused(): Promise<void> { async whenIdleAndFocused(): Promise<void> {
while (true) { while (true) {
if (!this.operations.isIdle()) { if (!this.operations.isIdle()) {
await eventToPromise(this.onDidRunOperation); await eventToPromise(this.onDidRunOperation);
@@ -835,6 +962,36 @@ export class Repository implements Disposable {
} }
} }
get headLabel(): string {
const HEAD = this.HEAD;
if (!HEAD) {
return '';
}
const tag = this.refs.filter(iref => iref.type === RefType.Tag && iref.commit === HEAD.commit)[0];
const tagName = tag && tag.name;
const head = HEAD.name || tagName || (HEAD.commit || '').substr(0, 8);
return head
+ (this.workingTreeGroup.resourceStates.length > 0 ? '*' : '')
+ (this.indexGroup.resourceStates.length > 0 ? '+' : '')
+ (this.mergeGroup.resourceStates.length > 0 ? '!' : '');
}
get syncLabel(): string {
if (!this.HEAD
|| !this.HEAD.name
|| !this.HEAD.commit
|| !this.HEAD.upstream
|| !(this.HEAD.ahead || this.HEAD.behind)
) {
return '';
}
return `${this.HEAD.behind}${this.HEAD.ahead}`;
}
dispose(): void { dispose(): void {
this.disposables = dispose(this.disposables); this.disposables = dispose(this.disposables);
} }
+3 -16
View File
@@ -6,7 +6,7 @@
'use strict'; 'use strict';
import { Disposable, Command, EventEmitter, Event } from 'vscode'; import { Disposable, Command, EventEmitter, Event } from 'vscode';
import { RefType, Branch } from './git'; import { Branch } from './git';
import { Repository, Operation } from './repository'; import { Repository, Operation } from './repository';
import { anyEvent, dispose } from './util'; import { anyEvent, dispose } from './util';
import * as nls from 'vscode-nls'; import * as nls from 'vscode-nls';
@@ -24,20 +24,7 @@ class CheckoutStatusBar {
} }
get command(): Command | undefined { get command(): Command | undefined {
const HEAD = this.repository.HEAD; const title = `$(git-branch) ${this.repository.headLabel}`;
if (!HEAD) {
return undefined;
}
const tag = this.repository.refs.filter(iref => iref.type === RefType.Tag && iref.commit === HEAD.commit)[0];
const tagName = tag && tag.name;
const head = HEAD.name || tagName || (HEAD.commit || '').substr(0, 8);
const title = '$(git-branch) '
+ head
+ (this.repository.workingTreeGroup.resourceStates.length > 0 ? '*' : '')
+ (this.repository.indexGroup.resourceStates.length > 0 ? '+' : '')
+ (this.repository.mergeGroup.resourceStates.length > 0 ? '!' : '');
return { return {
command: 'git.checkout', command: 'git.checkout',
@@ -112,7 +99,7 @@ class SyncStatusBar {
if (HEAD && HEAD.name && HEAD.commit) { if (HEAD && HEAD.name && HEAD.commit) {
if (HEAD.upstream) { if (HEAD.upstream) {
if (HEAD.ahead || HEAD.behind) { if (HEAD.ahead || HEAD.behind) {
text += `${HEAD.behind}${HEAD.ahead}`; text += this.repository.syncLabel;
} }
command = 'git.sync'; command = 'git.sync';
tooltip = localize('sync changes', "Synchronize Changes"); tooltip = localize('sync changes', "Synchronize Changes");
+17
View File
@@ -8,6 +8,7 @@
import { Event } from 'vscode'; import { Event } from 'vscode';
import { dirname } from 'path'; import { dirname } from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import * as byline from 'byline';
export function log(...args: any[]): void { export function log(...args: any[]): void {
console.log.apply(console, ['git:', ...args]); console.log.apply(console, ['git:', ...args]);
@@ -189,3 +190,19 @@ export function find<T>(array: T[], fn: (t: T) => boolean): T | undefined {
return result; return result;
} }
export async function grep(filename: string, pattern: RegExp): Promise<boolean> {
return new Promise<boolean>((c, e) => {
const fileStream = fs.createReadStream(filename, { encoding: 'utf8' });
const stream = byline(fileStream);
stream.on('data', (line: string) => {
if (pattern.test(line)) {
fileStream.close();
c(true);
}
});
stream.on('error', e);
stream.on('end', () => c(false));
});
}
+6 -1
View File
@@ -50,6 +50,11 @@
"scopeName": "text.git-rebase", "scopeName": "text.git-rebase",
"path": "./syntaxes/git-rebase.tmLanguage.json" "path": "./syntaxes/git-rebase.tmLanguage.json"
} }
] ],
"configurationDefaults": {
"[git-commit]": {
"editor.rulers": [72]
}
}
} }
} }
+1
View File
@@ -82,6 +82,7 @@
{ {
"id": "backup-history-server-insight", "id": "backup-history-server-insight",
"contrib": { "contrib": {
"cacheId": "backup-history-server-insight",
"name": "Backup Status", "name": "Backup Status",
"provider": "MSSQL", "provider": "MSSQL",
"edition": [0,1,2,3,4], "edition": [0,1,2,3,4],
@@ -6,13 +6,13 @@ SUM(ALOC.data_pages) AS data_pages,
(SUM(ALOC.total_pages)*8/1024) AS total_space_MB, (SUM(ALOC.total_pages)*8/1024) AS total_space_MB,
(SUM(ALOC.used_pages)*8/1024) AS used_space_MB, (SUM(ALOC.used_pages)*8/1024) AS used_space_MB,
(SUM(ALOC.data_pages)*8/1024) AS data_space_MB (SUM(ALOC.data_pages)*8/1024) AS data_space_MB
FROM sys.Tables AS TABL FROM sys.tables AS TABL
INNER JOIN sys.Indexes AS INDX INNER JOIN sys.indexes AS INDX
ON TABL.object_id = INDX.object_id ON TABL.object_id = INDX.object_id
INNER JOIN sys.Partitions AS PART INNER JOIN sys.partitions AS PART
ON INDX.object_id = PART.object_id ON INDX.object_id = PART.object_id
AND INDX.index_id = PART.index_id AND INDX.index_id = PART.index_id
INNER JOIN sys.Allocation_Units AS ALOC INNER JOIN sys.allocation_units AS ALOC
ON PART.partition_id = ALOC.container_id ON PART.partition_id = ALOC.container_id
WHERE WHERE
INDX.object_id > 255 INDX.object_id > 255
+5 -5
View File
@@ -7,11 +7,11 @@
"request": "launch", "request": "launch",
"runtimeExecutable": "${execPath}", "runtimeExecutable": "${execPath}",
"args": [ "args": [
"--extensionDevelopmentPath=${workspaceRoot}" "--extensionDevelopmentPath=${workspaceFolder}"
], ],
"stopOnEntry": false, "stopOnEntry": false,
"sourceMaps": true, "sourceMaps": true,
"outFiles": ["${workspaceRoot}/client/out"], "outFiles": ["${workspaceFolder}/client/out"],
"preLaunchTask": "npm" "preLaunchTask": "npm"
}, },
{ {
@@ -19,10 +19,10 @@
"type": "extensionHost", "type": "extensionHost",
"request": "launch", "request": "launch",
"runtimeExecutable": "${execPath}", "runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/client/out/test" ], "args": ["--extensionDevelopmentPath=${workspaceFolder}", "--extensionTestsPath=${workspaceFolder}/client/out/test" ],
"stopOnEntry": false, "stopOnEntry": false,
"sourceMaps": true, "sourceMaps": true,
"outFiles": ["${workspaceRoot}/client/out/test"], "outFiles": ["${workspaceFolder}/client/out/test"],
"preLaunchTask": "npm" "preLaunchTask": "npm"
}, },
{ {
@@ -31,7 +31,7 @@
"request": "attach", "request": "attach",
"port": 6004, "port": 6004,
"sourceMaps": true, "sourceMaps": true,
"outFiles": ["${workspaceRoot}/server/out"] "outFiles": ["${workspaceFolder}/server/out"]
} }
] ]
+1 -1
View File
@@ -1,5 +1,5 @@
// Available variables which can be used inside of strings. // Available variables which can be used inside of strings.
// ${workspaceRoot}: the root folder of the team // ${workspaceFolder}: the root folder of the team
// ${file}: the current opened file // ${file}: the current opened file
// ${fileBasename}: the current opened file's basename // ${fileBasename}: the current opened file's basename
// ${fileDirname}: the current opened file's dirname // ${fileDirname}: the current opened file's dirname
+94 -46
View File
@@ -6,21 +6,25 @@
import * as path from 'path'; import * as path from 'path';
import { workspace, languages, ExtensionContext, extensions, Uri, TextDocument, ColorRange, Color } from 'vscode'; import { workspace, languages, ExtensionContext, extensions, Uri, TextDocument, ColorInformation, Color, ColorPresentation } from 'vscode';
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification } from 'vscode-languageclient'; import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification } from 'vscode-languageclient';
import TelemetryReporter from 'vscode-extension-telemetry'; import TelemetryReporter from 'vscode-extension-telemetry';
import { ConfigurationFeature } from 'vscode-languageclient/lib/proposed'; import { ConfigurationFeature } from 'vscode-languageclient/lib/configuration.proposed';
import { DocumentColorRequest, DocumentColorParams, ColorPresentationParams, ColorPresentationRequest } from 'vscode-languageserver-protocol/lib/protocol.colorProvider.proposed';
import { DocumentColorRequest } from 'vscode-languageserver-protocol/lib/protocol.colorProvider.proposed';
import * as nls from 'vscode-nls'; import * as nls from 'vscode-nls';
import { hash } from './utils/hash';
let localize = nls.loadMessageBundle(); let localize = nls.loadMessageBundle();
namespace VSCodeContentRequest { namespace VSCodeContentRequest {
export const type: RequestType<string, string, any, any> = new RequestType('vscode/content'); export const type: RequestType<string, string, any, any> = new RequestType('vscode/content');
} }
namespace SchemaContentChangeNotification {
export const type: NotificationType<string, any> = new NotificationType('json/schemaContent');
}
export interface ISchemaAssociations { export interface ISchemaAssociations {
[pattern: string]: string[]; [pattern: string]: string[];
} }
@@ -56,16 +60,13 @@ interface JSONSchemaSettings {
schema?: any; schema?: any;
} }
const ColorFormat_HEX = {
opaque: '"#{red:X}{green:X}{blue:X}"',
transparent: '"#{red:X}{green:X}{blue:X}{alpha:X}"'
};
export function activate(context: ExtensionContext) { export function activate(context: ExtensionContext) {
let toDispose = context.subscriptions;
let packageInfo = getPackageInfo(context); let packageInfo = getPackageInfo(context);
let telemetryReporter: TelemetryReporter = packageInfo && new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey); let telemetryReporter: TelemetryReporter = packageInfo && new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
context.subscriptions.push(telemetryReporter); toDispose.push(telemetryReporter);
// The server is implemented in node // The server is implemented in node
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'jsonServerMain.js')); let serverModule = context.asAbsolutePath(path.join('server', 'out', 'jsonServerMain.js'));
@@ -102,6 +103,7 @@ export function activate(context: ExtensionContext) {
client.registerFeature(new ConfigurationFeature(client)); client.registerFeature(new ConfigurationFeature(client));
let disposable = client.start(); let disposable = client.start();
toDispose.push(disposable);
client.onReady().then(() => { client.onReady().then(() => {
client.onTelemetry(e => { client.onTelemetry(e => {
if (telemetryReporter) { if (telemetryReporter) {
@@ -119,27 +121,48 @@ export function activate(context: ExtensionContext) {
}); });
}); });
let handleContentChange = (uri: Uri) => {
if (uri.scheme === 'vscode' && uri.authority === 'schemas') {
client.sendNotification(SchemaContentChangeNotification.type, uri.toString());
}
};
toDispose.push(workspace.onDidChangeTextDocument(e => handleContentChange(e.document.uri)));
toDispose.push(workspace.onDidCloseTextDocument(d => handleContentChange(d.uri)));
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context)); client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociation(context));
// register color provider // register color provider
context.subscriptions.push(languages.registerColorProvider(documentSelector, { toDispose.push(languages.registerColorProvider(documentSelector, {
provideDocumentColors(document: TextDocument): Thenable<ColorRange[]> { provideDocumentColors(document: TextDocument): Thenable<ColorInformation[]> {
let params = client.code2ProtocolConverter.asDocumentSymbolParams(document); let params: DocumentColorParams = {
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document)
};
return client.sendRequest(DocumentColorRequest.type, params).then(symbols => { return client.sendRequest(DocumentColorRequest.type, params).then(symbols => {
return symbols.map(symbol => { return symbols.map(symbol => {
let range = client.protocol2CodeConverter.asRange(symbol.range); let range = client.protocol2CodeConverter.asRange(symbol.range);
let color = new Color(symbol.color.red * 255, symbol.color.green * 255, symbol.color.blue * 255, symbol.color.alpha); let color = new Color(symbol.color.red, symbol.color.green, symbol.color.blue, symbol.color.alpha);
return new ColorRange(range, color, [ColorFormat_HEX]); return new ColorInformation(range, color);
});
});
},
provideColorPresentations(color: Color, context): Thenable<ColorPresentation[]> {
let params: ColorPresentationParams = {
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(context.document),
color: color,
range: client.code2ProtocolConverter.asRange(context.range)
};
return client.sendRequest(ColorPresentationRequest.type, params).then(presentations => {
return presentations.map(p => {
let presentation = new ColorPresentation(p.label);
presentation.textEdit = p.textEdit && client.protocol2CodeConverter.asTextEdit(p.textEdit);
presentation.additionalTextEdits = p.additionalTextEdits && client.protocol2CodeConverter.asTextEdits(p.additionalTextEdits);
return presentation;
}); });
}); });
} }
})); }));
}); });
// Push the disposable to the context's subscriptions so that the
// client can be deactivated on extension deactivation
context.subscriptions.push(disposable);
languages.setLanguageConfiguration('json', { languages.setLanguageConfiguration('json', {
wordPattern: /("(?:[^\\\"]*(?:\\.)?)*"?)|[^\s{}\[\],:]+/, wordPattern: /("(?:[^\\\"]*(?:\\.)?)*"?)|[^\s{}\[\],:]+/,
indentationRules: { indentationRules: {
@@ -184,9 +207,6 @@ function getSchemaAssociation(context: ExtensionContext): ISchemaAssociations {
function getSettings(): Settings { function getSettings(): Settings {
let httpSettings = workspace.getConfiguration('http'); let httpSettings = workspace.getConfiguration('http');
let jsonSettings = workspace.getConfiguration('json');
let schemas = [];
let settings: Settings = { let settings: Settings = {
http: { http: {
@@ -194,42 +214,70 @@ function getSettings(): Settings {
proxyStrictSSL: httpSettings.get('proxyStrictSSL') proxyStrictSSL: httpSettings.get('proxyStrictSSL')
}, },
json: { json: {
format: jsonSettings.get('format'), format: workspace.getConfiguration('json').get('format'),
schemas: schemas, schemas: [],
}
};
let schemaSettingsById: { [schemaId: string]: JSONSchemaSettings } = Object.create(null);
let collectSchemaSettings = (schemaSettings: JSONSchemaSettings[], rootPath?: string, fileMatchPrefix?: string) => {
for (let setting of schemaSettings) {
let url = getSchemaId(setting, rootPath);
if (!url) {
continue;
}
let schemaSetting = schemaSettingsById[url];
if (!schemaSetting) {
schemaSetting = schemaSettingsById[url] = { url, fileMatch: [] };
settings.json.schemas.push(schemaSetting);
}
let fileMatches = setting.fileMatch;
if (Array.isArray(fileMatches)) {
if (fileMatchPrefix) {
fileMatches = fileMatches.map(m => fileMatchPrefix + m);
}
schemaSetting.fileMatch.push(...fileMatches);
}
if (setting.schema) {
schemaSetting.schema = setting.schema;
}
} }
}; };
let settingsSchemas = jsonSettings.get('schemas');
if (Array.isArray(settingsSchemas)) {
schemas.push(...settingsSchemas);
}
// merge global and folder settings. Qualify all file matches with the folder path.
let globalSettings = workspace.getConfiguration('json', null).get<JSONSchemaSettings[]>('schemas');
if (Array.isArray(globalSettings)) {
collectSchemaSettings(globalSettings, workspace.rootPath);
}
let folders = workspace.workspaceFolders; let folders = workspace.workspaceFolders;
if (folders) { if (folders) {
folders.forEach(folder => { for (let folder of folders) {
let jsonConfig = workspace.getConfiguration('json', folder.uri); let folderUri = folder.uri;
let schemaConfigInfo = jsonConfig.inspect<JSONSchemaSettings[]>('schemas'); let schemaConfigInfo = workspace.getConfiguration('json', folderUri).inspect<JSONSchemaSettings[]>('schemas');
let folderSchemas = schemaConfigInfo.workspaceFolderValue; let folderSchemas = schemaConfigInfo.workspaceFolderValue;
if (Array.isArray(folderSchemas)) { if (Array.isArray(folderSchemas)) {
folderSchemas.forEach(schema => { let folderPath = folderUri.toString();
let url = schema.url; if (folderPath[folderPath.length - 1] !== '/') {
if (!url && schema.schema) { folderPath = folderPath + '/';
url = schema.schema.id; }
} collectSchemaSettings(folderSchemas, folderUri.fsPath, folderPath + '*');
if (url && url[0] === '.') {
url = Uri.file(path.normalize(path.join(folder.uri.fsPath, url))).toString();
}
let fileMatch = schema.fileMatch;
if (fileMatch) {
fileMatch = fileMatch.map(m => folder.uri.toString() + '*' + m);
}
schemas.push({ url, fileMatch, schema: schema.schema });
});
}; };
}); };
} }
return settings; return settings;
} }
function getSchemaId(schema: JSONSchemaSettings, rootPath?: string) {
let url = schema.url;
if (!url) {
if (schema.schema) {
url = schema.schema.id || `vscode://schemas/custom/${encodeURIComponent(hash(schema.schema).toString(16))}`;
}
} else if (rootPath && (url[0] === '.' || url[0] === '/')) {
url = Uri.file(path.normalize(path.join(rootPath, url))).toString();
}
return url;
}
function getPackageInfo(context: ExtensionContext): IPackageInfo { function getPackageInfo(context: ExtensionContext): IPackageInfo {
let extensionPackage = require(context.asAbsolutePath('./package.json')); let extensionPackage = require(context.asAbsolutePath('./package.json'));
if (extensionPackage) { if (extensionPackage) {
+59
View File
@@ -0,0 +1,59 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
/**
* Return a hash value for an object.
*/
export function hash(obj: any, hashVal = 0): number {
switch (typeof obj) {
case 'object':
if (obj === null) {
return numberHash(349, hashVal);
} else if (Array.isArray(obj)) {
return arrayHash(obj, hashVal);
}
return objectHash(obj, hashVal);
case 'string':
return stringHash(obj, hashVal);
case 'boolean':
return booleanHash(obj, hashVal);
case 'number':
return numberHash(obj, hashVal);
case 'undefined':
return numberHash(obj, 937);
default:
return numberHash(obj, 617);
}
}
function numberHash(val: number, initialHashVal: number): number {
return (((initialHashVal << 5) - initialHashVal) + val) | 0; // hashVal * 31 + ch, keep as int32
}
function booleanHash(b: boolean, initialHashVal: number): number {
return numberHash(b ? 433 : 863, initialHashVal);
}
function stringHash(s: string, hashVal: number) {
hashVal = numberHash(149417, hashVal);
for (let i = 0, length = s.length; i < length; i++) {
hashVal = numberHash(s.charCodeAt(i), hashVal);
}
return hashVal;
}
function arrayHash(arr: any[], initialHashVal: number): number {
initialHashVal = numberHash(104579, initialHashVal);
return arr.reduce((hashVal, item) => hash(item, hashVal), initialHashVal);
}
function objectHash(obj: any, initialHashVal: number): number {
initialHashVal = numberHash(181387, initialHashVal);
return Object.keys(obj).sort().reduce((hashVal, key) => {
hashVal = stringHash(key, hashVal);
return hash(obj[key], hashVal);
}, initialHashVal);
}
+12 -12
View File
@@ -13,24 +13,24 @@
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz" "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz"
}, },
"vscode-jsonrpc": { "vscode-jsonrpc": {
"version": "3.3.1", "version": "3.5.0-next.2",
"from": "vscode-jsonrpc@>=3.3.0 <4.0.0", "from": "vscode-jsonrpc@3.5.0-next.2",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.3.1.tgz" "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.5.0-next.2.tgz"
}, },
"vscode-languageclient": { "vscode-languageclient": {
"version": "3.4.0-next.17", "version": "3.5.0-next.4",
"from": "vscode-languageclient@next", "from": "vscode-languageclient@3.5.0-next.4",
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.4.0-next.17.tgz" "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.5.0-next.4.tgz"
}, },
"vscode-languageserver-protocol": { "vscode-languageserver-protocol": {
"version": "3.1.1", "version": "3.5.0-next.5",
"from": "vscode-languageserver-protocol@>=3.1.1 <4.0.0", "from": "vscode-languageserver-protocol@3.5.0-next.5",
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.1.1.tgz" "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.0-next.5.tgz"
}, },
"vscode-languageserver-types": { "vscode-languageserver-types": {
"version": "3.3.0", "version": "3.5.0-next.2",
"from": "vscode-languageserver-types@>=3.3.0 <4.0.0", "from": "vscode-languageserver-types@3.5.0-next.2",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.3.0.tgz" "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0-next.2.tgz"
}, },
"vscode-nls": { "vscode-nls": {
"version": "2.0.2", "version": "2.0.2",
+2 -3
View File
@@ -133,11 +133,10 @@
}, },
"dependencies": { "dependencies": {
"vscode-extension-telemetry": "0.0.8", "vscode-extension-telemetry": "0.0.8",
"vscode-languageclient": "3.4.0-next.17", "vscode-languageclient": "3.5.0-next.4",
"vscode-languageserver-protocol": "^3.1.1",
"vscode-nls": "2.0.2" "vscode-nls": "2.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^6.0.51" "@types/node": "7.0.43"
} }
} }
+4 -4
View File
@@ -8,25 +8,25 @@
"request": "attach", "request": "attach",
"port": 6004, "port": 6004,
"sourceMaps": true, "sourceMaps": true,
"outDir": "${workspaceRoot}/out" "outDir": "${workspaceFolder}/out"
}, },
{ {
"name": "Unit Tests", "name": "Unit Tests",
"type": "node", "type": "node",
"request": "launch", "request": "launch",
"program": "${workspaceRoot}/../../../node_modules/mocha/bin/_mocha", "program": "${workspaceFolder}/../../../node_modules/mocha/bin/_mocha",
"stopOnEntry": false, "stopOnEntry": false,
"args": [ "args": [
"--timeout", "--timeout",
"999999", "999999",
"--colors" "--colors"
], ],
"cwd": "${workspaceRoot}", "cwd": "${workspaceFolder}",
"runtimeExecutable": null, "runtimeExecutable": null,
"runtimeArgs": [], "runtimeArgs": [],
"env": {}, "env": {},
"sourceMaps": true, "sourceMaps": true,
"outDir": "${workspaceRoot}/out" "outDir": "${workspaceFolder}/out"
} }
] ]
} }
+14 -14
View File
@@ -43,29 +43,29 @@
"resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.1.tgz" "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.1.tgz"
}, },
"vscode-json-languageservice": { "vscode-json-languageservice": {
"version": "2.0.16", "version": "3.0.0",
"from": "vscode-json-languageservice@next", "from": "vscode-json-languageservice@next",
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-2.0.16.tgz" "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.0.0.tgz"
}, },
"vscode-jsonrpc": { "vscode-jsonrpc": {
"version": "3.3.1", "version": "3.5.0-next.2",
"from": "vscode-jsonrpc@>=3.3.0 <4.0.0", "from": "vscode-jsonrpc@3.5.0-next.2",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.3.1.tgz" "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.5.0-next.2.tgz"
}, },
"vscode-languageserver": { "vscode-languageserver": {
"version": "3.4.0-next.6", "version": "3.5.0-next.6",
"from": "vscode-languageserver@next", "from": "vscode-languageserver@3.5.0-next.6",
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.4.0-next.6.tgz" "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.5.0-next.6.tgz"
}, },
"vscode-languageserver-protocol": { "vscode-languageserver-protocol": {
"version": "3.1.1", "version": "3.5.0-next.5",
"from": "vscode-languageserver-protocol@>=3.1.1 <4.0.0", "from": "vscode-languageserver-protocol@3.5.0-next.5",
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.1.1.tgz" "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.0-next.5.tgz"
}, },
"vscode-languageserver-types": { "vscode-languageserver-types": {
"version": "3.3.0", "version": "3.5.0-next.2",
"from": "vscode-languageserver-types@>=3.0.3 <4.0.0", "from": "vscode-languageserver-types@3.5.0-next.2",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.3.0.tgz" "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0-next.2.tgz"
}, },
"vscode-nls": { "vscode-nls": {
"version": "2.0.2", "version": "2.0.2",
+5 -5
View File
@@ -10,13 +10,13 @@
"dependencies": { "dependencies": {
"jsonc-parser": "^1.0.0", "jsonc-parser": "^1.0.0",
"request-light": "^0.2.1", "request-light": "^0.2.1",
"vscode-json-languageservice": "^2.0.16", "vscode-json-languageservice": "3.0.0",
"vscode-languageserver": "3.4.0-next.6", "vscode-languageserver": "3.5.0-next.6",
"vscode-languageserver-protocol": "^3.1.1", "vscode-nls": "^2.0.2",
"vscode-nls": "^2.0.2" "vscode-uri": "^1.0.1"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^6.0.51" "@types/node": "7.0.43"
}, },
"scripts": { "scripts": {
"compile": "gulp compile-extension:json-server", "compile": "gulp compile-extension:json-server",
+22 -14
View File
@@ -10,12 +10,11 @@ import {
DocumentRangeFormattingRequest, Disposable, ServerCapabilities DocumentRangeFormattingRequest, Disposable, ServerCapabilities
} from 'vscode-languageserver'; } from 'vscode-languageserver';
import { DocumentColorRequest, ServerCapabilities as CPServerCapabilities } from 'vscode-languageserver-protocol/lib/protocol.colorProvider.proposed'; import { DocumentColorRequest, ServerCapabilities as CPServerCapabilities, ColorPresentationRequest } from 'vscode-languageserver-protocol/lib/protocol.colorProvider.proposed';
import { xhr, XHRResponse, configure as configureHttpRequests, getErrorStatusDescription } from 'request-light'; import { xhr, XHRResponse, configure as configureHttpRequests, getErrorStatusDescription } from 'request-light';
import path = require('path');
import fs = require('fs'); import fs = require('fs');
import URI from './utils/uri'; import URI from 'vscode-uri';
import * as URL from 'url'; import * as URL from 'url';
import Strings = require('./utils/strings'); import Strings = require('./utils/strings');
import { JSONDocument, JSONSchema, LanguageSettings, getLanguageService } from 'vscode-json-languageservice'; import { JSONDocument, JSONSchema, LanguageSettings, getLanguageService } from 'vscode-json-languageservice';
@@ -36,6 +35,10 @@ namespace VSCodeContentRequest {
export const type: RequestType<string, string, any, any> = new RequestType('vscode/content'); export const type: RequestType<string, string, any, any> = new RequestType('vscode/content');
} }
namespace SchemaContentChangeNotification {
export const type: NotificationType<string, any> = new NotificationType('json/schemaContent');
}
// Create a connection for the server // Create a connection for the server
let connection: IConnection = createConnection(); let connection: IConnection = createConnection();
@@ -54,9 +57,7 @@ let clientDynamicRegisterSupport = false;
// After the server has started the client sends an initilize request. The server receives // After the server has started the client sends an initilize request. The server receives
// in the passed params the rootPath of the workspace plus the client capabilities. // in the passed params the rootPath of the workspace plus the client capabilities.
let workspaceRoot: URI;
connection.onInitialize((params: InitializeParams): InitializeResult => { connection.onInitialize((params: InitializeParams): InitializeResult => {
workspaceRoot = URI.parse(params.rootPath);
function hasClientCapability(...keys: string[]) { function hasClientCapability(...keys: string[]) {
let c = params.capabilities; let c = params.capabilities;
@@ -175,6 +176,11 @@ connection.onNotification(SchemaAssociationNotification.type, associations => {
updateConfiguration(); updateConfiguration();
}); });
// A schema has changed
connection.onNotification(SchemaContentChangeNotification.type, uri => {
languageService.resetSchema(uri);
});
function updateConfiguration() { function updateConfiguration() {
let languageSettings: LanguageSettings = { let languageSettings: LanguageSettings = {
validate: true, validate: true,
@@ -192,19 +198,12 @@ function updateConfiguration() {
} }
} }
if (jsonConfigurationSettings) { if (jsonConfigurationSettings) {
jsonConfigurationSettings.forEach(schema => { jsonConfigurationSettings.forEach((schema, index) => {
let uri = schema.url; let uri = schema.url;
if (!uri && schema.schema) { if (!uri && schema.schema) {
uri = schema.schema.id; uri = schema.schema.id || `vscode://schemas/custom/${index}`;
}
if (!uri && schema.fileMatch) {
uri = 'vscode://schemas/custom/' + encodeURIComponent(schema.fileMatch.join('&'));
} }
if (uri) { if (uri) {
if (uri[0] === '.' && workspaceRoot) {
// workspace relative path
uri = URI.file(path.normalize(path.join(workspaceRoot.fsPath, uri))).toString();
}
languageSettings.schemas.push({ uri, fileMatch: schema.fileMatch, schema: schema.schema }); languageSettings.schemas.push({ uri, fileMatch: schema.fileMatch, schema: schema.schema });
} }
}); });
@@ -321,5 +320,14 @@ connection.onRequest(DocumentColorRequest.type, params => {
return []; return [];
}); });
connection.onRequest(ColorPresentationRequest.type, params => {
let document = documents.get(params.textDocument.uri);
if (document) {
let jsonDocument = getJSONDocument(document);
return languageService.getColorPresentations(document, jsonDocument, params.color, params.range);
}
return [];
});
// Listen on the connection // Listen on the connection
connection.listen(); connection.listen();
@@ -388,11 +388,11 @@
"c": "\\u0056", "c": "\\u0056",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json constant.character.escape.json", "t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json constant.character.escape.json",
"r": { "r": {
"dark_plus": "string: #CE9178", "dark_plus": "constant.character.escape: #D7BA7D",
"light_plus": "string: #A31515", "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string: #CE9178", "dark_vs": "string: #CE9178",
"light_vs": "string: #A31515", "light_vs": "string: #A31515",
"hc_black": "string: #CE9178" "hc_black": "constant.character: #569CD6"
} }
}, },
{ {
@@ -37,5 +37,8 @@
["(", ")"], ["(", ")"],
["[", "]"], ["[", "]"],
["`", "`"] ["`", "`"]
] ],
"folding": {
"offSide": true
}
} }
+131 -17
View File
@@ -2,74 +2,188 @@
"name": "vscode-markdown", "name": "vscode-markdown",
"version": "0.2.0", "version": "0.2.0",
"dependencies": { "dependencies": {
"@types/highlight.js": {
"version": "9.1.10",
"from": "@types/highlight.js@9.1.10",
"resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.1.10.tgz",
"dev": true
},
"@types/markdown-it": {
"version": "0.0.2",
"from": "@types/markdown-it@0.0.2",
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-0.0.2.tgz",
"dev": true
},
"@types/node": {
"version": "7.0.43",
"from": "@types/node@7.0.43",
"resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz",
"dev": true
},
"applicationinsights": { "applicationinsights": {
"version": "0.18.0", "version": "0.18.0",
"from": "applicationinsights@0.18.0", "from": "applicationinsights@https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz",
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz" "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz"
}, },
"argparse": { "argparse": {
"version": "1.0.9", "version": "1.0.9",
"from": "argparse@>=1.0.7 <2.0.0", "from": "argparse@https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz" "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz"
}, },
"binaryextensions": {
"version": "1.0.1",
"from": "binaryextensions@1.0.1",
"resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-1.0.1.tgz",
"dev": true
},
"core-util-is": {
"version": "1.0.2",
"from": "core-util-is@1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"dev": true
},
"entities": { "entities": {
"version": "1.1.1", "version": "1.1.1",
"from": "entities@>=1.1.1 <1.2.0", "from": "entities@https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz" "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz"
}, },
"escape-string-regexp": {
"version": "1.0.5",
"from": "escape-string-regexp@1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"dev": true
},
"gulp-rename": {
"version": "1.2.2",
"from": "gulp-rename@1.2.2",
"resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.2.2.tgz",
"dev": true
},
"gulp-replace": {
"version": "0.5.4",
"from": "gulp-replace@0.5.4",
"resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-0.5.4.tgz",
"dev": true
},
"highlight.js": { "highlight.js": {
"version": "9.5.0", "version": "9.5.0",
"from": "highlight.js@>=9.3.0 <10.0.0", "from": "highlight.js@https://registry.npmjs.org/highlight.js/-/highlight.js-9.5.0.tgz",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.5.0.tgz" "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.5.0.tgz"
}, },
"inherits": {
"version": "2.0.3",
"from": "inherits@2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"dev": true
},
"isarray": {
"version": "1.0.0",
"from": "isarray@1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"dev": true
},
"istextorbinary": {
"version": "1.0.2",
"from": "istextorbinary@1.0.2",
"resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-1.0.2.tgz",
"dev": true
},
"linkify-it": { "linkify-it": {
"version": "2.0.3", "version": "2.0.3",
"from": "linkify-it@>=2.0.0 <3.0.0", "from": "linkify-it@https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz" "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz"
}, },
"markdown-it": { "markdown-it": {
"version": "8.2.2", "version": "8.4.0",
"from": "markdown-it@8.2.2", "from": "markdown-it@8.4.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.2.2.tgz" "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.0.tgz"
}, },
"markdown-it-named-headers": { "markdown-it-named-headers": {
"version": "0.0.4", "version": "0.0.4",
"from": "markdown-it-named-headers@0.0.4", "from": "markdown-it-named-headers@https://registry.npmjs.org/markdown-it-named-headers/-/markdown-it-named-headers-0.0.4.tgz",
"resolved": "https://registry.npmjs.org/markdown-it-named-headers/-/markdown-it-named-headers-0.0.4.tgz" "resolved": "https://registry.npmjs.org/markdown-it-named-headers/-/markdown-it-named-headers-0.0.4.tgz"
}, },
"mdurl": { "mdurl": {
"version": "1.0.1", "version": "1.0.1",
"from": "mdurl@>=1.0.1 <1.1.0", "from": "mdurl@https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz" "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz"
}, },
"object-assign": {
"version": "4.1.1",
"from": "object-assign@4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"dev": true
},
"process-nextick-args": {
"version": "1.0.7",
"from": "process-nextick-args@1.0.7",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
"dev": true
},
"readable-stream": {
"version": "2.3.3",
"from": "readable-stream@2.3.3",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
"dev": true
},
"replacestream": {
"version": "4.0.2",
"from": "replacestream@4.0.2",
"resolved": "https://registry.npmjs.org/replacestream/-/replacestream-4.0.2.tgz",
"dev": true
},
"safe-buffer": {
"version": "5.1.1",
"from": "safe-buffer@5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"dev": true
},
"sprintf-js": { "sprintf-js": {
"version": "1.0.3", "version": "1.0.3",
"from": "sprintf-js@>=1.0.2 <1.1.0", "from": "sprintf-js@https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
}, },
"string": { "string": {
"version": "3.3.1", "version": "3.3.1",
"from": "string@>=3.0.1 <4.0.0", "from": "string@https://registry.npmjs.org/string/-/string-3.3.1.tgz",
"resolved": "https://registry.npmjs.org/string/-/string-3.3.1.tgz" "resolved": "https://registry.npmjs.org/string/-/string-3.3.1.tgz"
}, },
"string_decoder": {
"version": "1.0.3",
"from": "string_decoder@1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"dev": true
},
"textextensions": {
"version": "1.0.2",
"from": "textextensions@1.0.2",
"resolved": "https://registry.npmjs.org/textextensions/-/textextensions-1.0.2.tgz",
"dev": true
},
"uc.micro": { "uc.micro": {
"version": "1.0.3", "version": "1.0.3",
"from": "uc.micro@>=1.0.3 <2.0.0", "from": "uc.micro@https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.3.tgz",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.3.tgz" "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.3.tgz"
}, },
"util-deprecate": {
"version": "1.0.2",
"from": "util-deprecate@1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"dev": true
},
"vscode-extension-telemetry": { "vscode-extension-telemetry": {
"version": "0.0.7", "version": "0.0.8",
"from": "vscode-extension-telemetry@>=0.0.8 <0.0.9", "from": "vscode-extension-telemetry@https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz",
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz" "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz"
}, },
"vscode-nls": { "vscode-nls": {
"version": "2.0.2", "version": "2.0.2",
"from": "vscode-nls@>=2.0.1 <3.0.0", "from": "vscode-nls@https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz" "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz"
}, },
"winreg": { "winreg": {
"version": "1.2.3", "version": "1.2.3",
"from": "winreg@1.2.3", "from": "winreg@https://registry.npmjs.org/winreg/-/winreg-1.2.3.tgz",
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.3.tgz" "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.3.tgz"
} }
} }
+84 -17
View File
@@ -41,7 +41,52 @@
{ {
"language": "markdown", "language": "markdown",
"scopeName": "text.html.markdown", "scopeName": "text.html.markdown",
"path": "./syntaxes/markdown.tmLanguage" "path": "./syntaxes/markdown.tmLanguage",
"embeddedLanguages": {
"meta.embedded.block.html": "html",
"source.js": "javascript",
"source.css": "css",
"meta.embedded.block.frontmatter": "yaml",
"meta.embedded.block.css": "css",
"meta.embedded.block.ini": "ini",
"meta.embedded.block.java": "java",
"meta.embedded.block.lua": "lua",
"meta.embedded.block.makefile": "makefile",
"meta.embedded.block.perl": "perl",
"meta.embedded.block.r": "r",
"meta.embedded.block.ruby": "ruby",
"meta.embedded.block.php": "php",
"meta.embedded.block.sql": "sql",
"meta.embedded.block.vs_net": "vs_net",
"meta.embedded.block.xml": "xml",
"meta.embedded.block.xsl": "xsl",
"meta.embedded.block.yaml": "yaml",
"meta.embedded.block.dosbatch": "dosbatch",
"meta.embedded.block.clojure": "clojure",
"meta.embedded.block.coffee": "coffee",
"meta.embedded.block.c": "c",
"meta.embedded.block.cpp": "cpp",
"meta.embedded.block.diff": "diff",
"meta.embedded.block.dockerfile": "dockerfile",
"meta.embedded.block.go": "go",
"meta.embedded.block.groovy": "groovy",
"meta.embedded.block.jade": "jade",
"meta.embedded.block.javascript": "javascript",
"meta.embedded.block.json": "json",
"meta.embedded.block.less": "less",
"meta.embedded.block.objc": "objc",
"meta.embedded.block.scss": "scss",
"meta.embedded.block.perl6": "perl6",
"meta.embedded.block.powershell": "powershell",
"meta.embedded.block.python": "python",
"meta.embedded.block.rust": "rust",
"meta.embedded.block.scala": "scala",
"meta.embedded.block.shellscript": "shellscript",
"meta.embedded.block.typescript": "typescript",
"meta.embedded.block.typescriptreact": "typescriptreact",
"meta.embedded.block.csharp": "csharp",
"meta.embedded.block.fsharp": "fsharp"
}
} }
], ],
"commands": [ "commands": [
@@ -131,6 +176,10 @@
{ {
"command": "markdown.showPreviewSecuritySelector", "command": "markdown.showPreviewSecuritySelector",
"when": "editorLangId == markdown" "when": "editorLangId == markdown"
},
{
"command": "markdown.showPreviewSecuritySelector",
"when": "resourceScheme == markdown"
} }
] ]
}, },
@@ -162,7 +211,8 @@
"markdown.styles": { "markdown.styles": {
"type": "array", "type": "array",
"default": [], "default": [],
"description": "%markdown.styles.dec%" "description": "%markdown.styles.dec%",
"scope": "resource"
}, },
"markdown.previewFrontMatter": { "markdown.previewFrontMatter": {
"type": "string", "type": "string",
@@ -171,52 +221,62 @@
"show" "show"
], ],
"default": "hide", "default": "hide",
"description": "%markdown.previewFrontMatter.dec%" "description": "%markdown.previewFrontMatter.dec%",
"scope": "resource"
}, },
"markdown.preview.breaks": { "markdown.preview.breaks": {
"type": "boolean", "type": "boolean",
"default": false, "default": false,
"description": "%markdown.preview.breaks.desc%" "description": "%markdown.preview.breaks.desc%",
"scope": "resource"
}, },
"markdown.preview.linkify": { "markdown.preview.linkify": {
"type": "boolean", "type": "boolean",
"default": true, "default": true,
"description": "%markdown.preview.linkify%" "description": "%markdown.preview.linkify%",
"scope": "resource"
}, },
"markdown.preview.fontFamily": { "markdown.preview.fontFamily": {
"type": "string", "type": "string",
"default": "-apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', 'HelveticaNeue-Light', 'Ubuntu', 'Droid Sans', sans-serif", "default": "-apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', 'HelveticaNeue-Light', 'Ubuntu', 'Droid Sans', sans-serif",
"description": "%markdown.preview.fontFamily.desc%" "description": "%markdown.preview.fontFamily.desc%",
"scope": "resource"
}, },
"markdown.preview.fontSize": { "markdown.preview.fontSize": {
"type": "number", "type": "number",
"default": 14, "default": 14,
"description": "%markdown.preview.fontSize.desc%" "description": "%markdown.preview.fontSize.desc%",
"scope": "resource"
}, },
"markdown.preview.lineHeight": { "markdown.preview.lineHeight": {
"type": "number", "type": "number",
"default": 1.6, "default": 1.6,
"description": "%markdown.preview.lineHeight.desc%" "description": "%markdown.preview.lineHeight.desc%",
"scope": "resource"
}, },
"markdown.preview.scrollPreviewWithEditorSelection": { "markdown.preview.scrollPreviewWithEditorSelection": {
"type": "boolean", "type": "boolean",
"default": true, "default": true,
"description": "%markdown.preview.scrollPreviewWithEditorSelection.desc%" "description": "%markdown.preview.scrollPreviewWithEditorSelection.desc%",
"scope": "resource"
}, },
"markdown.preview.markEditorSelection": { "markdown.preview.markEditorSelection": {
"type": "boolean", "type": "boolean",
"default": true, "default": true,
"description": "%markdown.preview.markEditorSelection.desc%" "description": "%markdown.preview.markEditorSelection.desc%",
"scope": "resource"
}, },
"markdown.preview.scrollEditorWithPreview": { "markdown.preview.scrollEditorWithPreview": {
"type": "boolean", "type": "boolean",
"default": true, "default": true,
"description": "%markdown.preview.scrollEditorWithPreview.desc%" "description": "%markdown.preview.scrollEditorWithPreview.desc%",
"scope": "resource"
}, },
"markdown.preview.doubleClickToSwitchToEditor": { "markdown.preview.doubleClickToSwitchToEditor": {
"type": "boolean", "type": "boolean",
"default": true, "default": true,
"description": "%markdown.preview.doubleClickToSwitchToEditor.desc%" "description": "%markdown.preview.doubleClickToSwitchToEditor.desc%",
"scope": "resource"
}, },
"markdown.trace": { "markdown.trace": {
"type": "string", "type": "string",
@@ -225,7 +285,8 @@
"verbose" "verbose"
], ],
"default": "off", "default": "off",
"description": "%markdown.trace.desc%" "description": "%markdown.trace.desc%",
"scope": "window"
} }
} }
}, },
@@ -234,7 +295,13 @@
"editor.wordWrap": "on", "editor.wordWrap": "on",
"editor.quickSuggestions": false "editor.quickSuggestions": false
} }
} },
"jsonValidation": [
{
"fileMatch": "package.json",
"url": "./schemas/package.schema.json"
}
]
}, },
"scripts": { "scripts": {
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:markdown ./tsconfig.json", "vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:markdown ./tsconfig.json",
@@ -242,15 +309,15 @@
}, },
"dependencies": { "dependencies": {
"highlight.js": "9.5.0", "highlight.js": "9.5.0",
"markdown-it": "8.2.2", "markdown-it": "^8.4.0",
"markdown-it-named-headers": "0.0.4", "markdown-it-named-headers": "0.0.4",
"vscode-extension-telemetry": "0.0.8", "vscode-extension-telemetry": "0.0.8",
"vscode-nls": "2.0.2" "vscode-nls": "2.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/highlight.js": "^9.1.9", "@types/highlight.js": "9.1.10",
"@types/markdown-it": "0.0.2", "@types/markdown-it": "0.0.2",
"@types/node": "^7.0.4", "@types/node": "8.0.33",
"gulp-rename": "^1.2.2", "gulp-rename": "^1.2.2",
"gulp-replace": "^0.5.4" "gulp-replace": "^0.5.4"
} }
@@ -0,0 +1,32 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Markdown contributions to package.json",
"type": "object",
"properties": {
"contributes": {
"type": "object",
"properties": {
"markdown.previewStyles": {
"type": "array",
"description": "Contributed CSS files that change the look or layout of the Markdown preview",
"items": {
"type": "string",
"description": "Extension relative path to a css file"
}
},
"markdown.previewScripts": {
"type": "array",
"description": "Contributed scripts that are executed in the Markdown preview",
"items": {
"type": "string",
"description": "Extension relative path to a JavaScript file"
}
},
"markdown.markdownItPlugins": {
"type": "boolean",
"description": "Does this extension contribute a markdown-it plugin?"
}
}
}
}
}

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