Skip to content

Steps toward pursuit 2#1067

Merged
paf31 merged 7 commits intopurescript:masterfrom
hdgarrood:pursuit2
May 5, 2015
Merged

Steps toward pursuit 2#1067
paf31 merged 7 commits intopurescript:masterfrom
hdgarrood:pursuit2

Conversation

@hdgarrood
Copy link
Copy Markdown
Contributor

Fixes #747, continues from #1041, #1055. Much of this code comes from psc-pages.

The idea with the AsHtml module is that it is general enough that it could potentially be used in different environments with different stylesheets and page hierarchies - the rest of the code required to display documentation as HTML (eg including style sheets, templating) should end up in the pursuit server, I think.

I renamed psc-upload-package to psc-publish since it doesn't upload anything.

I commented on #1055 that I thought this tool should check for dependencies which aren't declared in bower.json, but I can't see an easy way of handling transitive dependencies. That is, if package A exists in bower_dependencies but is not listed in bower.json, we would need to tell the difference between A being pulled in as a transitive dependency of one of the other packages (which is OK), and A not being a transitive dependency of any other package, but having just been bower install-ed without being added to bower.json (which is an error on the part of the maintainer, and could cause issues for users of that package). Given that this tool only exists to publish package information, and given that it would be quite complex, I no longer think this check should be in scope for psc-publish.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

The build is failing because I was using cabal sandbox add-source for aeson-better-errors, and I forgot to publish the changes I made, so this code depends on an unreleased version of aeson-better-errors. Now Hackage is not letting me publish a new version. :(

@coveralls
Copy link
Copy Markdown

Coverage Status

Coverage increased (+0.28%) to 78.61% when pulling 63d1eff on hdgarrood:pursuit2 into fa59cf1 on purescript:master.

@coveralls
Copy link
Copy Markdown

Coverage Status

Coverage increased (+0.28%) to 78.61% when pulling f292d71 on hdgarrood:pursuit2 into fa59cf1 on purescript:master.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice :)

@paf31
Copy link
Copy Markdown
Contributor

paf31 commented Apr 23, 2015

Looks good. Could you please do me a favour and summarise what requests wreq is used for?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just occurred to me that this won't work if any purescript package author decides to use the main key in bower.json. This code assumes that bower list --paths --json prints a JSON object mapping package names to directory paths, which is not true if the main key is specified.

For example, purescript-timers#0.0.8 specifies main in its bower.json, and in the output of bower list --paths --json, you get:

  "purescript-timers": "bower_components/purescript-timers/src/Control/Reactive/Timer.purs",

