0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-15 03:01:37 -05:00

Merge pull request #5357 from ErisDS/misc

Misc grunt /dev updates
This commit is contained in:
Matt Enlow 2015-05-29 10:10:18 +02:00
commit da9fcc7a19
13 changed files with 213 additions and 150 deletions

View file

@ -270,7 +270,7 @@ var _ = require('lodash'),
coverage: {
// TODO fix the timing/async & cleanup issues with the route and integration tests so that
// they can also have coverage generated for them & the order doesn't matter
src: ['core/test/integration', 'core/test/unit'],
src: ['core/test/unit'],
options: {
mask: '**/*_spec.js',
coverageFolder: 'core/test/coverage',
@ -336,7 +336,7 @@ var _ = require('lodash'),
test: {
command: function (test) {
return 'node ' + mochaPath + ' --timeout=15000 --ui=bdd --reporter=spec core/test/' + test;
return 'node ' + mochaPath + ' --timeout=15000 --ui=bdd --reporter=spec --colors core/test/' + test;
}
},
@ -361,8 +361,8 @@ var _ = require('lodash'),
src: ['.'],
options: {
onlyUpdated: true,
exclude: 'node_modules,.git,.tmp,bower_components,content,*built,*test,*doc*,*vendor,' +
'config.js,.travis.yml,*.min.css,screen.css',
exclude: 'node_modules,bower_components,content,core/client,*test,*doc*,' +
'*vendor,config.js,*buil*,.dist*,.idea,.git*,.travis.yml,.bower*,.editorconfig,.js*,*.md',
extras: ['fileSearch']
}
}
@ -540,6 +540,23 @@ var _ = require('lodash'),
// Run `grunt docs` to generate annotated source code using the documentation described in the code comments.
grunt.registerTask('docs', 'Generate Docs', ['docker']);
// Runun `grunt watch-docs` to setup livereload & watch whilst you're editing the docs
grunt.registerTask('watch-docs', function () {
grunt.config.merge({
watch: {
docs: {
files: ['core/server/**/*', 'index.js', 'Gruntfile.js', 'config.example.js'],
tasks: ['docker'],
options: {
livereload: true
}
}
}
});
grunt.task.run('watch:docs');
});
// ## Testing
// Ghost has an extensive set of test suites. The following section documents the various types of tests
@ -938,5 +955,4 @@ var _ = require('lodash'),
['init', 'shell:ember:prod', 'uglify:release', 'clean:release', 'shell:shrinkwrap', 'copy:release', 'compress:release']);
};
// Export the configuration
module.exports = configureGrunt;

View file

