commercialhaskell / stack

The Haskell Tool Stack
http://haskellstack.org
BSD 3-Clause "New" or "Revised" License
4k stars 843 forks source link

Method to combine multiple project stack.yaml files #732

Open rrnewton opened 9 years ago

rrnewton commented 9 years ago

A I understand it, stack.yaml is a passive/declarative format. It doesn't have any executable or expanded bits, or #include syntax, or whatever. That's all well and good, but it does seem to leave us doing ad-hoc cat commands on fragments of stack.yaml to build the right one.

In particular this comes up when varying things. Like a really simple example would be to build in docker and non-docker environments (and multiple resolvers of course). Currently, we would put the normal base config in stack.yaml, and then have a separate file, say enable_docker.yaml, with just this entry:

docker:
  enable: true
  repo: ...

Then we could build by running:

$ cat stack.yaml enable_docker.yaml > stack2.yaml
$ stack --stack-yaml=stack2.yaml build

This is ok, but it is kind of ugly/messy, and it doesn't scale super well. If we had command line arguments for all the docker config bits, we could vary this by varying the command line arguments, but we currently don't.

Initially, by the way, I kind of thought the following might work:

$ stack --stack-yaml=stack.yaml --stack-yaml=enable_docker.yaml build

But currently this is an error.

Internally, there's already the ability to combine configs (Monoid), right? And we already mix configs from global / user / project. So the restriction to only mix exactly those three configs seems a bit arbitrary.

This is somewhat related to #392 and #378.

borsboom commented 9 years ago

For this particular case, you should be able to use the --docker/--no-docker command-line options (just about all Docker config options can be overridden on the command-line).

For the more general issue, I do like the idea of being able to specify a "local overrides" file for the project file, and I don't think that would be difficult to support. I could see a number of ways to do this, one of which could be something like loading stack.local.yaml after stack.yaml, if it exists (and also support specifying a different/additional file on the command-line).

radix commented 8 years ago

I'm in pretty much exactly the same situation, and --docker is kind of a pain because I have many scripts throughout my project that invoke stack, and I want them all to implicitly use docker, but only in my CI environment (or if a developer on my project chooses to enable docker).

My current workaround is to have my CI process add a docker section to the stack.yaml file before running the rest of its process.

radix commented 8 years ago

fwiw a STACK_OPTS environment variable, which specifies extra arguments for stack, would also solve this problem for me, since I could put --docker in it.

mgsloan commented 8 years ago

It would indeed be really nice to have stack.local.yaml, to set things you don't want in git. Since it wouldn't usually be checked in, it'd also be more amenable to automatic manipulation (not as big of a deal to do a parse + re-serialize round trip)

This shouldn't be very hard to implement, the config datatypes are already monoids.