You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
5.7 KiB
171 lines
5.7 KiB
'use strict'; |
|
const hasGulplog = require('has-gulplog'); |
|
const micromatch = require('micromatch'); |
|
const unique = require('array-unique'); |
|
const findup = require('findup-sync'); |
|
const resolve = require('resolve'); |
|
const path = require('path'); |
|
|
|
function arrayify(el) { |
|
return Array.isArray(el) ? el : [el]; |
|
} |
|
|
|
function camelize(str) { |
|
return str.replace(/-(\w)/g, (m, p1) => p1.toUpperCase()); |
|
} |
|
|
|
// code from https://github.com/gulpjs/gulp-util/blob/master/lib/log.js |
|
// to use the same functionality as gulp-util for backwards compatibility |
|
// with gulp 3x cli |
|
function logger() { |
|
if (hasGulplog()) { |
|
// specifically deferring loading here to keep from registering it globally |
|
const gulplog = require('gulplog'); |
|
gulplog.info.apply(gulplog, arguments); |
|
} else { |
|
// specifically deferring loading because it might not be used |
|
const fancylog = require('fancy-log'); |
|
fancylog.apply(null, arguments); |
|
} |
|
} |
|
|
|
function getPattern(options) { |
|
const defaultPatterns = ['gulp-*', 'gulp.*', '@*/gulp{-,.}*']; |
|
const overridePattern = 'overridePattern' in options ? !!options.overridePattern : true; |
|
if (overridePattern) { |
|
return arrayify(options.pattern || defaultPatterns); |
|
} |
|
return defaultPatterns.concat(arrayify(options.pattern)); |
|
} |
|
|
|
module.exports = function(options) { |
|
const finalObject = {}; |
|
let requireFn; |
|
options = options || {}; |
|
|
|
const DEBUG = options.DEBUG || false; |
|
const pattern = getPattern(options); |
|
const config = options.config || findup('package.json', { cwd: path.dirname(module.parent.filename) }); |
|
const scope = arrayify(options.scope || ['dependencies', 'devDependencies', 'peerDependencies']); |
|
const replaceString = options.replaceString || /^gulp(-|\.)/; |
|
const camelizePluginName = options.camelize !== false; |
|
const lazy = 'lazy' in options ? !!options.lazy : true; |
|
const renameObj = options.rename || {}; |
|
const maintainScope = 'maintainScope' in options ? !!options.maintainScope : true; |
|
|
|
logDebug(`Debug enabled with options: ${JSON.stringify(options)}`); |
|
|
|
const renameFn = options.renameFn || function(name) { |
|
name = name.replace(replaceString, ''); |
|
return camelizePluginName ? camelize(name) : name; |
|
}; |
|
|
|
const postRequireTransforms = options.postRequireTransforms || {}; |
|
|
|
if (typeof options.requireFn === 'function') { |
|
requireFn = options.requireFn; |
|
} else if (typeof config === 'string') { |
|
requireFn = function(name) { |
|
// This searches up from the specified package.json file, making sure |
|
// the config option behaves as expected. See issue #56. |
|
const src = resolve.sync(name, { basedir: path.dirname(config) }); |
|
return require(src); |
|
}; |
|
} else { |
|
requireFn = require; |
|
} |
|
|
|
const configObject = (typeof config === 'string') ? require(config) : config; |
|
|
|
if (!configObject) { |
|
throw new Error('Could not find dependencies. Do you have a package.json file in your project?'); |
|
} |
|
|
|
const names = scope.reduce((result, prop) => result.concat(Object.keys(configObject[prop] || {})), []); |
|
|
|
logDebug(`${names.length} plugin(s) found: ${names.join(' ')}`); |
|
|
|
pattern.push('!gulp-load-plugins'); |
|
|
|
function logDebug(message) { |
|
if (DEBUG) { |
|
logger(`gulp-load-plugins: ${message}`); |
|
} |
|
} |
|
|
|
function defineProperty(object, transform, requireName, name, maintainScope) { |
|
let err; |
|
if (object[requireName]) { |
|
logDebug(`error: defineProperty ${name}`); |
|
err = maintainScope |
|
? `Could not define the property "${requireName}", you may have repeated dependencies in your package.json like` + ` "gulp-${requireName}" and ` + `"${requireName}"` |
|
: `Could not define the property "${requireName}", you may have repeated a dependency in another scope like` + ` "gulp-${requireName}" and ` + `"@foo/gulp-${requireName}"`; |
|
throw new Error(err); |
|
} |
|
|
|
if (lazy) { |
|
logDebug(`lazyload: adding property ${requireName}`); |
|
Object.defineProperty(object, requireName, { |
|
enumerable: true, |
|
get: function() { |
|
logDebug(`lazyload: requiring ${name}...`); |
|
return transform(requireName, requireFn(name)); |
|
} |
|
}); |
|
} else { |
|
logDebug(`requiring ${name}...`); |
|
object[requireName] = transform(requireName, requireFn(name)); |
|
} |
|
} |
|
|
|
function getRequireName(name) { |
|
let requireName; |
|
|
|
if (renameObj[name]) { |
|
requireName = options.rename[name]; |
|
} else { |
|
requireName = renameFn(name); |
|
} |
|
|
|
logDebug(`renaming ${name} to ${requireName}`); |
|
|
|
return requireName; |
|
} |
|
|
|
function applyTransform(requireName, plugin) { |
|
const transform = postRequireTransforms[requireName]; |
|
|
|
if (transform && typeof transform === 'function') { // if postRequireTransform function is passed, pass it the plugin and return it |
|
logDebug(`transforming ${requireName}`); |
|
return transform(plugin); |
|
} else { |
|
return plugin; // if no postRequireTransform function passed, return the plugin as is |
|
} |
|
} |
|
|
|
const scopeTest = /^@/; |
|
const scopeDecomposition = /^@(.+)\/(.+)/; |
|
|
|
unique(micromatch(names, pattern)).forEach((name) => { |
|
let decomposition; |
|
let fObject = finalObject; |
|
if (scopeTest.test(name)) { |
|
decomposition = scopeDecomposition.exec(name); |
|
if (maintainScope) { |
|
if (!Object.prototype.hasOwnProperty.call(fObject, decomposition[1])) { |
|
finalObject[decomposition[1]] = {}; |
|
} |
|
fObject = finalObject[decomposition[1]]; |
|
} |
|
|
|
defineProperty(fObject, applyTransform, getRequireName(decomposition[2]), name, maintainScope); |
|
} else { |
|
defineProperty(fObject, applyTransform, getRequireName(name), name, maintainScope); |
|
} |
|
}); |
|
|
|
return finalObject; |
|
}; |
|
|
|
// Necessary to get the current `module.parent` and resolve paths correctly. |
|
delete require.cache[__filename];
|
|
|