diff --git a/.travis.yml b/.travis.yml index 1e3cd4fa1..228695786 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,10 @@ before_install: - npm install -g typescript install: +- wget http://download.eclipse.org/jdtls/snapshots/jdt-language-server-latest.tar.gz +- mkdir server +- tar -xvzf jdt-language-server-latest.tar.gz -C ./server +- rm jdt-language-server-latest.tar.gz - npm install - npm run vscode:prepublish - npm install -g vsce diff --git a/.vscodeignore b/.vscodeignore index ae95b0063..c3412c211 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -11,4 +11,4 @@ vsc-extension-quickstart.md undefined/** CONTRIBUTING.md .vscode-test/** -server/** \ No newline at end of file +**/**.vsix diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 12809cf05..39f1e6286 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,13 +33,16 @@ This assumes that you are starting on the `vscode-java` directory ```bash $ cd ..\vscode-java - $ npm run-script build-server + $ npm run build-server ``` -You can run faster builds by calling the `build-server-mac`, `build-server-win` or `build-server-linux` script instead, depending on your OS. These commands run Maven in offline mode, so you might need to run `build-server` at least once, to fetch all the dependencies. +You can run faster server builds during development by calling `./node_modules/.bin/gulp dev_server` script instead, this will build server binaries that are required by your host OS only. You can also use `npm run watch-server` which will build and place them on the extension for Java changes. These commands run Maven in offline mode, so you might need to run `build-server` at least once, to fetch all the dependencies. -This will build and place the binaries under the `server` folder. Alternately you can download -and unzip a pre-built server. For pre-built server information refer to eclipse.jdt.ls -project. +This will build and place the binaries under the `server` folder. Alternately you can download and use the latest snapshot build from [Eclipse ™ JDT Language Server](https://github.com/eclipse/eclipse.jdt.ls) project with the following + + ```bash + $ cd ..\vscode-java + $ ./node_modules/.bin/gulp download_server + ``` ## Sideloading @@ -53,11 +56,11 @@ You can create a binary that you can sideload to your VS Code installation. $ npm install ``` 4. Optionally, follow the instruction to build the server. -5. See documentation on [extension installation](https://github.com/Microsoft/vscode-docs/blob/master/docs/extensions/install-extension.md) +5. See documentation on [extension installation](https://github.com/Microsoft/vscode-docs/blob/master/docs/extensions/publish-extension.md) on ways to sideload or share. # Reporting issues If you encounter a problem and know it is caused by eclipse.jdt.ls, then please open a bug report over [there](https://github.com/eclipse/eclipse.jdt.ls/issues). In doubt, you can report issues in the [vscode-java issue tracker](https://github.com/redhat-developer/vscode-java/issues). -Try to collect as much informations as you can to describe the issue and help us reproduce the problem. Head over to the [troubleshooting page](https://github.com/redhat-developer/vscode-java/wiki/Troubleshooting#enable-logging) to see how to collect useful logging informations. \ No newline at end of file +Try to collect as much informations as you can to describe the issue and help us reproduce the problem. Head over to the [troubleshooting page](https://github.com/redhat-developer/vscode-java/wiki/Troubleshooting#enable-logging) to see how to collect useful logging informations. diff --git a/Jenkinsfile b/Jenkinsfile index 6a63945f3..d711deb52 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,24 +12,14 @@ def buildVscodeExtension(){ sh "npm run vscode:prepublish" } -def updateArchiveDownloadUrl(url){ - def downloadConfig = readJSON file: 'server_archive.json' - downloadConfig.production.url = url - writeJSON file:'server_archive.json', json: downloadConfig -} - node('rhel7'){ stage 'Build JDT LS' git url: 'https://github.com/eclipse/eclipse.jdt.ls.git' def mvnHome = tool 'maven-3.3.9' sh "${mvnHome}/bin/mvn clean verify -B -U -fae -e -Pserver-distro" - stage 'Upload Server to staging' def files = findFiles(glob: '**/org.eclipse.jdt.ls.product/distro/**.tar.gz') - sh "rsync -Pzrlt --rsh=ssh --protocol=28 ${files[0].path} tools@10.5.105.197:/downloads_htdocs/jbosstools/jdt.ls/staging" stash name: 'server_distro',includes :files[0].path - env.stageUrl = 'http://download.jboss.org/jbosstools/jdt.ls/staging/' + files[0].name - } node('rhel7'){ @@ -38,14 +28,15 @@ node('rhel7'){ deleteDir() git url: 'https://github.com/redhat-developer/vscode-java.git' - stage 'Update server archive url to staging' - updateArchiveDownloadUrl(env.stageUrl) - stage 'install vscode-java build requirements' installBuildRequirements() stage 'Build vscode-java' buildVscodeExtension() + unstash 'server_distro' + def files = findFiles(glob: '**/org.eclipse.jdt.ls.product/distro/**.tar.gz') + sh "mkdir ./server" + sh "tar -xvzf ${files[0].path} -C ./server" stage 'Test vscode-java for staging' wrap([$class: 'Xvnc']) { @@ -59,7 +50,7 @@ node('rhel7'){ stage 'Upload vscode-java to staging' def vsix = findFiles(glob: '**.vsix') sh "rsync -Pzrlt --rsh=ssh --protocol=28 ${vsix[0].path} tools@10.5.105.197:/downloads_htdocs/jbosstools/jdt.ls/staging" - stash excludes:'server/, .vscode-test/, **.vsix, target/' , name:'extension_source' + stash name:'vsix', includes:files[0].path } node('rhel7'){ @@ -67,31 +58,12 @@ node('rhel7'){ timeout(time:5, unit:'DAYS') { input message:'Approve deployment?', submitter: 'bercan' } - stage 'Upload Server to release' - unstash 'server_distro' - def files = findFiles(glob: '**/org.eclipse.jdt.ls.product/distro/**.tar.gz') - sh "rsync -Pzrlt --rsh=ssh --protocol=28 ${files[0].path} tools@10.5.105.197:/downloads_htdocs/tools/static/vscode" - def prodUrl = 'http://download.jboss.org/jbosstools/static/vscode/' + files[0].name - - stage 'Checkout vscode-java for release build' - deleteDir() - unstash 'extension_source' - - stage 'Update server archive url to release' - updateArchiveDownloadUrl(prodUrl) - archive includes:"server_archive.json" - - stage 'install vscode-java build requirements' - installBuildRequirements() - - stage 'Test vscode-java for release' - wrap([$class: 'Xvnc']) { - sh "npm test --silent" - } stage "Publish to Marketplace" + unstash vsix; withCredentials([[$class: 'StringBinding', credentialsId: 'vscode_java_marketplace', variable: 'TOKEN']]) { - sh 'vsce publish -p ${TOKEN}' + def vsix = findFiles(glob: '**.vsix') + sh 'vsce publish -p ${TOKEN} --packagePath ${vsix[0].path}' } archive includes:"**.vsix" }//if publishMarketPlace diff --git a/README.md b/README.md index f90509fe5..1c9c5f520 100644 --- a/README.md +++ b/README.md @@ -66,19 +66,15 @@ The following settings are supported: Troubleshooting =============== -1. Due to size restrictions on the marketplace extension downloads additional required parts check that they -are downloaded under `~/.vscode/extensions/redhat.java-0.2.0/server` folder. -You should see a folder named `plugins`. - -2. Check the status of the language tools on the lower right corner (marked with A on image below). +1. Check the status of the language tools on the lower right corner (marked with A on image below). It should show ready (thumbs up) as on the image below. You can click on the status and open the language tool logs for further information in case of a failure. ![ status indicator ](https://raw.githubusercontent.com/redhat-developer/vscode-java/master/images/statusMarker.png) -3. Read the [troubleshooting guide](https://github.com/redhat-developer/vscode-java/wiki/Troubleshooting) for collecting informations about issues you might encounter. +2. Read the [troubleshooting guide](https://github.com/redhat-developer/vscode-java/wiki/Troubleshooting) for collecting informations about issues you might encounter. -4. Report any problems you face to the [project](https://github.com/redhat-developer/vscode-java/issues). +3. Report any problems you face to the [project](https://github.com/redhat-developer/vscode-java/issues). Contributing =============== diff --git a/gulpfile.js b/gulpfile.js index 33ea9e300..114498737 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,9 +1,54 @@ 'use strict'; const gulp = require('gulp'); const gulp_tslint = require('gulp-tslint'); +const cp = require('child_process'); +const decompress = require('gulp-decompress'); +const download = require('gulp-download'); + //... gulp.task('tslint', () => { return gulp.src(['**/*.ts', '!**/*.d.ts', '!node_modules/**']) .pipe(gulp_tslint()) .pipe(gulp_tslint.report()); -}); \ No newline at end of file +}); + +gulp.task('download_server', ()=> +{ + download("http://download.eclipse.org/jdtls/snapshots/jdt-language-server-latest.tar.gz") + .pipe(decompress()) + .pipe(gulp.dest('./server')) +}); + +gulp.task('build_server', ()=> +{ + cp.execSync('mvn -f ../eclipse.jdt.ls/pom.xml -Pserver-distro clean package', {stdio:[0,1,2]} ); + gulp.src('../eclipse.jdt.ls/org.eclipse.jdt.ls.product/distro/*.tar.gz') + .pipe(decompress()) + .pipe(gulp.dest('./server')) +}); + +gulp.task('dev_server', ()=> +{ + let isWin = /^win/.test(process.platform); + let isMac = /^darwin/.test(process.platform); + let isLinux = /^linux/.test(process.platform); + let command = 'mvn -f ../eclipse.jdt.ls/pom.xml -Pserver-distro,fast -o clean package '; + if(isLinux){ + command +='-Denvironment.os=linux -Denvironment.ws=gtk -Denvironment.arch=x86_64'; + } + if(isMac){ + command += '-Denvironment.os=macosx -Denvironment.ws=cocoa -Denvironment.arch=x86_64'; + }else + if(isWin){ + command += '-Denvironment.os=win32 -Denvironment.ws=win32 -Denvironment.arch=x86_64'; + } + console.log('executing '+command); + cp.execSync(command, {stdio:[0,1,2]} ); + gulp.src('../eclipse.jdt.ls/org.eclipse.jdt.ls.product/distro/*.tar.gz') + .pipe(decompress()) + .pipe(gulp.dest('./server')) +}); + +gulp.task('watch_server',()=>{ + gulp.watch('../eclipse.jdt.ls/org.eclipse.jdt.ls.core/**/*.java',['dev_server']); +}) diff --git a/package.json b/package.json index 748327b47..7d8555409 100644 --- a/package.json +++ b/package.json @@ -114,11 +114,9 @@ "compile": "tsc -watch -p ./", "postinstall": "node ./node_modules/vscode/bin/install", "test": "node ./node_modules/vscode/bin/test", - "build-server": "mvn -f ../eclipse.jdt.ls/pom.xml -Pvscode-build clean package", - "build-server-mac": "mvn -f ../eclipse.jdt.ls/pom.xml -Pvscode-build,fast -Denvironment.os=macosx -Denvironment.ws=cocoa -Denvironment.arch=x86_64 clean package -o", - "build-server-win": "mvn -f ../eclipse.jdt.ls/pom.xml -Pvscode-build,fast -Denvironment.os=win32 -Denvironment.ws=win32 -Denvironment.arch=x86_64 clean package -o", - "build-server-linux": "mvn -f ../eclipse.jdt.ls/pom.xml -Pvscode-build,fast -Denvironment.os=linux -Denvironment.ws=gtk -Denvironment.arch=x86_64 clean package -o", - "tslint": "gulp tslint" + "build-server": "./node_modules/.bin/gulp build_server", + "watch-server": "./node_modules/.bin/gulp watch_server", + "tslint": "./node_modules/.bin/gulp tslint" }, "devDependencies": { "typescript": "^2.2.1", @@ -129,13 +127,13 @@ "@types/glob":"5.0.30", "gulp" :"^3.9.1", "gulp-tslint": "^7.1.0", - "tslint" : "^4.4.2" + "tslint" : "^4.4.2", + "gulp-decompress":"2.0.1", + "gulp-download":"0.0.1" }, "dependencies": { "vscode-languageclient": "^3.2.0", "find-java-home": "0.1.4", - "http-proxy-agent": "^1.0.0", - "https-proxy-agent": "^1.0.0", "tmp" : "^0.0.31", "decompress": "^4.0.0", "progress-stream": "^1.2.0", @@ -143,4 +141,4 @@ "expand-home-dir":"^0.0.3", "glob":"^7.1.1" } -} \ No newline at end of file +} diff --git a/src/downloadManager.ts b/src/downloadManager.ts deleted file mode 100644 index 851a00103..000000000 --- a/src/downloadManager.ts +++ /dev/null @@ -1,133 +0,0 @@ - -import * as https from 'https'; -import * as http from 'http'; -import * as fs from 'fs'; -import * as vscode from 'vscode'; -import * as path from 'path'; -import * as stream from 'stream'; -import {Url, parse} from 'url'; - -const HttpProxyAgent = require('http-proxy-agent'); -const HttpsProxyAgent = require('https-proxy-agent'); -const tmp = require('tmp'); -const decompress = require('decompress'); -const progress = require('progress-stream'); - -let downloadProgressItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, Number.MIN_VALUE); -function closeDownloadProgressItem(){ - downloadProgressItem.hide(); - downloadProgressItem.dispose(); -} - -function download(urlString: string, proxy?: string, strictSSL?: boolean): Promise { - let url = parse(urlString); - const agent = getProxyAgent(url, proxy, strictSSL); - - let options: https.RequestOptions = { - host: url.host, - port: url.port ? parseInt(url.port) : (url.protocol === 'https:' ? 443 : 80), - path: url.path, - agent: agent, - rejectUnauthorized: strictSSL - }; - - return new Promise((resolve, reject) => { - var request; - var downloadExec = function(res : http.IncomingMessage) { - // handle redirection - if (res.statusCode === 302) { - return download(res.headers.location).then(is => resolve(is)).catch(err => reject(err)); - } - else if (res.statusCode !== 200) { - return reject(Error(`Download failed with code ${res.statusCode}.`)); - } - let len = parseInt(res.headers['content-length'], 10); - let progressStream = progress({ - length: len, - time: 500 - }); - downloadProgressItem.text = 'Completing Java installation'; - downloadProgressItem.show(); - progressStream.on('progress', function (progressData) { - downloadProgressItem.text = 'Completing Java installation ' + Number.parseInt(progressData.percentage) + '%'; - }); - return resolve(res.pipe(progressStream)); - - }; - if (url.protocol.startsWith('https')){ - request = https.get(options, downloadExec); - } else { - request = http.get(options, downloadExec); - } - request.setTimeout(30000, ()=>{request.abort();}); - return request; - }); -} - -function getSystemProxyURL(requestURL: Url): string { - if (requestURL.protocol === 'http:') { - return process.env.HTTP_PROXY || process.env.http_proxy || null; - } else if (requestURL.protocol === 'https:') { - return process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy || null; - } - return null; -} - -function getProxyAgent(requestURL: Url, proxy?: string, strictSSL?: boolean): any { - const proxyURL = proxy || getSystemProxyURL(requestURL); - if (!proxyURL) { - return null; - } - const proxyEndpoint = parse(proxyURL); - - if (!/^https?:$/.test(proxyEndpoint.protocol)) { - return null; - } - - const opts = { - host: proxyEndpoint.hostname, - port: Number(proxyEndpoint.port), - auth: proxyEndpoint.auth, - rejectUnauthorized: strictSSL - }; - return requestURL.protocol === 'http:' ? new HttpProxyAgent(opts) : new HttpsProxyAgent(opts); -} - -export function downloadAndInstallServer() { - return new Promise((resolve, reject) => { - const config = vscode.workspace.getConfiguration(); - const proxy = config.get('http.proxy'); - const strictSSL = config.get('http.proxyStrictSSL', true); - const SERVER_FOLDER = path.resolve(__dirname, '../../server/'); - // const SERVER_ARCHIVE = "https://dl.bintray.com/gorkem/java-language-server/jdt-language-server-.tar.gz"; - // Always use HTTPS download for http adresses may not work over proxies. - const SERVER_ARCHIVE_CONFIG = require('../../server_archive.json'); - - return download(SERVER_ARCHIVE_CONFIG['production']['url'], proxy, strictSSL).then(is => { - tmp.file((err, tmpPath, fd, cleanupCallback) => { - const out = fs.createWriteStream(null, { fd: fd }); - // handle errors - out.once('error', err => { - closeDownloadProgressItem(); - reject(err); - }); - is.once('error', err => { - closeDownloadProgressItem(); - reject(err); - }); - out.once('finish', () => { - decompress(tmpPath, SERVER_FOLDER).then(files => { - closeDownloadProgressItem(); - return resolve(true); - }).catch(err => { - closeDownloadProgressItem(); - return reject(err); - }); - }); - is.pipe(out); - }); - }).catch(err => { - console.log(err); - }); - }); -} diff --git a/src/requirements.ts b/src/requirements.ts index aa4b29150..993e826f9 100644 --- a/src/requirements.ts +++ b/src/requirements.ts @@ -2,9 +2,7 @@ import { workspace, Uri } from 'vscode'; import * as cp from 'child_process'; -import * as fs from 'fs'; import * as path from 'path'; -import * as downloadManager from './downloadManager'; const pathExists = require('path-exists'); const expandHomeDir = require('expand-home-dir'); @@ -24,16 +22,15 @@ interface ErrorData { replaceClose: boolean; } /** - * Resolves the requirements needed to run the extension. - * Returns a promise that will resolve to a RequirementsData if - * all requirements are resolved, it will reject with ErrorData if + * Resolves the requirements needed to run the extension. + * Returns a promise that will resolve to a RequirementsData if + * all requirements are resolved, it will reject with ErrorData if * if any of the requirements fails to resolve. - * + * */ export async function resolveRequirements(): Promise { let java_home = await checkJavaRuntime(); let javaVersion = await checkJavaVersion(java_home); - await checkServerInstalled(); return Promise.resolve({ 'java_home': java_home, 'java_version': javaVersion}); } @@ -94,20 +91,6 @@ function checkJavaVersion(java_home: string): Promise { }); } -function checkServerInstalled(): Promise { - let pluginsPath = path.resolve(__dirname, '../../server/plugins'); - try { - let isDirectory = fs.lstatSync(pluginsPath); - if (isDirectory) { - return Promise.resolve(true); - } - } - catch (err) { - // Directory does not exist - } - return downloadManager.downloadAndInstallServer(); -} - function openJDKDownload(reject, cause) { let jdkUrl = 'http://developers.redhat.com/products/openjdk/overview/'; if (process.platform === 'darwin') { @@ -119,4 +102,4 @@ function openJDKDownload(reject, cause) { openUrl: Uri.parse(jdkUrl), replaceClose: false }); -} \ No newline at end of file +} diff --git a/test/downloadManager.test.ts b/test/downloadManager.test.ts deleted file mode 100644 index b80bb8979..000000000 --- a/test/downloadManager.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -import * as assert from 'assert'; -import * as path from 'path'; -import * as fs from 'fs'; -import * as downloadManager from '../src/downloadManager'; - - -suite('Java Language Extension downloadManager tests', () => { - - // Defines a Mocha unit test - test('Download server', function() { - this.timeout(2*60*1000); - return downloadManager.downloadAndInstallServer() - .then(() => { - let pluginsPath = path.resolve(__dirname, '../../server/plugins'); - try { - console.log(pluginsPath); - let isDirectory = fs.lstatSync(pluginsPath); - assert.ok(isDirectory,'plugins folder is not found'); - } - catch (err) { - assert.ifError(err); - } - }); - }); -}); \ No newline at end of file