Add `--offline` flag
Currently there's no way to ensure that spago does not connect to the network. Even if all dependencies are installed, --no-install is set, there's still traffic.
This makes spago unusable in pure CI environments, such as nix. And it would be nice if that was not the case.
@f-f Is this a feature you'd be willing to accept before the Registry work gets done?
@JordanMartinez yes, definitely!
I think it's a big enough feature that it'd be worth discussing possible approaches before going for the code, either here or in the #spago channel in Discord.
Let's keep the discussion here for the time being because not everyone is on Discord and this change can affect a lot of people.
Correct me if I'm wrong, but the idea behind this flag is to make spago continue to work as much as possible without using an internet connection and failing otherwise, right? While Nix is definitely the main use case for that, there are other use cases where not using a network connection could be useful.
If we look at the commands we can pass to spago, here are the ones where adding an --offline flag doesn't make sense. So, I don't think --offline should be a 'global flag':
-
spago docs -
spago search -
spago sources -
spago path -
spago ls -
spago verify- Is this even used outside of the package-set repo? -
spago verify-set- Is this even used outside of the package-set repo? -
spago upgrade-set- When the--tagflag isn't specified, this command can only fail in an offline context. -
spago bump-version- This prepares for a release, but AFAIK doesn't actually use any network. -
spago version- :smile:
Here are the commands whose behavior could be affected by an --offline flag. I believe I've described the default behavior correctly, but please correct me where I'm wrong:
-
spago init- Normally, Spago will upgrade to the latest package set. If we include--offline, it should reuse the one defined in the binary when the release is made, correct? Or potentially use the latest one it knows about? I assume this could still be valuable because files could be "installed" from the global cache. -
spago install- Normally, Spago will download whatever package it doesn't already have in the global cache and copy from the global cache if it's already there. If we include--offline, it should only copy packages from the global cache if they don't already exist in the.spagofolder. Any package not found should cause the command to fail -
spago upgrade-set --tag TAG- Normally, Spago will change the package set to whatever the tag is. Including the--offlineflag here means we could change the tag to some other one so long as that tag is within the global cache. Otherwise, the command should fail. This likely won't be used that often, so it would simplify the implementation if we didn't support this. -
spago repl(not in a Spago project) - Normally, Spago will realize there is notspago.dhallfile, "install" its default packages (in memory? in a temp dir?), and then start a REPL session. If we include--offline, the command should only work if the packages exist in the global cache. -
spago repl(Inside a Spago project) - Normally, Spago will detect thespago.dhallfile, "install" the dependencies listed in that file (if they haven't already been installed), import anything in the.purs-replfile, and then start a REPL session. If we include--offline, the command should only work if the packages are already installed in the.spagodir or they can be copied over from the global cache. -
spago build/spago run/spago test/spago bundle-app/spago bundle-module- I think the--offlineflag implies--no-install. Would keeping both explicit be preferable (i.e.spago build --no-install --offline)? Or just--offline(i.e.spago build --offline)? -
spago script- I don't know how this works, so I can't comment further.
I think supporting the --offline flag in only the spago build etc. commands enables 80% of use cases. Support in the other commands could be added over time later.
but the idea behind this flag is to make spago continue to work as much as possible without using an internet connection and failing otherwise, right?
Yes! We should try to provide sane defaults, print warnings when we make assumptions about things that we could usually verify through a network call, and if we can't do even the bare minimum we just fail with "sorry, we really need to talk to the internet for this one"
So, I don't think
--offlineshould be a 'global flag'
"Being offline" is really an operational mode for the program, and it's going to affect a lot of things, I'd say so many that it should really be a global flag, so that we are able to check for it easily and without rewiring flags if we figure out that we need it in a new place.
For example, anything that evaluates Dhall (so really the majority of the commands we have) will need to know the value of the flag, and will need to figure out what to do when Dhall wants to make network calls.
We might want to do different things in different places: just let it fail with a Dhall error complaining that it can't reach the network, or swap in a new HTTP Manager in Dhall's EvaluateSettings.
I think a good start for this would be to:
- add the
--offlineflag - try to make
spago buildcomply to that - then we can chart how the rest of the commands are going to be affected by this (I suspect that figuring out what to do with Dhall's evaluation is already going to make things clearer)
We could already ship an offline flag that works only for build, as long as we put a giant warning saying "the offline flag is very experimental, it will probably not work". We can then take away the warning when we feel confident that things are offline-compliant.