-
Notifications
You must be signed in to change notification settings - Fork 264
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: Hygen extensibility loading, and first integration - helpers…
…. (also align flow types)
- Loading branch information
Showing
33 changed files
with
505 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
--- | ||
title: Extensibility | ||
doc: 4 | ||
section: 1 | ||
category: "tech" | ||
type: "doc" | ||
--- | ||
|
||
You can extend these properties of Hygen, using a special `.hygen.js` file: | ||
|
||
* Helper functions in templates. | ||
* Customizing logger, template location and shell executor. | ||
* (_WIP_) Custom generator operations in addition to the built-in `add`, `inject`, `shell` | ||
|
||
# .hygen.js | ||
|
||
Hygen supports a bubbling-up mechanism for searching a `.hygen.js` file and loading it. Where ever you run `hygen` from, it will start searching for this file upwards, and stop at the first one it finds. | ||
|
||
This means: | ||
|
||
* You can set up a _single file_ per project. | ||
* For some special sub-projects, set a different file for a different behavior. | ||
* You can also set up one global file to use if you drop it in your user folder. | ||
|
||
_Note:_ The current strategy when there are two or more `.hygen.js` files in the path upwards is to _take the first one_ and ignore the rest. | ||
|
||
# Helpers | ||
|
||
Here's a template that uses a function that doesn't exist in the helper accessor `h`. This function is plainly called `extended`, for lack of a better name. | ||
|
||
```yaml{5} | ||
--- | ||
to: given/hygen-js/new.md | ||
--- | ||
this demonstrates hygen loaded up .hygen.js and extended helpers. | ||
<%= h.extended('hello') %> | ||
``` | ||
|
||
In order to add the function `extended` to the standard `hygen` helpers collection, we'll create a `.hygen.js` file at the root of our project: | ||
|
||
``` | ||
src/ | ||
package.json | ||
.hygen.js | ||
``` | ||
|
||
This `.hygen.js` file will be the home of all of our extension points. For this example, we'll use the following content: | ||
|
||
```javascript{3} | ||
module.exports = { | ||
helpers: { | ||
extended: s => s.toUpperCase() | ||
} | ||
} | ||
``` | ||
|
||
Note that beyond inlining a utility function like in this example, you can require and use any piece of code in your project here and export it for Hygen to use. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
"use strict"; | ||
|
||
var _config = require("./config"); | ||
|
||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
|
||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _next(value) { step("next", value); } function _throw(err) { step("throw", err); } _next(); }); }; } | ||
|
||
const L = require('lodash'); | ||
|
||
const fs = require('fs-extra'); | ||
|
||
const path = require('path'); | ||
|
||
const resolver = new _config.ConfigResolver('.hygen.js', { | ||
exists: fs.exists, | ||
// $FlowFixMe | ||
load: f => Promise.resolve(require(f)) | ||
}); | ||
|
||
module.exports = | ||
/*#__PURE__*/ | ||
function () { | ||
var _ref = _asyncToGenerator(function* (config) { | ||
const cwd = config.cwd, | ||
templates = config.templates; | ||
const fileConfig = yield resolver.resolve(cwd); | ||
const resolvedTemplates = L.find([process.env.HYGEN_TMPLS, path.join(cwd, '_templates')], _ => fs.existsSync(_)) || templates; | ||
return _extends({}, config, { | ||
templates: resolvedTemplates | ||
}, fileConfig); | ||
}); | ||
|
||
return function (_x) { | ||
return _ref.apply(this, arguments); | ||
}; | ||
}(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
"use strict"; | ||
|
||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.ConfigResolver = exports.configLookup = void 0; | ||
|
||
var _path = _interopRequireDefault(require("path")); | ||
|
||
var _lodash = _interopRequireDefault(require("lodash")); | ||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
|
||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _next(value) { step("next", value); } function _throw(err) { step("throw", err); } _next(); }); }; } | ||
|
||
// inline fp methods due to perf | ||
const reduce = (f, init) => arr => _lodash.default.reduce(arr, f, init); | ||
|
||
const reversePathsToWalk = _lodash.default.flow(f => _path.default.resolve(f), f => f.split(_path.default.sep), reduce((acc, p) => p === '' ? [_path.default.sep] : [...acc, _path.default.join(_lodash.default.last(acc), p)], []), _lodash.default.reverse); | ||
|
||
const configLookup = (file, folder) => _lodash.default.map(reversePathsToWalk(folder), p => _path.default.join(p, file)); | ||
|
||
exports.configLookup = configLookup; | ||
|
||
class ConfigResolver { | ||
constructor(configFile, io) { | ||
Object.defineProperty(this, "configFile", { | ||
configurable: true, | ||
enumerable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "io", { | ||
configurable: true, | ||
enumerable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
this.configFile = configFile; | ||
this.io = io; | ||
} | ||
|
||
resolve(from) { | ||
var _this = this; | ||
|
||
return _asyncToGenerator(function* () { | ||
const configCandidates = configLookup(_this.configFile, from); | ||
const _this$io = _this.io, | ||
exists = _this$io.exists, | ||
load = _this$io.load; | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
|
||
try { | ||
for (var _iterator = configCandidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
const candidate = _step.value; | ||
|
||
if (yield exists(candidate)) { | ||
return yield load(candidate); | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return != null) { | ||
_iterator.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
|
||
return {}; | ||
})(); | ||
} | ||
|
||
} | ||
|
||
exports.ConfigResolver = ConfigResolver; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,39 @@ | ||
"use strict"; | ||
|
||
var _config = require("./config"); | ||
|
||
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
|
||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _next(value) { step("next", value); } function _throw(err) { step("throw", err); } _next(); }); }; } | ||
|
||
const L = require('lodash'); | ||
|
||
const fs = require('fs-extra'); | ||
|
||
const path = require('path'); | ||
|
||
module.exports = config => { | ||
const cwd = config.cwd, | ||
templates = config.templates; | ||
const resolvedTemplates = L.find([// $FlowFixMe | ||
process.env.HYGEN_TMPLS, path.join(cwd, '_templates')], _ => fs.existsSync(_)) || templates; | ||
return _extends({}, config, { | ||
templates: resolvedTemplates | ||
const resolver = new _config.ConfigResolver('.hygen.js', { | ||
exists: fs.exists, | ||
load: f => Promise.resolve(require(f)) | ||
}); | ||
|
||
module.exports = | ||
/*#__PURE__*/ | ||
function () { | ||
var _ref = _asyncToGenerator(function* (config) { | ||
const cwd = config.cwd, | ||
templates = config.templates; | ||
const start = new Date(); | ||
const fileConfig = yield resolver.resolve(cwd); | ||
console.log('timing:', new Date() - start); | ||
const resolvedTemplates = L.find([// $FlowFixMe | ||
process.env.HYGEN_TMPLS, path.join(cwd, '_templates')], _ => fs.existsSync(_)) || templates; | ||
return _extends({}, config, { | ||
templates: resolvedTemplates | ||
}, fileConfig); | ||
}); | ||
}; | ||
|
||
return function (_x) { | ||
return _ref.apply(this, arguments); | ||
}; | ||
}(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.