src/neat.coffee |
|
|---|---|
This file contains the creation process of the Table Of Content
|
|
fs = require 'fs' pr = require 'commander' path = require 'path' resolve = path.resolve existsSync = fs.existsSync or path.existsSync |
|
We need a reference to the Neat module root directory for later use. |
NEAT_ROOT = resolve __dirname, '..' |
Requiring internal utilities. |
{logger, puts, warn, error, missing, neatBroken} = require "./utils/logs" {findSync, neatRootSync, isNeatRootSync} = require "./utils/files" cup = require "./utils/cup" require "./core" Signal = require "./core/signal" {I18n} = require "./i18n" |
Neat |
|
A |
class Neat
|
Neat::constructor |
constructor: (@ROOT) -> |
Other Constructor Setup |
@defaultEnvironment = 'default' @root = @ROOT @neatRoot = @NEAT_ROOT = NEAT_ROOT |
Paths where environments and initializers can be found. |
@envPath = @ENV_PATH = 'lib/config/environments' @initPath = @INIT_PATH = 'lib/config/initializers' |
|
@paths = @PATHS = [@neatRoot] |
The config object is defined asynchronously through
the |
@config = @config = null @env = @ENV = null @discoverUserPaths() if @root? @initI18n() @initHooks() |
The |
@meta = @META = @loadMeta @neatRoot |
The current project meta are available through |
@project = @PROJECT = @loadMeta @root if @root? |
Neat::initHooks |
|
Initialize the hooks provided by Neat. |
initHooks: -> |
The |
@beforeCommand = new Signal @afterCommand = new Signal |
The |
@beforeCompilation = new Signal @afterCompilation = new Signal |
The |
@beforeTask = new Signal @afterTask = new Signal |
The |
@beforeEnvironment = new Signal @afterEnvironment = new Signal |
The |
@beforeInitialize = new Signal @afterInitialize = new Signal |
Neat::initI18n |
|
Initialize the internationalization for the current Neat instance. |
initI18n: -> @i18n = new I18n @paths.map (s) -> "#{s}/config/locales" @i18n.load() puts "Available languages: #{@i18n.languages.join ', '}" |
Neat::require |
|
Loads a module from the Neat directory using the
|
require: (module) -> require "#{@neatRoot}/lib/#{module}" |
Neat::resolve |
resolve: (path) -> resolve @neatRoot, path |
Neat::rootResolve |
rootResolve: (path) -> resolve @root, path |
Neat::task |
|
Returns the cake task whose name is
|
task: (name) -> @require('tasks')[name] |
Environment Setup |
|
Neat::initLogging |
|
Setup the logging engine for this |
initLogging: -> logger.add @config.engines.logging[@config.defaultLoggingEngine] |
Neat::initEnvironment |
|
Initializes the |
initEnvironment: (callback) -> @setEnvironment process.env['NEAT_ENV'] or @defaultEnvironment, => @initLogging() callback?() |
Neat::setEnvironment |
|
Changes the environment of the |
setEnvironment: (env, callback) -> |
The environment object contains the paths defined in the |
envObject = { @root, @neatRoot, @paths, @initPath, @envPath, @ROOT, @NEAT_ROOT, @PATHS, @INIT_PATH, @ENV_PATH, } @beforeEnvironment.dispatch this, envObject, => |
ConfigurationsConfiguration of the environment is done through A configurator is a function exposed as a module and that have the following form:
The The name of the file is the name of the environment to configure. The default configurators are always called to ensure that the environment defaults are present if not overriden by the specified environment. |
|
The |
paths = @paths.map (p)=> "#{p}/#{@envPath}" configurators = findSync /^default$/, 'js', paths unless configurators? and configurators.length isnt 0 return error """#{@i18n.getHelper()('neat.errors.missing', missing: 'config/environments/default.js')} #{@i18n.get('neat.errors.broken')}""" |
Configurators for the given environment are searched in the
|
files = findSync ///^#{env}$///, "js", paths configurators.push f for f in files when f not in configurators |
All the configurators found are required and then executed. |
for configurator in configurators puts "Running #{configurator}" |
The execution of a configurator is handled in a |
try setup = require configurator setup? envObject catch e |
However errors are reported to the console. |
error """#{@i18n.get('neat.errors.broken_environment').red} #{e.stack}""" @afterEnvironment.dispatch this, envObject, => @beforeInitialize.dispatch this, envObject, => |
InitializationsInitializations of plugins or components are done through
An initializer is basically a configurator that will be run after the environment configuration.
Its purpose is to setup the configuration of a module, a command, or anything else that will run on top of Neat. The sole difference is that an initializer file can't have any name, it will be loaded anyway. |
|
Every initializers are executed whatever the environment. |
initializers = findSync 'js', @paths.map (o) => "#{o}/#{@initPath}" for initializer in initializers |
The same precautions are taken towards initializers execution as for configurators. |
try initialize = require initializer initialize? envObject catch e error """#{@i18n.get('neat.errors.broken_initializer').red} #{e.stack}""" |
After configurators and initializers have been run,
the new environment object is then stored in |
@CONFIG = @config = envObject o = {} o[env] = true @ENV = @env = Object::merge.call env, o @afterInitialize.dispatch this, envObject, callback |
Environment Setup Utilities |
|
Neat::discoverUserPaths |
|
Browses the user directory to find neat projects either at the root directory or in the node modules installed in the project. |
discoverUserPaths: -> modulesDir = resolve @root, 'node_modules' if existsSync modulesDir |
All the node modules that contains a |
modules = fs.readdirSync modulesDir modules = (resolve modulesDir, m for m in modules when m isnt 'neat') @paths.push m for m in modules when isNeatRootSync m else warn 'No node modules found, run neat install.' |
The current Neat project root is the last path in |
@paths.push @root if @root not in @paths |
Neat::loadMeta |
|
Loads and returns the meta contained in the |
loadMeta: (root) -> neatFilePath = "#{root}/.neat" _ = @i18n.getHelper() try neatFile = fs.readFileSync neatFilePath catch e return error """#{_('neat.errors.missing', missing: neatFilePath.red)} #{_('neat.errors.broken')}""" meta = cup.read neatFile.toString() meta or error """#{_('neat.errors.invalid_neat', path: neatFilePath.red)} #{_('neat.errors.broken')}""" module.exports = new Neat neatRootSync() |