Instead, I think this code should just glob bower_components/* and then attempt to parse the second component as the package name.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thoughts, we can get all the information we need from bower list --json.

Using bower list --json also allows us to easily identify bower dependencies which haven't been installed, because Bower includes "missing": true in the output where appropriate. So we can fail with a nice error if the user forgot to bower install.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

At the moment, wreq is only used to ask Bower about the package, in order to get its git url (which we then extract a github username / repository name from). See https://github.com/purescript/purescript/pull/1067/files#diff-8668135e8cf73d8f5109bc17a79e0826R119

I was originally planning on using wreq to upload the generated JSON blob to pursuit as well, but if this ends up happening in a separate program then obviously we won't need to.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

Come to think of it, given the HTTP client needs of this program are quite a lot simpler than I originally imagined, it may well be worth switching to HTTP, which is in the Haskell Platform, and has a much smaller list of dependencies. edit: HTTP does not support HTTPS, and I think we should therefore rule it out.

@paf31
Copy link
Copy Markdown
Contributor

paf31 commented Apr 23, 2015

We don't necessarily have to use HTTP, that's fine. I'm just wondering, what can we get from the service that we can't get from the file? We could always require custom fields for the file. I'd prefer to have everything in one place honestly. That way, if Bower ever disappears, we can still keep the file format.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

Bower does have the repository key, which we could use instead: https://github.com/bower/bower.json-spec#repository

So, we could check that the type is git, and check that url is a GitHub URL, and then extract GitHub user/repo from the URL in the same way as this code currently does. I would hope that Bower has some kind of check in place to ensure that the repository key is the same as what is on the Bower registry (ie, where the code comes from when you bower install pkg but I am not sure about this.

The downsides are:

  • it's a bit of extra hassle for PureScript package maintainers to have to put this in; I'm not aware of any that do have it currently. None of the core packages do.
  • it's not the 'real' source of that information - the Bower registry is.

See also https://github.com/paf31/psc-pages/pull/18, @bodil's comment in particular.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

We also aren't really getting everything from one place at the moment - a large chunk comes from the .purs files in the current directory, the version comes from git tag --points-at HEAD, the resolved dependencies (i.e. specific versions of dependencies which we use for links in published HTML documentation) come from digging around in bower_components...

@paf31
Copy link
Copy Markdown
Contributor

paf31 commented Apr 23, 2015

Well, given that we're going to create a cached snapshot of the docs at a particular version, the URL could become out of date at any point later anyway. At least with the bower.json approach, we know that it was the right URL for the version of the code at the time the docs were created.

Rather than parsing the repository field, we could require an optional, custom field, containing the GitHub user and repo names - just a thought. If those were missing, we could just omit source links.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

Given that specifying a repository ought to be a very small amount of effort on the part of the maintainer however we choose to do it, and also given that we're happy assuming that PureScript packages are hosted on GitHub, I think I'd rather require this information be present, to ensure that we have source links in Pursuit documentation. I find them very useful for Haskell documentation on Hackage - and when they don't appear, I think it's quite irritating.

I think if we want to know that we've got the right URL for the code at the time the docs were created, we're better off using the URL from the Bower registry, since this is the one that gets used when you bower install things.

Also, if we do want to get this information from the Bower registry, we could switch to http-conduit, which provides an equally simple interface for what we want, and has a tiny dependency list in comparison.

@bodil
Copy link
Copy Markdown

bodil commented Apr 23, 2015

I can have Pulp enforce the presence of this information to some extent as well. Absent the ability to reject published packages lacking it, that's probably the closest we'll get to a guarantee.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

Sorry, the presence of which information?

@bodil
Copy link
Copy Markdown

bodil commented Apr 23, 2015

Specifying a repository, in particular.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

Ok then - let's take it from bower.json. I'd rather use the Bower-specified repository key - as far as I can tell, the only benefit to adding a custom key would be that it's marginally easier to put the information in, and I don't see that as a good enough reason to deviate from the standard.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

I've fixed the issue stemming from bower list --paths not always returning directories, and the repository now comes from the repository field of bower.json. I think this is good to go. Perhaps a rebase would be a good idea, but I'll wait for you to look over the new commits.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

Oh, one last thing I forgot, but would like to do - make all of the errors pluralise properly. The errors that refer to a list of things should use the singular if the list only has one thing in it.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

Ok, I'm really done now. :)

@hdgarrood
Copy link
Copy Markdown
Contributor Author

Oh, also, I suppose we should warn people that psc-docs (and probably also Pursuit, when we get there) will not display instance documentation. If any instances are worth documenting, I think we could suggest that documentation should go on the type itself.

@paf31
Copy link
Copy Markdown
Contributor

paf31 commented Apr 29, 2015

Getting ready to merge this. Code looks great (@garyb, any comments?), but when I build, I pull in a lot of dependencies, including wai. Any idea where they're coming from?

@hdgarrood
Copy link
Copy Markdown
Contributor Author

Not sure - I'll take a look.

@paf31
Copy link
Copy Markdown
Contributor

paf31 commented Apr 29, 2015

Looks like cheapskate depends on wai for something :(

@paf31
Copy link
Copy Markdown
Contributor

paf31 commented Apr 29, 2015

Looks like it's used by the binary. How disappointing.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

Ahhh, ok. I did waver about whether the AsHtml module should go into the purescript package. If we moved it somewhere else we would no longer need lucid, blaze-html, cheapskate, or data-default. Also it might be useful to be able to update the HTML generation code without having to produce a new compiler release. Up to you.

@paf31
Copy link
Copy Markdown
Contributor

paf31 commented Apr 29, 2015

So I compiled and ran this with purescript-prelude, and the results are nice, but should we be concerned at all about the verbosity of the JSON files (all the spaces, etc.)? I'm not sure, but I thought it might be worth bringing up.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

I'm not really bothered about the size of the JSON files - purescript-prelude is 66K, gzipping takes it down to 7K, and I think it's reasonable to guess that the vast majority of PureScript packages will be, say, no more than 10x that.

With respect to how human-readable it is, it's admittedly not great. Running it through a JSON formatting tool does make it a lot easier, though. Also, I think ease of encoding/decoding is much more important, and I can't immediately see a good way of improving the verbosity without adding a fair bit of complexity to the encoding/decoding steps.

@paf31
Copy link
Copy Markdown
Contributor

paf31 commented Apr 29, 2015

Makes sense 👍

@garyb
Copy link
Copy Markdown
Member

garyb commented Apr 29, 2015

@paf31: Sorry, I've not really been keeping track of the progress with this - if you're fine with it, I am!

@hdgarrood
Copy link
Copy Markdown
Contributor Author

I've just realised I've introduced a bug in psc-docs - the code in Language.PureScript.AST.Exported assumes that the desugarImports step has been performed, but psc-docs doesn't currently run it. The effect of this is that psc-docs incorrectly thinks that all instance declarations are 'private' and doesn't display them.

The obvious fix is to require desugarImports to be called first, and this requires providing the same source file list as would be necessary to compile the file normally. This is unfortunate, because psc-docs is currently very simple to use: simply running psc-docs file.purs works at the moment.

Alternatively, I could investigate modifying exportedDeclarations so that it works before or after calling desugarImports.

* Include a large chunk of code from psc-pages, allowing easier
  documentation output in multiple formats.
* Rework psc-docs in order to use this new code. This makes psc-docs
  much simpler.
* Partially fix #747, by putting instances in one chunk under their
  relevant data types and type classes.
* Language.PureScript.Docs.RenderedCode now uses pattern-arrows in
  order to avoid unnecessary parentheses appearing in rendered code.
* Remove unused code from psc-docs/Main.hs
@paf31
Copy link
Copy Markdown
Contributor

paf31 commented May 1, 2015

That is a bit of a shame, but honestly, I think most people use a tool to generate docs anyway.

The one case which would break is where we want to generate lots of small docs files, one per module. Maybe we need something analogous to --codegen from psc - to only generate docs for the given modules.

I think desugaring imports etc. is the right way to go though. If we ever want to do things like add links in the generated Markdown, we need to do that.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

Ok, sounds good. I thought the same re --codegen. How about specifying it like moduleName:destFile, so for example:

$ psc-docs src/**/*.purs bower_components/*/src/**/*.purs \
   --docgen Data.FingerTree:docs/Data.FingerTree.md \
            Data.Sequence:docs/Data.Sequence.md

