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
Show all changes
40 commits
Select commit Hold shift + click to select a range
d843a60
initial commit
cvignola Sep 15, 2017
9a51ba8
Merge pull request #1 from ibm-developer/initial2
Sep 16, 2017
681c7a7
add config files and remove node_modules
cvignola Sep 17, 2017
bcaa70a
more fix-ups to publish without swaggerize
cvignola Sep 17, 2017
8bffb76
fix coveralls problem
cvignola Sep 17, 2017
033b6db
add exclude to .nycrc
cvignola Sep 17, 2017
749e5f6
fix .nycrc json
cvignola Sep 17, 2017
25e3259
increase coverage
cvignola Sep 17, 2017
8868f47
Merge pull request #2 from ibm-developer/configfiles
Sep 17, 2017
8c4a978
[Travis - npm version patch] Increment package version to 0.0.44
Sep 17, 2017
022eb28
fix readme
cvignola Sep 17, 2017
1301f22
Merge pull request #3 from ibm-developer/fixreadme
Sep 17, 2017
4e9199e
[Travis - npm version patch] Increment package version to 0.0.45
Sep 17, 2017
d4948c8
change codacy branch to development for now
cvignola Sep 18, 2017
cb094c9
change travis branch in readme to development for now
cvignola Sep 18, 2017
bb60c3b
Merge pull request #4 from ibm-developer/readme
Sep 18, 2017
0b9e817
[Travis - npm version patch] Increment package version to 0.0.46
Sep 18, 2017
b6323d6
Merge pull request #5 from ibm-developer/readme2
Sep 18, 2017
b6fe257
[Travis - npm version patch] Increment package version to 0.0.47
Sep 18, 2017
7824827
remove extraneous npm script
cvignola Sep 18, 2017
e250d55
Merge pull request #6 from ibm-developer/readme2
Sep 18, 2017
fd2e0a6
[Travis - npm version patch] Increment package version to 0.0.48
Sep 18, 2017
1062ce6
swagger support
cvignola Sep 20, 2017
659dc3e
misc
cvignola Sep 21, 2017
ff6479b
misc
cvignola Sep 21, 2017
5570f90
Merge pull request #7 from ibm-developer/swagger
Sep 21, 2017
a62ce5e
[Travis - npm version patch] Increment package version to 0.0.49
Sep 21, 2017
4d644b6
update package version
cvignola Sep 21, 2017
e3b1fd6
update package version
cvignola Sep 21, 2017
a2e2ee6
Merge branch 'development' of https://github.com/ibm-developer/genera…
cvignola Sep 21, 2017
76f77cf
fixup
cvignola Sep 21, 2017
c63bec9
Merge pull request #8 from ibm-developer/fixup
Sep 21, 2017
640a038
[Travis - npm version patch] Increment package version to 0.0.51
Sep 21, 2017
1efc374
Fixed Generated Tests
EnriqueL8 Sep 20, 2017
7ac5814
Making routes and test for routes work without a basepath
EnriqueL8 Sep 21, 2017
884e59b
Merge pull request #9 from EnriqueL8/fixing_generated_tests
Sep 22, 2017
9f42616
[Travis - npm version patch] Increment package version to 0.0.52
Sep 22, 2017
bdfc480
remove package.lock
Sep 22, 2017
162ebb8
Merge pull request #10 from ibm-developer/bug/package_lock
Sep 22, 2017
e9e74d6
[Travis - npm version patch] Increment package version to 0.0.53
Sep 22, 2017
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
6 changes: 6 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
# If eslint goes into this dir it will read package.json as a config file
# We either rename the package.json template, or we don't lint this dir
app/templates/
coverage/
lib/
14 changes: 14 additions & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
env:
node: true
es6: true
mocha: true

rules:
strict: 0
no-var: 2
no-console: 0
indent: [2, 2, { "SwitchCase": 1}]

extends: eslint:recommended

plugins: [ejs]
49 changes: 49 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history

test/tmp
.idea
.vscode

# output from generator
# Dockerfile
# Dockerfile-tools
# cli-config.yml
# manifest.yml
# .cfignore
# .bluemix
13 changes: 13 additions & 0 deletions .nycrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"check-coverage": true,
"statements": 82,
"branches": 70,
"functions": 87,
"lines": 83,
"include": [
"app/*.js"
],
"exclude": [
"app/templates/**"
]
}
23 changes: 23 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
language: node_js

