purescript-contrib / pulp

A build tool for PureScript projects
GNU Lesser General Public License v3.0
444 stars 86 forks source link

Per-project configuration file #192

Open paulyoung opened 8 years ago

paulyoung commented 8 years ago

I mentioned https://github.com/nwolverson/atom-ide-purescript/issues/53 to @paf31 and this came up.

hdgarrood commented 8 years ago

It's not clear what the problem is that you're trying to solve here.

Looking at that issue, is it that you want a command that compiles everything in both src and test, but which doesn't actually run the tests? Because I think that's just pulp build --include test. I think it's probably right that pulp build by default doesn't look inside test, btw; I don't think we should be doing anything that might slow that down unnecessarily.

paulyoung commented 8 years ago

pulp build --include test makes more sense – thanks for that.

The problem is that if I open a project that doesn't have a test directory, then the command fails and nothing works.

If different projects could specify their own pulp configuration, then potentially various tooling could reliably call a single command in order to build them.

hdgarrood commented 8 years ago

If different projects could specify their own pulp configuration, then potentially various tooling could reliably call a single command in order to build them.

What about npm run build?

paulyoung commented 8 years ago

I can work with that, not sure if it covers what @paf31 had in mind.

hdgarrood commented 8 years ago

To expand on that a little; it's the closest thing we have to that currently. Lots of purescript packages (admittedly not all) will need a package.json file; almost certainly they will if it's a node project, but even if it's completely client side, there's a good chance you're already using something like webpack or less or whatever. And once you do have one, npm scripts are the natural choice. And I know that lots of projects are using an npm "build" script for this already.

I think it's also worth noting a couple of things:

paulyoung commented 8 years ago

Thanks for pointing it out. Not sure why I didn't think of that in the first place.

damncabbage commented 8 years ago

This is more a follow-up on the title than the specific 'including tests' case:

I've now rigged up a couple of different projects with package scripts that wrap the pulp commands, entirely because they're apps which have a different location for src, test and output. The two specific cases are:

I really, really would love to have per-project build "defaults". Every time something makes the assumption it can call pulp build (or psci or bundle or) on these projects, I need to go and hack an override in, and hope it supports making a project-specific exemptions.

To be frank, Pulp is the de facto standard, and supporting tools I run into are starting to wrap its interface. In the same way that JS benefits from a uniform npm test interface with internalised configuration, a way for us to internalise Pulp's project configuration saves devs needing to give the same config over and over again.

'convention over configuration'

Ex-Ruby dev here: "Convention Over Configuration" is having strong conventions in preference to, but not excluding, configuration. You can rewire a Rails app entirely if you'd like by changing the config, and plugins that look to those configuration values will still work. You still boot it up with rails server, rails console, etc. without needing to supply a pile of config options each time. The only real "convention" in this case is rails and its set of sub-commands; everything on down is codified instead of guessed.

It sounds like this configuration file would essentially contain information that is already present in the project directory tree.

In @paulyoung's case, where test is the default location for tests, this works. It doesn't work so great if you need to put test in a different spot, as it has no idea how to find this convention-deviance without tacking --test-path onto literally every pulp subcommand.

One last thing in case it's relevant:

I don't see this being needed very often for libraries, but it seems that applications, gaffer-taped compositions of these libraries, benefit this flexibility in order to keep with the community's conventions. Like Rails devs benefit from being able to pick up a project and at least get to a working server+console, we'd benefit from being able to assume that pulp build will build a freshly-downloaded repo, or that pulp build --json-errors is what the IDE can assume as a sensible default.

damncabbage commented 8 years ago

Failing that, I suggest we rally around a common set of npm package scripts every PureScript package defines. Include it in the generated pulp init. Pull request everything to get it in. But please, let's give devs a common "in" to projects, instead of needing to figure out the way <project-I'm-trying-out-or-returning-to> has decided to set up its build process.

