apply-extends.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. 'use strict'
  2. const fs = require('fs')
  3. const path = require('path')
  4. const YError = require('./yerror')
  5. let previouslyVisitedConfigs = []
  6. function checkForCircularExtends (cfgPath) {
  7. if (previouslyVisitedConfigs.indexOf(cfgPath) > -1) {
  8. throw new YError(`Circular extended configurations: '${cfgPath}'.`)
  9. }
  10. }
  11. function getPathToDefaultConfig (cwd, pathToExtend) {
  12. return path.resolve(cwd, pathToExtend)
  13. }
  14. function applyExtends (config, cwd) {
  15. let defaultConfig = {}
  16. if (config.hasOwnProperty('extends')) {
  17. if (typeof config.extends !== 'string') return defaultConfig
  18. const isPath = /\.json|\..*rc$/.test(config.extends)
  19. let pathToDefault = null
  20. if (!isPath) {
  21. try {
  22. pathToDefault = require.resolve(config.extends)
  23. } catch (err) {
  24. // most likely this simply isn't a module.
  25. }
  26. } else {
  27. pathToDefault = getPathToDefaultConfig(cwd, config.extends)
  28. }
  29. // maybe the module uses key for some other reason,
  30. // err on side of caution.
  31. if (!pathToDefault && !isPath) return config
  32. checkForCircularExtends(pathToDefault)
  33. previouslyVisitedConfigs.push(pathToDefault)
  34. defaultConfig = isPath ? JSON.parse(fs.readFileSync(pathToDefault, 'utf8')) : require(config.extends)
  35. delete config.extends
  36. defaultConfig = applyExtends(defaultConfig, path.dirname(pathToDefault))
  37. }
  38. previouslyVisitedConfigs = []
  39. return Object.assign({}, defaultConfig, config)
  40. }
  41. module.exports = applyExtends