summaryrefslogtreecommitdiffstats
path: root/lib/cli
diff options
context:
space:
mode:
authorSamy Pesse <samypesse@gmail.com>2016-04-26 15:51:52 +0200
committerSamy Pesse <samypesse@gmail.com>2016-04-26 15:51:52 +0200
commit7a46d3b4977bcd1e115324880a409e88032899a7 (patch)
treee2294e1054c5301a03f91ae7685ca3efcf92cc9b /lib/cli
parent357aa92e31df8f4809ebb01438878ec3ace96ae6 (diff)
downloadgitbook-7a46d3b4977bcd1e115324880a409e88032899a7.zip
gitbook-7a46d3b4977bcd1e115324880a409e88032899a7.tar.gz
gitbook-7a46d3b4977bcd1e115324880a409e88032899a7.tar.bz2
Add command "serve"
Diffstat (limited to 'lib/cli')
-rw-r--r--lib/cli/build.js11
-rw-r--r--lib/cli/getOutputFolder.js17
-rw-r--r--lib/cli/helper.js140
-rw-r--r--lib/cli/indexe.js199
-rw-r--r--lib/cli/serve.js80
-rw-r--r--lib/cli/server.js4
6 files changed, 102 insertions, 349 deletions
diff --git a/lib/cli/build.js b/lib/cli/build.js
index 49931bd..978bc87 100644
--- a/lib/cli/build.js
+++ b/lib/cli/build.js
@@ -1,10 +1,12 @@
var path = require('path');
+var Parse = require('../parse');
+var Output = require('../output');
+
var options = require('./options');
var getBook = require('./getBook');
+var getOutputFolder = require('./getOutputFolder');
-var Parse = require('../parse');
-var Output = require('../output');
module.exports = {
name: 'build [book] [output]',
@@ -15,13 +17,12 @@ module.exports = {
],
exec: function(args, kwargs) {
var book = getBook(args, kwargs);
+ var outputFolder = getOutputFolder(args);
+
var Generator = Output.getGenerator(kwargs.format);
return Parse.parseBook(book)
.then(function(resultBook) {
- var defaultOutputRoot = path.join(resultBook.getRoot(), '_book');
- var outputFolder = args[1]? path.resolve(process.cwd(), args[1]) : defaultOutputRoot;
-
return Output.generate(Generator, resultBook, {
root: outputFolder
});
diff --git a/lib/cli/getOutputFolder.js b/lib/cli/getOutputFolder.js
new file mode 100644
index 0000000..272dff9
--- /dev/null
+++ b/lib/cli/getOutputFolder.js
@@ -0,0 +1,17 @@
+var path = require('path');
+
+/**
+ Return path to output folder
+
+ @param {Array} args
+ @return {String}
+*/
+function getOutputFolder(args) {
+ var bookRoot = path.resolve(args[0] || process.cwd());
+ var defaultOutputRoot = path.join(bookRoot, '_book');
+ var outputFolder = args[1]? path.resolve(process.cwd(), args[1]) : defaultOutputRoot;
+
+ return outputFolder;
+}
+
+module.exports = getOutputFolder;
diff --git a/lib/cli/helper.js b/lib/cli/helper.js
deleted file mode 100644
index 02cede6..0000000
--- a/lib/cli/helper.js
+++ /dev/null
@@ -1,140 +0,0 @@
-var _ = require('lodash');
-var path = require('path');
-
-var Book = require('../book');
-var NodeFS = require('../fs/node');
-var Logger = require('../utils/logger');
-var Promise = require('../utils/promise');
-var fs = require('../utils/fs');
-var JSONOutput = require('../output/json');
-var WebsiteOutput = require('../output/website');
-var EBookOutput = require('../output/ebook');
-
-var nodeFS = new NodeFS();
-
-var LOG_OPTION = {
- name: 'log',
- description: 'Minimum log level to display',
- values: _.chain(Logger.LEVELS)
- .keys()
- .map(function(s) {
- return s.toLowerCase();
- })
- .value(),
- defaults: 'info'
-};
-
-var FORMAT_OPTION = {
- name: 'format',
- description: 'Format to build to',
- values: ['website', 'json', 'ebook'],
- defaults: 'website'
-};
-
-var FORMATS = {
- json: JSONOutput,
- website: WebsiteOutput,
- ebook: EBookOutput
-};
-
-// Commands which is processing a book
-// the root of the book is the first argument (or current directory)
-function bookCmd(fn) {
- return function(args, kwargs) {
- var input = path.resolve(args[0] || process.cwd());
- var book = new Book({
- fs: nodeFS,
- root: input,
- logLevel: kwargs.log
- });
-
- return fn(book, args.slice(1), kwargs);
- };
-}
-
-// Commands which is working on a Output instance
-function outputCmd(fn) {
- return bookCmd(function(book, args, kwargs) {
- var Out = FORMATS[kwargs.format];
- var outputFolder = undefined;
-
- // Set output folder
- if (args[0]) {
- outputFolder = path.resolve(process.cwd(), args[0]);
- }
-
- return fn(new Out(book, {
- root: outputFolder
- }), args);
- });
-}
-
-// Command to generate an ebook
-function ebookCmd(format) {
- return {
- name: format + ' [book] [output] [file]',
- description: 'generates ebook '+format,
- options: [
- LOG_OPTION
- ],
- exec: bookCmd(function(book, args, kwargs) {
- return fs.tmpDir()
- .then(function(dir) {
- var ext = '.'+format;
- var outputFile = path.resolve(process.cwd(), args[0] || ('book' + ext));
- var output = new EBookOutput(book, {
- root: dir,
- format: format
- });
-
- return output.book.parse()
- .then(function() {
- return output.generate();
- })
-
- // Copy the ebook files
- .then(function() {
- if (output.book.isMultilingual()) {
- return Promise.serie(output.book.langs.list(), function(lang) {
- var _outputFile = path.join(
- path.dirname(outputFile),
- path.basename(outputFile, ext) + '_' + lang.id + ext
- );
-
- return fs.copy(
- path.resolve(dir, lang.id, 'index' + ext),
- _outputFile
- );
- })
- .thenResolve(output.book.langs.count());
- } else {
- return fs.copy(
- path.resolve(dir, 'index' + ext),
- outputFile
- ).thenResolve(1);
- }
- })
- .then(function(n) {
- output.book.log.info.ok(n+' file(s) generated');
-
- output.book.log.info('cleaning up... ');
- return output.book.log.info.promise(fs.rmDir(dir));
- });
- });
- })
- };
-}
-
-module.exports = {
- nodeFS: nodeFS,
- bookCmd: bookCmd,
- outputCmd: outputCmd,
- ebookCmd: ebookCmd,
-
- options: {
- log: LOG_OPTION,
- format: FORMAT_OPTION
- },
-
- FORMATS: FORMATS
-};
diff --git a/lib/cli/indexe.js b/lib/cli/indexe.js
deleted file mode 100644
index eea707f..0000000
--- a/lib/cli/indexe.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/* eslint-disable no-console */
-
-var _ = require('lodash');
-var path = require('path');
-var tinylr = require('tiny-lr');
-
-var Promise = require('../utils/promise');
-var PluginsManager = require('../plugins');
-var Book = require('../book');
-
-var helper = require('./helper');
-var Server = require('./server');
-var watch = require('./watch');
-
-module.exports = {
- commands: [
- {
- name: 'init [book]',
- description: 'setup and create files for chapters',
- options: [
- helper.options.log
- ],
- exec: function(args) {
- var input = path.resolve(args[0] || process.cwd());
- return Book.init(helper.nodeFS, input);
- }
- },
-
- {
- name: 'parse [book]',
- description: 'parse and returns debug information for a book',
- options: [
- helper.options.log
- ],
- exec: helper.bookCmd(function(book) {
- return book.parse()
- .then(function() {
- book.log.info.ln('Book located in:', book.root);
- book.log.info.ln('');
-
- if (book.config.exists()) book.log.info.ln('Configuration:', book.config.path);
-
- if (book.isMultilingual()) {
- book.log.info.ln('Multilingual book detected:', book.langs.path);
- } else {
- book.log.info.ln('Readme:', book.readme.path);
- book.log.info.ln('Summary:', book.summary.path);
- if (book.glossary.exists()) book.log.info.ln('Glossary:', book.glossary.path);
-
- book.log.info.ln('Pages:');
- _.each(book.pages, function(page) {
- book.log.info.ln('\t-', page.path);
- });
- }
- });
- })
- },
-
- {
- name: 'install [book]',
- description: 'install all plugins dependencies',
- options: [
- helper.options.log
- ],
- exec: helper.bookCmd(function(book, args) {
- var plugins = new PluginsManager(book);
-
- return book.config.load()
- .then(function() {
- return plugins.install();
- });
- })
- },
-
- {
- name: 'build [book] [output]',
- description: 'build a book',
- options: [
- helper.options.log,
- helper.options.format
- ],
- exec: helper.outputCmd(function(output, args, kwargs) {
- return output.book.parse()
- .then(function() {
- return output.generate();
- });
- })
- },
-
- helper.ebookCmd('pdf'),
- helper.ebookCmd('epub'),
- helper.ebookCmd('mobi'),
-
- {
- name: 'serve [book]',
- description: 'Build then serve a book from a directory',
- options: [
- {
- name: 'port',
- description: 'Port for server to listen on',
- defaults: 4000
- },
- {
- name: 'lrport',
- description: 'Port for livereload server to listen on',
- defaults: 35729
- },
- {
- name: 'watch',
- description: 'Enable/disable file watcher',
- defaults: true
- },
- helper.options.format,
- helper.options.log
- ],
- exec: function(args, kwargs) {
- var input = path.resolve(args[0] || process.cwd());
- var server = new Server();
-
- // Init livereload server
- var lrServer = tinylr({});
- var port = kwargs.port;
- var lrPath;
-
- var generate = function() {
-
- // Stop server if running
- if (server.isRunning()) console.log('Stopping server');
- return server.stop()
-
- // Generate the book
- .then(function() {
- var book = new Book({
- fs: helper.nodeFS,
- root: input,
- logLevel: kwargs.log
- });
-
- return book.parse()
- .then(function() {
- // Add livereload plugin
- book.config.set('plugins',
- book.config.get('plugins')
- .concat([
- { name: 'livereload' }
- ])
- );
-
- var Out = helper.FORMATS[kwargs.format];
- var output = new Out(book);
-
- return output.generate()
- .thenResolve(output);
- });
- })
-
- // Start server and watch changes
- .then(function(output) {
- console.log();
- console.log('Starting server ...');
- return server.start(output.root(), port)
- .then(function() {
- console.log('Serving book on http://localhost:'+port);
-
- if (lrPath) {
- // trigger livereload
- lrServer.changed({
- body: {
- files: [lrPath]
- }
- });
- }
-
- if (!kwargs.watch) return;
-
- return watch(output.book.root)
- .then(function(filepath) {
- // set livereload path
- lrPath = filepath;
- console.log('Restart after change in file', filepath);
- console.log('');
- return generate();
- });
- });
- });
- };
-
- return Promise.nfcall(lrServer.listen.bind(lrServer), kwargs.lrport)
- .then(function() {
- console.log('Live reload server started on port:', kwargs.lrport);
- console.log('Press CTRL+C to quit ...');
- console.log('');
- return generate();
- });
- }
- }
-
- ]
-};
diff --git a/lib/cli/serve.js b/lib/cli/serve.js
index d97cfed..628f591 100644
--- a/lib/cli/serve.js
+++ b/lib/cli/serve.js
@@ -1,19 +1,93 @@
-var path = require('path');
+/* eslint-disable no-console */
-var options = require('./options');
-var getBook = require('./getBook');
+var tinylr = require('tiny-lr');
var Parse = require('../parse');
var Output = require('../output');
+var options = require('./options');
+var getBook = require('./getBook');
+var getOutputFolder = require('./getOutputFolder');
+var Server = require('./server');
+var watch = require('./watch');
+
+var server, lrServer, lrPath;
+
+function generateBook(args, kwargs) {
+ var port = kwargs.port;
+ var outputFolder = getOutputFolder(args);
+ var book = getBook(args, kwargs);
+ var Generator = Output.getGenerator(kwargs.format);
+
+ // Stop server if running
+ if (server.isRunning()) console.log('Stopping server');
+
+ return server.stop()
+ .then(function() {
+ return Parse.parseBook(book)
+ .then(function(resultBook) {
+ return Output.generate(Generator, resultBook, {
+ root: outputFolder
+ });
+ });
+ })
+ .then(function() {
+ console.log();
+ console.log('Starting server ...');
+ return server.start(outputFolder, port);
+ })
+ .then(function() {
+ console.log('Serving book on http://localhost:'+port);
+
+ if (lrPath) {
+ // trigger livereload
+ lrServer.changed({
+ body: {
+ files: [lrPath]
+ }
+ });
+ }
+ })
+ .then(function() {
+ if (!kwargs.watch) return;
+
+ return watch(book.getRoot())
+ .then(function(filepath) {
+ // set livereload path
+ lrPath = filepath;
+ console.log('Restart after change in file', filepath);
+ console.log('');
+ return generateBook(args, kwargs);
+ });
+ });
+}
+
module.exports = {
name: 'serve [book] [output]',
description: 'serve the book as a website for testing',
options: [
+ {
+ name: 'port',
+ description: 'Port for server to listen on',
+ defaults: 4000
+ },
+ {
+ name: 'lrport',
+ description: 'Port for livereload server to listen on',
+ defaults: 35729
+ },
+ {
+ name: 'watch',
+ description: 'Enable/disable file watcher',
+ defaults: true
+ },
options.log,
options.format
],
exec: function(args, kwargs) {
+ server = new Server();
+ lrServer = tinylr({});
+ return generateBook(args, kwargs);
}
};
diff --git a/lib/cli/server.js b/lib/cli/server.js
index 8d3d7ce..936ff4e 100644
--- a/lib/cli/server.js
+++ b/lib/cli/server.js
@@ -6,12 +6,12 @@ var url = require('url');
var Promise = require('../utils/promise');
-var Server = function() {
+function Server() {
this.running = null;
this.dir = null;
this.port = 0;
this.sockets = [];
-};
+}
util.inherits(Server, events.EventEmitter);
// Return true if the server is running