diff --git a/vscode-extensions/vscode-application-properties/.vscodeignore b/vscode-extensions/vscode-application-properties/.vscodeignore index 71d147879..8111020de 100644 --- a/vscode-extensions/vscode-application-properties/.vscodeignore +++ b/vscode-extensions/vscode-application-properties/.vscodeignore @@ -23,7 +23,7 @@ scripts/** # Compiler output out/test/** target/** -!target/fat-jar.jar +!target/vscode-application-properties-*.jar # Extensions .gitignore diff --git a/vscode-extensions/vscode-application-properties/README.md b/vscode-extensions/vscode-application-properties/README.md index f68f6fc68..80e80de29 100644 --- a/vscode-extensions/vscode-application-properties/README.md +++ b/vscode-extensions/vscode-application-properties/README.md @@ -7,21 +7,24 @@ files containing Spring Boot configuration properties. ## Bulding and Running -The extension implemented in this example consists out of two pieces: - - - client: a vscode extension implemented in typescript. It launches and connects - to the language server. - - server: server app, implemented in Java. - -First build the server: +This project consists of three pieces: - mvn clean package + - a vscode-extension which is a language-server client implemented in TypeScript. + - commons-vscode: a local npm module with some utilities implemented in TypeScript. + - a language server implemented in Java. -The server will be produced in `out/fat-jar.jar`. +To build all these pieces you normally only need to run: -Then build the client: + npm install - npm clean install +**However, the first time you build** it might fail trying to +find the `commons-vscode` module on npm central. Once we publish a stable +version of that module on npm central that will no longer be a problem. +Until that time, you can work around this by doing a one time manual +run of the `preinstall` script prior to running `npm install`: + + ./scripts/preinstall.sh + npm install Now you can open the client-app in vscode. From the root of this project. @@ -32,17 +35,20 @@ To launch the language server in a vscode runtime, press F5. ## Debugging To debug the language server, open `lib/Main.ts` and edit to set the -`DEBUG` constant to `true`. When you laucnh the app next by pressing +`DEBUG` option to `true`. When you laucnh the app next by pressing `F5` it will launch with debug options being passed to the JVM. You can then connect a 'Remote Java' Eclipse debugger on port 8000. -Note that in debug mode we launch not from the 'fatjar' produced by the -maven build, but instead use the classes from 'target/classes' directory. -This allows you to edit the server code in Eclipse and relaunch the -client from vscode without rebuilding the fatjar. - ## Packaging as a vscode extension -Run the `package.sh` script. This will produce a `.vsix` file that can -be directly installed into vscode. +First make sure the stuff is all built locally: + + ./scripts/preinstall.sh # only needed if this is the first build. + npm install + +Then package it: + + npm run vsce-package + +This produces a `.vsix` file which you can install directly into vscode. \ No newline at end of file diff --git a/vscode-extensions/vscode-application-properties/lib/Main.ts b/vscode-extensions/vscode-application-properties/lib/Main.ts index 9a6140921..97ceee0fd 100644 --- a/vscode-extensions/vscode-application-properties/lib/Main.ts +++ b/vscode-extensions/vscode-application-properties/lib/Main.ts @@ -5,40 +5,20 @@ import * as VSCode from 'vscode'; import * as Path from 'path'; import * as FS from 'fs'; -import * as PortFinder from 'portfinder'; import * as Net from 'net'; import * as ChildProcess from 'child_process'; import {LanguageClient, LanguageClientOptions, SettingMonitor, ServerOptions, StreamInfo} from 'vscode-languageclient'; import {TextDocument} from 'vscode'; -PortFinder.basePort = 55282; - -var DEBUG = false; -const DEBUG_ARG = '-agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n'; - //If DEBUG is falsy then - // we launch from the 'fat jar' (which has to be built by running mvn package) - //if DEBUG is truthy then - // - we launch the Java project directly from the classes folder produced by Eclipse JDT compiler - // - we add DEBUG_ARG to the launch so that remote debugger can attach on port 8000 +import * as commons from 'commons-vscode'; /** Called when extension is activated */ export function activate(context: VSCode.ExtensionContext) { - let javaExecutablePath = findJavaExecutable('java'); - - if (javaExecutablePath == null) { - VSCode.window.showErrorMessage("Couldn't locate java in $JAVA_HOME or $PATH"); - return; - } - - isJava8(javaExecutablePath).then(eight => { - if (!eight) { - VSCode.window.showErrorMessage('Java language support requires Java 8 (using ' + javaExecutablePath + ')'); - return; - } - - // Options to control the language client - let clientOptions: LanguageClientOptions = { - + let options : commons.ActivatorOptions = { + DEBUG: false, + extensionId: 'vscode-application-properties', + fatJarFile: 'target/vscode-application-properties-0.0.1-SNAPSHOT.jar', + clientOptions: { // HACK!!! documentSelector only takes string|string[] where string is language id, but DocumentFilter object is passed instead // Reasons: // 1. documentSelector is just passed over to functions like #registerHoverProvider(documentSelector, ...) that take documentSelector @@ -53,119 +33,12 @@ export function activate(context: VSCode.ExtensionContext) { {language: 'properties', pattern: '**/application*.properties'} ], synchronize: { - // Synchronize the setting section to the server: - configurationSection: 'languageServerExample', - // Notify the server about file changes to 'javaconfig.json' files contain in the workspace - fileEvents: [ - //What's this for? Don't think it does anything useful for this example: - VSCode.workspace.createFileSystemWatcher('**/.clientrc') - ], - // TODO: Remove textDocumentFilter property ones https://github.com/Microsoft/vscode-languageserver-node/issues/9 is resolved textDocumentFilter: function(textDocument : TextDocument) : boolean { return /^(.*\/)?application[^\s\\/]*.properties$/i.test(textDocument.fileName); } } } - - function createServer(): Promise { - return new Promise((resolve, reject) => { - PortFinder.getPort((err, port) => { - Net.createServer(socket => { - console.log('Child process connected on port ' + port); - - resolve({ - reader: socket, - writer: socket - }); - }).listen(port, () => { - let options = { - cwd: VSCode.workspace.rootPath - }; - let child: ChildProcess.ChildProcess; - // let classpath = getClasspath(context); - let projectDir = context.extensionPath; - let fatJar = Path.resolve(projectDir, 'target/vscode-application-properties-0.0.1-SNAPSHOT.jar'); - let args = [ - '-Dserver.port=' + port, - '-jar', - fatJar, - ]; - if (DEBUG) { - args.unshift(DEBUG_ARG); - } - console.log(javaExecutablePath + ' ' + args.join(' ')); - - // Start the child java process - child = ChildProcess.execFile(javaExecutablePath, args, options); - child.stdout.on('data', (data) => { - console.log(data); - }); - child.stderr.on('data', (data) => { - console.error(data); - }) - }); - }); - }); - } - - // Create the language client and start the client. - let client = new LanguageClient('lsapi-example', 'Language Server Example', - createServer, clientOptions); - let disposable = client.start(); - - // Push the disposable to the context's subscriptions so that the - // client can be deactivated on extension deactivation - context.subscriptions.push(disposable); - }); -} - -function isJava8(javaExecutablePath: string): Promise { - return new Promise((resolve, reject) => { - let result = ChildProcess.execFile(javaExecutablePath, ['-version'], { }, (error, stdout, stderr) => { - let eight = stderr.indexOf('1.8') >= 0; - - resolve(eight); - }); - }); -} - -function findJavaExecutable(binname: string) { - binname = correctBinname(binname); - - // First search each JAVA_HOME bin folder - if (process.env['JAVA_HOME']) { - let workspaces = process.env['JAVA_HOME'].split(Path.delimiter); - for (let i = 0; i < workspaces.length; i++) { - let binpath = Path.join(workspaces[i], 'bin', binname); - if (FS.existsSync(binpath)) { - return binpath; - } - } - } - - // Then search PATH parts - if (process.env['PATH']) { - let pathparts = process.env['PATH'].split(Path.delimiter); - for (let i = 0; i < pathparts.length; i++) { - let binpath = Path.join(pathparts[i], binname); - if (FS.existsSync(binpath)) { - return binpath; - } - } - } - - // Else return the binary name directly (this will likely always fail downstream) - return null; -} - -function correctBinname(binname: string) { - if (process.platform === 'win32') - return binname + '.exe'; - else - return binname; -} - -// this method is called when your extension is deactivated -export function deactivate() { + }; + commons.activate(options, context); } diff --git a/vscode-extensions/vscode-application-properties/package.json b/vscode-extensions/vscode-application-properties/package.json index 86779d2bc..0c9100de0 100644 --- a/vscode-extensions/vscode-application-properties/package.json +++ b/vscode-extensions/vscode-application-properties/package.json @@ -1,17 +1,18 @@ { - "name": "application-properties", + "name": "vscode-application-properties", "displayName": "Spring Boot Application Properties Support", "description": "Provides validation and content assist for Spring Boot application.properties file", "icon": "spring.gif", "version": "0.0.1", - "publisher": "pivotal", + "publisher": "Pivotal", "repository": { "type": "git", "url": "https://github.com/spring-projects/sts4.git" }, "license": "EPL-1.0", "engines": { - "vscode": "^0.10.10" + "npm": "^3.0.0", + "vscode": "^1.5.0" }, "categories": [ "Languages", @@ -26,9 +27,6 @@ "onLanguage:properties" ], "main": "./out/lib/Main", - "files": [ - "target/fat-jar.jar" - ], "contributes": { "configuration": { "type": "object", @@ -42,20 +40,23 @@ } } }, - "preview": "true", + "preview": true, "scripts": { - "vscode:prepublish": "node ./node_modules/vscode/bin/compile", - "compile": "node ./node_modules/vscode/bin/compile -watch -p ./", + "prepublish": "tsc -p .", + "clean": "rm -fr node_modules out *.vsix", + "compile": "tsc -watch -p ./", + "preinstall": "./scripts/preinstall.sh", "postinstall": "node ./node_modules/vscode/bin/install", - "test": "mocha out/test" + "vsce-package": "vsce package" }, "dependencies": { - "portfinder": "^0.4.0", - "vscode-languageclient": "2.5.x" + "vscode-languageclient": "2.5.x", + "commons-vscode": "^0.0.1" }, "devDependencies": { - "typescript": "^1.8.5", - "vscode": "^0.11.0", - "mocha": "^2.4.5" + "vsce": "^1.17.0", + "typescript": "^2.0.x", + "@types/node": "^6.0.40", + "vscode": "^1.0.0" } } diff --git a/vscode-extensions/vscode-application-properties/package.sh b/vscode-extensions/vscode-application-properties/package.sh deleted file mode 100755 index 3cda60f54..000000000 --- a/vscode-extensions/vscode-application-properties/package.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -## run this script to package up this extension using vsce tool. -## This assumes you have vsce tool installed. -## You can install it via npm - -set -e # fail at the first sign of trouble - -#Ensure commons are built and uptodate in local maven cache -mvn -f ../commons/pom.xml clean install -mvn clean package -npm install -vsce package - - diff --git a/vscode-extensions/vscode-application-properties/scripts/preinstall.sh b/vscode-extensions/vscode-application-properties/scripts/preinstall.sh new file mode 100755 index 000000000..7eed017ff --- /dev/null +++ b/vscode-extensions/vscode-application-properties/scripts/preinstall.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -e +(cd ../commons-vscode ; npm install) +npm install ../commons-vscode +../mvnw -f ../pom.xml -pl vscode-application-properties -am clean package diff --git a/vscode-extensions/vscode-application-properties/tsconfig.json b/vscode-extensions/vscode-application-properties/tsconfig.json index afb8e79d2..1905ffea7 100644 --- a/vscode-extensions/vscode-application-properties/tsconfig.json +++ b/vscode-extensions/vscode-application-properties/tsconfig.json @@ -1,11 +1,20 @@ { "compilerOptions": { "module": "commonjs", - "target": "es5", + "moduleResolution": "node", + "target": "es6", + "lib": [ + "es6" + ], + "declaration": true, "outDir": "out", "sourceMap": true, "rootDir": "." }, + "include": [ + "typings/*.d.ts", + "lib/**/*.ts" + ], "exclude": [ "node_modules" ] diff --git a/vscode-extensions/vscode-application-properties/tsd.json b/vscode-extensions/vscode-application-properties/tsd.json deleted file mode 100644 index 50cd71dcf..000000000 --- a/vscode-extensions/vscode-application-properties/tsd.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "version": "v4", - "repo": "borisyankov/DefinitelyTyped", - "ref": "master", - "path": "typings", - "bundle": "typings/tsd.d.ts", - "installed": { - "node/node.d.ts": { - "commit": "d22516f9f089de107d7e7d5938566377370631f6" - } - } -} diff --git a/vscode-extensions/vscode-application-properties/typings/portfinder.d.ts b/vscode-extensions/vscode-application-properties/typings/portfinder.d.ts deleted file mode 100644 index 554fa8db2..000000000 --- a/vscode-extensions/vscode-application-properties/typings/portfinder.d.ts +++ /dev/null @@ -1,7 +0,0 @@ - - -declare module 'portfinder' { - var basePort: number; - - function getPort(callback: (err: any, port: number) => void); -} \ No newline at end of file diff --git a/vscode-extensions/vscode-application-properties/typings/tsd.d.ts b/vscode-extensions/vscode-application-properties/typings/tsd.d.ts deleted file mode 100644 index 2916e4c11..000000000 --- a/vscode-extensions/vscode-application-properties/typings/tsd.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// \ No newline at end of file