node_js:
- '8'

script: npm test && npm run coveralls && ./npm_patch.sh

branches:
only:
- development
- master

notifications:
slack:
rooms:
- $SLACK_ARF_DEVOPS

deploy:
provider: npm
email: $NPM_EMAIL
api_key: $NPM_TOKEN
on:
branch: master
76 changes: 75 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,75 @@
# generator-ibm-core-node-express
# IBM Core Node Express Generator

[![Bluemix powered][img-bluemix-powered]][url-bluemix]
[![Travis][img-travis-master]][url-travis-master]
[![Coveralls][img-coveralls-master]][url-coveralls-master]
[![Codacy][img-codacy]][url-codacy]
[![Version][img-version]][url-npm]
[![DownloadsMonthly][img-npm-downloads-monthly]][url-npm]
[![DownloadsTotal][img-npm-downloads-total]][url-npm]
[![License][img-license]][url-npm]

[img-bluemix-powered]: https://img.shields.io/badge/bluemix-powered-blue.svg
[url-bluemix]: http://bluemix.net
[url-npm]: https://www.npmjs.com/package/generator-ibm-core-node-express
[img-license]: https://img.shields.io/npm/l/generator-ibm-core-node-express.svg
[img-version]: https://img.shields.io/npm/v/generator-ibm-core-node-express.svg
[img-npm-downloads-monthly]: https://img.shields.io/npm/dm/generator-ibm-core-node-express.svg
[img-npm-downloads-total]: https://img.shields.io/npm/dt/generator-ibm-core-node-express.svg

[img-travis-master]: https://travis-ci.org/ibm-developer/generator-ibm-core-node-express.svg?branch=development
[url-travis-master]: https://travis-ci.org/ibm-developer/generator-ibm-core-node-express/branches

[img-coveralls-master]: https://coveralls.io/repos/github/ibm-developer/generator-ibm-core-node-express/badge.svg
[url-coveralls-master]: https://coveralls.io/github/ibm-developer/generator-ibm-core-node-express

[img-codacy]: https://api.codacy.com/project/badge/Grade/a5893a4622094dc8920c8a372a8d3588?branch=development
[url-codacy]: https://www.codacy.com/app/ibm-developer/generator-ibm-core-node-express

## Pre-requisites

Install [Yeoman](http://yeoman.io)

```bash
npm install -g yo
```

## Installation

``bash
npm install -g generator-ibm-core-node-express
``

## Usage

Following command line arguments are supported

* `--bluemix='{"name":"<project-name>","backendPlatform":"NODE"}'`.
* You will need at least a name and backendPlatform to run it locally.
* You can alternatively supply a local file containing compatible JSON object by using `--bluemix file:path/to/file.json`

## Development

Clone this repository and link it via npm

```
git clone https://github.com/ibm-developer/generator-ibm-core-node-express
cd generator-ibm-core-node-express
npm link
```

In a separate directory invoke the generator via

```
yo ibm-core-node-express --bluemix='{"name":"<project-name>","backendPlatform":"NODE"}'
```

## Publishing Changes

In order to publish changes, you will need to fork the repository or ask to join the `ibm-developer` org and branch off the development branch.

Once you are finished with your changes, run `npm test` to make sure all tests pass.

Do a pull request against `development`, make sure the build passes. A team member will review and merge your pull request.
Once merged to development, the version will be auto-incremented.
Do a pull request against master, once that PR is reviewed and merged, a new version will be published.
174 changes: 174 additions & 0 deletions app/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/*
Copyright 2017 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';
const Generator = require('yeoman-generator');
const Bundle = require("./../package.json")
const Log4js = require('log4js');
const logger = Log4js.getLogger("generator-core-node-express");
const helpers = require('../lib/helpers');
const swaggerize = require('ibm-openapi-support');
const OPTION_BLUEMIX = "bluemix";
const OPTION_SPEC = "spec";

const REGEX_LEADING_ALPHA = /^[^a-zA-Z]*/;
const REGEX_ALPHA_NUM = /[^a-zA-Z0-9]/g;

module.exports = class extends Generator {

constructor(args, opts) {
super(args, opts);
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.',
required: false,
hide: true,
type: String
});

// spec as json
this.argument(OPTION_SPEC, {
desc: 'The generator specification. Stringified JSON.',
required: false,
hide: true,
type: String
});
}