@paf31
Copy link
Copy Markdown
Contributor

paf31 commented May 1, 2015

Sounds good, but is that sort of thing easily supported with optparse-applicative? Can we give good errors etc?

@hdgarrood
Copy link
Copy Markdown
Contributor Author

I'm not sure, I'll have a go and see what happens.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

psc-docs seems to work, and the error messages are decent, I think. Perhaps the wording could be improved for this one - any ideas?

$ psc-docs Foo.purs --docgen Foo --docgen Foo:Foo.md
psc-docs: error in --docgen option:
  Can't mix module names and module name/file path pairs in the same invocation.

Here's a draft changelog entry for these changes:

As far as I can tell, all we need to do now is:

  • update grunt-purescript
  • update gulp-purescript
  • update pulp
  • decide what to do about the dependencies issue / where the HTML generation code goes. I think we should put all HTML generation code inside the Pursuit server for now. We can always move it to a standalone library if we need to reuse that code elsewhere.

@paf31
Copy link
Copy Markdown
Contributor

paf31 commented May 3, 2015

I think putting the HTML code into the Pursuit server sounds fine. 👍

Also, before I forget, whatever new dependencies we add should be noted in the LICENSE file, since we're redistributing them in binary form.

@hdgarrood
Copy link
Copy Markdown
Contributor Author

