Skip to content
This repository was archived by the owner on Feb 28, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 29 additions & 24 deletions app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ module.exports = class extends Generator {
constructor(args, opts) {
super(args, opts);

if ( typeof opts.bluemix.quiet == "undefined" || ! opts.bluemix.quiet ) {
logger.info("Package info ::", Bundle.name, Bundle.version);
}

// bluemix option for YaaS integration
this.argument(OPTION_BLUEMIX, {
desc: 'Option for deploying with Bluemix. Stringified JSON.',
Expand All @@ -50,16 +54,16 @@ module.exports = class extends Generator {
this.skipPrompt = true;
let bluemix_ok= this._sanitizeOption(this.options, OPTION_BLUEMIX);
let spec_ok= this._sanitizeOption(this.options, OPTION_SPEC);
if ( ! (bluemix_ok || spec_ok )) throw ("Must specify either bluemix or spec parameter");
if ( typeof this.options.bluemix.quiet == "undefined" || ! this.options.bluemix.quiet ) {
if ( ! (bluemix_ok || spec_ok )) throw ("Must specify either bluemix or spec parameter");

if ( typeof this.options.bluemix.quiet == "undefined" || ! this.options.bluemix.quiet ) {
logger.info("Package info ::", Bundle.name, Bundle.version);
}
}

let appName = this.options.bluemix.name || this.options.spec.appname;
this.options.sanitizedAppName = this._sanitizeAppName(appName);
this.options.genSwagger= false;
this.options.openApiFileType= "yaml"; // default
this.options.genSwagger= false;
this.options.openApiFileType= "yaml"; // default

this.options.parsedSwagger = undefined;
let formatters = {
Expand All @@ -75,18 +79,18 @@ module.exports = class extends Generator {
.then(response => {
this.options.loadedApi = response.loaded;
this.options.parsedSwagger = response.parsed;
this.options.openApiFileType= response.type;
this.options.genSwagger= true;
this.options.openApiFileType= response.type;
this.options.genSwagger= true;
})
.catch(err => {
err.message = 'failed to parse document from bluemix.openApiServers ' + err.message;
throw err;
})
}

// micro service always gets swagger ui and no public
// micro service always gets swagger ui and no public
if(this.options.spec && this.options.spec.applicationType === 'MS') {
this.options.genSwagger= true;
this.options.genSwagger= true;
}

}
Expand Down Expand Up @@ -115,34 +119,35 @@ module.exports = class extends Generator {
this.fs.copyTpl(this.templatePath('Dockerfile-tools'), this.destinationPath('Dockerfile-tools'), this.options);
this.fs.copyTpl(this.templatePath('package.json'), this.destinationPath('package.json'), this.options);
this.fs.copyTpl(this.templatePath('README.md'), this.destinationPath('README.md'), this.options);
this.fs.copyTpl(this.templatePath('idt.js'), this.destinationPath('idt.js'), this.options);

// if project will have swagger doc, ensure swagger ui and api route
// if project will have swagger doc, ensure swagger ui and api route
if ( this.options.genSwagger ) {
this.fs.copy(this.templatePath('public/swagger-ui'), this.destinationPath('public/swagger-ui'));
// if open api doc provided, write it else write default
// if open api doc provided, write it else write default

if ( this.options.loadedApi ) {
let yaml= this.options.bluemix.openApiServers[0].spec;
//this.fs.writeJSON('public/swagger.'+this.options.openApiFileType, this.options.loadedApi);
this.fs.write('public/swagger.'+this.options.openApiFileType, yaml);
}
this.fs.write('public/swagger.'+this.options.openApiFileType, yaml);
}
else {
this.fs.copyTpl(this.templatePath('public/swagger.yaml'), this.destinationPath('public/swagger.yaml'), this.options);
}
}
else {
else {
this.fs.delete(this.destinationPath('server/routers/swagger.js'));
}

// if there is swagger, there is no index page
if( this.options.genSwagger ) {
this.fs.delete(this.destinationPath('server/routers/public.js'));
}
else {
else {
this.fs.copy(this.templatePath('public/index.html'), this.destinationPath('public/index.html'));
}

// blank project is stripped down to bare minimum
// blank project is stripped down to bare minimum
if(this.options.spec && this.options.spec.applicationType === 'BLANK') {
this.fs.delete(this.destinationPath('server/routers/health.js'));
}
Expand All @@ -153,29 +158,29 @@ module.exports = class extends Generator {
return name.toLowerCase().replace(REGEX_LEADING_ALPHA, '').replace(REGEX_ALPHA_NUM, '');
}

// return true if 'sanitized', false if missing, exception if bad data
// return true if 'sanitized', false if missing, exception if bad data
_sanitizeOption(options, name) {
let optionValue = options[name];
if (!optionValue) {
logger.error("Missing", name, "parameter");
return false;
return false;
}

if (typeof optionValue === "string" && optionValue.indexOf("file:") === 0) {
let fileName = optionValue.replace("file:", "");
let filePath = this.destinationPath("./" + fileName);
logger.info("Reading", name, "parameter from local file", filePath);
this.options[name] = this.fs.readJSON(filePath);
return true;
return true;
}

try {
this.options[name] = typeof(this.options[name]) === "string" ?
JSON.parse(this.options[name]) : this.options[name];
return true;
return true;
} catch (e) {
logger.error(e);
throw name + " parameter is expected to be a valid stringified JSON object";
}
}
}
};
};
77 changes: 77 additions & 0 deletions app/templates/idt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const fs = require('fs');
const process = require('process');
const cp = require('child_process');
const request = require('request');
const path = require('path');

const chalk = require('chalk');

const node = process.execPath;
// Array of args passed to idt.js.
const args = process.argv.slice(2);
let win = (process.platform === 'win32');

// Either install idt or run bx dev.
if (args.includes('install')) {
downloadInstaller();
} else {
// TODO(gib): Check for idt once this works in scripts.
// const checkCmd = win ? 'where idt' : 'which idt';
const checkCmd = 'bx plugin show dev';
let hasIDT = false;
try {
console.log(chalk.blue('Checking for idt'));
cp.execSync(checkCmd); // Don't inherit stdio, we don't want to print the path.
hasIDT = true; // If we didn't have idt, the previous command would have thrown.
} catch (e) {
const prompt = require('prompt-confirm');
new prompt({ name: 'install',
message: 'IDT not found, do you want to install it? y/N',
default: false
}).ask((answer) => {
if (answer) {
downloadInstaller(() => runIDT(args));
} else {
console.error(chalk.red(`Not installing idt, so not running: idt ${args.join(' ')}`));
}
});
}
if (hasIDT) runIDT(args);
}

// Run IDT with whatever args we were given.
function runIDT(args) {
const cmd = 'bx dev ' + args.join(' ');
console.log(chalk.blue('Running:'), cmd);
cp.execSync(cmd, {stdio: 'inherit'});
}

// Download the IDT installer script and trigger run.
function downloadInstaller(cb) {
const url = win ?
'http://ibm.biz/idt-win-installer' :
'https://ibm.biz/idt-installer';

const fileName = url.split('/').pop()

console.log(chalk.blue('Downloading installer from:'), url);

const file = fs.createWriteStream(fileName);

request
.get({url, followAllRedirects: true})
.on('error', (err) => { console.error(err); })
.pipe(file)
.on('finish', () => runInstaller(fileName, cb));
}

// Run the installer script and trigger callback (cb).
function runInstaller(fileName, cb) {
const shell = win ? 'powershell.exe' : 'bash';

const filePath = path.resolve(__dirname, fileName);
console.log(`Now running: ${shell} ${filePath}`);

cp.spawnSync(shell, [filePath], {stdio: 'inherit'});
cb();
}
14 changes: 12 additions & 2 deletions app/templates/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@
"start": "node server/server.js",
"start:cluster": "sl-run server/server.js",
"debug": "node --debug server/server.js",
"test": "nyc mocha"
"test": "nyc mocha",
"build": "npm run build:idt",
"build:idt": "node idt.js build",
"test:idt": "node idt.js test",
"debug:idt": "node idt.js debug",
"run:idt": "node idt.js run",
"deploy:idt": "node idt.js deploy",
"install:idt": "node idt.js install"
},
"dependencies": {
"appmetrics-dash": "^3.3.2",
Expand All @@ -21,8 +28,11 @@
},
"devDependencies": {
"chai": "^4.0.0",
"chalk": "^1.1.3",
"mocha": "^3.4.2",
"nyc": "^10.3.2",
"proxyquire": "^1.8.0"
"prompt-confirm": "^1.2.0",
"proxyquire": "^1.8.0",
"request": "^2.82.0"
}
}
Loading