Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for remote templates #261

Merged
merged 10 commits into from
Mar 27, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 16 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,40 +34,37 @@ asyncapi/generator -o ./output asyncapi.yml markdown
### From the command-line interface (CLI)

```bash
Usage: ag [options] <asyncapi> <template>


Options:

-V, --version output the version number
-w, --watch watches the templates directory and the AsyncAPI document for changes, and re-generate the files when they occur
-o, --output <outputDir> directory where to put the generated files (defaults to current directory)
-d, --disable-hook <hookName> disable a specific hook
-n, --no-overwrite <glob> glob or path of the file(s) to skip when regenerating
-p, --param <name=value> additional param to pass to templates
-t, --templates <templateDir> directory where templates are located (defaults to internal templates directory)
--force-install forces the installation of the template dependencies. By default, dependencies are installed and this flag is taken into account only if `node_modules` is not in place.
-h, --help output usage information
--force-write force writing of the generated files to given directory even if it is a git repo with unstaged files or not empty dir (defaults to false)
Usage: cli [options] <asyncapi> <template>

Options:
-V, --version output the version number
-d, --disable-hook <hookName> disable a specific hook
-i, --install installs the template and its dependencies (defaults to false)
-n, --no-overwrite <glob> glob or path of the file(s) to skip when regenerating
-o, --output <outputDir> directory where to put the generated files (defaults to current directory)
-p, --param <name=value> additional param to pass to templates
--force-write force writing of the generated files to given directory even if it is a git repo with unstaged files or not empty dir (defaults to false)
--watch-template watches the template directory and the AsyncAPI document, and re-generate the files when changes occur
-h, --help output usage information
```

Please check out the **templates** directory to get a list of the supported languages/formats.
:mag: Do you want to find a template? **[Click here!](https://github.com/search?q=topic%3Aasyncapi+topic%3Agenerator+topic%3Atemplate)**

#### Examples

The shortest possible syntax:
```bash
ag asyncapi.yaml markdown
ag asyncapi.yaml @asyncapi/html-template
```

Specify where to put the result:
```bash
ag -o ./docs asyncapi.yaml markdown
ag asyncapi.yaml @asyncapi/html-template -o ./docs
```

Passing parameters to templates:
```bash
ag -o ./docs --param title='Hello from param' asyncapi.yaml markdown
ag asyncapi.yaml @asyncapi/html-template -o ./docs -p title='Hello from param'
fmvilas marked this conversation as resolved.
Show resolved Hide resolved
fmvilas marked this conversation as resolved.
Show resolved Hide resolved
```
In the template you can use it like this: ` {{ params.title }}`

Expand Down
23 changes: 13 additions & 10 deletions cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const packageInfo = require('./package.json');
const mkdirp = require('mkdirp');
const Generator = require('./lib/generator');
const Watcher = require('./lib/watcher');
const { isLocalTemplate } = require('./lib/utils');

const red = text => `\x1b[31m${text}\x1b[0m`;
const magenta = text => `\x1b[35m${text}\x1b[0m`;
Expand Down Expand Up @@ -52,14 +53,13 @@ program
asyncapiFile = path.resolve(asyncAPIPath);
template = tmpl;
})
.option('-w, --watch', 'watches the templates directory and the AsyncAPI document for changes, and re-generate the files when they occur')
.option('-o, --output <outputDir>', 'directory where to put the generated files (defaults to current directory)', parseOutput, process.cwd())
.option('-d, --disable-hook <hookName>', 'disable a specific hook', disableHooksParser)
.option('-i, --install', 'installs the template and its dependencies (defaults to false)')
.option('-n, --no-overwrite <glob>', 'glob or path of the file(s) to skip when regenerating', noOverwriteParser)
.option('-o, --output <outputDir>', 'directory where to put the generated files (defaults to current directory)', parseOutput, process.cwd())
.option('-p, --param <name=value>', 'additional param to pass to templates', paramParser)
.option('-t, --templates <templateDir>', 'directory where templates are located (defaults to internal templates directory)', Generator.DEFAULT_TEMPLATES_DIR, path.resolve(__dirname, 'templates'))
.option('--force-install', 'forces the installation of the template dependencies. By default, dependencies are installed and this flag is taken into account only if `node_modules` is not in place.')
.option('--force-write', 'force writing of the generated files to given directory even if it is a git repo with unstaged files or not empty dir (defaults to false)')
.option('--watch-template', 'watches the template directory and the AsyncAPI document, and re-generate the files when changes occur')
.parse(process.argv);

