path = require 'path'
config = require 'config'
class PackageManager
@normalizePath: (path, capitalize = false) ->
i8n = require 'inflection'
parts = for part, i in path.split '/'
i8n.camelize i8n.underscore(
part.replace /[^\w]/g, '_'
0 is i
)
i8n.camelize (i8n.underscore parts.join ''), not capitalize
PackageManager#constructor
constructor: ->
@_hookIndex = {}
@_pkgIndex = {}
@_packageList = []
PackageManager#invoke
-
(String)
hook
- The hook to invoke. -
(Array)
args
- The arguments passed to the hook implementations.
Invoke a hook, heying the results by package implementations.
invoke: (hook, args...) ->
results = {}
for pkg in @packagesImplementing hook
results[pkg] = @invokePackage pkg, hook, args...
return results
PackageManager#invokeFlat
-
(String)
hook
- The hook to invoke. -
(Array)
args
- The arguments passed to the hook implementations.
Invoke a hook, returning the results as a flattened array.
invokeFlat: (hook, args...) ->
for pkg in @packagesImplementing hook
@invokePackage pkg, hook, args...
PackageManager#invokePackage
-
(String)
pkg
- The package. -
(String)
hook
- The hook to invoke. -
(Array)
args
- The arguments passed to the hook implementation.
Invoke a hook, returning the result.
invokePackage: (pkg, hook, args...) -> @_pkgIndex?[pkg]?[hook]? args...
PackageManager#isPackageRegistered
- (String)
pkg
- The package.
Check whether a package is registered.
isPackageRegistered: (pkg) -> -1 isnt @_packageList.indexOf pkg
PackageManager#packageImplements
-
(String)
pkg
- The package. -
(String)
hook
- The hook to check.
Check whether a package implements a hook.
packageImplements: (pkg, hook) -> @_pkgIndex?[pkg]?[hook]?
PackageManager#packageList
Get the list of registered packages.
packageList: -> @_packageList
PackageManager#packagePath
- (String)
pkg
- The package.
Get the filepath of a package.
packagePath: (pkg) ->
path_ = config.get 'path'
path.relative path_, path.dirname require.resolve pkg
PackageManager#packagesImplementing
- (String)
hook
- The hook to check.
Get the list of registered packages implementing a hook.
packagesImplementing: (hook) -> @_hookIndex?[hook] ? []
PackageManager#registerPackage
- (String)
pkg
- The package.
Register a package.
registerPackage: (pkg) ->
return if @isPackageRegistered pkg
try
module_ = require pkg
Suppress missing package errors.
catch error
if error.toString() is "Error: Cannot find module '#{pkg}'"
return
throw error
@_packageList.push pkg
module_.pkgmanRegister? new PackageManager.Registrar(
@_hookIndex, @_pkgIndex, pkg
)
PackageManager#registerPackages
- (Array of String)
pkgs
- The packages.
Register packages.
registerPackages: (pkgs) -> @registerPackage pkg for pkg in pkgs
PackageManager#unregisterPackage
- (String)
pkg
- The package.
Unregister a package.
unregisterPackage: (pkg) ->
return unless @isPackageRegistered pkg
for hook of @_pkgIndex[pkg]
if -1 isnt index = @_hookIndex[hook].indexOf pkg
@_hookIndex[hook].splice index, 1
delete @_hookIndex[hook] if @_hookIndex[hook].length is 0
delete @_pkgIndex[pkg]
index = @_packageList.indexOf pkg
@_packageList.splice index, 1
return
PackageManager#unregisterPackages
- (Array of String)
pkgs
- The packages.
Unregister a list of packages.
unregisterPackages: (pkgs) -> @unregisterPackage pkg for pkg in pkgs
class PackageManager.Registrar
constructor: (@_hookIndex, @_pkgIndex, @_path) ->
path: -> @_path
recur: (paths) ->
for path_ in paths
subpath = "#{@_path}/#{path_}"
submodule = require subpath
submodule.pkgmanRegister? new PackageManager.Registrar(
@_hookIndex, @_pkgIndex, subpath
)
registerHook: (submodule, hook, impl) ->
If submodule
was passed in, modify the path this hook is registered
against.
if impl?
path_ = "#{@_path}/#{submodule}"
Otherwise, fix up the args.
else
path_ = @_path
impl = hook
hook = submodule
(@_hookIndex[hook] ?= []).push path_
(@_pkgIndex[path_] ?= {})[hook] = impl
module.exports = new PackageManager()
module.exports.PackageManager = PackageManager