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

No Docs Generated #79

Closed
ghost opened this issue Mar 20, 2014 · 13 comments
Closed

No Docs Generated #79

ghost opened this issue Mar 20, 2014 · 13 comments

Comments

@ghost
Copy link

ghost commented Mar 20, 2014

Currently running grunt-jsdoc against the following file, produces the Index, that includes my README and then produces a file called ujumbe.js.html, that contains the source code but, no documentation is generated from the source.

https://github.com/ossreleasefeed/ujumbe/blob/master/js/ujumbe.js

From what I can see and having read over the JSDoc documentation, my doc comments looks fine, the task completes fine with no errors, but alas, no docs are being generated.

Here is my Grunt file:

https://github.com/ossreleasefeed/ujumbe/blob/master/Gruntfile.js

@krampstudio
Copy link
Owner

Please try using directly the jsdoc command, you can have the exact command by running grunt jsdoc --debug.
I guess this is not related to the grunt plugin but jsdoc itself (see #46), as jsdoc generates the documentation not for each tag he found but by pattern (pseudo class, module, etc.)

@porjo
Copy link

porjo commented Apr 16, 2014

This post helped me with a similar issue: http://stackoverflow.com/questions/19230971/how-do-i-jsdoc-a-nested-objects-methods

@andrew-luhring
Copy link

Same.
No docs generated if using grunt jsdoc

I've tried this with and without a jsdoc config.json file. I've also tried this on individual files (without globs) and the results are the same:

nothing in documents.

Gruntfile.js:

var config =    {
     pkg: grunt.file.readJSON('package.json')
    , jsdoc : {
                    dist : {
                        src: ["js/*.js", "test/*.js", "filetest_jsdoc.js"],
                        options : {
                            destination : 'doc',
                            template : "templates/default",
                            configure : "jsdoc_conf.json"
                        }
                    }
            }
}

grunt.initConfig( config );
grunt.loadNpmTasks('grunt-jsdoc');

jsdoc_conf.json

{
    "tags": {
        "allowUnknownTags": true
    },
    "source": {
        "include": ["./js", "./tests", "tests/", "js"]

    },
    "plugins": [],
    "templates": {
        "cleverLinks": false,
        "monospaceLinks": false
    },
    "opts": {
        "template": "node_modules/ink-docstrap/template",
        "encoding": "utf8",
        "destination": "./doc/",
        "recurse": true,
        "query": "value",
        "private": true,
        "lenient": true

    }
}

filetest_jsdoc.js

/**
 * @fileOverview file test tasks. These tasks are intended to help you when modifying the template. If you are
 * just using the template, don't sweat this stuff. To use these tasks, you must install grunt, if you haven't already,
 * and install the dependencies. All of this requires node.js, of course.
 *
 * @module filez
 * @requires path
 * @requires lodash
 * @requires http
 * @requires async
 * @requires fs
 */
var path = require( "path" );
var sys = require( "lodash" );
var http = require( "http" );
var async = require( "async" );
var fs = require( "fs" );

// this rather odd arrangement of composing tasks like this to make sure this works on both
// windows and linux correctly. We can't depend on Grunt or Node to normalize
// paths for us because we shell out to make this work. So we gather up
// our relative paths here, normalize them later and then pass them into
// the shell to be run by JSDoc3.

/**
 * The definition to run the development test files. This runs the files in `fixtures` with the
 * project's `conf.json` file.
 * @private
 */
var jsdocTestPages = {
    src       : ["./fixtures/*.js", "./README.md"],
    dest      : "./testdocs",
    tutorials : "./fixtures/tutorials",
    template  : "./template",
    config    : "./template/jsdoc.conf.json",
    options   : " --lenient --verbose"
};
/**
 * The definition to run the sample files. This runs the files in `fixtures` with the
 * sample's `conf.json` file. No task directly exposes this configuration. The `fixtures` task
 * modifies this for each swatch it finds and then run the docs command against it.
 * @private
 */
var jsdocExamplePages = {
    src       : ["./fixtures/*.js", "./README.md"],
    dest      : "./themes",
    tutorials : "",
    template  : "./template",
    config    : "./fixtures/example.conf.json",
    options   : " --lenient --verbose --recurse"
};

/**
 * This definition provides the project's main, published documentation.
 *  @private
 */
var projectDocs = {
    src       : ["./Gruntfile*.js", "./README.md", "./template/publish.js"],
    dest      : "./dox",
    tutorials : "",
    template  : "./template",
    config    : "./template/jsdoc.conf.json",
    options   : " --lenient --verbose --recurse --private"
};

/**
 * Normalizes all paths from a JSDoc task definition and and returns an executable string that can be passed to the shell.
 * @param {object} jsdoc A JSDoc definition
 * @returns {string}
 */
function jsdocCommand( jsdoc ) {
    var cmd = [];
    cmd.unshift( jsdoc.options );
    if ( jsdoc.tutorials.length > 0 ) {
        cmd.push( "-u " + path.resolve( jsdoc.tutorials ) );
    }
    cmd.push( "-d " + path.resolve( jsdoc.dest ) );
    cmd.push( "-t " + path.resolve( jsdoc.template ) );
    cmd.push( "-c " + path.resolve( jsdoc.config ) );
    sys.each( jsdoc.src, function ( src ) {
        cmd.push( path.resolve( src ) );
    } );
    cmd.unshift( path.resolve( "./node_modules/jsdoc/jsdoc" ) );
    return cmd.join( " " );
}

var tasks = {
    shell : {
        options  : {
            stdout : true,
            stderr : true
        },
        /**
         * TASK: Create the a documentation set for testing changes to the template
         * @name shell:testdocs
         * @memberOf module:Gruntfile
         */
        testdocs : {
            command : jsdocCommand( jsdocTestPages )
        },
        /**
         * TASK: Create project documentation
         * @name shell:dox
         * @memberOf module:Gruntfile
         */
        dox      : {
            command : jsdocCommand( projectDocs )
        }
    },
    /**
     * TASK: The less task creates the themed css file from main.less. The file is written to the template styles
     * directory as site.[name of theme].css. Later the .conf file will look for the theme to apply based
     * on this naming convention.
     * @name less
     * @memberOf module:Gruntfile
     */
    less  : {
        dev : {
            files : {
                "template/static/styles/site.<%= jsdocConf.templates.theme %>.css" : "styles/main.less"
            }
        }
    },
    copy   : {
        docs : {
            files : [
                {expand : true, cwd : "dox/", src : ['**'], dest : '../docstrap-dox/'},
                {expand : true, cwd : "themes/", src : ['**'], dest : '../docstrap-dox/themes'}
            ]
        }
    }
};

module.exports = function ( grunt ) {
    tasks.jsdocConf = grunt.file.readJSON( 'template/jsdoc.conf.json' );
    grunt.initConfig( tasks );

    grunt.loadNpmTasks( 'grunt-contrib-less' );
    grunt.loadNpmTasks( 'grunt-shell' );
    grunt.loadNpmTasks( 'grunt-contrib-copy' );

    grunt.registerTask( "default", ["docs"] );

    /**
     * Builds the project's documentation
     * @name docs
     * @memberof module:Gruntfile
     */
    grunt.registerTask( "docs", "Create the project documentation", ["shell:dox"] );
    /**
     * Compile the CSS and create the project documentation
     * @name dev
     * @memberof module:Gruntfile
     */
    grunt.registerTask( "dev", "Compile the CSS and create the project documentation", ["less","shell:dox"] );
    /**
     * TASK: Builds the main less file and then generates the test documents
     * @name testdocs
     * @memberof module:Gruntfile
     */
    grunt.registerTask( "testdocs", "Builds the main less file and then generates the test documents", ["less:dev", "shell:testdocs"] );
    /**
     * TASK: Builds the whole shebang. Which means creating testdocs, the bootswatch fixtures and then resetting the
     * styles directory.
     * @name build
     * @memberof module:Gruntfile
     */
    grunt.registerTask( "build", "Builds the whole shebang. Which means creating testdocs, the bootswatch samples and then resetting the styles directory", ["testdocs", "shell:dox", "bootswatch", "examples", "apply", "copy"] );
    /**
     * TASK: Applies the theme in the conf file and applies it to the styles directory.
     * @name apply
     * @memberof module:Gruntfile
     */
    grunt.registerTask( "apply", "Applies the theme in the conf file and applies it to the styles directory", function () {
        var def = {
            less          : "http://bootswatch.com/" + tasks.jsdocConf.templates.theme + "/bootswatch.less",
            lessVariables : "http://bootswatch.com/" + tasks.jsdocConf.templates.theme + "/variables.less"
        };
        grunt.registerTask( "swatch-apply", sys.partial( applyTheme, grunt, def ) );
        grunt.task.run( ["swatch-apply"] );
    } );
    /**
     * TASK: Grab all Bootswatch themes and create css from each one based on the main.less in the styles directory. NOTE that this will
     * leave the last swatch downloaded in the styles directory, you will want to call "apply" afterwards
     * @name bootswatch
     * @memberof module:Gruntfile
     */
    grunt.registerTask( "bootswatch", "Grab all Bootswatch themes and create css from each one based on the main.less in the styles directory", function () {
        var toRun = [];

        var done = this.async();
        getBootSwatchList( function ( err, list ) {
            if ( err ) {return done( err );}

            sys.each( list.themes, function ( entry ) {

                toRun.push( "swatch" + entry.name );
                grunt.registerTask( "swatch" + entry.name, sys.partial( applyTheme, grunt, entry ) );

                var key = "template/static/styles/site." + entry.name.toLowerCase() + ".css";
                var def = {};
                def[key] = "styles/main.less";
                tasks.less["swatch" + entry.name] = {
                    files : def
                };
                toRun.push( "less:swatch" + entry.name );
            } );
            grunt.task.run( toRun );
            done();
        } );

    } );
    /**
     * TASK:Create fixtures from the themes. The files must have been built first from the bootswatch task.
     * @name examples
     * @memberof module:Gruntfile
     */
    grunt.registerTask( "examples", "Create samples from the themes", function () {
        var toRun = [];
        var done = this.async();
        getBootSwatchList( function ( err, list ) {
            if ( err ) {return done( err );}

            sys.each( list.themes, function ( entry ) {
                var conf = grunt.file.readJSON( './fixtures/example.conf.json' );
                conf.templates.theme = entry.name.toLowerCase();
                grunt.file.write( "tmp/example.conf." + conf.templates.theme + ".json", JSON.stringify( conf, null, 4 ) );

                var jsdenv = sys.cloneDeep( jsdocExamplePages );
                jsdenv.config = "./tmp/example.conf." + conf.templates.theme + ".json";
                jsdenv.dest = "./themes/" + conf.templates.theme;
                tasks.shell["example" + conf.templates.theme] = {
                    command : jsdocCommand( jsdenv )
                };
                toRun.push( "shell:example" + conf.templates.theme );
            } );

            grunt.registerTask( "cleanup", "", function () {
                grunt.file["delete"]( "tmp/" );
            } );
            toRun.push( "cleanup" );
            grunt.task.run( toRun );
            done();
        } );

    } );
};

/**
 * Applies one of the Bootswatch themes to the working `styles` directory. When you want to modify a particular theme, this where you
 * get the basis for it. The files are written to `./styles/variables.less` and `./styles/bootswatch.less`. The `./styles/main.less`
 * file includes them directly, so after you apply the theme, modify `main.less` to your heart's content and then run the `less` task
 * as in
 *
 *      grunt less
 *
 * @param {object} grunt The grunt object reference
 * @param {object} definition The swatch definition files
 * @param {string} definition.less The url to the `bootswatch.less` file
 * @param {string} definition.lessVariables The url to the `variables.less` file
 * @private
 */
function applyTheme( grunt, definition ) {
    //noinspection JSHint
    var done = this.async();
    async.waterfall( [
        function ( cb ) {
            getBootSwatchComponent( definition.less, function ( err, swatch ) {
                if ( err ) {return cb( err );}
                var fullPath = path.join( __dirname, "styles/bootswatch.less" );
                fs.writeFile( fullPath, swatch.replace("http://", "//"), cb );
            } );
        },
        function ( cb ) {
            getBootSwatchComponent( definition.lessVariables, function ( err, swatch ) {
                if ( err ) {return cb( err );}
                var fullPath = path.join( __dirname, "styles/variables.less" );
                fs.writeFile( fullPath, swatch.replace("http://", "//"), cb );
            } );
        }
    ], done );
}

/**
 * Gets the list of available Bootswatches from, well, Bootswatch.
 *
 * @see http://news.bootswatch.com/post/22193315172/bootswatch-api
 * @param {function(err, responseBody)} done The callback when complete
 * @param {?object} done.err If an error occurred, you will find it here.
 * @param {object} done.responseBody This is a parsed edition of the bootswatch server's response. It's format it defined
 * by the return message from [here](http://api.bootswatch.com/)
 * @private
 */
function getBootSwatchList( done ) {
    var options = {
        hostname : 'api.bootswatch.com',
        port     : 80,
        path     : '/',
        method   : 'GET'
    };
    var body = "";
    var req = http.request( options, function ( res ) {
        res.setEncoding( 'utf8' );
        res.on( 'data', function ( chunk ) {
            body += chunk;
        } );

        res.on( 'end', function () {
            done( null, JSON.parse( body ) );
        } );
        res.on( 'error', function ( e ) {
            done( 'problem with response: ' + e.message );
        } );
    } );

    req.on( 'error', function ( e ) {
        done( 'problem with request: ' + e.message );
    } );
    req.end();
}

/**
 * This method will get one of the components from Bootswatch, which is generally a `less` file or a `lessVariables` file.
 *
 * @see http://news.bootswatch.com/post/22193315172/bootswatch-api
 * @param {string} url The url to retreive from
 * @param {function(err, responseText)} done The callback when complete
 * @param {?object} done.err If an error occurred, you will find it here.
 * @param {string} done.responseText The body of whatever was returned
 * @private
 */
function getBootSwatchComponent( url, done ) {
    var body = "";
    var req = http.request( url, function ( res ) {
        res.setEncoding( 'utf8' );
        res.on( 'data', function ( chunk ) {
            body += chunk;
        } );

        res.on( 'end', function () {
            done( null, body );
        } );
        res.on( 'error', function ( e ) {
            done( 'problem with response: ' + e.message );
        } );
    } );

    req.on( 'error', function ( e ) {
        done( 'problem with request: ' + e.message );
    } );
    req.end();
}

Output of "grunt jsdoc"

screen shot 2014-04-23 at 8 38 52 pm


Output of " jsdoc -c jsdoc_conf.json "

screen shot 2014-04-23 at 8 37 42 pm

Output of "grunt jsdoc --debug"

screen shot 2014-04-23 at 8 47 40 pm

@krampstudio
Copy link
Owner

@andrew-luhring this is a jsdoc related issue, please post your issue on their google group

@andrew-luhring
Copy link

why do you think that it's a jsdoc issue? jsdoc works fine when I run it from the command line; when I run this grunt plugin, everything except for the actual documentation gets made- the stylesheets, scripts, etc...

@krampstudio
Copy link
Owner

The plugin just wraps the jsdoc command. Try to run the command the debug gave you. As you can see the command arguments are different when you run it with the plugin than your test with jsdoc.
And this is a classical issue of jsdoc3 to fails generating the doc when he encounters wrong tags.

@andrew-luhring
Copy link

Yeah but thats my point-
My config file is the same for both grunt-jsdoc and grunt-shell running jsdoc -c config.json
The only difference is that running jsdoc from the command line outputs everything correctly whereas grunt-jsdoc runs but doesn't produce the correct output.

If this plugin is simply a wrapper for jsdoc,
and if running jsdoc by itself works correctly, (it does)
then why would jsdoc be the problem?

@treyeckels
Copy link

I'm having the same issue. This Grunt plugin doesn't work for me when any of the source js files to be documented are in a directory with an underscore starting the name of the directory. If I move the files to a directory without an underscore, it works.

@rockie
Copy link

rockie commented Jun 9, 2014

Hi @krampstudio , I had the same issue. However, it works fine if I change the jsdoc from v3.2.2 into v3.3.0-alpha5 (the latest version in npm repos). The jsdoc(3.2.2) command line on my mac only generates a index.html file, img, styles and scripts folders regardless of any source files.

@belicekm
Copy link

I confirm that solution proposed by @treyeckels fixed my issue.

@dotherightthing
Copy link

grunt-jsdoc wasn't working for me either, but following the jsdoc-grunt-generation-example I updated from ~0.5.7 to ^0.6.0 and it now works as expected.

@mmaelzer
Copy link

mmaelzer commented Jan 3, 2015

Something worth noting (that I just spent an hour or so debugging) is that by default, jsdoc will not process files inside a folder that starts with an underscore; e.g. jsdoc -r _src/ will generate empty docs since _src starts with an underscore. To troubleshoot this and other empty output issues, use the jsdoc CLI and pass the -X flag to see what files jsdoc plans to process.

@mmaelzer
Copy link

I was just reminded that I never provided a solution to this for those that still encounter the problem. In the root of your project directory, drop a jsdoc.conf file with the following content:

{
    "source": {
        "includePattern": ".+\\.js(doc)?$",
        "excludePattern": ""
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants