dgeni
Advanced tools
Comparing version 0.3.0 to 0.4.0-beta.1
#!/usr/bin/env node | ||
var rimraf = require('rimraf'); | ||
var path = require('canonical-path'); | ||
var myArgs = require('optimist') | ||
.usage('Usage: $0 path/to/config') | ||
.usage('Usage: $0 path/to/mainPackage [path/to/other/packages ...]') | ||
.demand(1) | ||
.argv; | ||
var dgeni = require('../lib/index'); | ||
var log = dgeni.log; | ||
var Dgeni = require('dgeni'); | ||
// Set up logging to look nice on the command line | ||
log.cli(); | ||
// Extract the paths to the packages from the command line arguments | ||
var packagePaths = myArgs._; | ||
// Load in the config file and run it over the top of the default config | ||
var config = dgeni.loadConfig(myArgs._[0]); | ||
// Require each of these packages and then create a new dgeni using them | ||
var packages = packagePaths.map(function(packagePath) { | ||
if ( packagePath.startsWith('.') ) { | ||
packagePath = path.resolve(packagePath); | ||
} | ||
return require(packagePath); | ||
}); | ||
var outputFolder = config.get('rendering.outputFolder'); | ||
if ( config.get('rendering.cleanOutputFolder') && outputFolder ) { | ||
// Delete the previous output | ||
rimraf.sync(outputFolder); | ||
log.info('Removed previous output files from "' + outputFolder + '"'); | ||
} | ||
var dgeni = new Dgeni(packages); | ||
var generateDocs = dgeni.generator(config); | ||
generateDocs().then(function() { | ||
log.info('Finished generating docs'); | ||
// Run the document generation | ||
dgeni.generate().then(function() { | ||
console.log('Finished generating docs'); | ||
}).done(); |
# ChangeLog | ||
## v0.4.0-beta.1 (25th July 2014) | ||
This is a major re-architecting of how Dgeni uses Dependency Injection and configuration. | ||
This version of Dgeni is compatible with dgeni-packages@^0.10.0 | ||
* Dgeni is now configured by **Packages**, which can depend on other **Packages**. | ||
* **Packages** contain **Services**, **Processors** and **Config Blocks**, which are all | ||
instantiated or invoked by the DI system. | ||
* **Processors** themselves are special instances of DI **Service** rather than the | ||
**process()** being invoked by the DI system. | ||
* Dgeni specific properties on **Processors** are now prefixed with a `$`. E.g. `$process()`, | ||
`$runBefore`, `$runAfter`. | ||
* **Processors** can now be "validated" using [validatejs.org](validatejs.org) constraints, | ||
specified in the `processor.$validate` property. | ||
* **Processors** can now be disabled by setting `processor.$enabled = false`. | ||
* **Processors** with the same name will override previously registered **Processors**, say | ||
from a Package dependency. | ||
* New injectable helper services have been provided: `dgeni`, `log`, `getInjectables`. | ||
* Use injectable `log` service in your Processors and Services instead of requiring `winston`. | ||
* Test coverage of the source files is now at 100%. | ||
The most significant commits are listed below: | ||
* fix(Dgeni): allow config blocks to change $enabled on a Processor d231c244 | ||
* feat(Dgeni): allow processors to be disabled by setting `$enabled: false` d390fcd3 | ||
* feat(Dgeni): allow config blocks to make changes to processor order 604fcbfb | ||
* feat(Dgeni): add package info to processors to help with error reporting 81184052 | ||
* fix(Dgeni): processors with the same name should override previous ones ff7ec049 | ||
* feat(getInjectables): add new shared service 6d9cef0a | ||
* test(mock/log): add simple mock log service for testing 51a8dc92 | ||
* feat(Package): allow processors and service to override their name a9584fd2 | ||
* test(Dgeni): add tests to improve code coverage 7b4a757b | ||
* feat(Package): allow processors to be defined as an object a75e9181 | ||
* feat(Dgeni): add new (no config - DI based) Dgeni e8d30958 | ||
* feat(Package): add Package type 87cbf122 | ||
* feat(log): add wrapper around winston c303a9a6 | ||
* refact(*): remove previous Dgeni implementation 1cf67e2d | ||
## v0.3.0 (11th April 2014) | ||
@@ -13,7 +52,7 @@ | ||
** New Stuff ** | ||
**New Stuff** | ||
* feat(doc-processor): processors can declare injectable exports cfd19f08 | ||
** Breaking Changes ** | ||
**Breaking Changes** | ||
@@ -58,2 +97,2 @@ * refactor(index): provide a cleaner API surface 3c78776d | ||
* Initial version to support AngularJS documentation generation. | ||
* Initial version to support AngularJS documentation generation. |
{ | ||
"name": "dgeni", | ||
"version": "0.3.0", | ||
"version": "0.4.0-beta.1", | ||
"description": "Flexible JavaScript documentation generator used by AngularJS", | ||
"main": "lib/index.js", | ||
"main": "lib/Dgeni.js", | ||
"scripts": { | ||
"test": "jasmine-node spec", | ||
"cover": "istanbul cover jasmine-node -- spec" | ||
"cover": "istanbul cover jasmine-node -- spec", | ||
"docs": "bin/gen-docs.js ./docs/dgeni-docs.js" | ||
}, | ||
@@ -22,15 +23,16 @@ "repository": { | ||
"dependencies": { | ||
"winston": "~0.7.2", | ||
"rimraf": "~2.2.5", | ||
"canonical-path": "~0.0.2", | ||
"dependency-graph": "~0.1.0", | ||
"di": "0.0.1", | ||
"es6-shim": "^0.12.0", | ||
"optimist": "~0.6.0", | ||
"lodash": "~2.4.1", | ||
"dependency-graph": "~0.1.0", | ||
"q": "~0.9.7", | ||
"di": "0.0.1", | ||
"canonical-path": "~0.0.2" | ||
"validate.js": "^0.2.0", | ||
"winston": "~0.7.2" | ||
}, | ||
"devDependencies": { | ||
"jasmine-node": "~1.12.0", | ||
"rewire": "~2.0.0", | ||
"istanbul": "^0.2.7" | ||
"dgeni-packages": "^0.10.0", | ||
"istanbul": "^0.2.7", | ||
"jasmine-node": "^2.0.0", | ||
"rewire": "~2.0.0" | ||
}, | ||
@@ -37,0 +39,0 @@ "contributors": [ |
244
README.md
@@ -11,5 +11,7 @@ # Dgeni - Documentation Generator [![Build Status](https://travis-ci.org/angular/dgeni.svg?branch=master)](https://travis-ci.org/angular/dgeni) | ||
You'll need node.js and a bunch of npm modules installed to run this tool. Get node.js from here: | ||
http://nodejs.org/. Then, in your project folder run: | ||
You'll need node.js and a bunch of npm modules installed to use Dgeni. Get node.js from here: | ||
http://nodejs.org/. | ||
In the project you want to document you install Dgeni by running: | ||
``` | ||
@@ -22,59 +24,215 @@ npm install dgeni --save | ||
## Architecture | ||
## Running Dgeni | ||
The tool is modular. There are three main phases of document generation: | ||
Dgeni on its own doesn't do much. You much configure it with **Packages** that contain **Services** | ||
and **Processors**. It is the **Processors** that actually convert your source files to | ||
documentation files. | ||
* File Reading - reading docs from files. | ||
* Doc Processing - parsing ngdocs and calculating meta data | ||
* HTML Rendering - converting the parsed docs into HTML | ||
To the run the processors we create a new instance of `Dgeni`, providing to it an array of **Packages** | ||
to load. Then simply call the `generate()` method on this instance. The `generate()` method runs the | ||
processors asynchronously and returns a **Promise** to the generated documents. | ||
Each of these phases will execute a set of plugins (extractors, processors and renderers) to | ||
generate the documentation. | ||
```js | ||
var Dgeni = require('dgeni'); | ||
### Document Processors | ||
var packages = [require('./myPackage')]; | ||
In practice all these phases are executed by a pipeline of **document processors**. Each processor | ||
can provide a list of other processors that it must come before or after, and it can provide zero or | ||
more of the following handlers: | ||
var dgeni = new Dgeni(packages); | ||
* `init(config, injectables) { ... }` - gives the processor and opportunity to initialize itself | ||
based on the configuration object and also add items to the dependency injection container. | ||
* `process(docs, ...) { ... }` - invoked by the dependency injector. Each processor's process | ||
handler is called an order that fits with the declared `runBefore` and `runAfter` dependencies. | ||
dgeni.generate().then(function(docs) { | ||
console.log(docs.length, 'docs generated'); | ||
}); | ||
``` | ||
The `before` and `after` handlers can be synchronous or asynchronous. If they are synchronous then | ||
they should return undefined or a new array of documents. If they are asynchronous then they must | ||
return a promise, which will resolve to undefined or a new collection of documents. | ||
## Packages | ||
#### Pseudo Marker Processors | ||
**Services**, **Processors**, configuration values and templates are be bundled into a `Package`. Packages | ||
can depend upon other Packages. In this way you can build up your custom configuration on | ||
top of an existing configuration. | ||
### Defining a Package | ||
Dgeni provides a `Package` type that you instantiate. This instance has methods to register **Services** and | ||
**Processors**, and to configure the properties of **Processors**: | ||
```js | ||
var Package = require('dgeni').Package; | ||
var myPackage = new Package('myPackage', ['packageDepencency1', 'packageDependency2']); | ||
myPackage.processor(requre('./processors/processor1')); | ||
myPackage.processor(require('./processors/processor2')); | ||
myPackage.factory(require('./services/service1')); | ||
myPackage.factory(require('./services/service2')); | ||
myPackage.config(function(processor1, service2) { | ||
service2.someProperty = 'some value'; | ||
processor1.specialService = service2; | ||
}); | ||
``` | ||
## Services | ||
Dgeni makes significant use of **Dependency Injection (DI)** to instantiate objects. Objects that | ||
will be instantiated by the DI system must be provided by a **factory function**, which is registered | ||
in a **Package**, either as a **Processor**, by `myPackage.processor(factoryFn)`, or as a **Service**, | ||
by `myPackage.factory(factoryFn)`. | ||
### Defining a Service | ||
The parameters to a factory function are dependencies on other services that the DI system must find | ||
or instantiate and provide to the factory function. | ||
```js | ||
module.exports = function car(function(engine, wheels) { | ||
return { | ||
drive: function() { | ||
engine.start(); | ||
wheels.turn(); | ||
} | ||
}; | ||
}) | ||
``` | ||
Here we have defined a `car` service, which depends upon two other services, `engine` and `wheels` | ||
defined elsewhere. Note that this `car` service doesn't care how and where these dependencies are | ||
defined. It relies on the DI system to provide them when needed. | ||
The `car` service returned by the factory function is an object containing one method, `drive()`, | ||
which in turn calls methods on `engine` and `wheels`. | ||
## Processors | ||
**Processors** are **Services** that contain a `$process(docs)` method. The processors are run | ||
one after another in a pipeline. Each Processor takes the collection documents from the previous | ||
Processor and manipulates it, maybe inserting new documents or adding meta data to documents that are | ||
there already. | ||
Processors can expose properties that tell Dgeni where in the pipeline they should be run and | ||
how to validate the configuration of the Processor. | ||
* `$enabled` - if set to `false` then this Processor will not be included in the pipeline | ||
* `$runAfter` - an array of strings, where each string is the name of a Processor that must appear | ||
**earlier** in the pipeline than this Processor | ||
* `$runBefore` - an array of strings, where each string is the name of a Processor that must appear | ||
**later** in the pipeline than this one | ||
* `$validate` - a [http://validatejs.org/](http://validatejs.org/) constraint object that Dgeni uses | ||
to validate the properties of this Processor. | ||
### Defining a Processor | ||
You define Processors just like you would a Service: | ||
**myDocProcessor.js**: | ||
```js | ||
module.exports = function myDocProcessor(dependency1, dependency2) { | ||
return { | ||
$process(docs) { ... do stuff with the docs ... } | ||
$runAfter: ['otherProcessor1'], | ||
$runBefore: ['otherProcessor2', 'otherProcessor3'], | ||
$validate: { | ||
myProperty: { presence: true } | ||
}, | ||
myProperty: 'some config value' | ||
}; | ||
``` | ||
### Registering a Processor | ||
You then register the Processor with a Package: | ||
**myPackage.js**: | ||
```jsv | ||
var Package = require('dgeni').Package; | ||
module.exports = new Package('myPackage') | ||
.processor(require('./myDocProcessor')); | ||
``` | ||
### Asynchronous Processing | ||
The `$process(docs)` method can be synchronous or asynchronous: | ||
* If synchronous then it should return `undefined` or a new array of documents. | ||
If it returns a new array of docs then this array will replace the previous `docs` array. | ||
* If asynchronous then it must return a **Promise**, which should resolve to `undefined` | ||
or a new collection of documents. By returning a **Promise**, the processor tells Dgeni | ||
that it is asynchronous and Dgeni will wait for the promise to resolve before calling the | ||
next processor. | ||
Here is an example of an asynchronous **Processor** | ||
```js | ||
var qfs = require('q-io/fs'); | ||
module.exports = function readFileProcessor() { | ||
return { | ||
filePath: 'some/file.js', | ||
$process(docs) { | ||
return qfs.readFile(this.filePath).then(function(response) { | ||
docs.push(response.data); | ||
}); | ||
} | ||
}; | ||
``` | ||
### Standard Dgeni Packages | ||
The [dgeni-packages repository](https://github.com/angular/dgeni-packages) contains a many Processors | ||
- from basic essentials to complex, angular.js specific. These processors are grouped into Packages: | ||
* `base` - contains the basic file reading and writing Processors as well as an abstract | ||
rendering Processor. | ||
* `jsdoc` - depends upon `base` and adds Processors and Services to support parsing and | ||
extracting jsdoc style tags from comments in code. | ||
* `nunjucks` - provides a [nunjucks](http://mozilla.github.io/nunjucks/) based rendering | ||
engine. | ||
* `ngdoc` - depends upon `jsdoc` and `nunjucks` and adds additional processing for the | ||
AngularJS extensions to jsdoc. | ||
* `examples` - depends upon `jsdoc` and provides Processors for extracting examples from jsdoc | ||
comments and converting them to files that can be run. | ||
### Pseudo Marker Processors | ||
There are a number of processors that don't do anything but act as markers for stages of the | ||
processing. You can use these markers in `runBefore` and `runAfter` properties to ensure that your | ||
processor is run at the right time. Here is the list of these marker processors in order: | ||
processing. You can use these markers in `$runBefore` and `$runAfter` properties to ensure | ||
that your Processor is run at the right time. Here is a list of these marker processors in order: | ||
* loading-files | ||
* files-loaded | ||
* parsing-tags | ||
* tags-parsed | ||
* extracting-tags | ||
* tags-extracted | ||
* processing-docs | ||
* docs-processed | ||
* adding-extra-docs | ||
* extra-docs-added | ||
* rendering-docs | ||
* docs-rendered | ||
* writing-files | ||
* files-written | ||
* reading-files *(defined in base)* | ||
* files-read *(defined in base)* | ||
* parsing-tags *(defined in jsdoc)* | ||
* tags-parsed *(defined in jsdoc)* | ||
* extracting-tags *(defined in jsdoc)* | ||
* tags-extracted *(defined in jsdoc)* | ||
* processing-docs *(defined in base)* | ||
* docs-processed *(defined in base)* | ||
* adding-extra-docs *(defined in base)* | ||
* extra-docs-added *(defined in base)* | ||
* rendering-docs *(defined in base)* | ||
* docs-rendered *(defined in base)* | ||
* writing-files *(defined in base)* | ||
* files-written *(defined in base)* | ||
## Packages | ||
Document processors, templates and other configuration can be bundled into a `package`. Packages | ||
can load up and extend other packages. In this way you can build up your custom configuration on | ||
top of an existing configuration. | ||
## Configuration Blocks | ||
There are some initial packages defined in the | ||
[dgeni-packages repository](https://github.com/angular/dgeni-packages). | ||
You can configure the **Services** and **Processors** defined in a **Package** or its dependencies | ||
by registering **Configuration Blocks** with the **Package**. These are functions that can be | ||
injected with **Services** and **Processors** by the DI system, giving you the opportunity to | ||
set properties on them. | ||
### Registering a Configuration Block | ||
You register a **Configuration Block** by calling `config(configFn)` on a Package. | ||
```js | ||
myPackage.config(function(readFilesProcessor) { | ||
readFilesProcessor.sourceFiles = ['src/**/*.js']; | ||
}); | ||
``` |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
85885
63
983
237
4
+ Addedes6-shim@^0.12.0
+ Addedvalidate.js@^0.2.0
+ Addedes6-shim@0.12.0(transitive)
+ Addedvalidate.js@0.2.0(transitive)
- Removedlodash@~2.4.1
- Removedrimraf@~2.2.5
- Removedlodash@2.4.2(transitive)
- Removedrimraf@2.2.8(transitive)