LICENSE file should be done now (see 719dde6).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth using the safe package for this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so. I'll add it

@paf31
Copy link
Copy Markdown
Contributor

paf31 commented May 5, 2015

Reviewed, looks great. Sorry this took so long.

Could you please squash commits, and I'll merge this in?

@paf31 paf31 removed the needs review label May 5, 2015
hdgarrood added 6 commits May 5, 2015 18:17
Fixes #747

In addition to its previous behaviour of filtering out declarations
which are not exported, `exportedDeclarations` will now also:

* Filter out instance declarations which refer to non-exported types,
  as these can be considered as unexported.
* Descend into data declarations, and filter out unexported constructors

The effect of this is that tooling like psci and psc-docs can now simply
call `exportedDeclarations` and not have to worry about anything.
Adds a new program which collects all information necessary for
publishing a version of a package on pursuit, and dumps it to stdout
as JSON.

Included changes:

* expand rendered docs types (Language.PureScript.Docs.Types)

* add ToJSON instances and aeson-better-errors parsers

* add ToJSON/FromJSON tests for UploadedPackage

* look through devDependencies as well as normal dependencies in order
  to decide which dependencies are undeclared

* make undeclared dependencies a warning, not an error

  It turns out making undeclared dependencies an error can be quite
  annoying - for example, when trying to run psc-publish on
  purescript-prelude, I had purescript-eff installed and undeclared (for
  testing), and it was failing because of this.

  Arguably, this should have been an error, and I should have added
  purescript-eff to devDependencies. But, I didn't want to do that,
  because there's no suitable version of purescript-eff to use yet.

  There are probably other situations where it would make sense to install
  packages for development locally and not add them to devDependencies
  too, which just haven't occurred to me. Given this, I think emitting
  warnings is enough; I think the strategy of throwing errors would carry
  a much higher risk of just being annoying than actually preventing
  errors.
This will allow parseAndDesugar to be reused in psc-docs.
psc-docs now requires all modules to be passed on the command line so
that it can performs the desugarImports step of desugaring. This is
necessary for it to be able to work out which instances should be
displayed in the output.

Accordingly, a new --docgen option has been added, similar to psc's
--codegen, which allows you to specify the modules you want
documentation for. See psc-docs --help for more information.

This commit also removes the 'Module Documentation' header.
* Add packageName function, as a small convenience

* Remove HTML generation from Language.PureScript.Docs

  It's moving into Pursuit server for now.

* parameterize the Language.PureScript.Docs.Types.Package type
  so that packages with and without an uploader have different types,
  allowing stronger guarantees.
@hdgarrood
Copy link
Copy Markdown
Contributor Author

Is that ok?

paf31 added a commit that referenced this pull request May 5, 2015
@paf31 paf31 merged commit c5f28f4 into purescript:master May 5, 2015
@paf31
Copy link
Copy Markdown
Contributor

paf31 commented May 5, 2015

👍 x 100, thanks!

@hdgarrood
Copy link
Copy Markdown
Contributor Author

Hooray :)

@hdgarrood hdgarrood deleted the pursuit2 branch May 5, 2015 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Instances for private classes and types still appear in psc-docs output

5 participants