UNPKG

2.81 kBJavaScriptView Raw
1"use strict"
2
3const p = require("path")
4const flatten = require("./fn").flatten
5const isObject = require("./fn").isObject
6const co = require("bluebird").coroutine
7const $ = require("./utils")
8
9const rgx = /^@(taskr|fly)|(taskr|fly)-/i
10const dirname = p.dirname
11const resolve = p.resolve
12const join = p.join
13
14/**
15 * Attempt to dynamically `require()` a file or package
16 * @param {String} name The dep-name or filepath to require.
17 * @param {String} base Path to `node_modules` directory.
18 */
19function req(name, base) {
20 try {
21 try {
22 name = require.resolve(name)
23 } catch (_) {
24 name = join(base, name)
25 } finally {
26 return require(name);
27 }
28 } catch (e) {
29 $.alert(e.message)
30 }
31}
32
33/**
34 * Find a sibling `package.json` file & return its contents.
35 * @param {Object} file A `package.json` contents as JSON
36 * @return {Array} The names of all dependencies, flattened
37 */
38function getDependencies(pkg) {
39 if (!pkg) {
40 return []
41 }
42
43 if (!isObject(pkg)) {
44 $.error("Content from `package.json` must be an `Object`!")
45 return []
46 }
47
48 // get all possible dependencies
49 const deps = ["dependencies", "devDependencies", "peerDependencies"]
50 .filter(key => key in pkg).map(dep => Object.keys(pkg[dep]))
51
52 return flatten(deps)
53}
54
55/**
56 * Find & Read a `package.json` file, starting from `dir`.
57 * @param {String} dir
58 * @yield {Object} If found, returns as `{file, data}`
59 */
60const getPackage = co(function * (dir) {
61 // traverse upwards from `dir`
62 const file = yield $.find("package.json", dir)
63
64 if (!file) {
65 return false
66 }
67
68 // check if there"s a "taskr" config entry
69 const data = JSON.parse(yield $.read(file))
70
71 if (data.taskr && data.taskr.pkg) {
72 dir = resolve(dir, data.taskr.pkg)
73 return yield getPackage(dir)
74 }
75
76 return {file, data}
77})
78
79/**
80 * Loads all (fly|taskr)-related plugins!
81 * @param {String} taskfile The full `taskfile.js` path
82 * @return {Array} All loaded plugins.
83 */
84const load = co(function * (taskfile) {
85 // find a `package.json`, starting with `taskfile` dir
86 const pkg = yield getPackage(dirname(taskfile))
87
88 if (!pkg) {
89 $.error("No `package.json` found!")
90 return []
91 }
92
93 // get ALL deps filter down to (taskr|fly)-only
94 const deps = getDependencies(pkg.data).filter(dep => rgx.test(dep))
95 const locals = pkg.data.taskr && pkg.data.taskr.requires
96 const hasNext = deps.indexOf("@taskr/esnext")
97
98 if (locals) {
99 let i = 0
100 const len = locals.length
101 const pkgDir = dirname(pkg.file)
102 for (; i < len; i++) {
103 deps.push(join(pkgDir, locals[i]))
104 }
105 }
106
107 // if "@taskr/esnext" remove from `deps`
108 if (hasNext !== -1) {
109 deps.splice(hasNext, 1)
110 }
111
112 const modules = join(dirname(pkg.file), "node_modules")
113
114 // format return
115 return deps.map(str => req(str, modules))
116})
117
118module.exports = {
119 load,
120 getPackage,
121 getDependencies
122}