(I'm showing both my PHP and Ruby experiences here. Ruby being the "I type X and I have a working thing in all likelihood", and PHP being seven years of snowflake apps and libraries with custom setup scripts. Ruby being "I type rails console and I have a REPL", PHP being ... more custom. PS with my aforementioned project being an npm script wrapping pulp psci with three options, inevitably found in the docs after pulp psci explodes as-is.)

damncabbage commented 8 years ago

One more thing before I stop nattering: this just came up in IRC about this issue, and I need to be clear that I completely agree:

<nwolverson> Anyway I think it's important this is a community discussion and
             doesn't feel like it comes off as a criticism/problem of pulp in
             particular, which if anything is a victim of its own success.

If my tone comes across as at all antagonistic and/or aimed at Pulp specifically, I apologise. I think this particular thing is a growing pain that needs solving, but it's definitely not on any of you to solve for the entire community. Thanks for your hard work on Pulp.

(This quote and some resulting discussion here: http://ircbrowse.net/browse/purescript?id=295314&timestamp=1459178548#t1459178548)

dkoontz commented 8 years ago

I am in the same boat as damncabbage. I have a very non-standard config for an Electron based project and then other ones that could work with pulp build. My ideal solution is a .pulp type file that allows me to specify defaults for the current project that are read when a pulp command is run and passed along as if I had typed them in and are ignored if the same parameter is explicitly passed. Allowing pulp to run independently of npm tasks has the benefit of being able to go places npm can't/won't.

For example if in the near future I have a Purescript project using the C++ backend, using Pulp feels natural. It's part of the Purescript ecosystem and it knowing about various backends does not seem out of place. Triggering my C++ build from an npm script that only exists because everyone uses npm is kind of strange. I might be encouraged to use the npm equivalent of whatever lang my backend is for. I'm not advocating that Pulp should be the be-all-do-everything tool but as a place to standardize tooling it is extremely important for the PS ecosystem. If Pulp ends up detecting that you have a package.json and thus calls some standard npm tasks or detecting you have some other C++ config thing (makefile?) and calling an equivalent task in there, that would be fine too, as long as my tool can call pulp build and have that work out.

hdgarrood commented 8 years ago

Yeah, npm scripts obviously aren't going to work once alternate backends become a thing. However, I really don't want to try to design features around stuff that doesn't really exist yet.

hdgarrood commented 8 years ago

@damncabbage what project is this, btw? Why doesn't pulp psci work as is?

damncabbage commented 8 years ago

@hdgarrood: Something with PS (and JS and Haskell) living in a support/purs/src/... directory, and some other modules living in top-level modules/**/*.purs and components/**/*.purs folders.

It's bizarre by regular-PS standards. It does work if I supply some options to pulp build, bundle, test and psci; to keep running these commands at all friendly, though, I need to wrap every one of these very long commands, each having practically identical options. Being able to "pass" these options to pulp build, bundle, test and psci would mean pulp would "just work" out of the box, for both my own and others' less obscure setups.

(A less bizarre example is the aforementioned pux-boilerplate/pux-starter-app; that mostly works, but there's an Unable to parse foreign module warning you hit every time you start pulp psci, because it's a hybrid JS/PS app with src/js/... and src/purs/...)

hdgarrood commented 8 years ago

Ok, makes sense. I wonder if, rather than just a file with defaults, though, it would be better to have a slightly higher-level approach that specifies build targets (kind of like what cabal files do, maybe). So for example, if you want 3 different entry points for your app, or if you want to build with or without bundling, or if you want to just build in order to test on node.js, or you want to create a bundle for in-browser testing, or you want to build and run benchmarks, etc, you can use different sets of options for each.

I think it's probably right that pulp is kind of low-level (at least for now). It doesn't really try to get you to a point where you don't need know what's going on underneath, as anyone who has tried to use it for a more complex build process probably understands. Building stuff for the web is hard, and I certainly don't feel that I know enough about it to be able to design a higher-level system well.

I've been toying with the idea of extracting a PureScript library from pulp, which mostly mirrors the CLI, so that this repo just becomes a tiny wrapper over the library. That could allow you to experiment with more sophisticated build tools without making any (potentially irreversible) changes to pulp itself. How does that sound?

Unfortunately I've never worked on apps that mix purescript with other languages and have complex build processes. The most complex one I've made is for multipac: https://github.com/hdgarrood/multipac/blob/b78c45c0003e608157fe8c3b3888f51fc9de5f29/package.json (ie, not very), so I'm not in the best position to help in this discussion.