-
Notifications
You must be signed in to change notification settings - Fork 842
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
Write pantry hashes into a .lock file instead of emitting warnings #4288
Comments
This looks to be a sensible alternative approach, it appears to be a bit more intrusive and a bit less explicit about the resulting constraints. E.g. shouldn't I set explicit hashes for my library so users should be able to get reproducible result when trying to build on their machines? With somewhat implicit lock file this will look as not quite required so in my opinion having visible warnings is a good thing to promote more accurate constraints. I'd prefer to follow "explicit is better than implicit" for this case but probably @snoyberg has some more arguments on this question. |
Let's separate out the case of snapshot files and stack.yaml files. For snapshot files: a fair assumption is that authors will want to share these files outside of their project at some point. Having a lock file to go along with snapshot files in that context probably wouldn't make much sense. For example: imagine saying "if you download a snapshot file from http://example.com/snapshot.yaml, also check http://example.com/snapshot.yaml.lock." That seems pretty arbitrary and awkward. By contrast, I can picture having lock files for
I'd say a good next step is identifying exactly what Stack would do in the possible cases it could encounter:
As I'm starting to think this through, it may not be as complicated as I was worried it would be. |
@snoyberg I think the last 2 questions you posted are easily resolved with what @sol originally proposed: missing hash will get completed and will get saved in a lock file a successful build, and that new lock file will contain only data corresponding to a |
And another thing which bothers me while implementing this: what to do with changes user specifies on the command line? That could influence dependency graph quite a bit and it doesn't seem meaningful to store exact dependencies per every used CLI flag combination. |
I don't have a strong opinion on custom snapshots; what I care about is
That makes things more complicated indeed. I'll describe what I would ideally want to use from a users perspective:
DiscussionRegarding (2) I think this is a corner case that should be relatively rare (you would need both, a dependency that is guarded by a flag + that same dependency listed as If a user still runs into this then I think there is a workaround that s/he can use in most situations: The user can change the Why is this ok?
Finally, there is only one thing I'm worried about. Let's consider the following scenario:
One way to address this could be to fail on missing entries in the lock file on ImplementationI'm not sure what (1) would mean on the implementation side. |
At the risk of stating the obvious, I think this implies that if we e.g. have
in That is, the |
I'd say, for now, let's ignore the problems of creating snapshot files. That seems like something distinctly out of scope for Stack itself. Perhaps we'll have a Pantry executable that is useful for filling in missing info in a snapshot. After all, Pantry snapshots will hopefully work for more than just Stack users (e.g., Nix users).
Seems to be totally out of scope. The lock file should only address things that are in the stack.yaml itself. Command line changes are non-reproducible by nature. Let's try to make things just a bit more concrete. Let's say we have @sol's example stack.yaml: extra-deps:
- github: hspec/hspec
commit: 3c0f266bd3ce71958bf6b6daaf7d0cbcda7e7227
subdirs:
- hspec-core I'm imagining we'll end up with a lock file that looks like this: dependencies:
- original:
github: hspec/hspec
commit: 3c0f266bd3ce71958bf6b6daaf7d0cbcda7e7227
subdirs:
- hspec-core
complete:
- size: 99713
subdir: hspec-core
url: https://github.com/hspec/hspec/archive/3c0f266bd3ce71958bf6b6daaf7d0cbcda7e7227.tar.gz
cabal-file:
size: 4506
sha256: f79008d723c203f36815b304c0db90b065fa1b20cc06033e5055ccea8b096c3b
name: hspec-core
version: 2.6.0
sha256: ad03a807857ce4ed07c6a8410dbce8b5244c4e193e86767ce0ca93a3ba28dadd
pantry-tree:
size: 3751
sha256: 1bad19b4c4afde31c5f57d919ed768a0e034587e30070e4ac3420896fcb48b90 Rules:
I think this approach will address all of the reproducibility and performance concerns I have, and mean that the original stack.yaml can be even more lightweight than it is today, e.g. including the |
👍
That makes sense. I was misguided by the wrong assumption that you can specify Hackage dependencies without exact versions as Now everything actually looks neat and simple! That's great! |
Actually I have one question still: the original proposal talks about saving lock file only on successful build but what if that build was modified by some flags - in that case we don't have any guarantees about original (completed) dependencies. Should we exclude that requirement of a successful build then @snoyberg ? And use lock file only to lock package versions without giving extra guarantees? |
Regarding the question of |
At least I would be fine with that. My original feature request is influenced by what I implemented in
I used
to edit Still, should we consider |
Yes, I think so, good catch. Regarding the file name, we need to consider the fact that the stack.yaml file may not be called stack.yaml. It might be |
Sounds good to me, also I think it makes sense to resolve symlinks to get the real file name so |
I like this 👍 |
This is also vital for improving performance. Currently, Stack will spend significant time completing package information on each startup. Automatically writing a |
Specification for this lock file implementation is now written here: https://github.com/commercialhaskell/stack/blob/f2ac3e64d70c990c6a5045f02c13f5869a77c5c4/doc/lock_files.md |
Looks great 👍
No strong preference, but it's the approach I tend to go for. Maybe even simplify the file format by skipping |
@simonmichael regarding |
Currently
stack build
will emit warnings if I do not specifysize
andsha256
forgithub
dependencies instack.yaml
.Running
stack freeze
will output the relevant information that I then can add tostack.yaml
manually.I propose to write the information that is currently produced by
stack freeze
to a.lock
file after every successful build (e.g.pantry.lock
):.lock
file exists then for each listed dependency:stack
uses the information as if it were directly listed instack.yaml
; specifically it errors out on any hash mismatchesstack
detects that a dependency was updated instack.yaml
it silently ignores the information from the.lock
filestack
creates the.lock
file, overwriting any existing versions (which in effect means that we remove unused entries and add missing entries)Regarding revision control, we can follow conventions that have been developed elsewhere:
When developing an application, the
.lock
file should be checked into revision control. When developing a library, the.lock
file should be added to.gitignore
.A word on naming: If we expect the
.lock
file to be specific tostack
we may want to name itstack.lock
(or possibly.stack.lock
to not interfere with file name completion); if on the other hand we think that it will be relevant for other build tools that implement support forpantry
then we could name itpantry.lock
.Assuming we adopt this approach we can:
stack freeze
commandCC @snoyberg
The text was updated successfully, but these errors were encountered: