diff --git a/.gitignore b/.gitignore index 1f4eda1..2102644 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,10 @@ cli/lib/galen/* core/lib/location.js lcli/ib/location.js core/coverage/* +core/target/* cli/coverage/* +cli/target/* + # IDE .idea/* diff --git a/.travis.yml b/.travis.yml index fd262d3..461801d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,9 +3,10 @@ dist: trusty language: node_js after_success: npm run coverage && cat ./coverage/lcov.info | coveralls node_js: - - "0.12" - "4.0" - "4.3" + - "4.4" + - "4.6" - "4" - "5.0" - "5" diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..b22b2e6 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,46 @@ +properties properties: [ + [$class: 'BuildDiscarderProperty', strategy: [$class: 'LogRotator', artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '30', numToKeepStr: '10']], + [$class: 'GithubProjectProperty', displayName: '', projectUrlStr: 'https://github.com/hypery2k/galenframework-cli'], +] + +node { + def buildNumber = env.BUILD_NUMBER + def workspace = env.WORKSPACE + def buildUrl = env.BUILD_URL + + // PRINT ENVIRONMENT TO JOB + echo "workspace directory is $workspace" + echo "build URL is $buildUrl" + echo "build Number is $buildNumber" + echo "PATH is $env.PATH" + + try { + stage('Checkout') { + checkout scm + } + + stage('Build') { + sh "cd core && npm install" + sh "cd cli && npm install" + } + + stage('Test') { + sh "cd core && npm run test" + sh "cd cli && npm run test" + junit '*/target/tests.js.xml' + } + + stage('Publish NPM snapshot') { + def currentVersionCore = sh(returnStdout: true, script: "cd core && npm version | grep \"{\" | tr -s ':' | cut -d \"'\" -f 2").trim() + def newVersionCore = "${currentVersionCore}-${buildNumber}" + sh "cd core && npm version ${newVersionCore} --no-git-tag-version && npm publish --tag next" + def currentVersionCli = sh(returnStdout: true, script: "cd cli && npm version | grep \"{\" | tr -s ':' | cut -d \"'\" -f 4").trim() + def newVersionCli = "${currentVersionCli}-${buildNumber}" + sh "cd cli && npm version ${newVersionCli} --no-git-tag-version && npm publish --tag next" + } + + } catch (e) { + mail subject: "${env.JOB_NAME} (${env.BUILD_NUMBER}): Error on build", to: 'github@martinreinhardt-online.de', body: "Please go to ${env.BUILD_URL}." + throw e + } +} diff --git a/README.md b/README.md index 3d79db4..ce37d5b 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,6 @@ The [core](core/) module is just the node wrapper for [Galen](http://galenframework.com) and can be used within CI environments -The [CLI](cli/) module is a command line module for [Galen](http://galenframework.com). This includes the core above and webdriver downloads for different browsers. +The [cli](cli/) module is a command line module for [Galen](http://galenframework.com). This includes the core above and webdriver downloads for different browsers. [![Join the chat at https://gitter.im/hypery2k/galenframework-cli](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/hypery2k/galenframework-cli?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=15642797)](https://www.bountysource.com/trackers/15642797-hypery2k-galenframework-cli?utm_source=15642797&utm_medium=shield&utm_campaign=TRACKER_BADGE) [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=mreinhardt&url=https://github.com/hypery2k/galenframework-cli&title=badges&language=&tags=github&category=software) diff --git a/cli/README.MD b/cli/README.MD index b7c1ceb..f7776c7 100644 --- a/cli/README.MD +++ b/cli/README.MD @@ -1,6 +1,6 @@ # Galenframework CLI -[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](LICENSE) +[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](LICENSE) [![npm version](https://badge.fury.io/js/galenframework-cli.svg)](http://badge.fury.io/js/galenframework-cli) [![Dependency Status](https://david-dm.org/hypery2k/galenframework-cli.svg)](https://david-dm.org/hypery2k/galenframework-cli) [![devDependency Status](https://david-dm.org/hypery2k/galenframework-cli/dev-status.svg)](https://david-dm.org/hypery2k/galenframework-cli#info=devDependencies) [![Coverage Status](https://coveralls.io/repos/hypery2k/galenframework-cli/badge.svg?branch=master&service=github)](https://coveralls.io/github/hypery2k/galenframework-cli?branch=master) @@ -12,14 +12,14 @@ [![NPM](https://nodei.co/npm/galenframework-cli.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/galenframework-cli/) > Feel free to **donate** -> +> > Click here to lend your support to: NPM packages and make a donation at pledgie.com ! > > > > Or donate [Bitcoins](bitcoin:3NKtxw1SRYgess5ev4Ri54GekoAgkR213D): > [![Bitcoin](https://martinreinhardt-online.de/bitcoin.png)](bitcoin:3NKtxw1SRYgess5ev4Ri54GekoAgkR213D) -> +> > Also via [greenaddress](https://greenaddress.it/pay/GA3ZPfh7As3Gc2oP6pQ1njxMij88u/) @@ -29,6 +29,10 @@ You must have Java 6+ installed. > (sudo) npm install -g galenframework-cli +Or the develop build, which maybe **not be stable** + +> (sudo) npm install -g galenframework-cli@next + If you want to enable tab completion on Linux, run > galen completion >> ~/.~/.bashrc diff --git a/cli/install.js b/cli/install.js index ed144ab..b17f0de 100755 --- a/cli/install.js +++ b/cli/install.js @@ -1,4 +1,4 @@ -// Copyright 2015 Martin Reinhardt +// Copyright 2016 Martin Reinhardt /* * This simply downloads Galen @@ -14,6 +14,7 @@ var npmconf = require('npmconf'); var path = require('path'); var httpreq = require('httpreq'); var which = require('which'); +var log = require('npmlog'); var originalPath = process.env.PATH; @@ -22,7 +23,7 @@ var validExit = false; process.on('exit', function () { if (!validExit) { - console.log('Install exited unexpectedly'); + log.info('Install exited unexpectedly'); exit(1); } }); @@ -54,13 +55,13 @@ whichDeferred.promise // Horrible hack to avoid problems during global install. We check to see if // the file `which` found is our own bin script. if (galenPath.indexOf(path.join('npm', 'galenframework-cli')) !== -1) { - console.log('Looks like an `npm install -g` on windows; unable to check for already installed version.'); + log.info('Looks like an `npm install -g` on windows; unable to check for already installed version.'); throw new Error('Global install'); } var contents = fs.readFileSync(galenPath, 'utf8'); if (/NPM_INSTALL_MARKER/.test(contents)) { - console.log('Looks like an `npm install -g`; unable to check for already installed version.'); + log.info('Looks like an `npm install -g`; unable to check for already installed version.'); throw new Error('Global install'); } else { var checkVersionDeferred = kew.defer(); @@ -69,7 +70,7 @@ whichDeferred.promise } }) .then(function () { - console.log('galenframework-cli detected'); + log.info('galenframework-cli detected'); var npmconfDeferred = kew.defer(); npmconf.load(npmconfDeferred.makeNodeResolver()); return npmconfDeferred.promise; @@ -87,22 +88,22 @@ whichDeferred.promise var fileName = downloadUrl.split('/').pop(); var downloadedFile = path.join(tmpPath, fileName); if (!fs.existsSync(downloadedFile)) { - console.log('Downloading', downloadUrl); + log.info('Downloading', downloadUrl); return requestBinary(downloadUrl, downloadedFile); } else { - console.log('Download already available at', downloadedFile); + log.info('Download already available at', downloadedFile); return downloadedFile; } }).then(function (downloadedFile) { // request to open safari extension installation var spawn = require('child_process').spawn; - console.log('Opening file ', downloadedFile); + log.info('Opening file ', downloadedFile); spawn('open', [downloadedFile], { detached: true }); exit(0); }).fail(function (err) { - console.error('Safari Driver installation failed', err, err.stack); + log.error('Safari Driver installation failed', err, err.stack); exit(1); }); } else { @@ -110,7 +111,7 @@ whichDeferred.promise } }) .fail(function (err) { - console.error('Galen installation failed', err, err.stack); + log.error('Galen installation failed', err, err.stack); exit(1); }); @@ -142,30 +143,30 @@ function findSuitableTempDirectory(npmConf) { fs.unlinkSync(testFile); return candidatePath; } catch (e) { - console.log(candidatePath, 'is not writable:', e.message); + log.info(candidatePath, 'is not writable:', e.message); } } - console.error('Can not find a writable tmp directory.'); + log.error('Can not find a writable tmp directory.'); exit(1); } function requestBinary(url, dest) { var deferred = kew.defer(); - console.log('Receiving...'); + log.info('Receiving...'); httpreq.get(url, {binary: true}, function (err, res) { if (err) { deferred.reject(err); - console.error('Error making request.'); + log.error('Error making request.'); } else { fs.writeFile(dest, res.body, function (err) { if (err) { deferred.reject(err); - console.log('Error writing file'); + log.info('Error writing file'); } else { - console.log('Saved to', dest); + log.info('Saved to', dest); deferred.resolve(dest); } }); diff --git a/cli/package.json b/cli/package.json index f5c5583..30df1fb 100644 --- a/cli/package.json +++ b/cli/package.json @@ -22,7 +22,7 @@ "galen": "bin/galen", "install": "node install.js", "postinstall": "node postinstall.js", - "test": "nodeunit --reporter=minimal test/tests.js", + "test": "nodeunit --reporter=junit test/tests.js --output target", "pretest": "jshint -c ../.jshintrc --filename *.js && jshint -c ../.jshintrc --filename lib/*.js && jshint -c ../.jshintrc --filename test/*.js", "coverage": "istanbul -- cover nodeunit test/tests.js && istanbul-coveralls --no-rm" }, @@ -33,10 +33,11 @@ "dependencies": { "chromedriver": "*", "fs-extra": "0.26.2", - "galenframework": "2.3.0", + "galenframework": "2.3.1", "httpreq": "0.4.13", "kew": "0.7.0", "npmconf": "2.1.2", + "npmlog": "4.0.0", "path": "0.12.7", "which": "1.2.0", "yargs": "3.30.0" diff --git a/core/README.MD b/core/README.MD index 8b23f92..c45d231 100644 --- a/core/README.MD +++ b/core/README.MD @@ -13,14 +13,14 @@ If you want to install Galen as CLI command install the [CLI-module](https://www > Feel free to **donate** -> +> > Click here to lend your support to: NPM packages and make a donation at pledgie.com ! > > > > Or donate [Bitcoins](bitcoin:3NKtxw1SRYgess5ev4Ri54GekoAgkR213D): > [![Bitcoin](https://martinreinhardt-online.de/bitcoin.png)](bitcoin:3NKtxw1SRYgess5ev4Ri54GekoAgkR213D) -> +> > Also via [greenaddress](https://greenaddress.it/pay/GA3ZPfh7As3Gc2oP6pQ1njxMij88u/) ## Installation @@ -29,6 +29,10 @@ You must have Java 6+ installed. > (sudo) npm install -g galenframework +Or the develop build, which maybe **not be stable** + +> (sudo) npm install -g galenframework@next + In case of errors within Ubuntu/Debian, e.g. ``` sh: 1: node: not find diff --git a/core/install.js b/core/install.js index 49e0133..b24f1c6 100755 --- a/core/install.js +++ b/core/install.js @@ -1,4 +1,4 @@ -// Copyright 2015 Martin Reinhardt +// Copyright 2016 Martin Reinhardt /* * This simply downloads Galen @@ -19,6 +19,7 @@ var path = require('path'); var request = require('request'); var url = require('url'); var which = require('which'); +var log = require('npmlog'); var cdnUrl = process.env.npm_config_galen_url || process.env.GALEN_CDNURL || @@ -32,7 +33,7 @@ var validExit = false; process.on('exit', function () { if (!validExit) { - console.log('Install exited unexpectedly'); + log.error('Install exited unexpectedly'); exit(1); } }); @@ -66,13 +67,13 @@ whichDeferred.promise // Horrible hack to avoid problems during global install. We check to see if // the file `which` found is our own bin script. if (galenPath.indexOf(path.join('npm', 'galenframework')) !== -1) { - console.log('Looks like an `npm install -g` on windows; unable to check for already installed version.'); + log.info('Looks like an `npm install -g` on windows; unable to check for already installed version.'); throw new Error('Global install'); } var contents = fs.readFileSync(galenPath, 'utf8'); if (/NPM_INSTALL_MARKER/.test(contents)) { - console.log('Looks like an `npm install -g`; unable to check for already installed version.'); + log.info('Looks like an `npm install -g`; unable to check for already installed version.'); throw new Error('Global install'); } else { var checkVersionDeferred = kew.defer(); @@ -81,13 +82,15 @@ whichDeferred.promise } }) .then(function (stdout) { - var version = stdout.trim(); + var regex = /^Version: ([0-9\.]+)$/ + var result = stdout.trim().match(regex); + var version = result[1]; if (helper.version == version) { writeLocationFile(galenPath); - console.log('galenframework is already installed at', galenPath + '.'); + log.info('galenframework is already installed at', galenPath + '.'); exit(0); } else { - console.log('galenframework detected, but wrong version', stdout.trim(), '@', galenPath + '.'); + log.info('galenframework detected, but wrong version', stdout.trim(), '@', galenPath + '.'); throw new Error('Wrong version'); } }) @@ -104,15 +107,15 @@ whichDeferred.promise var fileName = downloadUrl.split('/').pop(); var downloadedFile = path.join(tmpPath, fileName); - console.log('Running at platform: ' + process.platform); + log.info('Running at platform: ' + process.platform); // Start the install. if (!fs.existsSync(downloadedFile)) { - console.log('Downloading', downloadUrl); - console.log('Saving to', downloadedFile); + log.info('Downloading', downloadUrl); + log.info('Saving to', downloadedFile); return requestBinary(getRequestOptions(conf), downloadedFile); } else { - console.log('Download already available at', downloadedFile); + log.info('Download already available at', downloadedFile); return { requestOptions: getRequestOptions(conf), downloadedFile: downloadedFile @@ -129,7 +132,7 @@ whichDeferred.promise var location = libPath; writeLocationFile(location); - console.log('Done. galen binary available at ', location); + log.info('Done. galen binary available at ', location); // Ensure executable is executable by all users fs.chmodSync(location, '755'); fs.chmodSync(location + '/galen/galen', '755'); @@ -142,15 +145,15 @@ whichDeferred.promise function (error, changedFiles) { //Catch errors if (error) { - console.error('Error occurred:', error); + log.error('Error occurred:', error); } //List changed files - console.log('Modified files:', changedFiles.join(', ')); + log.info('Modified files:', changedFiles.join(', ')); exit(0); }); }) .fail(function (err) { - console.error('Galen installation failed', err, err.stack); + log.error('Galen installation failed', err, err.stack); exit(1); }); @@ -159,7 +162,7 @@ whichDeferred.promise * @param {string} location - path of the directory */ function writeLocationFile(location) { - console.log('Writing location.js file'); + log.info('Writing location.js file'); if (process.platform === 'win32') { location = location.replace(/\\/g, '\\\\'); } @@ -205,11 +208,11 @@ function findSuitableTempDirectory(npmConf) { fs.unlinkSync(testFile); return candidatePath; } catch (e) { - console.log(candidatePath, 'is not writable:', e.message); + log.info(candidatePath, 'is not writable:', e.message); } } - console.error('Can not find a writable tmp directory.'); + log.error('Can not find a writable tmp directory.'); exit(1); } @@ -222,7 +225,7 @@ function findSuitableTempDirectory(npmConf) { function getRequestOptions(conf) { var strictSSL = conf.get('strict-ssl'); if (process.version == 'v0.10.34') { - console.log('Node v0.10.34 detected, turning off strict ssl due to https://github.com/joyent/node/issues/8894'); + log.info('Node v0.10.34 detected, turning off strict ssl due to https://github.com/joyent/node/issues/8894'); strictSSL = false; } @@ -244,7 +247,7 @@ function getRequestOptions(conf) { // Mask password proxy.auth = proxy.auth.replace(/:.*$/, ':******'); } - console.log('Using proxy ' + url.format(proxy)); + log.info('Using proxy ' + url.format(proxy)); // Enable proxy options.proxy = proxyUrl; @@ -256,7 +259,7 @@ function getRequestOptions(conf) { // Use certificate authority settings from npm var ca = conf.get('ca'); if (ca) { - console.log('Using npmconf ca'); + log.info('Using npmconf ca'); options.ca = ca; } @@ -274,13 +277,13 @@ function requestBinary(requestOptions, filePath) { var deferred = kew.defer(); var writePath = filePath + '-download-' + Date.now(); - console.log('Receiving...'); + log.info('Receiving...'); var bar = null; requestProgress(request(requestOptions, function (error, response, body) { - console.log(''); + log.info(''); if (!error && response.statusCode === 200) { fs.writeFileSync(writePath, body); - console.log('Received ' + Math.floor(body.length / 1024) + 'K total.'); + log.info('Received ' + Math.floor(body.length / 1024) + 'K total.'); fs.renameSync(writePath, filePath); deferred.resolve({ requestOptions: requestOptions, @@ -288,21 +291,21 @@ function requestBinary(requestOptions, filePath) { }); } else if (response) { - console.error('Error requesting archive.\n' + + log.error('Error requesting archive.\n' + 'Status: ' + response.statusCode + '\n' + 'Request options: ' + JSON.stringify(requestOptions, null, 2) + '\n' + 'Response headers: ' + JSON.stringify(response.headers, null, 2) + '\n' + 'Make sure your network and proxy settings are correct.\n\n'); exit(1); } else if (error && error.stack && error.stack.indexOf('SELF_SIGNED_CERT_IN_CHAIN') != -1) { - console.error('Error making request.'); + log.error('Error making request.'); exit(1); } else if (error) { - console.error('Error making request.\n' + error.stack + '\n\n' + + log.error('Error making request.\n' + error.stack + '\n\n' + 'Please report this full log at https://github.com/hypery2k/galenframework-cli/issues'); exit(1); } else { - console.error('Something unexpected happened, please report this full ' + + log.error('Something unexpected happened, please report this full ' + 'log at https://github.com/hypery2k/galenframework-cli/issues'); exit(1); } @@ -338,30 +341,30 @@ function extractDownload(filePath, requestOptions, retry) { fs.chmodSync(extractedPath, '0777'); if (filePath.substr(-4) === '.zip') { - console.log('Extracting zip contents'); + log.info('Extracting zip contents'); try { var zip = new AdmZip(filePath); zip.extractAllTo(extractedPath, true); deferred.resolve(extractedPath); } catch (err) { - console.error('Error extracting zip'); + log.error('Error extracting zip'); deferred.reject(err); } } else { - console.log('Extracting tar contents (via spawned process)'); + log.info('Extracting tar contents (via spawned process)'); cp.execFile('tar', ['jxf', filePath], options, function (err) { if (err) { if (!retry) { - console.log('Error during extracting. Trying to download again.'); + log.info('Error during extracting. Trying to download again.'); fs.unlinkSync(filePath); return requestBinary(requestOptions, filePath).then(function (downloadedFile) { return extractDownload(downloadedFile, requestOptions, true); }); } else { deferred.reject(err); - console.error('Error extracting archive'); + log.error('Error extracting archive'); } } else { deferred.resolve(extractedPath); @@ -379,19 +382,19 @@ function extractDownload(filePath, requestOptions, retry) { * @function */ function copyIntoPlace(extractedPath, targetPath) { - console.log('Removing', targetPath); + log.info('Removing', targetPath); return kew.nfcall(fs.remove, targetPath).then(function () { // Look for the extracted directory, so we can rename it. var files = fs.readdirSync(extractedPath); for (var i = 0; i < files.length; i++) { var file = path.join(extractedPath, files[i]); if (fs.statSync(file).isDirectory() && file.indexOf(helper.version) != -1) { - console.log('Copying extracted folder', file, '->', targetPath); + log.info('Copying extracted folder', file, '->', targetPath); return kew.nfcall(fs.move, file, targetPath); } } - console.log('Could not find extracted file', files); + log.info('Could not find extracted file', files); throw new Error('Could not find extracted file'); }); } diff --git a/core/package.json b/core/package.json index 5272aad..76b17a5 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "galenframework", - "version": "2.3.0", + "version": "2.3.1", "description": "The command line tool to use the Galen Framework. This includes the wrapper above and webdriver downloads for different browsers", "homepage": "https://github.com/hypery2k/galenframework-cli", "bugs": { @@ -21,8 +21,9 @@ "scripts": { "galen": "bin/galen", "install": "node install.js", - "test": "nodeunit --reporter=minimal test/tests.js", + "test": "nodeunit --reporter=junit test/tests.js --output target", "pretest": "jshint -c ../.jshintrc --filename *.js && jshint -c ../.jshintrc --filename lib/*.js && jshint -c ../.jshintrc --filename test/*.js", + "prepublish": "npm run test", "coverage": "istanbul -- cover nodeunit test/tests.js && istanbul-coveralls --no-rm" }, "bin": { @@ -33,6 +34,7 @@ "fs-extra": "^0.23.0", "kew": "0.6.0", "npmconf": "2.1.2", + "npmlog": "4.0.0", "progress": "1.1.8", "replace-in-file": "1.0.2", "request": "2.60.0", @@ -53,7 +55,7 @@ "url": "git+https://github.com/hypery2k/galenframework-cli.git" }, "license": "MIT", - "_galenVersion": "2.3.0", + "_galenVersion": "2.3.1", "_npmVersion": "2.6.0", "_nodeVersion": "1.4.1" }