Skip to content
This repository
tag: v6.24.0
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

executable file 223 lines (181 sloc) 5.141 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
# Requires
pathUtil = require('path')
semver = require('semver')
balUtil = require('bal-util')
util = require('util')

# Define Plugin Loader
class PluginLoader

# ---------------------------------
# Constructed

# DocPad Instance
docpad: null

# BasePlugin Class
BasePlugin: null

# The full path of the plugin's directory
dirPath: null


# ---------------------------------
# Loaded

# The full path of the plugin's package.json file
packagePath: null

# The parsed contents of the plugin's package.json file
packageData: {}

# The full path of the plugin's main file
pluginPath: null

# The parsed content of the plugin's main file
pluginClass: {}

# Plugin name
pluginName: null

# Plugin version
pluginVersion: null

# Node modules path
nodeModulesPath: null


# ---------------------------------
# Functions

# Constructor
constructor: ({@docpad,@dirPath,@BasePlugin}) ->
# Prepare
docpad = @docpad

# Apply
@pluginName = pathUtil.basename(@dirPath).replace(/^docpad-plugin-/,'')
@pluginClass = {}
@packageData = {}
@nodeModulesPath = pathUtil.resolve(@dirPath, 'node_modules')

# Exists
# Loads in the plugin either via a package.json file, or a guessing based on the name
# next(err,exists)
exists: (next) ->
# Package.json
packagePath = @packagePath or pathUtil.resolve(@dirPath, "package.json")
pluginPath = @pluginPath or pathUtil.resolve(@dirPath, "#{@pluginName}.plugin.coffee")
# the fetch of the this value above allows advanced use cases of plugin loading
# hover, as of yet, we don't do any such advanced use cases
balUtil.exists packagePath, (exists) =>
unless exists
balUtil.exists pluginPath, (exists) =>
unless exists
return next(null,false)
else
@pluginPath = pluginPath
return next(null,true)
else
@packagePath = packagePath
balUtil.readFile packagePath, (err,data) =>
if err
return next(err,false)
else
try
@packageData = JSON.parse data.toString()
catch err
return next(err,false)
return next(null,false) unless @packageData

# Fetch the plugin path
pluginPath = @packageData.main? and pathUtil.join(@dirPath, @pluginPath) or pluginPath
@pluginVersion = @packageData.version
balUtil.exists pluginPath, (exists) =>
unless exists
return next(null,false)
else
@pluginPath = pluginPath
return next(null,true)

# Chain
@

# Unsupported
# Check if this plugin is unsupported
# next(err,supported)
unsupported: (next) ->
# Prepare
docpad = @docpad
unsupported = false

# Check type
if @packageData
keywords = @packageData.keywords or []
unless 'docpad-plugin' in keywords
unsupported = 'type'

# Check platform
if @packageData and @packageData.platforms
platforms = @packageData.platforms or []
unless process.platform in platforms
unsupported = 'platform'

# Check engines
if @packageData and @packageData.engines
engines = @packageData.engines or {}

# Node engine
if engines.node?
unless semver.satisfies(process.version, engines.node)
unsupported = 'engine'

# DocPad engine
if engines.docpad?
unless semver.satisfies(docpad.version, engines.docpad)
unsupported = 'version'

# Supported
next(null,unsupported)

# Chain
@

# Install
# Installs the plugins node modules
# next(err)
install: (next) ->
# Prepare
docpad = @docpad

# Only install if we have a package path
if @packagePath
# Install npm modules
docpad.initNodeModules(
path: @dirPath
next: (err,results) ->
# Forward
return next(err)
)
else
# Continue
next()

# Chain
@

# Load
# Load in the pluginClass from the pugin file
# next(err,pluginClass)
load: (next) ->
# Prepare
docpad = @docpad
locale = docpad.getLocale()

# Load
try
# Load in our plugin
@pluginClass = require(@pluginPath)(@BasePlugin)
@pluginClass::version ?= @pluginVersion
pluginPrototypeName = @pluginClass::name

# Checks
# Alphanumeric
if /^[a-z0-9]+$/.test(@pluginName) is false
validPluginName = @pluginName.replace(/[^a-z0-9]/,'')
docpad.log('warn', util.format(locale.pluginNamingConventionInvalid, @pluginName, validPluginName))
# Same name
if pluginPrototypeName is null
@pluginClass::name = @pluginName
docpad.log('warn', util.format(locale.pluginPrototypeNameUndefined, @pluginName))
else if pluginPrototypeName isnt @pluginName
docpad.log('warn', util.format(locale.pluginPrototypeNameDifferent, @pluginName, pluginPrototypeName))
catch err
# An error occured, return it
return next(err,null)

# Return our plugin
next(null,@pluginClass)

# Chain
@

# Create Instance
# next(err,pluginInstance)
create: (config,next) ->
# Load
try
# Create instance with merged configuration
docpad = @docpad
pluginInstance = new @pluginClass({docpad,config})
catch err
# An error occured, return it
return next(err,null)

# Return our instance
return next(null,pluginInstance)

# Chain
@


# Export
module.exports = PluginLoader
Something went wrong with that request. Please try again.