Test the vsix, not the build layout (#2156)
The VSCode C# Extension build process follows the VS Code docs and runs tests directly inside of its repo root. This unfortunately gives a false sense of security because bugs can be introduced during VSIX packaging [particularly due to missing content in node_modules or excluded via .vscodeignore]. This change addresses this problem by moving our CI tests to execute the VSIX instead of the build's intermediate artifacts. Specifically: build the vsix unpackage the vsix instrument the unpackaged vsix run tests with VS Code Host pointing to the unpackaged vsix This makes our CI tests ~= to the user's runtime experience and will greatly help us with size reduction efforts. To support this change, I also moved our build system from package.json to Gulp. This makes the build scripts significantly easier to understand, provides intellisense for build scripts, and build-time type checking for their contents. I also strengthened the repo's use of .vscodeignore by creating a copy of the file for each scenario [online packages and offline packages]. The new gulp packaging scripts take advantage of these files to produce packages with predictable contents regardless of when packaging occurs. [small caveat, @akshita31 will be adding a test that validates that net-new content does not start sneaking into the vsix package].
This commit is contained in:
Родитель
4001e8eb14
Коммит
ed60379138
|
@ -17,4 +17,7 @@ test/**/.vscode
|
|||
.nyc_output/
|
||||
coverage/
|
||||
|
||||
\.DS_Store
|
||||
\.DS_Store
|
||||
vsix/
|
||||
|
||||
\.vscodeignore
|
||||
|
|
12
.travis.yml
12
.travis.yml
|
@ -26,14 +26,14 @@ addons:
|
|||
|
||||
install:
|
||||
- npm install
|
||||
- npm run compile
|
||||
- npm install -g vsce
|
||||
- vsce package
|
||||
- npm i -g gulp
|
||||
- gulp 'vsix:release:package'
|
||||
|
||||
script:
|
||||
- npm run cov:instrument
|
||||
- npm test --silent
|
||||
- npm run cov:report
|
||||
- gulp 'vsix:release:unpackage'
|
||||
- gulp cov:instrument --codeExtensionPath ./vsix/extension
|
||||
- gulp test --codeExtensionPath ./vsix/extension
|
||||
- gulp cov:report --codeExtensionPath ./vsix/extension
|
||||
- npm run test:artifacts
|
||||
- 'if [[ "$TRAVIS_TAG" != "master" && "$TRAVIS_PULL_REQUEST" = "false" ]]; then npm run test:release; fi'
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
"--extensionTestsPath=${workspaceRoot}/out/test/featureTests"
|
||||
],
|
||||
"env": {
|
||||
"CODE_WORKSPACE_ROOT": "${workspaceRoot}",
|
||||
"CODE_TESTS_PATH": "${workspaceRoot}/out/test/featureTests",
|
||||
"CODE_EXTENSIONS_PATH": "${workspaceRoot}",
|
||||
"OSVC_SUITE": "featureTests"
|
||||
|
@ -46,6 +47,7 @@
|
|||
"--extensionTestsPath=${workspaceRoot}/out/test/integrationTests"
|
||||
],
|
||||
"env": {
|
||||
"CODE_WORKSPACE_ROOT": "${workspaceRoot}",
|
||||
"CODE_TESTS_PATH": "${workspaceRoot}/out/test/integrationTests",
|
||||
"CODE_TESTS_WORKSPACE": "${workspaceRoot}/test/integrationTests/testAssets/singleCsproj",
|
||||
"CODE_EXTENSIONS_PATH": "${workspaceRoot}",
|
||||
|
@ -68,6 +70,7 @@
|
|||
"--extensionTestsPath=${workspaceRoot}/out/test/integrationTests"
|
||||
],
|
||||
"env": {
|
||||
"CODE_WORKSPACE_ROOT": "${workspaceRoot}",
|
||||
"CODE_TESTS_PATH": "${workspaceRoot}/out/test/integrationTests",
|
||||
"CODE_TESTS_WORKSPACE": "${workspaceRoot}/test/integrationTests/testAssets/slnWithCsproj",
|
||||
"CODE_EXTENSIONS_PATH": "${workspaceRoot}",
|
||||
|
|
|
@ -4,16 +4,18 @@
|
|||
|
||||
"files.exclude": {
|
||||
"out": true,
|
||||
"typings": false
|
||||
"typings": false,
|
||||
"vsix": true
|
||||
},
|
||||
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
"out/": true
|
||||
"out/": true,
|
||||
"vsix/": true
|
||||
},
|
||||
|
||||
"csharp.suppressDotnetRestoreNotification": true,
|
||||
|
||||
|
||||
"tslint.rulesDirectory": "node_modules/tslint-microsoft-contrib",
|
||||
"typescript.tsdk": "./node_modules/typescript/lib",
|
||||
"mocha.enabled": true
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
.vscode/**
|
||||
typings/**
|
||||
out/test/**
|
||||
test/**
|
||||
src/**
|
||||
**/*.map
|
||||
|
||||
.gitignore
|
||||
.travis.yml
|
||||
tsconfig.json
|
||||
ISSUE_TEMPLATE
|
||||
tslint.json
|
||||
gulpfile.js
|
||||
|
||||
**/.nyc_output/**
|
||||
**/coverage/**
|
||||
|
||||
+RuntimeLicenses/dependencies/*
|
||||
coreclr-debug/install.log
|
184
gulpfile.ts
184
gulpfile.ts
|
@ -5,43 +5,17 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
import * as child_process from 'child_process';
|
||||
import * as debugUtil from './src/coreclr-debug/util';
|
||||
import * as del from 'del';
|
||||
import * as fs from 'fs';
|
||||
import * as gulp from 'gulp';
|
||||
import * as logger from './src/logger';
|
||||
import * as mocha from 'gulp-mocha';
|
||||
import * as optionsSchemaGenerator from './src/tools/GenerateOptionsSchema';
|
||||
import * as packageDependencyUpdater from './src/tools/UpdatePackageDependencies';
|
||||
import * as packages from './src/packages';
|
||||
import * as path from 'path';
|
||||
import * as platform from './src/platform';
|
||||
import * as util from './src/common';
|
||||
import * as vsce from 'vsce';
|
||||
|
||||
import { CsharpLoggerObserver } from './src/observers/CsharpLoggerObserver';
|
||||
import { EventStream } from './src/EventStream';
|
||||
import tslint from 'gulp-tslint';
|
||||
|
||||
const Logger = logger.Logger;
|
||||
const PackageManager = packages.PackageManager;
|
||||
const LinuxDistribution = platform.LinuxDistribution;
|
||||
const PlatformInformation = platform.PlatformInformation;
|
||||
|
||||
function cleanSync(deleteVsix) {
|
||||
del.sync('install.*');
|
||||
del.sync('.omnisharp*');
|
||||
del.sync('.debugger');
|
||||
|
||||
if (deleteVsix) {
|
||||
del.sync('*.vsix');
|
||||
}
|
||||
}
|
||||
|
||||
gulp.task('clean', () => {
|
||||
cleanSync(true);
|
||||
});
|
||||
require('./tasks/testTasks');
|
||||
require('./tasks/onlinePackagingTasks');
|
||||
require('./tasks/offlinePackagingTasks');
|
||||
require('./tasks/backcompatTasks');
|
||||
require('./tasks/coverageTasks');
|
||||
|
||||
gulp.task('generateOptionsSchema', () => {
|
||||
optionsSchemaGenerator.GenerateOptionsSchema();
|
||||
|
@ -51,141 +25,12 @@ gulp.task('updatePackageDependencies', () => {
|
|||
packageDependencyUpdater.updatePackageDependencies();
|
||||
});
|
||||
|
||||
// Install Tasks
|
||||
function install(platformInfo, packageJSON) {
|
||||
const packageManager = new PackageManager(platformInfo, packageJSON);
|
||||
let eventStream = new EventStream();
|
||||
const logger = new Logger(message => process.stdout.write(message));
|
||||
let stdoutObserver = new CsharpLoggerObserver(logger);
|
||||
eventStream.subscribe(stdoutObserver.post);
|
||||
const debuggerUtil = new debugUtil.CoreClrDebugUtil(path.resolve('.'));
|
||||
|
||||
return packageManager.DownloadPackages(eventStream, undefined, undefined, undefined)
|
||||
.then(() => {
|
||||
return packageManager.InstallPackages(eventStream, undefined);
|
||||
})
|
||||
.then(() => {
|
||||
return util.touchInstallFile(util.InstallFileType.Lock);
|
||||
})
|
||||
.then(() => {
|
||||
return debugUtil.CoreClrDebugUtil.writeEmptyFile(debuggerUtil.installCompleteFilePath());
|
||||
});
|
||||
}
|
||||
|
||||
gulp.task('install', ['clean'], () => {
|
||||
util.setExtensionPath(__dirname);
|
||||
|
||||
return PlatformInformation.GetCurrent()
|
||||
.then(platformInfo => {
|
||||
return install(platformInfo, getPackageJSON());
|
||||
});
|
||||
});
|
||||
|
||||
/// Packaging (VSIX) Tasks
|
||||
function doPackageSync(packageName, outputFolder) {
|
||||
|
||||
let vsceArgs = [];
|
||||
vsceArgs.push(path.join(__dirname, 'node_modules', 'vsce', 'out', 'vsce'));
|
||||
vsceArgs.push('package'); // package command
|
||||
|
||||
if (packageName !== undefined) {
|
||||
vsceArgs.push('-o');
|
||||
if (outputFolder) {
|
||||
//if we have specified an output folder then put the files in that output folder
|
||||
vsceArgs.push(path.join(outputFolder, packageName));
|
||||
}
|
||||
else {
|
||||
vsceArgs.push(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
let proc = child_process.spawnSync('node', vsceArgs);
|
||||
if (proc.error) {
|
||||
console.error(proc.error.toString());
|
||||
}
|
||||
}
|
||||
|
||||
function doOfflinePackage(platformInfo, packageName, packageJSON, outputFolder) {
|
||||
if (process.platform === 'win32') {
|
||||
throw new Error('Do not build offline packages on windows. Runtime executables will not be marked executable in *nix packages.');
|
||||
}
|
||||
|
||||
cleanSync(false);
|
||||
return install(platformInfo, packageJSON)
|
||||
.then(() => {
|
||||
doPackageSync(packageName + '-' + platformInfo.platform + '-' + platformInfo.architecture + '.vsix', outputFolder);
|
||||
});
|
||||
}
|
||||
|
||||
function getPackageJSON() {
|
||||
return JSON.parse(fs.readFileSync('package.json').toString());
|
||||
}
|
||||
|
||||
gulp.task('package:clean', () => {
|
||||
del.sync('*.vsix');
|
||||
});
|
||||
|
||||
gulp.task('package:online', ['clean'], () => {
|
||||
doPackageSync(undefined, undefined);
|
||||
});
|
||||
|
||||
gulp.task('package:offline', () => {
|
||||
util.setExtensionPath(__dirname);
|
||||
|
||||
let argv = require('minimist')(process.argv.slice(2), { boolean: ['retainVsix'] });
|
||||
if (argv['retainVsix']) {
|
||||
//if user doesnot want to clean up the existing vsix packages
|
||||
cleanSync(false);
|
||||
}
|
||||
else {
|
||||
cleanSync(true);
|
||||
}
|
||||
|
||||
let outputFolder;
|
||||
if (argv['o']) {
|
||||
outputFolder = argv['o'];
|
||||
}
|
||||
|
||||
const packageJSON = getPackageJSON();
|
||||
const name = packageJSON.name;
|
||||
const version = packageJSON.version;
|
||||
const packageName = name + '.' + version;
|
||||
|
||||
const packages = [];
|
||||
packages.push(new PlatformInformation('win32', 'x86_64'));
|
||||
packages.push(new PlatformInformation('darwin', 'x86_64'));
|
||||
packages.push(new PlatformInformation('linux', 'x86_64'));
|
||||
|
||||
let promise = Promise.resolve();
|
||||
|
||||
packages.forEach(platformInfo => {
|
||||
promise = promise
|
||||
.then(() => {
|
||||
return doOfflinePackage(platformInfo, packageName, packageJSON, outputFolder);
|
||||
});
|
||||
});
|
||||
|
||||
return promise;
|
||||
});
|
||||
|
||||
/// Misc Tasks
|
||||
const allTypeScript = [
|
||||
'src/**/*.ts',
|
||||
'!**/*.d.ts',
|
||||
'!**/typings**'
|
||||
];
|
||||
|
||||
const lintReporter = (output, file, options) => {
|
||||
//emits: src/helloWorld.c:5:3: warning: implicit declaration of function ‘prinft’
|
||||
let relativeBase = file.base.substring(file.cwd.length + 1).replace('\\', '/');
|
||||
output.forEach(e => {
|
||||
let message = relativeBase + e.name + ':' + (e.startPosition.line + 1) + ':' + (e.startPosition.character + 1) + ': ' + e.failure;
|
||||
console.log('[tslint] ' + message);
|
||||
});
|
||||
};
|
||||
|
||||
gulp.task('tslint', () => {
|
||||
gulp.src(allTypeScript)
|
||||
gulp.src([
|
||||
'src/**/*.ts',
|
||||
'!**/*.d.ts',
|
||||
'!**/typings**'
|
||||
])
|
||||
.pipe(tslint({
|
||||
program: require('tslint').Linter.createProgram("./tsconfig.json"),
|
||||
configuration: "./tslint.json"
|
||||
|
@ -195,3 +40,12 @@ gulp.task('tslint', () => {
|
|||
emitError: false
|
||||
}));
|
||||
});
|
||||
|
||||
const lintReporter = (output, file, options) => {
|
||||
//emits: src/helloWorld.c:5:3: warning: implicit declaration of function ‘prinft’
|
||||
let relativeBase = file.base.substring(file.cwd.length + 1).replace('\\', '/');
|
||||
output.forEach(e => {
|
||||
let message = relativeBase + e.name + ':' + (e.startPosition.line + 1) + ':' + (e.startPosition.character + 1) + ': ' + e.failure;
|
||||
console.log('[tslint] ' + message);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
!.debugger/**
|
||||
.logs/**
|
||||
.nyc_output/**
|
||||
!.omnisharp/**
|
||||
.rpt2_cache/**
|
||||
.travis/**
|
||||
.vscode/**
|
||||
.vscode-test/**
|
||||
coverage/**
|
||||
out/test/**
|
||||
src/**
|
||||
tasks/**
|
||||
test/**
|
||||
typings/**
|
||||
vsix/**
|
||||
|
||||
**/*.map
|
||||
*.vsix
|
||||
|
||||
.editorconfig
|
||||
.gitignore
|
||||
.travis.yml
|
||||
gulpfile.ts
|
||||
!install.Lock
|
||||
ISSUE_TEMPLATE
|
||||
mocha.opts
|
||||
*.vscodeignore
|
||||
package-lock.json
|
||||
package.json
|
||||
test-plan.md
|
||||
tsconfig.json
|
||||
tslint.json
|
||||
wallaby.js
|
||||
|
||||
|
||||
+RuntimeLicenses/dependencies/*
|
||||
coreclr-debug/install.log
|
|
@ -75,6 +75,12 @@
|
|||
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=",
|
||||
"dev": true
|
||||
},
|
||||
"@types/mkdirp": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz",
|
||||
|
@ -600,6 +606,16 @@
|
|||
"integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=",
|
||||
"dev": true
|
||||
},
|
||||
"binary": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
|
||||
"integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffers": "0.1.1",
|
||||
"chainsaw": "0.1.0"
|
||||
}
|
||||
},
|
||||
"bit-mask": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/bit-mask/-/bit-mask-1.0.1.tgz",
|
||||
|
@ -665,6 +681,12 @@
|
|||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
|
||||
},
|
||||
"buffers": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
|
||||
"integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=",
|
||||
"dev": true
|
||||
},
|
||||
"builtin-modules": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
|
||||
|
@ -745,6 +767,15 @@
|
|||
"integrity": "sha1-NZFAwFHTak5LGl/GuRAVL0OKjUk=",
|
||||
"dev": true
|
||||
},
|
||||
"chainsaw": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
|
||||
"integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"traverse": "0.3.9"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
|
@ -2513,6 +2544,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"gulp-sequence": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gulp-sequence/-/gulp-sequence-1.0.0.tgz",
|
||||
"integrity": "sha512-c+p+EcyBl1UCpbfFA/vUD6MuC7uxoY6Y4g2lq9lLtzOHh9o1wijAQ4o0TIRQ14C7cG6zR6Zi+bpA0cW78CFt6g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"thunks": "4.9.2"
|
||||
}
|
||||
},
|
||||
"gulp-sourcemaps": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz",
|
||||
|
@ -4384,6 +4424,30 @@
|
|||
"uc.micro": "1.0.5"
|
||||
}
|
||||
},
|
||||
"match-stream": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/match-stream/-/match-stream-0.0.2.tgz",
|
||||
"integrity": "sha1-mesFAJOzTf+t5CG5rAtBCpz6F88=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffers": "0.1.1",
|
||||
"readable-stream": "1.0.34"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "0.10.31"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mdurl": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||
|
@ -7720,6 +7784,12 @@
|
|||
"os-tmpdir": "1.0.2"
|
||||
}
|
||||
},
|
||||
"over": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/over/-/over-0.0.5.tgz",
|
||||
"integrity": "sha1-8phS5w/X4l82DgE6jsRMgq7bVwg=",
|
||||
"dev": true
|
||||
},
|
||||
"p-finally": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
||||
|
@ -8003,6 +8073,32 @@
|
|||
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
|
||||
"dev": true
|
||||
},
|
||||
"pullstream": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/pullstream/-/pullstream-0.4.1.tgz",
|
||||
"integrity": "sha1-1vs79a7Wl+gxFQ6xACwlo/iuExQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"over": "0.0.5",
|
||||
"readable-stream": "1.0.34",
|
||||
"setimmediate": "1.0.5",
|
||||
"slice-stream": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "0.10.31"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
|
@ -8569,6 +8665,12 @@
|
|||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"dev": true
|
||||
},
|
||||
"setimmediate": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
|
||||
"dev": true
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
|
||||
|
@ -8625,6 +8727,29 @@
|
|||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"dev": true
|
||||
},
|
||||
"slice-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slice-stream/-/slice-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-WzO9ZvATsaf4ZGCwPUY97DmtPqA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "1.0.34"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "0.10.31"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sntp": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
|
||||
|
@ -8955,6 +9080,12 @@
|
|||
"xtend": "4.0.1"
|
||||
}
|
||||
},
|
||||
"thunks": {
|
||||
"version": "4.9.2",
|
||||
"resolved": "https://registry.npmjs.org/thunks/-/thunks-4.9.2.tgz",
|
||||
"integrity": "sha1-qsLTU4ElEhYKRhHjAI16luN1b44=",
|
||||
"dev": true
|
||||
},
|
||||
"tildify": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz",
|
||||
|
@ -9007,6 +9138,12 @@
|
|||
"punycode": "1.4.1"
|
||||
}
|
||||
},
|
||||
"traverse": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
|
||||
"integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=",
|
||||
"dev": true
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-5.0.1.tgz",
|
||||
|
@ -9317,6 +9454,55 @@
|
|||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
|
||||
"integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc="
|
||||
},
|
||||
"unzip2": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/unzip2/-/unzip2-0.2.5.tgz",
|
||||
"integrity": "sha1-TveleaeMFcUfVQ9qBT2xlBSciZI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"binary": "0.3.0",
|
||||
"fstream": "0.1.31",
|
||||
"match-stream": "0.0.2",
|
||||
"pullstream": "0.4.1",
|
||||
"readable-stream": "1.0.34",
|
||||
"setimmediate": "1.0.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"fstream": {
|
||||
"version": "0.1.31",
|
||||
"resolved": "https://registry.npmjs.org/fstream/-/fstream-0.1.31.tgz",
|
||||
"integrity": "sha1-czfwWPu7vvqMn1YaKMqwhJICyYg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "3.0.11",
|
||||
"inherits": "2.0.3",
|
||||
"mkdirp": "0.5.1",
|
||||
"rimraf": "2.6.2"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "3.0.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz",
|
||||
"integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"natives": "1.1.1"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "0.10.31"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"url-join": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz",
|
||||
|
|
29
package.json
29
package.json
|
@ -30,23 +30,23 @@
|
|||
"compile": "tsc -p ./ && gulp tslint",
|
||||
"watch": "tsc -watch -p ./",
|
||||
"tdd": "mocha --opts ./mocha.opts --watch --watch-extensions ts test/unitTests/**/*.test.ts*",
|
||||
"test": "npm-run-all test:feature test:unit test:integration",
|
||||
"test:unit": "nyc -r lcovonly --report-dir coverage/unit mocha --ui tdd -- test/unitTests/**/*.test.ts",
|
||||
"test:feature": "cross-env OSVC_SUITE=featureTests CODE_EXTENSIONS_PATH=./ CODE_TESTS_PATH=./out/test/featureTests npm run test:runInVsCode",
|
||||
"test:integration": "npm-run-all test:integration:*",
|
||||
"test:integration:singleCsproj": "cross-env OSVC_SUITE=singleCsproj npm run test:runSuiteInVsCode",
|
||||
"test:integration:slnWithCsproj": "cross-env OSVC_SUITE=slnWithCsproj npm run test:runSuiteInVsCode",
|
||||
"test:runSuiteInVsCode": "cross-env CODE_EXTENSIONS_PATH=./ CODE_TESTS_PATH=./out/test/integrationTests CODE_TESTS_WORKSPACE=./test/integrationTests/testAssets/$OSVC_SUITE npm run test:runInVsCode",
|
||||
"test:runInVsCode": "node ./test/runVsCodeTestsWithAbsolutePaths.js",
|
||||
"test": "gulp test",
|
||||
"test:unit": "gulp test:unit",
|
||||
"test:feature": "gulp test:feature",
|
||||
"test:integration": "gulp test:integration",
|
||||
"test:integration:singleCsproj": "gulp test:integration:singleCsproj",
|
||||
"test:integration:slnWithCsproj": "gulp test:integration:slnWithCsproj",
|
||||
"test:release": "mocha --opts ./mocha.opts test/releaseTests/**/*.test.ts",
|
||||
"test:artifacts": "mocha --opts ./mocha.opts test/artifactTests/**/*.test.ts",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install",
|
||||
"cov:instrument": "rimraf ./coverage && rimraf ./.nyc_output && rimraf ./out && npm run compile && cd out && nyc instrument --require source-map-support/register --cwd ../ . . && cd ..",
|
||||
"cov:merge": "cd ./out && istanbul-combine -d ../coverage/integration -r lcovonly ../.nyc_output/integration/*.json && cd ..",
|
||||
"cov:merge-html": "istanbul-combine -d ./coverage -r html ./.nyc_output/integration/*.json",
|
||||
"cov:instrument": "gulp cov:instrument",
|
||||
"cov:merge": "gulp cov:merge",
|
||||
"cov:merge-html": "gulp cov:merge-html",
|
||||
"cov:report": "npm-run-all cov:report:integration cov:report:unit",
|
||||
"cov:report:unit": "codecov -f \"coverage/unit/lcov.info\" -F unit",
|
||||
"cov:report:integration": "npm run cov:merge && codecov -f \"coverage/integration/lcov.info\" -F integration"
|
||||
"cov:report:unit": "gulp cov:report:unit",
|
||||
"cov:report:integration": "gulp cov:report:integration",
|
||||
"unpackage:vsix": "gulp vsix:release:unpackage",
|
||||
"gulp": "gulp"
|
||||
},
|
||||
"nyc": {
|
||||
"include": [
|
||||
|
@ -86,6 +86,7 @@
|
|||
"@types/chai-as-promised": "^7.1.0",
|
||||
"@types/chai-string": "^1.4.0",
|
||||
"@types/fs-extra": "^5.0.1",
|
||||
"@types/minimist": "^1.2.0",
|
||||
"@types/mkdirp": "^0.5.2",
|
||||
"@types/mocha": "^2.2.48",
|
||||
"@types/node": "^9.4.7",
|
||||
|
@ -107,6 +108,7 @@
|
|||
"glob-promise": "^3.4.0",
|
||||
"gulp": "3.9.1",
|
||||
"gulp-mocha": "^5.0.0",
|
||||
"gulp-sequence": "^1.0.0",
|
||||
"gulp-tslint": "^8.1.3",
|
||||
"istanbul": "^0.4.5",
|
||||
"istanbul-combine": "^0.3.0",
|
||||
|
@ -124,6 +126,7 @@
|
|||
"tslint-microsoft-contrib": "^5.0.3",
|
||||
"tslint-no-unused-expression-chai": "^0.1.3",
|
||||
"typescript": "^2.7.2",
|
||||
"unzip2": "^0.2.5",
|
||||
"vsce": "^1.37.6",
|
||||
"vscode": "^1.1.14"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
.debugger/**
|
||||
.logs/**
|
||||
.nyc_output/**
|
||||
.omnisharp/**
|
||||
.rpt2_cache/**
|
||||
.travis/**
|
||||
.vscode/**
|
||||
.vscode-test/**
|
||||
coverage/**
|
||||
out/test/**
|
||||
src/**
|
||||
tasks/**
|
||||
test/**
|
||||
typings/**
|
||||
vsix/**
|
||||
|
||||
**/*.map
|
||||
*.vsix
|
||||
|
||||
.editorconfig
|
||||
.gitignore
|
||||
.travis.yml
|
||||
gulpfile.ts
|
||||
install.Lock
|
||||
ISSUE_TEMPLATE
|
||||
mocha.opts
|
||||
*.vscodeignore
|
||||
package-lock.json
|
||||
package.json
|
||||
test-plan.md
|
||||
tsconfig.json
|
||||
tslint.json
|
||||
wallaby.js
|
||||
|
||||
|
||||
+RuntimeLicenses/dependencies/*
|
||||
coreclr-debug/install.log
|
|
@ -107,7 +107,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<{ init
|
|||
}
|
||||
|
||||
return {
|
||||
initializationFinished: Promise.all([omniSharpPromise, coreClrDebugPromise])
|
||||
initializationFinished: Promise.all([omniSharpPromise.then(o => o.waitForEmptyEventQueue()), coreClrDebugPromise])
|
||||
.then(promiseResult => {
|
||||
// This promise resolver simply swallows the result of Promise.all. When we decide we want to expose this level of detail
|
||||
// to other extensions then we will design that return type and implement it here.
|
||||
|
|
|
@ -159,5 +159,5 @@ export function activate(context: vscode.ExtensionContext, eventStream: EventStr
|
|||
|
||||
context.subscriptions.push(...disposables);
|
||||
|
||||
return new Promise<string>(resolve => server.onServerStart(e => resolve(e)));
|
||||
return new Promise<OmniSharpServer>(resolve => server.onServerStart(e => resolve(server)));
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as gulp from 'gulp';
|
||||
|
||||
gulp.task('package:offline', ['vsix:offline:package']);
|
|
@ -0,0 +1,31 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as minimist from 'minimist';
|
||||
import * as path from 'path';
|
||||
|
||||
let argv = minimist(process.argv.slice(2), {
|
||||
boolean: ['retainVsix']
|
||||
});
|
||||
|
||||
export const commandLineOptions ={
|
||||
retainVsix: !!argv['retainVsix'],
|
||||
outputFolder: makePathAbsolute(argv['o']),
|
||||
codeExtensionPath: makePathAbsolute(argv['codeExtensionPath'])
|
||||
};
|
||||
|
||||
function makePathAbsolute(originalPath: string) {
|
||||
if (!originalPath || originalPath == '') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (path.isAbsolute(originalPath)) {
|
||||
return originalPath;
|
||||
}
|
||||
|
||||
return path.resolve(originalPath);
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as gulp from 'gulp';
|
||||
import * as path from 'path';
|
||||
import * as del from 'del';
|
||||
import spawnNode from './spawnNode';
|
||||
import { coverageRootPath, nycOutputPath, nycPath, codeExtensionSourcesPath, integrationTestCoverageRootPath, integrationTestNycOutputPath, istanbulCombinePath, codecovPath, unitTestCoverageRootPath } from './projectPaths';
|
||||
|
||||
gulp.task("cov:instrument", () => {
|
||||
del(coverageRootPath);
|
||||
del(nycOutputPath);
|
||||
|
||||
return spawnNode([
|
||||
nycPath,
|
||||
'instrument',
|
||||
'--require',
|
||||
'source-map-support/register',
|
||||
'.',
|
||||
'.'
|
||||
], {
|
||||
cwd: codeExtensionSourcesPath
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task("cov:merge", () => {
|
||||
return spawnNode([
|
||||
istanbulCombinePath,
|
||||
'-d',
|
||||
integrationTestCoverageRootPath,
|
||||
'-r',
|
||||
'lcovonly',
|
||||
`${integrationTestNycOutputPath}/*.json`
|
||||
], {
|
||||
cwd: codeExtensionSourcesPath
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task("cov:merge-html", () => {
|
||||
return spawnNode([
|
||||
istanbulCombinePath,
|
||||
'-d',
|
||||
integrationTestCoverageRootPath,
|
||||
'-r',
|
||||
'html',
|
||||
`${integrationTestNycOutputPath}/*.json`
|
||||
], {
|
||||
cwd: codeExtensionSourcesPath
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task("cov:report", ["cov:report:integration", "cov:report:unit"]);
|
||||
|
||||
gulp.task("cov:report:integration", ["cov:merge"], () => {
|
||||
return spawnNode([
|
||||
codecovPath,
|
||||
'-f',
|
||||
path.join(integrationTestCoverageRootPath, 'lcov.info'),
|
||||
'-F',
|
||||
'integration'
|
||||
], {
|
||||
cwd: codeExtensionSourcesPath
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task("cov:report:unit", () => {
|
||||
return spawnNode([
|
||||
codecovPath,
|
||||
'-f',
|
||||
path.join(unitTestCoverageRootPath, 'lcov.info'),
|
||||
'-F',
|
||||
'unit'
|
||||
], {
|
||||
cwd: codeExtensionSourcesPath
|
||||
});
|
||||
});
|
|
@ -0,0 +1,133 @@
|
|||
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as debugUtil from '../src/coreclr-debug/util';
|
||||
import * as del from 'del';
|
||||
import * as fs from 'fs';
|
||||
import * as gulp from 'gulp';
|
||||
import * as path from 'path';
|
||||
import * as unzip from 'unzip2';
|
||||
import * as util from '../src/common';
|
||||
import spawnNode from '../tasks/spawnNode';
|
||||
import { codeExtensionPath, offlineVscodeignorePath, vscodeignorePath, vscePath, packedVsixOutputRoot } from '../tasks/projectPaths';
|
||||
import { commandLineOptions } from '../tasks/commandLineArguments';
|
||||
import { CsharpLoggerObserver } from '../src/observers/CsharpLoggerObserver';
|
||||
import { EventStream } from '../src/EventStream';
|
||||
import { getPackageJSON } from '../tasks/packageJson';
|
||||
import { Logger } from '../src/logger';
|
||||
import { PackageManager } from '../src/packages';
|
||||
import { PlatformInformation } from '../src/platform';
|
||||
|
||||
gulp.task('vsix:offline:package', () => {
|
||||
del.sync(vscodeignorePath);
|
||||
|
||||
fs.copyFileSync(offlineVscodeignorePath, vscodeignorePath);
|
||||
|
||||
return doPackageOffline()
|
||||
.then(v => del(vscodeignorePath),
|
||||
e => {
|
||||
del(vscodeignorePath);
|
||||
throw e;
|
||||
});
|
||||
});
|
||||
|
||||
function doPackageOffline() {
|
||||
util.setExtensionPath(codeExtensionPath);
|
||||
|
||||
if (commandLineOptions.retainVsix) {
|
||||
//if user doesnot want to clean up the existing vsix packages
|
||||
cleanSync(false);
|
||||
}
|
||||
else {
|
||||
cleanSync(true);
|
||||
}
|
||||
|
||||
const packageJSON = getPackageJSON();
|
||||
const name = packageJSON.name;
|
||||
const version = packageJSON.version;
|
||||
const packageName = name + '.' + version;
|
||||
|
||||
const packages = [
|
||||
new PlatformInformation('win32', 'x86_64'),
|
||||
new PlatformInformation('darwin', 'x86_64'),
|
||||
new PlatformInformation('linux', 'x86_64')
|
||||
];
|
||||
|
||||
let promise = Promise.resolve();
|
||||
|
||||
packages.forEach(platformInfo => {
|
||||
promise = promise
|
||||
.then(() => doOfflinePackage(platformInfo, packageName, packageJSON, packedVsixOutputRoot));
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
function cleanSync(deleteVsix) {
|
||||
del.sync('install.*');
|
||||
del.sync('.omnisharp*');
|
||||
del.sync('.debugger');
|
||||
|
||||
if (deleteVsix) {
|
||||
del.sync('*.vsix');
|
||||
}
|
||||
}
|
||||
|
||||
function doOfflinePackage(platformInfo, packageName, packageJSON, outputFolder) {
|
||||
if (process.platform === 'win32') {
|
||||
throw new Error('Do not build offline packages on windows. Runtime executables will not be marked executable in *nix packages.');
|
||||
}
|
||||
|
||||
cleanSync(false);
|
||||
|
||||
return install(platformInfo, packageJSON)
|
||||
.then(() => doPackageSync(packageName + '-' + platformInfo.platform + '-' + platformInfo.architecture + '.vsix', outputFolder));
|
||||
}
|
||||
|
||||
// Install Tasks
|
||||
function install(platformInfo, packageJSON) {
|
||||
const packageManager = new PackageManager(platformInfo, packageJSON);
|
||||
let eventStream = new EventStream();
|
||||
const logger = new Logger(message => process.stdout.write(message));
|
||||
let stdoutObserver = new CsharpLoggerObserver(logger);
|
||||
eventStream.subscribe(stdoutObserver.post);
|
||||
const debuggerUtil = new debugUtil.CoreClrDebugUtil(path.resolve('.'));
|
||||
|
||||
return packageManager.DownloadPackages(eventStream, undefined, undefined, undefined)
|
||||
.then(() => {
|
||||
return packageManager.InstallPackages(eventStream, undefined);
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
return util.touchInstallFile(util.InstallFileType.Lock);
|
||||
})
|
||||
.then(() => {
|
||||
return debugUtil.CoreClrDebugUtil.writeEmptyFile(debuggerUtil.installCompleteFilePath());
|
||||
});
|
||||
}
|
||||
|
||||
/// Packaging (VSIX) Tasks
|
||||
function doPackageSync(packageName, outputFolder) {
|
||||
|
||||
let vsceArgs = [];
|
||||
vsceArgs.push(vscePath);
|
||||
vsceArgs.push('package'); // package command
|
||||
|
||||
if (packageName !== undefined) {
|
||||
vsceArgs.push('-o');
|
||||
if (outputFolder) {
|
||||
//if we have specified an output folder then put the files in that output folder
|
||||
vsceArgs.push(path.join(outputFolder, packageName));
|
||||
}
|
||||
else {
|
||||
vsceArgs.push(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
return spawnNode(vsceArgs);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as debugUtil from '../src/coreclr-debug/util';
|
||||
import * as del from 'del';
|
||||
import * as fs from 'fs';
|
||||
import * as gulp from 'gulp';
|
||||
import * as path from 'path';
|
||||
import * as unzip from 'unzip2';
|
||||
import * as util from '../src/common';
|
||||
import { offlineVscodeignorePath, onlineVscodeignorePath, rootPath, unpackedVsixPath, vscePath, vscodeignorePath } from './projectPaths';
|
||||
import { CsharpLoggerObserver } from '../src/observers/CsharpLoggerObserver';
|
||||
import { EventStream } from '../src/EventStream';
|
||||
import { Logger } from '../src/logger';
|
||||
import { PackageManager } from '../src/packages';
|
||||
import { PlatformInformation } from '../src/platform';
|
||||
import { getPackageJSON } from './packageJson';
|
||||
import spawnNode from './spawnNode';
|
||||
|
||||
gulp.task('vsix:release:unpackage', () => {
|
||||
const packageJSON = getPackageJSON();
|
||||
const name = packageJSON.name;
|
||||
const version = packageJSON.version;
|
||||
const packageName = `${name}-${version}.vsix`;
|
||||
const packagePath = path.join(rootPath, packageName);
|
||||
|
||||
del.sync(unpackedVsixPath);
|
||||
fs.createReadStream(packageName).pipe(unzip.Extract({ path: unpackedVsixPath }));
|
||||
});
|
||||
|
||||
gulp.task('vsix:release:package', (onError) => {
|
||||
del.sync(vscodeignorePath);
|
||||
|
||||
fs.copyFileSync(onlineVscodeignorePath, vscodeignorePath);
|
||||
|
||||
let onDone = (reason) => {
|
||||
|
||||
onError(reason);
|
||||
};
|
||||
|
||||
return spawnNode([vscePath, 'package'])
|
||||
.then(() => {
|
||||
del(vscodeignorePath);
|
||||
}, (error) => {
|
||||
del(vscodeignorePath);
|
||||
throw error;
|
||||
});
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as fs from 'fs';
|
||||
|
||||
export function getPackageJSON() {
|
||||
return JSON.parse(fs.readFileSync('package.json').toString());
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as gulp from 'gulp';
|
||||
import * as path from 'path';
|
||||
import { execFile, spawn } from 'child_process';
|
||||
import { commandLineOptions } from './commandLineArguments';
|
||||
|
||||
export const rootPath = path.resolve(__dirname, '..');
|
||||
|
||||
export const vscodeignorePath = path.join(rootPath, '.vscodeignore');
|
||||
export const offlineVscodeignorePath = path.join(rootPath, 'offline.vscodeignore');
|
||||
export const onlineVscodeignorePath = path.join(rootPath, 'release.vscodeignore');
|
||||
|
||||
export const nodeModulesPath = path.join(rootPath, 'node_modules');
|
||||
export const vscePath = path.join(nodeModulesPath, 'vsce', 'out', 'vsce');
|
||||
export const nycPath = path.join(nodeModulesPath, 'nyc', 'bin', 'nyc.js');
|
||||
export const mochaPath = path.join(nodeModulesPath, 'mocha', 'bin', 'mocha');
|
||||
export const istanbulCombinePath = path.join(nodeModulesPath, 'istanbul-combine', 'cli.js');
|
||||
export const codecovPath = path.join(nodeModulesPath, 'codecov', 'bin', 'codecov');
|
||||
export const vscodeTestHostPath = path.join(nodeModulesPath, 'vscode', 'bin', 'test');
|
||||
|
||||
export const packageJsonPath = path.join(rootPath, "package.json");
|
||||
|
||||
export const packedVsixOutputRoot = commandLineOptions.outputFolder || rootPath;
|
||||
export const unpackedVsixPath = path.join(rootPath, "vsix");
|
||||
export const unpackedExtensionPath = path.join(unpackedVsixPath, "extension");
|
||||
|
||||
export const codeExtensionPath = commandLineOptions.codeExtensionPath || rootPath;
|
||||
export const codeExtensionSourcesPath = path.join(codeExtensionPath, "out");
|
||||
|
||||
export const testRootPath = path.join(rootPath, "out", "test");
|
||||
export const testAssetsRootPath = path.join(rootPath, "test", "integrationTests", "testAssets");
|
||||
|
||||
export const coverageRootPath = path.join(rootPath, 'coverage');
|
||||
export const unitTestCoverageRootPath = path.join(coverageRootPath, 'unit');
|
||||
export const integrationTestCoverageRootPath = path.join(coverageRootPath, 'integration');
|
||||
|
||||
export const nycOutputPath = path.join(rootPath, '.nyc_output');
|
||||
export const integrationTestNycOutputPath = path.join(nycOutputPath, 'integration');
|
||||
|
||||
export const nodePath = path.join(process.env.NVM_BIN
|
||||
? `${process.env.NVM_BIN}${path.sep}`
|
||||
: '', 'node');
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { SpawnOptions, ChildProcess, spawn } from "child_process";
|
||||
import { join, Result } from "async-child-process";
|
||||
import { nodePath, rootPath } from "./projectPaths";
|
||||
|
||||
export default function spawnNode(args?: string[], options?: SpawnOptions): Promise<Result> {
|
||||
if (!options) {
|
||||
options = {
|
||||
env: {}
|
||||
};
|
||||
}
|
||||
|
||||
let optionsWithFullEnvironment = {
|
||||
cwd: rootPath,
|
||||
...options,
|
||||
env: {
|
||||
...process.env,
|
||||
...options.env
|
||||
}
|
||||
};
|
||||
|
||||
let spawned = spawn(nodePath, args, optionsWithFullEnvironment);
|
||||
|
||||
spawned.stdout.on('data', (data) => console.log(data.toString()));
|
||||
spawned.stderr.on('data', (data) => console.log(data.toString()));
|
||||
|
||||
return join(spawned);
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as gulp from 'gulp';
|
||||
import * as path from 'path';
|
||||
|
||||
import { codeExtensionPath, nodePath, nycPath, rootPath, testAssetsRootPath, testRootPath, unitTestCoverageRootPath, mochaPath, vscodeTestHostPath } from './projectPaths';
|
||||
import { execFile, spawn } from 'child_process';
|
||||
|
||||
import spawnNode from './spawnNode';
|
||||
|
||||
const gulpSequence = require('gulp-sequence');
|
||||
|
||||
gulp.task("test", gulpSequence(
|
||||
"test:feature",
|
||||
"test:unit",
|
||||
"test:integration"));
|
||||
|
||||
gulp.task("test:feature", () => {
|
||||
let env = {
|
||||
...process.env,
|
||||
OSVC_SUITE: "featureTests",
|
||||
CODE_TESTS_PATH: path.join(testRootPath, "featureTests")
|
||||
};
|
||||
|
||||
return spawnNode([vscodeTestHostPath], {
|
||||
env
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task("test:unit", () => {
|
||||
return spawnNode([
|
||||
nycPath,
|
||||
'-r',
|
||||
'lcovonly',
|
||||
'--report-dir',
|
||||
unitTestCoverageRootPath,
|
||||
mochaPath,
|
||||
'--ui',
|
||||
'tdd',
|
||||
'--',
|
||||
'test/unitTests/**/*.test.ts'
|
||||
]);
|
||||
});
|
||||
|
||||
gulp.task(
|
||||
"test:integration", gulpSequence(
|
||||
"test:integration:singleCsproj",
|
||||
"test:integration:slnWithCsproj"
|
||||
));
|
||||
|
||||
gulp.task("test:integration:singleCsproj", () => {
|
||||
return runIntegrationTest("singleCsproj");
|
||||
});
|
||||
|
||||
gulp.task("test:integration:slnWithCsproj", () => {
|
||||
return runIntegrationTest("slnWithCsproj");
|
||||
});
|
||||
|
||||
function runIntegrationTest(testAssetName: string) {
|
||||
let env = {
|
||||
OSVC_SUITE: testAssetName,
|
||||
CODE_TESTS_PATH: path.join(testRootPath, "integrationTests"),
|
||||
CODE_EXTENSIONS_PATH: codeExtensionPath,
|
||||
CODE_TESTS_WORKSPACE: path.join(testAssetsRootPath, testAssetName),
|
||||
CODE_WORKSPACE_ROOT: rootPath,
|
||||
};
|
||||
|
||||
return spawnNode([vscodeTestHostPath], { env, cwd: rootPath });
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
'use strict';
|
||||
|
||||
import shelljs = require("async-shelljs");
|
||||
|
||||
import path = require('path');
|
||||
const fs = require('async-file');
|
||||
import Mocha = require('mocha');
|
||||
|
@ -46,11 +45,7 @@ export default class CoverageWritingTestRunner {
|
|||
|
||||
private async writeCoverage(): Promise<void> {
|
||||
if (typeof __coverage__ !== 'undefined') {
|
||||
let nycFolderPath = path.join(process.env.CODE_EXTENSIONS_PATH, ".nyc_output", "integration");
|
||||
|
||||
if (!(await fs.exists(nycFolderPath))) {
|
||||
await fs.mkdir(nycFolderPath);
|
||||
}
|
||||
let nycFolderPath = path.join(process.env.CODE_WORKSPACE_ROOT, ".nyc_output", "integration");
|
||||
|
||||
let rawCoverageJsonPath: string;
|
||||
let remappedCoverageJsonPath: string;
|
||||
|
@ -59,51 +54,56 @@ export default class CoverageWritingTestRunner {
|
|||
let nodePath: string;
|
||||
|
||||
try {
|
||||
rawCoverageJsonPath = path.join(nycFolderPath, `${process.env.OSVC_SUITE}.json.raw`);
|
||||
remappedCoverageJsonPath = path.join(nycFolderPath, `${process.env.OSVC_SUITE}.json`);
|
||||
outFolderPath = path.join(process.env.CODE_EXTENSIONS_PATH, "out");
|
||||
remapIstanbulPath = path.join(process.env.CODE_EXTENSIONS_PATH, "node_modules", "remap-istanbul", "bin", "remap-istanbul.js");
|
||||
nodePath = "";
|
||||
if (process.env.NVM_BIN) {
|
||||
nodePath = `${process.env.NVM_BIN}${path.sep}`;
|
||||
}
|
||||
if (!(await fs.exists(nycFolderPath))) {
|
||||
await fs.mkdirp(nycFolderPath);
|
||||
|
||||
await fs.writeTextFile(rawCoverageJsonPath, JSON.stringify(__coverage__));
|
||||
|
||||
let result = await shelljs.asyncExec(`${nodePath}node ${remapIstanbulPath} -i ${rawCoverageJsonPath} -o ${remappedCoverageJsonPath}`, {
|
||||
cwd: outFolderPath
|
||||
});
|
||||
|
||||
|
||||
|
||||
let remappedResult = JSON.parse(await fs.readTextFile(remappedCoverageJsonPath));
|
||||
|
||||
let finalResult = {};
|
||||
|
||||
for (let key in remappedResult) {
|
||||
if (remappedResult[key].path) {
|
||||
let realPath = key.replace("../", "./");
|
||||
|
||||
finalResult[realPath] = remappedResult[key];
|
||||
finalResult[realPath].path = realPath;
|
||||
rawCoverageJsonPath = path.join(nycFolderPath, `${process.env.OSVC_SUITE}.json.raw`);
|
||||
remappedCoverageJsonPath = path.join(nycFolderPath, `${process.env.OSVC_SUITE}.json`);
|
||||
outFolderPath = path.join(process.env.CODE_WORKSPACE_ROOT, "out");
|
||||
remapIstanbulPath = path.join(process.env.CODE_WORKSPACE_ROOT, "node_modules", "remap-istanbul", "bin", "remap-istanbul.js");
|
||||
nodePath = "";
|
||||
if (process.env.NVM_BIN) {
|
||||
nodePath = `${process.env.NVM_BIN}${path.sep}`;
|
||||
}
|
||||
else {
|
||||
finalResult[key] = remappedResult[key];
|
||||
|
||||
await fs.writeTextFile(rawCoverageJsonPath, JSON.stringify(__coverage__));
|
||||
|
||||
let result = await shelljs.asyncExec(`${nodePath}node ${remapIstanbulPath} -i ${rawCoverageJsonPath} -o ${remappedCoverageJsonPath}`, {
|
||||
cwd: outFolderPath
|
||||
});
|
||||
|
||||
|
||||
|
||||
let remappedResult = JSON.parse(await fs.readTextFile(remappedCoverageJsonPath));
|
||||
|
||||
let finalResult = {};
|
||||
|
||||
for (let key in remappedResult) {
|
||||
if (remappedResult[key].path) {
|
||||
let realPath = key.replace("../", "./");
|
||||
|
||||
finalResult[realPath] = remappedResult[key];
|
||||
finalResult[realPath].path = realPath;
|
||||
}
|
||||
else {
|
||||
finalResult[key] = remappedResult[key];
|
||||
}
|
||||
}
|
||||
|
||||
await fs.writeTextFile(remappedCoverageJsonPath, JSON.stringify(finalResult));
|
||||
|
||||
console.log(`done remapping ${finalResult}`);
|
||||
}
|
||||
|
||||
await fs.writeTextFile(remappedCoverageJsonPath, JSON.stringify(finalResult));
|
||||
|
||||
console.log(`done remapping ${finalResult}`);
|
||||
}
|
||||
catch (e) {
|
||||
console.log(`Coverage remapping failure: ${JSON.stringify(e)}`);
|
||||
console.log(`* rawCoverageJsonPath: ${rawCoverageJsonPath}`);
|
||||
console.log(`* remappedCoverageJsonPath: ${remappedCoverageJsonPath}`);
|
||||
console.log(`* outFolderPath: ${outFolderPath}`);
|
||||
console.log(`* remapIstanbulPath: ${remapIstanbulPath}`);
|
||||
console.log(`* nodePath: ${nodePath}`);
|
||||
console.log(`Coverage remapping failure: ${JSON.stringify(e)}`);
|
||||
console.log(`* rawCoverageJsonPath: ${rawCoverageJsonPath}`);
|
||||
console.log(`* remappedCoverageJsonPath: ${remappedCoverageJsonPath}`);
|
||||
console.log(`* outFolderPath: ${outFolderPath}`);
|
||||
console.log(`* remapIstanbulPath: ${remapIstanbulPath}`);
|
||||
console.log(`* nodePath: ${nodePath}`);
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from 'async-file';
|
||||
|
@ -10,24 +10,24 @@ import poll from './poll';
|
|||
import { should, expect } from 'chai';
|
||||
import testAssetWorkspace from './testAssets/testAssetWorkspace';
|
||||
|
||||
const chai = require('chai');
|
||||
chai.use(require('chai-arrays'));
|
||||
chai.use(require('chai-fs'));
|
||||
|
||||
const chai = require('chai');
|
||||
chai.use(require('chai-arrays'));
|
||||
chai.use(require('chai-fs'));
|
||||
|
||||
suite(`Code Action Rename ${testAssetWorkspace.description}`, function() {
|
||||
suiteSetup(async function() {
|
||||
suiteSetup(async function() {
|
||||
should();
|
||||
|
||||
let csharpExtension = vscode.extensions.getExtension("ms-vscode.csharp");
|
||||
if (!csharpExtension.isActive) {
|
||||
await csharpExtension.activate();
|
||||
let csharpExtension = vscode.extensions.getExtension("ms-vscode.csharp");
|
||||
if (!csharpExtension.isActive) {
|
||||
await csharpExtension.activate();
|
||||
}
|
||||
|
||||
await csharpExtension.exports.initializationFinished;
|
||||
|
||||
});
|
||||
|
||||
test("Code actions can rename and open files", async () => {
|
||||
|
||||
test("Code actions can rename and open files", async () => {
|
||||
let fileUri = await testAssetWorkspace.projects[0].addFileWithContents("test.cs", "class C {}");
|
||||
await vscode.commands.executeCommand("vscode.open", fileUri);
|
||||
let c = await vscode.commands.executeCommand("vscode.executeCodeActionProvider", fileUri, new vscode.Range(0, 7, 0, 7)) as {command: string, title: string, arguments: string[]}[];
|
||||
|
@ -42,4 +42,4 @@ suite(`Code Action Rename ${testAssetWorkspace.description}`, function() {
|
|||
teardown(async () => {
|
||||
await testAssetWorkspace.cleanupWorkspace();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -34,7 +34,6 @@ suite(`Hover Provider: ${testAssetWorkspace.description}`, function () {
|
|||
let dir = path.dirname(testAssetWorkspace.projects[0].projectDirectoryPath);
|
||||
let loc = path.join(dir, fileName);
|
||||
let fileUri = vscode.Uri.file(loc);
|
||||
await omnisharp.waitForEmptyEventQueue();
|
||||
|
||||
await vscode.commands.executeCommand("vscode.open", fileUri);
|
||||
let c = await vscode.commands.executeCommand("vscode.executeHoverProvider", fileUri, new vscode.Position(10, 29));
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
import { SubscribeToAllLoggers } from "../../src/logger";
|
||||
import coverageWritingTestRunner from "../coverageWritingTestRunner";
|
||||
|
@ -32,12 +33,14 @@ testRunner.configure({
|
|||
useColors: true // colored output from test results
|
||||
});
|
||||
|
||||
if (process.env.OSVC_SUITE) {
|
||||
if (!fs.existsSync("./.logs")) {
|
||||
fs.mkdirSync("./.logs");
|
||||
if (process.env.CODE_EXTENSIONS_PATH && process.env.OSVC_SUITE) {
|
||||
let logDirPath = path.join(process.env.CODE_EXTENSIONS_PATH, "./.logs");
|
||||
|
||||
if (!fs.existsSync(logDirPath)) {
|
||||
fs.mkdirSync(logDirPath);
|
||||
}
|
||||
|
||||
let logFilePath = `./.logs/${process.env.OSVC_SUITE}.log`;
|
||||
let logFilePath = path.join(logDirPath, `${process.env.OSVC_SUITE}.log`);
|
||||
|
||||
SubscribeToAllLoggers(message => fs.appendFileSync(logFilePath, message));
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ suite(`SignatureHelp: ${testAssetWorkspace.description}`, function () {
|
|||
let dir = path.dirname(testAssetWorkspace.projects[0].projectDirectoryPath);
|
||||
let loc = path.join(dir, fileName);
|
||||
fileUri = vscode.Uri.file(loc);
|
||||
await omnisharp.waitForEmptyEventQueue();
|
||||
await vscode.commands.executeCommand("vscode.open", fileUri);
|
||||
});
|
||||
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
path=require('path');
|
||||
|
||||
if (process.env.CODE_TESTS_PATH
|
||||
&& process.env.CODE_TESTS_PATH.startsWith('.')){
|
||||
process.env.CODE_TESTS_PATH = path.join(process.cwd(), process.env.CODE_TESTS_PATH.substr(2));
|
||||
}
|
||||
|
||||
if (process.env.CODE_EXTENSIONS_PATH
|
||||
&& process.env.CODE_EXTENSIONS_PATH.startsWith('.')){
|
||||
process.env.CODE_EXTENSIONS_PATH = path.join(process.cwd(), process.env.CODE_EXTENSIONS_PATH.substr(2));
|
||||
}
|
||||
|
||||
require(path.resolve(__dirname, '../node_modules/vscode/bin/test'));
|
|
@ -11,6 +11,7 @@
|
|||
},
|
||||
"exclude": [
|
||||
"syntaxes",
|
||||
".vscode-test"
|
||||
".vscode-test",
|
||||
"vsix"
|
||||
]
|
||||
}
|
Загрузка…
Ссылка в новой задаче