Skip to content

Commit

Permalink
Support for loading plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
nknapp committed Mar 24, 2017
1 parent dac01c6 commit 84446b4
Show file tree
Hide file tree
Showing 21 changed files with 198 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .thought/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
plugins: [
require('thought-plugin-jsdoc')
]
}
27 changes: 27 additions & 0 deletions .thought/partials/usage.md.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,33 @@ Thought implicitly uses the [promised-handlebars](https://github.com/nknapp/prom
to allow helpers that return promises. So, in your helpers, you will never receive a promise as parameter or
as context data, but if you return promises, they will be resolved seamlessly.

## Plugin modules

The customizations described above can be extracted into reusable modules. A thought-plugin is just a
{{npm 'customize'}}-module that is loaded using the [customize.load()](https://github.com/bootprint/customize#module_customize..Customize+load)
function.

### Authoring modules

Have a look at {{npm 'customize-engine-handlebars'}} for an example on how to write a module. For
a real example have a look at {{npm 'thought-plugin-jsdoc'}}.

### Using modules

* Include you favorite plugins in the `devDependencies` of your `package.json`
* Place a file `config.js` into the `.thought`-folder in your project:

{{include '.thought/snippets/config.js'}}

This file loads multiple plugins that are applied to the `customize`-instance one after another.

You can also load plugins from other-plugins. The following example uses plugins that do not yet exist, but the
application is thinkable:

{{include '.thought/snippets/plugin-loading-plugins.js'}}

This allows you to create building-blocks that can then be assembled to a single plugin which can be included in your
projects...



Expand Down
10 changes: 10 additions & 0 deletions .thought/snippets/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
plugins: [
// JsDoc-Support
require('thought-plugin-jsdoc'),
// Some other feature plugin
require('thought-plugin-something-else'),
// Plugin containing my (nknapp's) personal preferences
require('thought-plugin-nknapp-preferences')
]
}
10 changes: 10 additions & 0 deletions .thought/snippets/plugin-loading-plugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = function (customize) {

return customize
// jsdoc-support
.load(require('thought-plugin-jsdoc'))
// include open-open-source disclaimer in CONTRIBUTING.md
.load(require('thought-plugin-open-open-source'))
// include standardjs-disclaimer in CONTRIBUTING.md
.load(require('thought-plugin-standardjs'))
}
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,59 @@ Thought implicitly uses the [promised-handlebars](https://github.com/nknapp/prom
to allow helpers that return promises. So, in your helpers, you will never receive a promise as parameter or
as context data, but if you return promises, they will be resolved seamlessly.

## Plugin modules

The customizations described above can be extracted into reusable modules. A thought-plugin is just a
[customize](https://npmjs.com/package/customize)-module that is loaded using the [customize.load()](https://github.com/bootprint/customize#module_customize..Customize+load)
function.

### Authoring modules

Have a look at [customize-engine-handlebars](https://npmjs.com/package/customize-engine-handlebars) for an example on how to write a module. For
a real example have a look at [thought-plugin-jsdoc](https://npmjs.com/package/thought-plugin-jsdoc).

### Using modules

* Include you favorite plugins in the `devDependencies` of your `package.json`
* Place a file `config.js` into the `.thought`-folder in your project:

```js
module.exports = {
plugins: [
// JsDoc-Support
require('thought-plugin-jsdoc'),
// Some other feature plugin
require('thought-plugin-something-else'),
// Plugin containing my (nknapp's) personal preferences
require('thought-plugin-nknapp-preferences')
]
}

```


This file loads multiple plugins that are applied to the `customize`-instance one after another.

You can also load plugins from other-plugins. The following example uses plugins that do not yet exist, but the
application is thinkable:

```js
module.exports = function (customize) {

return customize
// jsdoc-support
.load(require('thought-plugin-jsdoc'))
// include open-open-source disclaimer in CONTRIBUTING.md
.load(require('thought-plugin-open-open-source'))
// include standardjs-disclaimer in CONTRIBUTING.md
.load(require('thought-plugin-standardjs'))
}

```


This allows you to create building-blocks that can then be assembled to a single plugin which can be included in your
projects...



Expand Down
17 changes: 16 additions & 1 deletion customize.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@

'use strict'

var path = require('path')
const path = require('path')
const fs = require('fs')

// Default config if the file `.thought/config.js` does not exist
const defaultConfig = {
plugins: []
}

/**
*
Expand All @@ -18,6 +24,8 @@ var path = require('path')
*/
module.exports = function createSpec (workingDir) {
return function thoughtSpec (customize) {
const configFile = path.resolve('.thought', 'config.js')
var config = fs.existsSync(configFile) ? require(configFile) : defaultConfig
return customize
.registerEngine('handlebars', require('customize-engine-handlebars'))
.merge({
Expand All @@ -35,6 +43,13 @@ module.exports = function createSpec (workingDir) {
}
}
})
// Apply any customization from the config-files (such as loading modules)
.load(function (customize) {
const result = config.plugins.reduce((prev, plugin) => {
return prev.load(plugin)
}, customize)
return result
})
.merge({
handlebars: {
partials: path.join(workingDir, '.thought', 'partials'),
Expand Down
15 changes: 15 additions & 0 deletions test/fixtures/plugin-module/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const path = require('path')

module.exports = function plugin (customize) {
return customize.merge({
handlebars: {
partials: path.resolve(__dirname, 'partials'),
templates: path.resolve(__dirname, 'templates'),
helpers: {
npm: function (name) {
return `[${name.toUpperCase()}](https://npmjs.com/package/${name})`
}
}
}
})
}
1 change: 1 addition & 0 deletions test/fixtures/plugin-module/partials/license.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Overridden partial license.md
1 change: 1 addition & 0 deletions test/fixtures/plugin-module/templates/CONTRIBUTING.md.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file is overridden in the plugin-module
1 change: 1 addition & 0 deletions test/fixtures/plugin-module/templates/README.md.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file is overridden in the plugin-module
1 change: 1 addition & 0 deletions test/fixtures/plugin-module/templates/new-file.md.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This files is created in the plugin-module
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
plugins: [
require('../../../../plugin-module/index')
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
This file comes from the project-using-a-plugin-module

This name should be uppercase (due to the overwritten helper): {{npm 'customize'}}

----
{{>license.md}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file is overridden in the plugin-module
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
This file comes from the project-using-a-plugin-module

This name should be uppercase (due to the overwritten helper): [CUSTOMIZE](https://npmjs.com/package/customize)

----

Overridden partial license.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This files is created in the plugin-module
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "project-using-a-plugin",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
plugins: [
require('../../../../plugin-module/index')
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
This file comes from the project-using-a-plugin-module

This name should be uppercase (due to the overwritten helper): {{npm 'customize'}}

----
{{>license.md}}
12 changes: 12 additions & 0 deletions test/fixtures/scenarios/project-using-a-plugin/input/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "project-using-a-plugin",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
2 changes: 1 addition & 1 deletion test/lib/scenarios.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Scenario {
*/
prepare () {
return qfs.removeTree(this.actual)
.then(() => copy(this.input, this.actual))
.then(() => copy(this.input, this.actual, { dot: true }))
.then(() => this)
}

Expand Down

0 comments on commit 84446b4

Please sign in to comment.