@ -1,13 +1,14 @@
// # Ghost Configuration
// Setup your Ghost install for various environments
// Documentation can be found at http://support.ghost.org/config/
// Setup your Ghost install for various [environments](http://support.ghost.org/config/#about-environments).
// Ghost runs in `development` mode by default. Full documentation can be found at http://support.ghost.org/config/
var path = require('path'),
config;
config = {
// ### Production
// When running Ghost in the wild, use the production environment
// When running Ghost in the wild, use the production environment.
// Configure your URL and mail settings here
production: {
url: 'http://my-ghost-blog.com',
@ -21,9 +22,7 @@ config = {
},
server: {
// Host to be passed to node's `net.Server#listen()`
host: '127.0.0.1',
// Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
port: '2368'
}
},
@ -49,6 +48,8 @@ config = {
// },
// ```
// #### Database
// Ghost supports sqlite3 (default), MySQL & PostgreSQL
database: {
client: 'sqlite3',
connection: {
@ -56,12 +57,16 @@ config = {
},
debug: false
},
// #### Server
// Can be host & port (default), or socket
server: {
// Host to be passed to node's `net.Server#listen()`
host: '127.0.0.1',
// Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
port: '2368'
},
// #### Paths
// Specify where your content directory lives
paths: {
contentPath: path.join(__dirname, '/content/')
}
@ -130,5 +135,4 @@ config = {
}
};
// Export config
module.exports = config;

View file

@ -1,9 +1,8 @@
// # Ghost bootloader
// Orchestrates the loading of Ghost
// When run from command line.
// ## Server Loader
// Passes options through the boot process to get a server instance back
var server = require('./server');
// Set the default environment to be `development`
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
function makeGhost(options) {

View file

@ -1,8 +1,5 @@
// # Config
// General entry point for all configuration data
//
// This file itself is a wrapper for the root level config.js file.
// All other files that need to reference config.js should use this file.
var path = require('path'),
Promise = require('bluebird'),
chalk = require('chalk'),

View file

@ -1,3 +1,4 @@
// # Errors
/*jslint regexp: true */
var _ = require('lodash'),
chalk = require('chalk'),

View file

@ -1,3 +1,5 @@
// # Filters
// Filters are not yet properly used, this system is intended to allow Apps to extend Ghost in various ways.
var Promise = require('bluebird'),
pipeline = require('./utils/pipeline'),
_ = require('lodash'),

View file

@ -1,3 +1,5 @@
// # Ghost Server
// Handles the creation of an HTTP Server for Ghost
var Promise = require('bluebird'),
chalk = require('chalk'),
fs = require('fs'),
@ -6,6 +8,11 @@ var Promise = require('bluebird'),
errors = require('./errors'),
config = require('./config');
/**
* ## GhostServer
* @constructor
* @param {Object} rootApp - parent express instance
*/
function GhostServer(rootApp) {
this.rootApp = rootApp;
this.httpServer = null;
@ -17,6 +24,115 @@ function GhostServer(rootApp) {
this.config = config;
}
/**
* ## Public API methods
*
* ### Start
* Starts the ghost server listening on the configured port.
* Alternatively you can pass in your own express instance and let Ghost
* start listening for you.
* @param {Object} externalApp - Optional express app instance.
* @return {Promise} Resolves once Ghost has started
*/
GhostServer.prototype.start = function (externalApp) {
var self = this,
rootApp = externalApp ? externalApp : self.rootApp;
return new Promise(function (resolve) {
var socketConfig = config.getSocket();
if (socketConfig) {
// Make sure the socket is gone before trying to create another
try {
fs.unlinkSync(socketConfig.path);
} catch (e) {
// We can ignore this.
}
self.httpServer = rootApp.listen(socketConfig.path);
fs.chmod(socketConfig.path, socketConfig.permissions);
} else {
self.httpServer = rootApp.listen(
config.server.port,
config.server.host
);
}
self.httpServer.on('error', function (error) {
if (error.errno === 'EADDRINUSE') {
errors.logError(
'(EADDRINUSE) Cannot start Ghost.',
'Port ' + config.server.port + ' is already in use by another program.',
'Is another Ghost instance already running?'
);
} else {
errors.logError(
'(Code: ' + error.errno + ')',
'There was an error starting your server.',
'Please use the error code above to search for a solution.'
);
}
process.exit(-1);
});
self.httpServer.on('connection', self.connection.bind(self));
self.httpServer.on('listening', function () {
self.logStartMessages();
clearTimeout(self.upgradeWarning);
resolve(self);
});
});
};
/**
* ### Stop
* Returns a promise that will be fulfilled when the server stops. If the server has not been started,
* the promise will be fulfilled immediately
* @returns {Promise} Resolves once Ghost has stopped
*/
GhostServer.prototype.stop = function () {
var self = this;
return new Promise(function (resolve) {
if (self.httpServer === null) {
resolve(self);
} else {
self.httpServer.close(function () {
self.httpServer = null;
self.logShutdownMessages();
resolve(self);
});
self.closeConnections();
}
});
};
/**
* ### Restart
* Restarts the ghost application
* @returns {Promise} Resolves once Ghost has restarted
*/
GhostServer.prototype.restart = function () {
return this.stop().then(this.start.bind(this));
};
/**
* ### Hammertime
* To be called after `stop`
*/
GhostServer.prototype.hammertime = function () {
console.log(chalk.green('Can\'t touch this'));
return Promise.resolve(this);
};
/**
* ## Private (internal) methods
*
* ### Connection
* @param {Object} socket
*/
GhostServer.prototype.connection = function (socket) {
var self = this;
@ -30,9 +146,11 @@ GhostServer.prototype.connection = function (socket) {
self.connections[socket._ghostId] = socket;
};
// Most browsers keep a persistent connection open to the server
// which prevents the close callback of httpServer from returning
// We need to destroy all connections manually
/**
* ### Close Connections
* Most browsers keep a persistent connection open to the server, which prevents the close callback of
* httpServer from returning. We need to destroy all connections manually.
*/
GhostServer.prototype.closeConnections = function () {
var self = this;
@ -45,6 +163,9 @@ GhostServer.prototype.closeConnections = function () {
});
};
/**
* ### Log Start Messages
*/
GhostServer.prototype.logStartMessages = function () {
// Tell users if their node version is not supported, and exit
if (!semver.satisfies(process.versions.node, packageInfo.engines.node) &&
@ -101,10 +222,19 @@ GhostServer.prototype.logStartMessages = function () {
removeAllListeners('SIGTERM').on('SIGTERM', shutdown);
};
/**
* ### Log Shutdown Messages
*/
GhostServer.prototype.logShutdownMessages = function () {
console.log(chalk.red('Ghost is closing connections'));
};
/**
* ### Log Upgrade Warning
* Warning that the API for the node module version of Ghost changed in 0.5.2
*
* *This should be removed soon*
*/
GhostServer.prototype.logUpgradeWarning = function () {
errors.logWarn(
'Ghost no longer starts automatically when using it as an npm module.',
@ -113,95 +243,4 @@ GhostServer.prototype.logUpgradeWarning = function () {
);
};
/**
* Starts the ghost server listening on the configured port.
* Alternatively you can pass in your own express instance and let Ghost
* start listening for you.
* @param {Object=} externalApp Optional express app instance.
* @return {Promise}
*/
GhostServer.prototype.start = function (externalApp) {
var self = this,
rootApp = externalApp ? externalApp : self.rootApp;
// ## Start Ghost App
return new Promise(function (resolve) {
var socketConfig = config.getSocket();
if (socketConfig) {
// Make sure the socket is gone before trying to create another
try {
fs.unlinkSync(socketConfig.path);
} catch (e) {
// We can ignore this.
}
self.httpServer = rootApp.listen(socketConfig.path);
fs.chmod(socketConfig.path, socketConfig.permissions);
} else {
self.httpServer = rootApp.listen(
config.server.port,
config.server.host
);
}
self.httpServer.on('error', function (error) {
if (error.errno === 'EADDRINUSE') {
errors.logError(
'(EADDRINUSE) Cannot start Ghost.',
'Port ' + config.server.port + ' is already in use by another program.',
'Is another Ghost instance already running?'
);
} else {
errors.logError(
'(Code: ' + error.errno + ')',
'There was an error starting your server.',
'Please use the error code above to search for a solution.'
);
}
process.exit(-1);
});
self.httpServer.on('connection', self.connection.bind(self));
self.httpServer.on('listening', function () {
self.logStartMessages();
clearTimeout(self.upgradeWarning);
resolve(self);
});
});
};
// Returns a promise that will be fulfilled when the server stops.
// If the server has not been started, the promise will be fulfilled
// immediately
GhostServer.prototype.stop = function () {
var self = this;
return new Promise(function (resolve) {
if (self.httpServer === null) {
resolve(self);
} else {
self.httpServer.close(function () {
self.httpServer = null;
self.logShutdownMessages();
resolve(self);
});
self.closeConnections();
}
});
};
// Restarts the ghost application
GhostServer.prototype.restart = function () {
return this.stop().then(this.start.bind(this));
};
// To be called after `stop`
GhostServer.prototype.hammertime = function () {
console.log(chalk.green('Can\'t touch this'));
return Promise.resolve(this);
};
module.exports = GhostServer;

View file

@ -1,3 +1,6 @@
// # Bootup
// This file needs serious love & refactoring
// Module dependencies
var express = require('express'),
hbs = require('express-hbs'),
@ -21,7 +24,6 @@ var express = require('express'),
xmlrpc = require('./data/xml/xmlrpc'),
GhostServer = require('./ghost-server'),
// Variables
dbHash;
function doFirstRun() {
@ -133,9 +135,8 @@ function initNotifications() {
}
}
// ## Initializes the ghost application.
// Sets up the express server instance.
// Instantiates the ghost singleton, helpers, routes, middleware, and apps.
// ## Initialise Ghost
// Sets up the express server instances, runs init on a bunch of stuff, configures views, helpers, routes and more
// Finally it returns an instance of GhostServer
function init(options) {
// Get reference to an express app instance.

View file

@ -1,3 +1,5 @@
// # Mail
// Handles sending email for Ghost
var _ = require('lodash'),
Promise = require('bluebird'),
nodemailer = require('nodemailer'),

View file

@ -1,3 +1,5 @@
// # Require Tree
// Require a tree of directories - used for loading themes and other things
var _ = require('lodash'),
fs = require('fs'),
path = require('path'),

View file

@ -1,10 +1,12 @@
// # Update Checking Service
//
// Makes a request to Ghost.org to check if there is a new version of Ghost available.
// The service is provided in return for users opting in to anonymous usage data collection
// Blog owners can opt-out of update checks by setting 'updateCheck: false' in their config.js
// The service is provided in return for users opting in to anonymous usage data collection.
//
// Blog owners can opt-out of update checks by setting `privacy: { useUpdateCheck: false }` in their config.js
//
// The data collected is as follows:
//
// - blog id - a hash of the blog hostname, pathname and dbHash. No identifiable info is stored.
// - ghost version
// - node version

View file

@ -1,7 +1,5 @@
// # Ghost bootloader
// Orchestrates the loading of Ghost
// When run from command line.
// # Ghost Startup
// Orchestrates the startup of Ghost when run from command line.
var express,
ghost,
parentApp,
@ -18,11 +16,12 @@ errors = require('./core/server/errors');
// Create our parent express app instance.
parentApp = express();
// Call Ghost to get an instance of GhostServer
ghost().then(function (ghostServer) {
// Mount our ghost instance on our desired subdirectory path if it exists.
// Mount our Ghost instance on our desired subdirectory path if it exists.
parentApp.use(ghostServer.config.paths.subdir, ghostServer.rootApp);
// Let ghost handle starting our server instance.
// Let Ghost handle starting our server instance.
ghostServer.start(parentApp);
}).catch(function (err) {
errors.logErrorAndExit(err, err.context, err.help);

View file

@ -68,32 +68,31 @@
"pg": "4.1.1"
},
"devDependencies": {
"bower": "~1.3.10",
"bower": "1.4.1",
"csscomb": "3.0.4",
"grunt": "~0.4.5",
"grunt-bg-shell": "^2.3.1",
"grunt-cli": "~0.1.13",
"grunt-contrib-clean": "~0.6.0",
"grunt-contrib-compress": "~0.11.0",
"grunt-contrib-copy": "~0.5.0",
"grunt-contrib-jshint": "~0.11.2",
"grunt-contrib-uglify": "~0.6.0",
"grunt-contrib-watch": "~0.6.1",
"grunt-docker": "~0.0.8",
"grunt-express-server": "~0.4.19",
"grunt-jscs": "~1.8.0",
"grunt-mocha-cli": "~1.13.0",
"grunt": "0.4.5",
"grunt-bg-shell": "2.3.1",
"grunt-cli": "0.1.13",
"grunt-contrib-clean": "0.6.0",
"grunt-contrib-compress": "0.13.0",
"grunt-contrib-copy": "0.8.0",
"grunt-contrib-jshint": "0.11.2",
"grunt-contrib-uglify": "0.9.1",
"grunt-contrib-watch": "0.6.1",
"grunt-docker": "0.0.10",
"grunt-express-server": "0.5.1",
"grunt-jscs": "1.8.0",
"grunt-mocha-cli": "1.13.0",
"grunt-mocha-istanbul": "2.4.0",
"grunt-shell": "~1.1.1",
"grunt-update-submodules": "~0.4.1",
"matchdep": "~0.3.0",
"nock": "0.52.4",
"require-dir": "~0.1.0",
"rewire": "~2.1.0",
"should": "~6.0.1",
"sinon": "~1.12.2",
"supertest": "~0.15.0",
"testem": "^0.6.23",
"top-gh-contribs": "^1.0.0"
"grunt-shell": "1.1.2",
"grunt-update-submodules": "0.4.1",
"matchdep": "0.3.0",
"nock": "2.3.0",
"rewire": "2.3.3",
"should": "6.0.3",
"sinon": "1.14.1",
"supertest": "1.0.1",
"testem": "0.8.3",
"top-gh-contribs": "1.0.1"
}
}