Skip to content

Commit f0f5c59

Browse files
committed
Merge remote-tracking branch 'upstream/master'
* upstream/master: Document contribution to the code along with coding standards (#321)
2 parents 7aadc43 + 5430b5e commit f0f5c59

File tree

6 files changed

+161
-45
lines changed

6 files changed

+161
-45
lines changed

.travis.yml

+5-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ addons:
1212
- g++-4.9-multilib
1313
- libgtk2.0-0
1414
- libx11-dev
15-
- libxkbfile-dev
15+
- libxkbfile-dev
1616
- libsecret-1-dev
1717
- python-dev
1818
matrix:
@@ -41,8 +41,9 @@ before_install: |
4141
git submodule update --init --recursive
4242
git clone https://github.com/creationix/nvm.git ./.nvm
4343
source ./.nvm/nvm.sh
44-
nvm install 7.2.1
45-
nvm use 7.2.1
44+
nvm install 8.9.1
45+
nvm use 8.9.1
46+
4647
npm config set python `which python`
4748
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
4849
pyenv install $PYTHON
@@ -53,6 +54,6 @@ install:
5354
- pip install --upgrade -r requirements.txt
5455
- npm install
5556
- npm run vscode:prepublish
56-
57+
5758
script:
5859
- npm test --silent

.vscode/launch.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"outFiles": [
1616
"${workspaceFolder}/out/**/*.js"
1717
],
18-
"preLaunchTask": "compile"
18+
"preLaunchTask": "Compile"
1919
},
2020
{
2121
"name": "Launch Extension as debugServer", // https://code.visualstudio.com/docs/extensions/example-debuggers
@@ -30,7 +30,8 @@
3030
"outFiles": [
3131
"${workspaceFolder}/out/client/**/*.js"
3232
],
33-
"cwd": "${workspaceFolder}"
33+
"cwd": "${workspaceFolder}",
34+
"preLaunchTask": "Compile"
3435
},
3536
{
3637
"name": "Launch Tests",
@@ -47,7 +48,7 @@
4748
"outFiles": [
4849
"${workspaceFolder}/out/**/*.js"
4950
],
50-
"preLaunchTask": "compile"
51+
"preLaunchTask": "Compile"
5152
},
5253
{
5354
"name": "Launch Multiroot Tests",
@@ -64,7 +65,7 @@
6465
"outFiles": [
6566
"${workspaceFolder}/out/**/*.js"
6667
],
67-
"preLaunchTask": "compile"
68+
"preLaunchTask": "Compile"
6869
}
6970
],
7071
"compounds": [

.vscode/tasks.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"script": "compile",
1414
"isBackground": true,
1515
"problemMatcher": [
16-
"$tsc",
16+
"$tsc-watch",
1717
{
1818
"base": "$tslint5",
1919
"fileLocation": "relative"
@@ -36,7 +36,7 @@
3636
"panel": "shared"
3737
},
3838
"problemMatcher": [
39-
"$tsc",
39+
"$tsc-watch",
4040
{
4141
"base": "$tslint5",
4242
"fileLocation": "relative"

CODING_STANDARDS.md

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
## Coding guidelines for TypeScript
2+
* The following standards are inspired from [Coding guidelines for TypeScript](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines).
3+
4+
### Names
5+
* Use PascalCase for type names.
6+
* Use "I" as a prefix for interface names only when an interface is implemented by a class.
7+
* Use PascalCase for enum values.
8+
* Use camelCase for function names.
9+
* Use camelCase for property names and local variables.
10+
* Do not use "_" as a prefix for private properties (unless used as backing properties).
11+
* Use whole words in names when possible.
12+
13+
### Types
14+
15+
* Do not export types/functions unless you need to share it across multiple components.
16+
* Do not introduce new types/values to the global namespace.
17+
* Shared types should be defined in 'types.ts'.
18+
Within a file, type definitions should come first.
19+
20+
### null and undefined
21+
22+
Use undefined. Do not use null.
23+
24+
### Comments
25+
26+
Use JSDoc style comments for functions, interfaces, enums, and classes.
27+
28+
### Strings
29+
30+
Use single quotes for strings.
31+
32+
### Style
33+
34+
* Use arrow functions over anonymous function expressions.
35+
* Always surround loop and conditional bodies with curly braces. Statements on the same line are allowed to omit braces.
36+
* Open curly braces always go on the same line as whatever necessitates them.
37+
* Parenthesized constructs should have no surrounding whitespace.
38+
* A single space follows commas, colons, and semicolons in those constructs. For example:
39+
* `for (var i = 0, n = str.length; i < 10; i++) { }`
40+
* `if (x < 10) { }`
41+
* `function f(x: number, y: string): void { }`
42+
43+
* `else` goes on a the same line from the closing curly brace.
44+
* Use 4 spaces per indentation.
45+
46+

CONTRIBUTING.md

+34-15
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,64 @@
11
## Contribution
22
* Please feel free to fork and submit pull requests
3-
* Feature requests can be added [here](https://github.com/DonJayamanne/pythonVSCode/issues/183)
43

5-
## Prerequisites
6-
1. Node.js
4+
### Prerequisites
5+
6+
1. Node.js (>= 8.9.1, < 9.0.0)
77
2. Python 2.7 or later (required only for testing the extension and running unit tests)
88
3. Windows, OS X or Linux
9+
4. Visual Studio Code
10+
5. Following VS Code extensions:
11+
* [TSLint](https://marketplace.visualstudio.com/items?itemName=eg2.tslint)
12+
* [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig)
13+
14+
### Setup
915

10-
## Setup
1116
```
12-
git clone https://github.com/DonJayamanne/pythonVSCode
13-
cd pythonVSCode
17+
git clone https://github.com/microsoft/vscode-python
18+
cd vscode-python
1419
npm install
1520
```
16-
## Development workflow
21+
1722
### Incremental Build
18-
Run the build Task from the [Command Palette](https://code.visualstudio.com/docs/editor/tasks) (short cut CTRL+SHIFT+B or ⇧⌘B)
23+
24+
Run the `Compile` and `Hygiene` build Tasks from the [Command Palette](https://code.visualstudio.com/docs/editor/tasks) (short cut `CTRL+SHIFT+B` or `⇧⌘B`)
1925

2026
### Errors and Warnings
21-
TypeScript errors and warnings will be displayed in VS Code in the Problems Panel (CTRL+SHIFT+M or ⇧⌘M)
27+
28+
TypeScript errors and warnings will be displayed in VS Code in the following areas:
29+
* Problems Panel (`CTRL+SHIFT+M` or `⇧⌘M`)
30+
* Terminal running the `Compile` task
31+
* Terminal running the `Hygiene` task
2232

2333
### Validate your changes
34+
2435
To test the changes you launch a development version of VS Code on the workspace vscode, which you are currently editing.
25-
Use the "Launch Extension" launch option.
36+
Use the `Launch Extension` launch option.
2637

2738
### Unit Tests
28-
Run the Unit Tests via the "Launch Test" launch option.
29-
Currently unit tests only run on [Travis](https://travis-ci.org/DonJayamanne/pythonVSCode)
39+
40+
Run the Unit Tests via the `Launch Test` and `Launch Multiroot Tests` launch option.
41+
Currently unit tests only run on [Travis](https://travis-ci.org/Microsoft/vscode-python)
3042

3143
_Requirements_
3244
1. Ensure you have disabled breaking into 'Uncaught Exceptions' when running the Unit Tests
3345
2. For the linters and formatters tests to pass successfully, you will need to have those corresponding Python libraries installed locally
3446

35-
## Debugging the extension
3647
### Standard Debugging
48+
3749
Clone the repo into any directory and start debugging.
38-
From there use the "Launch Extension" launch option.
50+
From there use the `Launch Extension` launch option.
3951

4052
### Debugging the Python Extension Debugger
53+
4154
The easiest way to debug the Python Debugger (in our opinion) is to clone this git repo directory into [your](https://code.visualstudio.com/docs/extensions/install-extension#_your-extensions-folder) extensions directory.
42-
From there use the ```Launch Extension as debugserver``` launch option.
55+
From there use the ```Extension + Debugger``` launch option.
56+
57+
### Coding Standards
58+
59+
Information on our coding standards can be found [here](https://github.com/Microsoft/vscode-python/blob/master/CODING_STANDARDS.md).
60+
We have a pre-commit hook to ensure the code committed will adhere to the above coding standards.
61+
4362

4463
## Development process
4564

gulpfile.js

+69-20
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const colors = require('colors/safe');
2222
* named according to the checks performed on them. Each subset contains
2323
* the following one, as described in mathematical notation:
2424
*
25-
* all ⊃ eol ⊇ indentation ⊃ copyright ⊃ typescript
25+
* all ⊃ eol ⊇ indentation ⊃ typescript
2626
*/
2727

2828
const all = [
@@ -115,12 +115,12 @@ const hygiene = (some, options) => {
115115
.toString('utf8')
116116
.split(/\r\n|\r|\n/)
117117
.forEach((line, i) => {
118-
if (/^\s*$/.test(line)) {
118+
if (/^\s*$/.test(line) || /^\S+.*$/.test(line)) {
119119
// Empty or whitespace lines are OK.
120120
} else if (/^(\s\s\s\s)+.*/.test(line)) {
121121
// Good indent.
122122
} else if (/^[\t]+.*/.test(line)) {
123-
console.error(file.relative + '(' + (i + 1) + ',1): Bad whitespace indentation');
123+
console.error(file.relative + '(' + (i + 1) + ',1): Bad whitespace indentation (use 4 spaces instead of tabs or other)');
124124
errorCount++;
125125
}
126126
});
@@ -137,7 +137,7 @@ const hygiene = (some, options) => {
137137
tsfmt: true
138138
}).then(result => {
139139
if (result.error) {
140-
console.error(result.message);
140+
console.error(result.message.trim());
141141
errorCount++;
142142
}
143143
cb(null, file);
@@ -147,14 +147,14 @@ const hygiene = (some, options) => {
147147
});
148148
});
149149

150+
const program = require('tslint').Linter.createProgram("./tsconfig.json");
151+
const linter = new tslint.Linter(options, program);
150152
const tsl = es.through(function (file) {
151153
const configuration = tslint.Configuration.findConfiguration(null, '.');
152154
const options = {
153155
formatter: 'json'
154156
};
155157
const contents = file.contents.toString('utf8');
156-
const program = require('tslint').Linter.createProgram("./tsconfig.json");
157-
const linter = new tslint.Linter(options, program);
158158
linter.lint(file.relative, contents, configuration.results);
159159
const result = linter.getResult();
160160
if (result.failureCount > 0 || result.errorCount > 0) {
@@ -206,22 +206,16 @@ const hygiene = (some, options) => {
206206
.pipe(filter(f => !f.stat.isDirectory()))
207207
.pipe(filter(eolFilter))
208208
.pipe(options.skipEOL ? es.through() : eol)
209-
.pipe(filter(indentationFilter));
210-
211-
if (!options.skipIndentationCheck) {
212-
result = result
213-
.pipe(indentation);
214-
}
209+
.pipe(filter(indentationFilter))
210+
.pipe(indentation);
215211

216212
// Type script checks.
217213
let typescript = result
218-
.pipe(filter(tslintFilter));
214+
.pipe(filter(tslintFilter))
215+
.pipe(formatting);
219216

220-
if (!options.skipFormatCheck) {
221-
typescript = typescript
222-
.pipe(formatting);
223-
}
224-
typescript = typescript.pipe(tsl)
217+
typescript = typescript
218+
.pipe(tsl)
225219
.pipe(tscFilesTracker)
226220
.pipe(tsc());
227221

@@ -244,16 +238,32 @@ gulp.task('hygiene-staged', () => run({ mode: 'changes' }));
244238
gulp.task('hygiene-watch', ['hygiene-staged', 'hygiene-watch-runner']);
245239

246240
gulp.task('hygiene-watch-runner', function () {
241+
/**
242+
* @type {Deferred}
243+
*/
244+
let runPromise;
245+
247246
return watch(all, { events: ['add', 'change'] }, function (event) {
247+
// Damn bounce does not work, do our own checks.
248248
const start = new Date();
249+
if (runPromise && !runPromise.completed) {
250+
console.log(`[${start.toLocaleTimeString()}] Already running`);
251+
return;
252+
}
249253
console.log(`[${start.toLocaleTimeString()}] Starting '${colors.cyan('hygiene-watch-runner')}'...`);
254+
255+
runPromise = new Deferred();
250256
// Skip indentation and formatting checks to speed up linting.
251-
return run({ mode: 'watch', skipFormatCheck: true, skipIndentationCheck: true })
257+
run({ mode: 'watch', skipFormatCheck: true, skipIndentationCheck: true })
252258
.then(() => {
253259
const end = new Date();
254260
const time = (end.getTime() - start.getTime()) / 1000;
255261
console.log(`[${end.toLocaleTimeString()}] Finished '${colors.cyan('hygiene-watch-runner')}' after ${time} seconds`);
256-
});
262+
runPromise.resolve();
263+
})
264+
.catch(runPromise.reject.bind);
265+
266+
return runPromise.promise;
257267
});
258268
});
259269

@@ -402,7 +412,46 @@ function getModifiedFiles() {
402412
});
403413
});
404414
}
415+
405416
// this allows us to run hygiene as a git pre-commit hook.
406417
if (require.main === module) {
407418
run({ exitOnError: true, mode: 'staged' });
408419
}
420+
421+
class Deferred {
422+
constructor(scope) {
423+
this.scope = scope;
424+
this._resolved = false;
425+
this._rejected = false;
426+
427+
this._promise = new Promise((resolve, reject) => {
428+
this._resolve = resolve;
429+
this._reject = reject;
430+
});
431+
}
432+
resolve(value) {
433+
this._resolve.apply(this.scope ? this.scope : this, arguments);
434+
this._resolved = true;
435+
}
436+
/**
437+
* Rejects the promise
438+
* @param {any} reason
439+
* @memberof Deferred
440+
*/
441+
reject(reason) {
442+
this._reject.apply(this.scope ? this.scope : this, arguments);
443+
this._rejected = true;
444+
}
445+
get promise() {
446+
return this._promise;
447+
}
448+
get resolved() {
449+
return this._resolved === true;
450+
}
451+
get rejected() {
452+
return this._rejected === true;
453+
}
454+
get completed() {
455+
return this._rejected || this._resolved;
456+
}
457+
}

0 commit comments

Comments
 (0)