Skip to content
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

stack init should use a user configurable snapshot setting as a default #1590

Closed
harendra-kumar opened this issue Jan 2, 2016 · 13 comments
Closed

Comments

@harendra-kumar
Copy link
Collaborator

Currently stack init picks up the most recent LTS and nightly from the snapshots dir and then the downloaded ones. I propose that, by default, instead of selecting a snapshot via an automatic and opaque selection process, init should prefer a user configured snapshot.

This gives the user an explicit control over the set of packages/compiler being used by default. We could have a --auto flag which can be used for auto fallback (the current default). The user will have to explicitly choose the auto option. We will also suggest it as a next step if init fails. We already have the --resolver flag to use a specific snapshot.

This allows the default reuse of a snapshot with the user's explicit knowledge.

The default could be the global project's resolver setting or maybe a setting in config.yaml. We can also provide a CLI command to control the default. It could be stack config default-resolver or something like that.

This should also solve #1374 cleanly.

@harendra-kumar harendra-kumar changed the title stack init should use a default user configurable snapshot setting stack init should use a user configurable snapshot setting as a default Jan 2, 2016
@mgsloan
Copy link
Contributor

mgsloan commented Jan 3, 2016

How about allowing the user to explicitly override the list of resolvers tried for init? While this could be a simple list of resolvers, it could also be extended to support expressing the current default behavior, and more.

To just try one specific snapshot:

init-resolvers:
- lts-3.19

The current default (with neither --prefer-lts or --prefer-nightly) would be:

init-resolvers:
- lts-latest-installed    # Use the largest installed lts snapshot version, if any.
- lts-latest-installed-1  # Use the next-largest installed lts snapshot version, if any.
- nightly-latest-installed
- nightly-latest-installed-1
- lts-latest    # Latest available lts snapshot.
- lts-latest-1
- nightly-latest
- nightly-latest-1

These should probably just be special syntax for this particular field, rather than being supported as valid resolver values in stack.yaml. They might be valuable as CLI arguments, though. It'd be nice to be able to use stack init --resolver lts-latest. Does this make sense for the resolver parameter in all of its uses? This has some relevance to whether the refactoring to use global --resolver happens.

@harendra-kumar
Copy link
Collaborator Author

I like that. It is quite general and powerful. Should we call it preferred-resolvers or resolver-preference instead? Also, we can drop the second latest versions for the sake of simplicity.

I think it will be great to have a consistent correspondence between CLI and config file parameters as long as they make sense for the given context. We should perhaps have a way to do that programmatically rather than writing duplicate code always fraught with the possibility of inconsistency.

@mgsloan
Copy link
Contributor

mgsloan commented Jan 3, 2016

I like init-resolvers because it suggests which command the setting affects. How about preferred-init-resolvers? It doesn't seem quite right to use the term "preferred" here, though, as these are just all the resolvers that are tried by stack init.

This might be complicating things too far, but it'd also be nice to have lts-3-latest.

@mgsloan
Copy link
Contributor

mgsloan commented Jan 4, 2016

We might also want to change the default. I think it makes sense to try the latest snapshots of each major lts version.

It may even make sense to throw in a nightly snapshot that involves both ghc-7.8 and Cabal-1.22, if such a snapshot exists. (See the related issue #1021 )

@harendra-kumar
Copy link
Collaborator Author

init-resolvers is fine. I was wondering if there were cases other than init where you may need resolver selection. But perhaps there is no such case. stack solver also has a resolver to work on unless we want suggest a change of resolver.

There are two important use cases to consider when initing:

  • ability to stick to the same resolver every time
  • discovering a working resolver when our chosen resolver does not work

I thought of this setting more as a use case for fixing and reusing the same resolver every time rather than choosing or discovering the best or working resolver. For example I would perhaps put in a lts-3.x and a lts-2.x there and never change that unless I really run into a problem which necessitates the change of resolver. Most enterprises would most likely prefer that kind of setting in their dev environment.

Choosing a variable resolver like latest-* is orthogonal to the goal of fixing a resolver but it can serve the purpose of always using the latest and greatest resolver (many personal users would most likely prefer that) or specifying a pool of resolvers to discover from when trying to find something working. If we are compromising simplicity then I would prefer simplicity over providing more power for this use case.

For discovering something working we can even use resolvers which are not specified here - automatically or via a CLI switch (e.g. --auto). And for that I am willing to exhaustively search all possibilities that make sense and can be done efficiently.

Though I still like providing simple and useful variable stuff here like latest-lts or latest-nightly or maybe even something for latest-lts-having-ghc-7.8.x may be useful. But it gets complicated soon and would perhaps require regexes or a simple expression language to express more complex choices elegantly.

For default latest-lts-installed is a good choice at the top followed by latest-lts for the case when nothing is installed. That's it. If they don't work we can try major/minor lts versions automatically without explicit configuration as I said above and as we are doing today.

@mgsloan
Copy link
Contributor

mgsloan commented Jan 5, 2016

Yeah, I'm not convinced that full on complexity of init-resolvers as described is worth it. I do like the idea of being able to specify stack init --resolver lts-latest, though.

A simple alternative would be to use the resolver of the global project as the default. So, stack init will always first try the global project's resolver. Then, we don't even have to add a configuration option! On the other hand, some folks might not like this default magic..

I'll leave the details up to you, since I'm not really sure what's best. A simple configuration option would be fine.

@juhp
Copy link
Contributor

juhp commented Jan 6, 2016

Could just lts be used instead of lts-latest and similarly nightly for nightly-latest?
I am not sure how important the "latest-1" cases are? Are they for some specific use-case?

@mgsloan
Copy link
Contributor

mgsloan commented Jan 6, 2016

Well, lts-3.* is significant, because all of the packages involved have the same major version - only minor version bumps are allowed. So, if the packages all follow the PVP properly, there should be no risk to using lts-3-latest (or whatever the syntax is)

@juhp
Copy link
Contributor

juhp commented Jan 6, 2016

Ah sorry I see, I think you were just using "*-latest-1" to describe the current default behavior.

I just wondered if we could avoid the "-latest" suffix completely.

@harendra-kumar
Copy link
Collaborator Author

A simple alternative would be to use the resolver of the global project as the default.

I started with that thought. But on closer investigation it seems inconsistent. If we use the global project config then it should be used fully including any other settings in that file (e.g. extra-deps) or we should not use it at all. Currently it seems global project is only used by install and exec commands outside of a project. We can keep it that way.

We can add a global default resolver(s) config option in config.yaml. To start with it could be a single entry which can be extended into an ordered list later.

@mgsloan
Copy link
Contributor

mgsloan commented Jan 8, 2016

Yeah, using the global project's resolver is likely too magical. Feel free to open a PR adding the single entry.

@harendra-kumar
Copy link
Collaborator Author

Anyone wanting to pick this up please feel free to do so. I will not be able to get back to this anytime soon.

@snoyberg
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants