Closed Bug 1352316 Opened 3 years ago Closed 2 months ago

Add a jsdoc task to generate JS code documentation

Categories

(Firefox Build System :: Task Configuration, task)

task
Not set

Tracking

(Not tracked)

RESOLVED INCOMPLETE

People

(Reporter: MattN, Unassigned)

References

()

Details

Attachments

(1 file)

Throughout mozilla-central JSDoc-style comments are used to document APIs but we don't currently generate documentation from them. I'd like to start generating documentation for UITour-lib.js so it can be used for consumers of the API (one consumer currently documents the API by their self at [1] which isn't always kept up-to-date with the mozilla-central code) and for data review such as bug 1343510 and bug 1305878.

If it works out then scope can be expanded to other APIs/files.

I have a task working at [2] with output at [3] but needs feedback/review to get this in production.

[1] https://bedrock.readthedocs.io/en/latest/uitour.html
[2] https://treeherder.mozilla.org/#/jobs?repo=try&revision=35586aa3274191244f287038c22b291a86ec98f8&selectedJob=87768701
[3] https://public-artifacts.taskcluster.net/Xa83wskbRia2m0ZnW9uQTA/0/public/jsdoc/Mozilla.UITour.html
Is it possible to blend this output with http://gecko.readthedocs.io/ ?
Comment on attachment 8853260 [details]
Bug 1352316 - Add a jsdoc task to generate JS code documentation.

https://reviewboard.mozilla.org/r/125330/#review128060

I know it seems minor, but I think the install from external sources is a bit of a dealbreaker here.

::: taskcluster/ci/source-test/jsdoc.yml:1
(Diff revision 1)
> -sphinx:
> +jsdoc:

I'd prefer to have this in the same file (doc.yml)

::: taskcluster/ci/source-test/jsdoc.yml:21
(Diff revision 1)
> -              path: /home/worker/checkouts/gecko/docs.tar.gz
> +              path: /home/worker/checkouts/gecko/out/
>      run:
>          using: run-task
>          command: >
>              cd /home/worker/checkouts/gecko &&
> -            ./mach doc --outdir docs-out --no-open &&
> +            npm install jsdoc &&

We should be avoiding pulling from external sources for any of our build processes.  It both saves load on the external sources and gets us a more reliable build process - necessary for Tier 1.  Otherwise an npmjs problem could close the trees.

The eslint checks also require a bunch of packages from npm, so you could look at how they do it.
Attachment #8853260 - Flags: review?(dustin) → review-
Apparently erikrose and rhelmer have been up to wizardry lately. https://github.com/rhelmer/sphinx-js

They can likely comment on the feasibility of using sphinx-js to plug JS docs into our existing Sphinx-based docs system.
Flags: needinfo?(rhelmer)
(In reply to Dustin J. Mitchell [:dustin] from comment #2)
> Is it possible to blend this output with http://gecko.readthedocs.io/ ?

(In reply to Gregory Szorc [:gps] from comment #4)
> Apparently erikrose and rhelmer have been up to wizardry lately.
> https://github.com/rhelmer/sphinx-js

I spent a lot of time looking into the possibility of RTD integration and none of the solutions I found supported all of the jsdoc tags that I'm using and I didn't have time to improve them. I didn't see sphinx-js so maybe that works with all the tags I'm using. Since what I had is a trivial task (only a few relevant lines) I figured it would be easy to switch away to something better once it exists but this addresses the immediate need I had and I was just going to link to the output from RTD for this one file.
(In reply to Dustin J. Mitchell [:dustin] from comment #3)
> I know it seems minor, but I think the install from external sources is a
> bit of a dealbreaker here.

I kind of expected this response but was hoping for help addressing it since I don't have the relevant permission to upgrade to tooltool. Who can help with this?
Note that Erik's github is the canonical one with the open issues and PRs etc, mine is just a fork of it:
https://github.com/erikrose/sphinx-js

RTD currently doesn't support running jsdoc, and also doesn't have sphinx-js installed, so unfortunately it's pretty much a non-starter until/unless we get them to do that.

A simple approach I have been exploring is to do `./mach doc` builds on travis and host on github pages. For instance this is a custom domain that points to GH pages:

http://foxdocs.org/toolkit/mozapps/extensions/addon-manager/AddonManager.html

Here are the changes I had to make in mozilla-central to support this:
https://github.com/mozilla/gecko-dev/compare/master...rhelmer:sphinx-js

So that side is fine, we can write jsdoc annotation docs rst files similar to how python autodoc works, and sphinx-js supports most of the important jsdoc tags (and it's easy to add more, it just parses the output of `jsdoc -X`).

The more complex bits are:

1) fixing out jsdoc tags so they actually produce valid output
2) documenting our object initializer type classes to appear as classes in jsdoc output

I've been looking into the feasibility of doing automatic rewrites for at least parts of these. One problem is that modern jsdoc requires types for @param and @return and types are not something we can easily automatically determine.

Anyway, all that said we could just enable this somewhere (taskcluster, travis, wherever) and host it ourselves or on a simple host like GH pages, and let individual modules opt-in, as we do with docs now.

A good way to find problems with jsdoc and keep your docs in shape is to use the eslint jsdoc plugin - I *highly* recommend getting this passing first if you want to automatically generate jsdoc and have it actually work, and not go out of date quickly.
Flags: needinfo?(rhelmer)
Anyone can upload things to tooltool. Follow the directions at https://wiki.mozilla.org/ReleaseEngineering/Applications/Tooltool#How_To_Upload_To_Tooltool to issue a new token.

Keep in mind that for things uploaded to tooltool, we prefer to have scripts somewhere that can reproduce that thing. Otherwise if you get hit by a bus, we have no idea how to reproduce the work. There are also security concerns with not knowing what's in the bits being downloaded from tooltool.

Alternatively to using tooltool, you can bake things into the Docker image used by TaskCluster tasks. The code for building the Docker images lives in taskcluster/docker. This is currently using the "lint" image. If the customizations become too much, it might be worth creating a specialized Docker image for documentation generation. A reviewer will make a determination when they see the changes.
FWIW I've been getting errors from RTD about gecko.readthedocs.org builds for several weeks. We've historically always been teetering on scaling limits for RTD. At this point, I'm tempted to forego using RTD for building and rely on the existing TaskCluster task. We can add plumbing to TC (or elsewhere) to take the docs tarball produced by CI and make it available on RTD (or elsewhere) somehow.

What I'm trying to say is: let's not worry about the actual docs generation working on RTD.
(In reply to Gregory Szorc [:gps] from comment #8)
> Anyone can upload things to tooltool. Follow the directions at
> https://wiki.mozilla.org/ReleaseEngineering/Applications/
> Tooltool#How_To_Upload_To_Tooltool to issue a new token.

That's definitely not the case for either of my accounts (employee or scm level 3 non-moco) and it even mentions this possibility on that page. "If you don't have internal permission, then the option won't be available to you." I only have options for download, not upload.

> Keep in mind that for things uploaded to tooltool, we prefer to have scripts
> somewhere that can reproduce that thing. Otherwise if you get hit by a bus,
> we have no idea how to reproduce the work. There are also security concerns
> with not knowing what's in the bits being downloaded from tooltool.

Great, if I could find the script for the eslint ones then it will be easy for me to modify.

> Alternatively to using tooltool, you can bake things into the Docker image
> used by TaskCluster tasks. The code for building the Docker images lives in
> taskcluster/docker. This is currently using the "lint" image. If the
> customizations become too much, it might be worth creating a specialized
> Docker image for documentation generation. A reviewer will make a
> determination when they see the changes.

OK, I'll consider that since I'm more familiar with Docker than tooltool (since every time I want to use tooltool I don't have permissions)
Yeah, I dunno how you get permission to upload to tooltool then. My guess is you ask the right person in #releng or #taskcluster?

We're definitely moving towards Docker images for things. It's a safe bet to use that over tooltool.
Yep, vpn_tooltool_editor is the LDAP group you need, and the Buildduty folks in #releng can get that for you.

Regarding uploading the docs somewhere for hosting, we can set up automatic uploads to an S3 bucket, and then serve that S3 bucket using CloudFront.  That's how we do https://docs.taskcluster.net for example.  We could configure things so that the upload only occurs from mozilla-central (and enforce that using scopes) but the build occurs everywhere, so you'll catch errors earlier.  I'd be happy to help set that up -- it requires a some behind-the-scenes fiddling with AWS policies.

But for the moment, let's get this functionality landed -- I suspect that means just the tooltool bit or, probably easier, just install it here:

  https://dxr.mozilla.org/mozilla-central/source/taskcluster/docker/lint/system-setup.sh#43
(In reply to Robert Helmer [:rhelmer] from comment #7)
> Note that Erik's github is the canonical one with the open issues and PRs
> etc, mine is just a fork of it:
> https://github.com/erikrose/sphinx-js
> 
> RTD currently doesn't support running jsdoc, and also doesn't have sphinx-js
> installed, so unfortunately it's pretty much a non-starter until/unless we
> get them to do that.
> 
> A simple approach I have been exploring is to do `./mach doc` builds on
> travis and host on github pages. For instance this is a custom domain that
> points to GH pages:
> 
> http://foxdocs.org/toolkit/mozapps/extensions/addon-manager/AddonManager.html
> 
> Here are the changes I had to make in mozilla-central to support this:
> https://github.com/mozilla/gecko-dev/compare/master...rhelmer:sphinx-js

Nice, that's basically the same as what I'm doing in this bug but has the following differences:

PROS of jsdoc directly with TC:
* Supports all features of jsdoc
* Will be kept up-to-date with new jsdoc features without work on our part
* Doesn't require adding a line to an RST file for each method, any documented method will appear in the docs automatically
* Built immediately as part of m-c instead of requiring someone to update a separate GH repo
* Doesn't require learning anything about sphinx/rst

CONS:
* Not as well integrated into the RTD hierarchy. Links to JSDocs can be added from rst files though.
** Personally I see this as a reason not to use RTD… unfortunately we didn't set up a custom domain on RTD so now people link to the subdomain making it harder to move away :(

> A good way to find problems with jsdoc and keep your docs in shape is to use
> the eslint jsdoc plugin - I *highly* recommend getting this passing first if
> you want to automatically generate jsdoc and have it actually work, and not
> go out of date quickly.

Yep, I enabled it for the file in question in bug 1310150.
(In reply to Matthew N. [:MattN] (behind on bugmail; PM if requests are blocking you) from comment #13)
> (In reply to Robert Helmer [:rhelmer] from comment #7)
> > Note that Erik's github is the canonical one with the open issues and PRs
> > etc, mine is just a fork of it:
> > https://github.com/erikrose/sphinx-js
> > 
> > RTD currently doesn't support running jsdoc, and also doesn't have sphinx-js
> > installed, so unfortunately it's pretty much a non-starter until/unless we
> > get them to do that.
> > 
> > A simple approach I have been exploring is to do `./mach doc` builds on
> > travis and host on github pages. For instance this is a custom domain that
> > points to GH pages:
> > 
> > http://foxdocs.org/toolkit/mozapps/extensions/addon-manager/AddonManager.html
> > 
> > Here are the changes I had to make in mozilla-central to support this:
> > https://github.com/mozilla/gecko-dev/compare/master...rhelmer:sphinx-js
> 
> Nice, that's basically the same as what I'm doing in this bug but has the
> following differences:
> 
> PROS of jsdoc directly with TC:
> * Supports all features of jsdoc
> * Will be kept up-to-date with new jsdoc features without work on our part
> * Doesn't require adding a line to an RST file for each method, any
> documented method will appear in the docs automatically
> * Built immediately as part of m-c instead of requiring someone to update a
> separate GH repo
> * Doesn't require learning anything about sphinx/rst
> 
> CONS:
> * Not as well integrated into the RTD hierarchy. Links to JSDocs can be
> added from rst files though.
> ** Personally I see this as a reason not to use RTD… unfortunately we didn't
> set up a custom domain on RTD so now people link to the subdomain making it
> harder to move away :(


I bought the "foxdocs.org" domain, I could transfer ownership to Mozilla and we could get everyone to standardize on that and point it wherever you want if you're interested.


> > A good way to find problems with jsdoc and keep your docs in shape is to use
> > the eslint jsdoc plugin - I *highly* recommend getting this passing first if
> > you want to automatically generate jsdoc and have it actually work, and not
> > go out of date quickly.
> 
> Yep, I enabled it for the file in question in bug 1310150.
Try push: https://treeherder.mozilla.org/#/jobs?repo=try&revision=55ed84c293d595b2da97d826b1dce047d5274107&filter-tier=1&filter-tier=2&filter-tier=3&selectedJob=88000025

Result: https://public-artifacts.taskcluster.net/XM6HspVWSRWbx5Nk9aXewQ/0/public/jsdoc/Mozilla.UITour.html

(In reply to Gregory Szorc [:gps] from comment #9)
> We can add plumbing to TC (or
> elsewhere) to take the docs tarball produced by CI and make it available on
> RTD (or elsewhere) somehow.
> 
> What I'm trying to say is: let's not worry about the actual docs generation
> working on RTD.

Since RTD removed the ability to upload a zip of generated docs (since it was getting abused to host arbitrary content) I think moving away from RTD makes sense so we can integrate JSDoc and other docs not using RST/MD into one documentation site.

(In reply to Dustin J. Mitchell [:dustin] from comment #12)
> Regarding uploading the docs somewhere for hosting, we can set up automatic
> uploads to an S3 bucket, and then serve that S3 bucket using CloudFront. 
> That's how we do https://docs.taskcluster.net for example.  We could
> configure things so that the upload only occurs from mozilla-central (and
> enforce that using scopes) but the build occurs everywhere, so you'll catch
> errors earlier.  I'd be happy to help set that up -- it requires a some
> behind-the-scenes fiddling with AWS policies.

That would be awesome but my understanding is that artifacts are already hosted on cloudfront so I would also be fine with a web front-end proxy that resolves a TC API call for something like …/gecko.v2.mozilla-central.latest.lint.jsdoc-opt/index.html to the latest jsdoc artifact for mozilla-central. I was hoping to support versioning like RTD does. 

> or, probably easier, just install it here:
>  
> https://dxr.mozilla.org/mozilla-central/source/taskcluster/docker/lint/system-setup.sh#43

Thanks, that saved me a lot of time!

(In reply to Robert Helmer [:rhelmer] from comment #14)
> I bought the "foxdocs.org" domain, I could transfer ownership to Mozilla and
> we could get everyone to standardize on that and point it wherever you want
> if you're interested.

I personally would prefer it to be on a subdomain of a mozilla.org site so that it shows up on "site:mozilla.org" searches (which I have a keyword for) and seems more official.
(In reply to Matthew N. [:MattN] (behind on bugmail; PM if requests are blocking you) from comment #16)
> Since RTD removed the ability to upload a zip of generated docs (since it
> was getting abused to host arbitrary content) I think moving away from RTD
> makes sense so we can integrate JSDoc and other docs not using RST/MD into
> one documentation site.

I've heard there's a plan to move Gecko-specific stuff off of developer.mozilla.org but perhaps it could be moved to a subdomain e.g. gecko.developer.mozilla.org?
Comment on attachment 8853260 [details]
Bug 1352316 - Add a jsdoc task to generate JS code documentation.

https://reviewboard.mozilla.org/r/125330/#review128252

This looks good enough for an r+ for me. But I haven't touched task graph in a while and dustin has review, so I defer to him.

::: taskcluster/ci/source-test/doc.yml:63
(Diff revision 3)
> +    when:
> +        files-changed:
> +            - 'taskcluster/ci/source-test/doc.yml'
> +            - 'tools/docs/jsdoc.json'
> +            # Paths being documented. Keep up-to-date with jsdoc.json
> +            - 'browser/components/uitour/**.js*'

I'd be tempted to remove the `browser/components/uitour` prefix and just go with `**/*.js*`. If this task only takes a few minutes to run, it is literally just a few pennies of compute time per invocation. The cost to developers keeping the files in sync will be much greater than the money we waste running the task when we don't really need to.
(In reply to Matthew N. [:MattN] (behind on bugmail; PM if requests are blocking you) from comment #13)
> (In reply to Robert Helmer [:rhelmer] from comment #7)
> > Note that Erik's github is the canonical one with the open issues and PRs
> > etc, mine is just a fork of it:
> > https://github.com/erikrose/sphinx-js
> > 
> > RTD currently doesn't support running jsdoc, and also doesn't have sphinx-js
> > installed, so unfortunately it's pretty much a non-starter until/unless we
> > get them to do that.
> > 
> > A simple approach I have been exploring is to do `./mach doc` builds on
> > travis and host on github pages. For instance this is a custom domain that
> > points to GH pages:
> > 
> > http://foxdocs.org/toolkit/mozapps/extensions/addon-manager/AddonManager.html
> > 
> > Here are the changes I had to make in mozilla-central to support this:
> > https://github.com/mozilla/gecko-dev/compare/master...rhelmer:sphinx-js
> 
> Nice, that's basically the same as what I'm doing in this bug but has the
> following differences:
> 
> PROS of jsdoc directly with TC:
> * Supports all features of jsdoc
> * Will be kept up-to-date with new jsdoc features without work on our part
> * Doesn't require adding a line to an RST file for each method, any
> documented method will appear in the docs automatically

sphinx-js supports autoclass now, it's not necessary to add a line for each method.

It could support automodule including for JSMs potentially, but autoclass is pretty convenient.

> * Built immediately as part of m-c instead of requiring someone to update a
> separate GH repo

I don't think there's anything about sphinx that requires updating a GH repo - the output is generated as part of `./mach doc`.

> * Doesn't require learning anything about sphinx/rst
> 
> CONS:
> * Not as well integrated into the RTD hierarchy. Links to JSDocs can be
> added from rst files though.
> ** Personally I see this as a reason not to use RTD… unfortunately we didn't
> set up a custom domain on RTD so now people link to the subdomain making it
> harder to move away :(
> 
> > A good way to find problems with jsdoc and keep your docs in shape is to use
> > the eslint jsdoc plugin - I *highly* recommend getting this passing first if
> > you want to automatically generate jsdoc and have it actually work, and not
> > go out of date quickly.
> 
> Yep, I enabled it for the file in question in bug 1310150.

I too considered just running jsdoc and linking to it from the docs.

However, one benefit to rst is that you can add additional info inline like code samples, etc. that are awkward to add in comments.

All that said, just sticking a jsdoc dump somewhere and linking to it from our docs is better than our current situation so I am not opposed.
Here is a newer branch that I have been working on which is probably more relevant than the one I linked earlier:

https://github.com/mozilla/gecko-dev/compare/master...rhelmer:sphinx-js-obj-initializer

Regardless of how we end up generating and publishing docs, one of the helpful things here is that it's possible to get output from object initializer style as the ES6 class sugar (which jsdoc understands), so rewriting the code isn't necessary.

AddonManager currently uses the "public object forwards to private object" pattern, with the documentation on the methods of the private object - the @lends jsdoc tag can be used there to get the desired output.

The only interesting sphinx-js thing here that is that this branch uses autoclass, so it's not necessary to explicitly document each method (unless you want to, for instance to put in code samples or some other details you don't want in the source comment for whatever reason), the rst document could be as simple as:

.. js:autoclass:: AddonManager
   :members:
Comment on attachment 8853260 [details]
Bug 1352316 - Add a jsdoc task to generate JS code documentation.

https://reviewboard.mozilla.org/r/125330/#review128632

::: tools/docs/jsdoc.json:10
(Diff revision 3)
> +  "source": {
> +    // Exclude files and directories beginning with an underscore
> +    "excludePattern": "(^|\\/|\\\\)_",
> +    "include": [
> +      // Keep this list in-sync with files-changed in
> +      // taskcluster/ci/source-test/doc.yml

I'm assuming this is parsed with node, and not a JSON interpreter, which is why comments are allowed?
Attachment #8853260 - Flags: review?(dustin) → review+
> I didn't see sphinx-js

That's because I just made it! :-) I, too, was unsatisfied with the state of JS documentation tools, and I wanted to actually *explain* the Fathom project to people, not just throw an alphabetical list of classes and routines at them and say "Here, you figure it out!" Those are really sphinx-js's selling points:

* The ability to organize your docs in a way that people can learn from, not just use for reference. A great example is https://mozilla.github.io/fathom/ruleset.html, which has high-level explanations interspersed with extracted documentation. jsdoc supports "tutorials", but you cannot call extracted docs into them.
* All the "sidecar" abilities that Sphinx brings, like a glossary (useful for any project large enough to accumulate its own vocabulary) and an all-inclusive index. Glossary example: https://mozilla.github.io/fathom/ruleset.html. Index example: https://mozilla.github.io/fathom/genindex.html.

And then, of course, a bonus for you is that you already have a Sphinx-based set of documentation. This avoids adding one more quasi-independent place for people to look.

sphinx-js isn't much of a maintenance burden, totalling around 300 lines of code, many of which are comments themselves. jsdoc does all the work. It's really just a templating engine.

My 2¢—I wanted you to have the whole story before committing to a long-term decision. Cheers!
I feel like it's the rare developer who distinguishes "I dumped my API in an HTML file" from written documentation suitable for learning.  A good talk topic? :)
Wow, have we fallen so far? Technical writers played a major role in the early Macintosh project, going back to the programmers when things were hard to explain, who would then fix them. This workflow is one reason I'm a fan of documentation-driven development. Maybe I should give a talk on it, but it's sad that I'd have to.
I am going to take this and land it as-is, the current situation is really confusing and this gives us something to build on.

Erik - I filed bug 1389341 to track getting sphinx-js integrated into mozilla-central, I have ideas for addressing Matt's points in comment 13 along with some other issues we're likely to run into.
Assignee: MattN+bmo → rhelmer
(In reply to Robert Helmer [:rhelmer] from comment #26)
> I am going to take this and land it as-is, the current situation is really
> confusing and this gives us something to build on.

Slight change of plans here - gps ended up moving off of readthedocs into a taskcluster job with hosting (firefox-source-docs.mozilla.org), so the majority of this patch is no longer needed.

I am going to land everything except the jsdoc config change in bug 1389341 - it should still be doable to generate "raw" jsdoc output instead of just sphinx, but some other changes might be necessary to get it to be exposed on the new site.
The stable hosting for firefox-source-docs that gps set up should make this patch much easier, now.. I have landed bug 1389341 in the meantime which adds jsdoc to the lint builders (and also the sphinx-js integration).

Matt, have you had a chance to look at the sphinx integration we ended up on? I'm open to reworking the patch in this bug if you have looked, and still want the option to host raw jsdoc output.

If you think sphinx-js is good enough for your needs though I won't bother :)

Here is an intro to the feature that I sent to dev-firefox recently:
https://mail.mozilla.org/pipermail/firefox-dev/2017-November/005955.html
Flags: needinfo?(MattN+bmo)
And if automodule support is a dealbreaker (that is, the ability to write one line in the docs that names a module and have it pull in docs for all exported symbols), I'm happy to add it to sphinx-js.
Assignee: rhelmer → nobody
Status: ASSIGNED → NEW
Product: TaskCluster → Firefox Build System
Flags: needinfo?(MattN+bmo)

I'll just use sphinx-js for now (bug 1595953). See https://phabricator.services.mozilla.com/D52772#change-snXodl5cwnP0 for all the changes I had to make, with the main ones being:

  • Not using {@link …}
  • Not using HTML tags for <ul>/<dl>/<li>/<code>/etc.
  • Having to explicitly specify js:autoclass:: Mozilla.UITour.Configuration and then add it to :exclude-members: for Mozilla.UITour since it wasn't recursively documented.
  • I think there are some other @ tags getting ignored still
Status: NEW → RESOLVED
Closed: 2 months ago
Resolution: --- → INCOMPLETE

FWIW, @link wouldn't be too hard to add for a motivated individual. I'd like to have it supported.

Inline HTML will probably never work because it doesn't suit the abstractions Sphinx is built upon, namely the assumption that from RST source we can build docs in a variety of formats—PDF, Latex, HTML. There exists no layer to translate inline HTML into RST (or equivalent AST) and thence into, say, PDF, for instance.

Note that there is the special .. htmlonly:: directive which, though icky, might be worth a look if you're out of options.

You need to log in before you can comment on or make changes to this bug.