initializing() {
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");
let appName = this.options.bluemix.name || this.options.spec.appname;
this.options.sanitizedAppName = this._sanitizeAppName(appName);
this.options.openApiFileType= "yaml"; // default
this.options.genSwagger= false;

this.options.parsedSwagger = undefined;
let formatters = {
'pathFormatter': helpers.reformatPathToNodeExpress,
'resourceFormatter': helpers.resourceNameFromPath
}

if (this.options.bluemix && this.options.bluemix.openApiServers && this.options.bluemix.openApiServers[0].spec) {
let openApiDocumentBytes = typeof this.options.bluemix.openApiServers[0].spec === 'object'
? JSON.stringify(this.options.bluemix.openApiServers[0].spec)
: this.options.bluemix.openApiServers[0].spec;
return swaggerize.parse(openApiDocumentBytes, formatters)
.then(response => {
this.options.loadedApi = response.loaded;
this.options.parsedSwagger = response.parsed;
if ( this.options.loadedApi ) this.options.openApiFileType= "json";
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
if(this.options.spec && this.options.spec.applicationType === 'MS') {
this.options.genSwagger= true;
}

}

writing() {

this.fs.copyTpl(this.templatePath('server'), this.destinationPath('server'), this.options);

if (this.options.parsedSwagger) {
Object.keys(this.options.parsedSwagger.resources).forEach(function(resource) {
let context = {
'resource': resource,
'routes': this.options.parsedSwagger.resources[resource],
'basepath': this.options.parsedSwagger.basepath
}
this.fs.copyTpl(this.templatePath('fromswagger/routers/router.js'), this.destinationPath(`server/routers/${resource}.js`), context);
this.fs.copyTpl(this.templatePath('test/resource.js'), this.destinationPath(`test/${resource}.js`), context);
}.bind(this));
}

this.fs.copyTpl(this.templatePath('test/test-server.js'), this.destinationPath('test/test-server.js'), this.options);
this.fs.copyTpl(this.templatePath('test/test-demo.js'), this.destinationPath('test/test-demo.js'), this.options);
this.fs.copyTpl(this.templatePath('_gitignore'), this.destinationPath('.gitignore'), this.options);
this.fs.copyTpl(this.templatePath('cli-config.yml'), this.destinationPath('cli-config.yml'), this.options);
this.fs.copyTpl(this.templatePath('Dockerfile'), this.destinationPath('Dockerfile'), this.options);
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);

// 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 ( this.options.loadedApi ) {
this.fs.writeJSON('public/swagger.json', this.options.loadedApi);
}
else {
this.fs.copyTpl(this.templatePath('public/swagger.yaml'), this.destinationPath('public/swagger.yaml'), this.options);
}
}
else {
this.fs.delete(this.destinationPath('server/routers/swagger.js'));
}

// microservice does not serve up default page
if(this.options.spec && this.options.spec.applicationType === 'MS') {
this.fs.delete(this.destinationPath('server/routers/public.js'));
}
else {
this.fs.copy(this.templatePath('public/index.html'), this.destinationPath('public/index.html'));
}

// 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'));
}
}

_sanitizeAppName(name) {
name = name || 'appname';
return name.toLowerCase().replace(REGEX_LEADING_ALPHA, '').replace(REGEX_ALPHA_NUM, '');
}

// 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;
}

if (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;
}

try {
this.options[name] = typeof(this.options[name]) === "string" ?
JSON.parse(this.options[name]) : this.options[name];
return true;
} catch (e) {
logger.error(e);
throw name + " parameter is expected to be a valid stringified JSON object";
}
}
};
16 changes: 16 additions & 0 deletions app/templates/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM ibmcom/ibmnode

ENV NODE_ENV production
ENV PORT 3000

WORKDIR "/app"

# Install app dependencies
COPY package.json package-lock.json /app/
RUN cd /app; npm install

# Bundle app source
COPY . /app

EXPOSE 3000
CMD ["npm", "start"]
Loading