UNPKG

5.91 kBJavaScriptView Raw
1/**
2 * @fileoverview Build file
3 * @author nzakas
4 */
5
6/* eslint comma-dangle: ["error", {"arrays": "only-multiline","objects": "only-multiline","functions": "never"}] */
7
8/* global target, cat, exec, echo, find, which, test, exit, mkdir */
9
10'use strict';
11
12//------------------------------------------------------------------------------
13// Requirements
14//------------------------------------------------------------------------------
15
16require('shelljs/make');
17
18var util = require('util');
19var nodeCLI = require('shelljs-nodecli');
20
21//------------------------------------------------------------------------------
22// Data
23//------------------------------------------------------------------------------
24
25var NODE = 'node ', // intentional extra space
26 NODE_MODULES = './node_modules/',
27 BUILD_DIR = './build/',
28 DIST_DIR = './dist/',
29 LIB_DIR = './lib/',
30 // Utilities - intentional extra space at the end of each string
31 JSON_LINT = NODE + NODE_MODULES + 'jsonlint/lib/cli.js ',
32 JSDOC = NODE + NODE_MODULES + 'jsdoc/jsdoc.js ',
33 ESLINT = NODE + NODE_MODULES + 'eslint/bin/eslint ',
34 BROWSERIFY = NODE + NODE_MODULES + 'browserify/bin/cmd.js',
35 // Directories
36 JS_DIRS = getSourceDirectories(),
37 // Files
38 JS_FILES = find(JS_DIRS).filter(fileType('js')).join(' '),
39 JSON_FILES =
40 find('config/').filter(fileType('json')).join(' ') + ' .eslintrc',
41 TEST_FILES = find('tests/').filter(fileType('js')).join(' '),
42 JSON_SCHEMA = './config/package.schema.json';
43
44//------------------------------------------------------------------------------
45// Helpers
46//------------------------------------------------------------------------------
47
48/**
49 * Executes a Node CLI and exits with a non-zero exit code if the
50 * CLI execution returns a non-zero exit code. Otherwise, it does
51 * not exit.
52 * @param {...string} [args] Arguments to pass to the Node CLI utility.
53 * @returns {void}
54 * @private
55 */
56function nodeExec(args) {
57 args = arguments; // make linting happy
58 var code = nodeCLI.exec.apply(nodeCLI, args).code;
59 if (code !== 0) {
60 exit(code);
61 }
62}
63
64/**
65 * Runs exec() but exits if the exit code is non-zero.
66 * @param {string} cmd The command to execute.
67 * @returns {void}
68 * @private
69 */
70function execOrExit(cmd) {
71 var code = exec(cmd).code;
72 if (code !== 0) {
73 exit(code);
74 }
75}
76
77/**
78 * Generates a function that matches files with a particular extension.
79 * @param {string} extension The file extension (i.e. 'js')
80 * @returns {Function} The function to pass into a filter method.
81 * @private
82 */
83function fileType(extension) {
84 return function(filename) {
85 return filename.substring(filename.lastIndexOf('.') + 1) === extension;
86 };
87}
88
89/**
90 * Determines which directories are present that might have JavaScript files.
91 * @returns {string[]} An array of directories that exist.
92 * @private
93 */
94function getSourceDirectories() {
95 var dirs = ['lib', 'src', 'app'], result = [];
96
97 dirs.forEach(function(dir) {
98 if (test('-d', dir)) {
99 result.push(dir);
100 }
101 });
102
103 return result;
104}
105
106/**
107 * Creates a release version tag and pushes to origin.
108 * @param {string} type The type of release to do (patch, minor, major)
109 * @returns {void}
110 */
111function release(type) {
112 target.test();
113
114 execOrExit('npm version ' + type);
115
116 target.generateDist();
117
118 execOrExit('git add -A');
119 execOrExit('git commit --amend --no-edit');
120
121 // ...and publish
122 execOrExit('git push origin master --tags');
123
124 // also publish to npm (requires authentication)
125 execOrExit('npm publish');
126}
127
128//------------------------------------------------------------------------------
129// Tasks
130//------------------------------------------------------------------------------
131
132target.all = function() {
133 target.test();
134};
135
136target.lint = function() {
137 echo('Validating JSON Files');
138 exec(JSON_LINT + '-q -c ' + JSON_FILES);
139
140 echo('Validating package.json');
141 exec(JSON_LINT + 'package.json -q -V ' + JSON_SCHEMA);
142
143 echo('Validating JavaScript files');
144 exec(ESLINT + ' ' + JS_FILES);
145};
146
147target.test = function() {
148 target.lint();
149
150 echo('Running tests');
151 execOrExit('./node_modules/karma/bin/karma start');
152};
153
154target.docs = function() {
155 echo('Generating documentation');
156 exec(JSDOC + '-d jsdoc ' + JS_DIRS.join(' '));
157 echo('Documentation has been output to /jsdoc');
158};
159
160target.generateDist = function() {
161 var pkg = require('./package.json'),
162 distFilename = DIST_DIR + pkg.name + '.js',
163 minDistFilename = distFilename.replace(/\.js$/, '.min.js');
164
165 if (!test('-d', DIST_DIR)) {
166 mkdir(DIST_DIR);
167 }
168
169 exec(
170 util.format(
171 '%s %s.js -o %s -s %s -i mocha',
172 BROWSERIFY,
173 LIB_DIR + pkg.name,
174 distFilename,
175 pkg.name
176 )
177 );
178
179 nodeExec('uglifyjs', distFilename, '-o', minDistFilename);
180
181 // Add copyrights
182 cat('./config/copyright.txt', distFilename).to(distFilename);
183 cat('./config/copyright.txt', minDistFilename).to(minDistFilename);
184
185 // ensure there's a newline at the end of each file
186 (cat(distFilename) + '\n').to(distFilename);
187 (cat(minDistFilename) + '\n').to(minDistFilename);
188};
189
190target.browserify = function() {
191 var pkg = require('./package.json'),
192 buildFilename = BUILD_DIR + pkg.name + '.js',
193 minDistFilename = buildFilename.replace(/\.js$/, '.min.js');
194
195 if (!test('-d', BUILD_DIR)) {
196 mkdir(BUILD_DIR);
197 }
198
199 exec(
200 util.format(
201 '%s %s.js -o %s -s %s -i mocha',
202 BROWSERIFY,
203 LIB_DIR + pkg.name,
204 buildFilename,
205 pkg.name
206 )
207 );
208};
209
210target.patch = function() {
211 release('patch');
212};
213
214target.minor = function() {
215 release('minor');
216};
217
218target.major = function() {
219 release('major');
220};