if (!asyncapiFile) {
Expand All @@ -76,15 +76,19 @@ mkdirp(program.output, async err => {
}

// If we want to watch for changes do that
if (program.watch) {
const watchDir = path.resolve(program.templates, template);
console.log(`[WATCHER] Watching for changes in the template directory ${magenta(watchDir)} and in the async api file ${magenta(asyncapiFile)}`);
if (program.watchTemplate) {
const watchDir = path.resolve(Generator.DEFAULT_TEMPLATES_DIR, template);
console.log(`[WATCHER] Watching for changes in the template directory ${magenta(watchDir)} and in the AsyncAPI file ${magenta(asyncapiFile)}`);

if (!(await isLocalTemplate(watchDir))) {
console.warn(`WARNING: ${template} is a remote template. Changes may be lost on subsequent installations.`);
}

const watcher = new Watcher([asyncapiFile, watchDir]);
watcher.watch(async (changedFiles) => {
console.clear();
console.log('[WATCHER] Change detected');
for (const [key, value] of Object.entries(changedFiles)) {
for (const [, value] of Object.entries(changedFiles)) {
let eventText;
switch (value.eventType) {
case 'changed':
Expand Down Expand Up @@ -121,12 +125,11 @@ function generate(targetDir) {
return new Promise(async (resolve, reject) => {
try {
const generator = new Generator(template, targetDir || path.resolve(os.tmpdir(), 'asyncapi-generator'), {
templatesDir: program.templates,
templateParams: params,
noOverwriteGlobs,
disabledHooks,
forceWrite: program.forceWrite,
forceInstall: program.forceInstall,
forceInstall: program.install,
});

await generator.generateFromFile(asyncapiFile);
Expand Down
33 changes: 3 additions & 30 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
* [.generate(asyncapiDocument)](#Generator+generate) ⇒ <code>Promise</code>
* [.generateFromString(asyncapiString, [asyncApiFileLocation])](#Generator+generateFromString) ⇒ <code>Promise</code>
* [.generateFromFile(asyncapiFile)](#Generator+generateFromFile) ⇒ <code>Promise</code>
* [.getAllParameters(asyncapiDocument)](#Generator+getAllParameters)
* [.installTemplate([force])](#Generator+installTemplate)
* _static_
* [.getTemplateFile(templateName, filePath, options)](#Generator.getTemplateFile) ⇒ <code>Promise</code>
Expand All @@ -25,14 +24,13 @@ Instantiates a new Generator object.
| templateName | <code>String</code> | | Name of the template to generate. |
| targetDir | <code>String</code> | | Path to the directory where the files will be generated. |
| options | <code>Object</code> | | |
| [options.templatesDir] | <code>String</code> | | Path to the directory where to find the given template. Defaults to internal `templates` directory. |
| [options.templateParams] | <code>String</code> | | Optional parameters to pass to the template. Each template define their own params. |
| [options.entrypoint] | <code>String</code> | | Name of the file to use as the entry point for the rendering process. Use in case you want to use only a specific template file. Note: this potentially avoids rendering every file in the template. |
| [options.noOverwriteGlobs] | <code>Array.&lt;String&gt;</code> | | List of globs to skip when regenerating the template. |
| [options.disabledHooks] | <code>Array.&lt;String&gt;</code> | | List of hooks to disable. |
| [options.output] | <code>String</code> | <code>&#x27;fs&#x27;</code> | Type of output. Can be either 'fs' (default) or 'string'. Only available when entrypoint is set. |
| [options.forceWrite] | <code>Boolean</code> | <code>false</code> | Force writing of the generated files to given directory even if it is a git repo with unstaged files or not empty dir. Default is set to false. |
| [options.forceInstall] | <code>Boolean</code> | <code>false</code> | Force the installation of the template dependencies. By default, dependencies are installed and this flag is taken into account only if `node_modules` is not in place. |
| [options.forceInstall] | <code>Boolean</code> | <code>false</code> | Force the installation of the template and its dependencies. |

**Example**
```js
Expand All @@ -48,13 +46,6 @@ const generator = new Generator('html', path.resolve(__dirname, 'example'), {
}
});
```
**Example** *(Specifying a custom directory for templates)*
```js
const path = require('path');
const generator = new Generator('myTemplate', path.resolve(__dirname, 'example'), {
templatesDir: path.resolve(__dirname, 'my-templates')
});
```
<a name="Generator+generate"></a>

### generator.generate(asyncapiDocument) ⇒ <code>Promise</code>
Expand Down Expand Up @@ -158,25 +149,16 @@ try {
console.error(e);
}
```
<a name="Generator+getAllParameters"></a>

### generator.getAllParameters(asyncapiDocument)
**Kind**: instance method of [<code>Generator</code>](#Generator)

| Param | Type | Description |
| --- | --- | --- |
| asyncapiDocument | <code>AsyncAPIDocument</code> | AsyncAPI document to use as the source. |

<a name="Generator+installTemplate"></a>

### generator.installTemplate([force])
Installs template dependencies.
Downloads and installs a template and its dependencies.

**Kind**: instance method of [<code>Generator</code>](#Generator)

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [force] | <code>Boolean</code> | <code>false</code> | Whether to force installation or not. |
| [force] | <code>Boolean</code> | <code>false</code> | Whether to force installation (and skip cache) or not. |

<a name="Generator.getTemplateFile"></a>

Expand All @@ -190,18 +172,9 @@ Returns the content of a given template file.
| templateName | <code>String</code> | Name of the template to generate. |
| filePath | <code>String</code> | Path to the file to render. Relative to the template directory. |
| options | <code>Object</code> | |
| [options.templatesDir] | <code>String</code> | Path to the directory where to find the given template. Defaults to internal `templates` directory. |

**Example**
```js
const Generator = require('asyncapi-generator');
const content = await Generator.getTemplateFile('html', '.partials/content.html');
```
**Example** *(Obtaining the content of a file from a custom template)*
```js
const path = require('path');
const Generator = require('asyncapi-generator');
const content = await Generator.getTemplateFile('myTemplate', 'a/file.js', {
templatesDir: path.resolve(__dirname, 'my-templates')
});
```
Loading