codo
Version:
A CoffeeScript documentation generator.
168 lines (137 loc) • 5.78 kB
text/coffeescript
Path = require 'path'
Codo = require './codo'
Optimist = require 'optimist'
Theme = require '../themes/default/lib/theme'
Table = require 'cli-table'
colors = require 'colors/safe'
module.exports = class Command
options: [
{name: 'help', alias: 'h', describe: 'Show this help'}
{name: 'version', describe: 'Show version'}
{name: 'extension', alias: 'x', describe: 'Coffee files extension', default: 'coffee'}
{name: 'output', alias: 'o', describe: 'The output directory', default: './doc'}
{name: 'min-coverage', alias: 'm', describe: 'Require a minimum percentage to be documented or fail', default: '0'}
{name: 'output-dir'}
{name: 'theme', describe: 'The theme to be used', default: 'default'}
{name: 'name', alias: 'n', describe: 'The project name used'}
{name: 'readme', alias: 'r', describe: 'The readme file used'}
{name: 'quiet', alias: 'q', describe: 'Supress warnings', boolean: true, default: false}
{name: 'verbose', alias: 'v', describe: 'Show parsing errors', boolean: true, default: false}
{name: 'undocumented', alias: 'u', describe: 'List undocumented objects', boolean: true, default: false}
{name: 'closure', describe: 'Try to parse closure-like block comments', boolean: true, default: false}
{name: 'debug', alias: 'd', boolean: true}
]
: ->
new @().run (code) ->
process.exit code
extendOptimist: (optimist, defaults={}, options={}) ->
for option in options
optimist.options option.name,
alias: option.alias,
describe: option.describe,
boolean: option.boolean,
default: defaults[option.name] || defaults[option.alias] || option.default
lookupTheme: (name) ->
if name == 'default'
= Theme
else
try
= require "codo-theme-#{name}"
catch
try
= require Path.resolve("node_modules/codo-theme-#{name}")
catch
console.log "Error loading theme #{name}: are you sure you have codo-theme-#{name} package installed?"
process.exit()
prepareOptions: (optimist, defaults) ->
options = optimist.argv
options._.push entry for entry in defaults._
keyword = 'inputs'
for entry in options._
if entry == '-'
keyword = 'extras'
else
options[keyword] ?= []
options[keyword].push entry
delete options._
options
run: (cb) ->
defaults = Codo.detectDefaults(process.cwd())
optimist = Optimist.usage('Usage: $0 [options] [source_files [- extra_files]]')
=
=
if ['output-dir']
console.log "The usage of outdated `--output-dir` option detected. Please switch to `--output`."
process.exit()
if .help
console.log optimist.help()
else if .version
console.log Codo.version()
else
collectStats: (environment) ->
sections =
Classes:
total: environment.allClasses().length
undocumented: environment.allClasses().filter((e) -> !e.documentation?).map (x) ->
[x.name, x.file.path]
Mixins:
total: environment.allMixins().length
undocumented: environment.allMixins().filter((e) -> !e.documentation?).map (x) ->
[x.name, x.file.path]
Methods:
total: environment.allMethods().length
undocumented: environment.allMethods().filter((e) -> !e.entity.documentation?).map (x) ->
["#{x.entity.name} (#{x.owner.name})", x.owner.file.path]
sections
generate: (dir = process.cwd(), options = , cb) ->
for option in
if option.default?
options[option.name] ?= option.default
?=
for option in ::options
if option.default?
options[option.name] ?= option.default
environment = Codo.parseProject(dir, options)
sections =
unless options.test
.compile(environment)
overall = 0
undocumented = 0
for section, data of sections
overall += data.total
undocumented += data.undocumented.length
if options.undocumented
for section, data of sections when data.undocumented.length != 0
table = new Table
head: [section, 'Path']
table.push(entry) for entry in data.undocumented
unless options.test
console.log table.toString()
console.log ''
else
table = new Table
head: ['', 'Total', 'Undocumented']
undocumented_percent = 100/overall*undocumented || 0
table.push(
['Files', environment.allFiles().length, ''],
['Extras', environment.allExtras().length, ''],
['Classes', sections['Classes'].total, sections['Classes'].undocumented.length],
['Mixins', sections['Mixins'].total, sections['Mixins'].undocumented.length],
['Methods', sections['Methods'].total, sections['Methods'].undocumented.length]
)
unless options.test
console.log table.toString()
console.log ''
console.log " Totally documented: #{(100 - undocumented_percent).toFixed(2)}%"
console.log ''
documentedRatio = 100 - (100*undocumented/overall).toFixed(2)
if documentedRatio < options["min-coverage"]
unless options.test
console.error colors.red(" Expected " + options["min-coverage"] +
"% to be documented, but only " + documentedRatio + "% were.")
cb 1 if cb
else
cb() if cb