stack 2.1.3.1 → 2.3.1
raw patch · 85 files changed
+1805/−1812 lines, 85 filesdep +casa-clientdep +casa-typesdep −resource-pooldep −resourcetdep −terminal-sizedep ~Cabaldep ~QuickCheckdep ~Win32setup-changed
Dependencies added: casa-client, casa-types
Dependencies removed: resource-pool, resourcet, terminal-size
Dependency ranges changed: Cabal, QuickCheck, Win32, aeson, ansi-terminal, array, async, attoparsec, base64-bytestring, colour, conduit, conduit-extra, containers, deepseq, directory, exceptions, extra, file-embed, filelock, filepath, generic-deriving, githash, hpack, hspec, http-client, http-conduit, http-download, http-types, memory, microlens, mono-traversable, mustache, neat-interpolation, network-uri, optparse-applicative, optparse-generic, optparse-simple, pantry, path, path-io, persistent-template, pretty, process, retry, rio, stm, streaming-commons, tar, template-haskell, temporary, text, th-reify-many, transformers, unicode-transforms, unix-compat, unordered-containers, vector, yaml, zip-archive, zlib
Files
- CONTRIBUTING.md +2/−2
- ChangeLog.md +100/−4
- README.md +0/−10
- Setup.hs +11/−11
- doc/CONTRIBUTING.md +2/−2
- doc/ChangeLog.md +100/−4
- doc/GUIDE.md +33/−124
- doc/SIGNING_KEY.md +6/−1
- doc/azure_ci.md +21/−58
- doc/build_command.md +17/−14
- doc/coverage.md +1/−1
- doc/dependency_visualization.md +2/−0
- doc/developing_on_windows.md +2/−2
- doc/faq.md +27/−24
- doc/ghcjs.md +2/−161
- doc/install_and_upgrade.md +43/−12
- doc/lock_files.md +0/−6
- doc/nix_integration.md +3/−4
- doc/nonstandard_project_init.md +17/−17
- doc/pantry.md +5/−162
- doc/stack_yaml_vs_cabal_package_file.md +5/−1
- doc/yaml_configuration.md +93/−21
- snapshot.yaml +0/−35
- src/Data/Attoparsec/Interpreter.hs +1/−1
- src/Network/HTTP/StackClient.hs +112/−6
- src/Path/Extended.hs +40/−0
- src/Path/Extra.hs +0/−1
- src/Stack/Build.hs +29/−1
- src/Stack/Build/Cache.hs +12/−0
- src/Stack/Build/ConstructPlan.hs +49/−19
- src/Stack/Build/Execute.hs +59/−48
- src/Stack/Build/Haddock.hs +3/−1
- src/Stack/Build/Installed.hs +3/−19
- src/Stack/BuildPlan.hs +0/−2
- src/Stack/Config.hs +28/−15
- src/Stack/ConfigCmd.hs +1/−1
- src/Stack/Constants.hs +2/−52
- src/Stack/Constants/Config.hs +20/−4
- src/Stack/Coverage.hs +11/−4
- src/Stack/Docker.hs +24/−5
- src/Stack/Dot.hs +102/−37
- src/Stack/FileWatch.hs +31/−43
- src/Stack/Freeze.hs +0/−79
- src/Stack/GhcPkg.hs +5/−7
- src/Stack/Ghci/Script.hs +1/−1
- src/Stack/Hoogle.hs +66/−50
- src/Stack/Init.hs +2/−2
- src/Stack/Lock.hs +3/−3
- src/Stack/Ls.hs +2/−4
- src/Stack/New.hs +14/−17
- src/Stack/Nix.hs +0/−1
- src/Stack/Options/BuildParser.hs +5/−0
- src/Stack/Options/ConfigParser.hs +8/−2
- src/Stack/Options/DotParser.hs +45/−19
- src/Stack/Options/FreezeParser.hs +0/−16
- src/Stack/Package.hs +17/−25
- src/Stack/Path.hs +0/−2
- src/Stack/Prelude.hs +1/−3
- src/Stack/Runners.hs +5/−6
- src/Stack/SDist.hs +4/−6
- src/Stack/Script.hs +5/−2
- src/Stack/Setup.hs +120/−203
- src/Stack/Setup/Installed.hs +0/−20
- src/Stack/SetupCmd.hs +1/−18
- src/Stack/SourceMap.hs +3/−1
- src/Stack/Storage/Project.hs +2/−1
- src/Stack/Storage/User.hs +2/−1
- src/Stack/Types/Build.hs +0/−3
- src/Stack/Types/Compiler.hs +18/−17
- src/Stack/Types/Config.hs +40/−41
- src/Stack/Types/Config/Build.hs +3/−0
- src/Stack/Types/Package.hs +1/−1
- src/Stack/Types/Version.hs +9/−9
- src/Stack/Unpack.hs +2/−2
- src/Stack/Upgrade.hs +1/−2
- src/Stack/Upload.hs +7/−4
- src/System/Process/Pager.hs +32/−20
- src/main/Main.hs +6/−19
- src/test/Stack/DotSpec.hs +3/−3
- src/test/Stack/LockSpec.hs +8/−24
- src/unix/System/Terminal.hsc +31/−0
- src/windows/System/Terminal.hs +59/−0
- stack.cabal +237/−240
- stack.yaml +17/−2
- test/integration/lib/StackTest.hs +1/−1
@@ -135,13 +135,13 @@ Running the integration tests is a little involved, you'll need to: ```bash-$ stack build --flag stack:integration-tests stack --interleaved-output --exec stack-integration-test+$ stack build --flag stack:integration-tests stack --exec stack-integration-test ``` Running an individual module works like this: ```bash-$ stack build --flag stack:integration-tests stack --interleaved-output --exec "stack-integration-test -m <PATTERN>"+$ stack build --flag stack:integration-tests stack --exec "stack-integration-test -m <PATTERN>" ``` Where `<PATTERN>` is the name of the folder listed in the
@@ -1,6 +1,101 @@ # Changelog +## v2.3.1 +**Changes since v2.1.3.1**++Release notes:+* We have reduced the number of platforms that we support with binary releases.+ The reason behind this is that we've been slowed down in our release process+ until now with issues trying to build binaries for less common platforms. In+ order to make sure we can address issues more quickly (like supporting new+ GHC versions), we're limiting support from the Stack team to:++ * Linux 64-bit (static)+ * MacOS+ * Windows 64-bit++ If others want to provide additional binaries, we will definitely be happy+ for the support. But since our CI system is currently able to produce these+ three bindists only, that's what we will be providing with the next release.++Major changes:+* `setup-info-locations` yaml configuration now allows overwriting the default locations of `stack-setup-2.yaml`.+ [#5031](https://github.com/commercialhaskell/stack/pull/5031)+ [#2983](https://github.com/commercialhaskell/stack/issues/2983)+ [#2913](https://github.com/commercialhaskell/stack/issues/2913)++* The `setup-info` configuration key now allows overwriting parts of the default `setup-info`++* The `--setup-info-yaml` command line flag now may be used in all stack commands such as `stack build`, and not only in `stack setup`++* The `--setup-info-yaml` may specify multiple locations for `stack-setup.yaml` files.++* The `stack upload` can read first reads environment Variable `$HACKAGE_USERNAME` and `$HACKAGE_PASSWORD` if they are missing only then asks for `username` or `password`++* Fully remove GHCJS support.++* Remove the `freeze` command. It has been replaced by lock files.++Behavior changes:+* Remove the deprecated `--stack-setup-yaml` command line argument in favor of `--setup-info-yaml`+ [#2647](https://github.com/commercialhaskell/stack/issues/2647)++* We now recommend checking in generated cabal files for repos. When generating lock files for+ extra-deps that only include `package.yaml` files, a deprecation warning will be generated.+ Also, those packages will no longer be included in the generated lock files.+ See [#5210](https://github.com/commercialhaskell/stack/issues/5210).++Other enhancements:+* Add `build-output-timestamps` flag in yaml. Setting it to true+ prefixes each build log output line with a timestamp.++* Show warning about `local-programs-path` with spaces on windows+ when running scripts. See + [#5013](https://github.com/commercialhaskell/stack/pull/5013)++* Add `ls dependencies json` which will print dependencies as JSON.+ `ls dependencies --tree` is now `ls dependencies tree`. See+ [#4424](https://github.com/commercialhaskell/stack/pull/4424)++* Remove warning for using Stack with GHC 8.8-8.10, and Cabal 3.0-3.2.++* Allow relative paths in `--setup-info-yaml` and tool paths+ [#3394](https://github.com/commercialhaskell/stack/issues/3394)++* Added the `--only-locals` flag. See+ [#5272](https://github.com/commercialhaskell/stack/issues/5272)++Bug fixes:++* Upgrade `pantry`: module mapping insertions into the database are now atomic.+ Previously, if you SIGTERMed at the wrong time while running a script, you+ could end up with an inconsistent database state.++* `--resolver global` doesn't retrieve snapshots list from the internet+ beause doesn't need it. See [#5103](https://github.com/commercialhaskell/stack/issues/5103)++* Fix using relative links in haddocks output. See+ [#4971](https://github.com/commercialhaskell/stack/issues/4971).+* Do not include generated cabal file information in lock files. See+ [#5045](https://github.com/commercialhaskell/stack/issues/5045).++* Use proper Hoogle executable path when installed automatically. See+ [#4905](https://github.com/commercialhaskell/stack/issues/4905)++* Fix GHC version for batched package unregistration. See+ [#4951](https://github.com/commercialhaskell/stack/issues/4951)++* Use Hoogle from the snapshot used and not the latest version. See+ [#4905](https://github.com/commercialhaskell/stack/issues/4905)++* Resolve "'stty' is not recognized". See+ [#4901](https://github.com/commercialhaskell/stack/issues/4901)++* Fix missing reconfigure check causing errors when a package gets+ used in multiple projects. See+ [#5147](https://github.com/commercialhaskell/stack/issues/5147)+ ## v2.1.3.1 Hackage-only release:@@ -9,6 +104,7 @@ * Support rio-0.1.11.0 * Add `stack.yaml` back to hackage sdist, and add `snapshot.yaml` + ## v2.1.3 **Changes since v2.1.1**@@ -59,7 +155,7 @@ * Expose package library when running tests. * Fix support for non-ASCII module names. See- [4938](https://github.com/commercialhaskell/stack/issues/4938)+ [#4938](https://github.com/commercialhaskell/stack/issues/4938) Other changes: @@ -202,7 +298,7 @@ use to avoid multiple runs of Stack from trampling each others' files. See [#2730](https://github.com/commercialhaskell/stack/issues/2730).-* Stack will check occassionally if there is a new version available and prompt+* Stack will check occasionally if there is a new version available and prompt the user to upgrade. This will not incur any additional network traffic, as it will piggy-back on the existing Hackage index updates. You can set `recommend-stack-upgrade: false` to bypass this. See@@ -233,7 +329,7 @@ * British English spelling of 'color' (colour) accepted as an alias for `--color`, `--stack-colors`, `stack ls stack-colors` at the command line and for `color:` and `stack-colors:` in yaml configuration files.-* New build option `--ddump-dir`. (See +* New build option `--ddump-dir`. (See [#4225](https://github.com/commercialhaskell/stack/issues/4225)) * Stack parses and respects the `preferred-versions` information from Hackage for choosing latest version of a package in some cases,@@ -678,7 +774,7 @@ conflicting versions of packages without issue. See [Stackage issue #3185](https://github.com/fpco/stackage/issues/3185). * When promoting packages from snapshot to local, we were- occassionally discarding the actual package location content and+ occasionally discarding the actual package location content and instead defaulting to pulling the package from the index. We now correctly retain this information. Note that if you were affected by this bug, you will likely need to delete the binary build cache
@@ -8,13 +8,3 @@ See [haskellstack.org](http://haskellstack.org) or the [doc](./doc) directory for more information.--### Subsystem maintainers--* GHCJS - [Matchwood](https://github.com/matchwood)--NOTE: GHCJS support is considered experimental. In Stack 2.0, we are-removing support for building GHCJS itself; links will be added to-this README for information on separate tools. Issues on GHCJS may be-closed as not supported, and the next major Stack release may remove-GHCJS support entirely.
@@ -3,19 +3,19 @@ import Data.List ( nub, sortBy ) import Data.Ord ( comparing )-import Distribution.Package ( PackageId, InstalledPackageId, packageVersion, packageName )+import Distribution.Package ( PackageId, UnitId, packageVersion, packageName ) import Distribution.PackageDescription ( PackageDescription(), Executable(..) )-import Distribution.InstalledPackageInfo (sourcePackageId, installedPackageId)+import Distribution.InstalledPackageInfo (sourcePackageId, installedUnitId) import Distribution.Simple ( defaultMainWithHooks, UserHooks(..), simpleUserHooks )-import Distribution.Simple.Utils ( rewriteFile, createDirectoryIfMissingVerbose )-import Distribution.Simple.BuildPaths ( autogenModulesDir )+import Distribution.Simple.Utils ( rewriteFileEx, createDirectoryIfMissingVerbose )+import Distribution.Simple.BuildPaths ( autogenPackageModulesDir ) import Distribution.Simple.PackageIndex (allPackages, dependencyClosure) import Distribution.Simple.Setup ( BuildFlags(buildVerbosity), fromFlag ) import Distribution.Simple.LocalBuildInfo ( installedPkgs, withLibLBI, withExeLBI, LocalBuildInfo(), ComponentLocalBuildInfo(componentPackageDeps) ) import Distribution.Types.PackageName (PackageName, unPackageName) import Distribution.Types.UnqualComponentName (unUnqualComponentName)-import Distribution.Verbosity ( Verbosity )-import Distribution.Version ( showVersion )+import Distribution.Verbosity ( Verbosity, normal )+import Distribution.Pretty ( prettyShow ) import System.FilePath ( (</>) ) main :: IO ()@@ -27,11 +27,11 @@ generateBuildModule :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO () generateBuildModule verbosity pkg lbi = do- let dir = autogenModulesDir lbi+ let dir = autogenPackageModulesDir lbi createDirectoryIfMissingVerbose verbosity True dir withLibLBI pkg lbi $ \_ libcfg -> do withExeLBI pkg lbi $ \exe clbi ->- rewriteFile (dir </> "Build_" ++ exeName' exe ++ ".hs") $ unlines+ rewriteFileEx normal (dir </> "Build_" ++ exeName' exe ++ ".hs") $ unlines [ "module Build_" ++ exeName' exe ++ " where" , "" , "deps :: [String]"@@ -40,13 +40,13 @@ where exeName' = unUnqualComponentName . exeName formatdeps = map formatone . sortBy (comparing unPackageName')- formatone p = unPackageName' p ++ "-" ++ showVersion (packageVersion p)+ formatone p = unPackageName' p ++ "-" ++ prettyShow (packageVersion p) unPackageName' = unPackageName . packageName transDeps xs ys = either (map sourcePackageId . allPackages) handleDepClosureFailure $ dependencyClosure allInstPkgsIdx availInstPkgIds where allInstPkgsIdx = installedPkgs lbi- allInstPkgIds = map installedPackageId $ allPackages allInstPkgsIdx+ allInstPkgIds = map installedUnitId $ allPackages allInstPkgsIdx -- instPkgIds includes `stack-X.X.X`, which is not a dependency hence is missing from allInstPkgsIdx. Filter that out. availInstPkgIds = filter (`elem` allInstPkgIds) $ testDeps xs ys handleDepClosureFailure unsatisfied =@@ -54,5 +54,5 @@ "Computation of transitive dependencies failed." ++ if null unsatisfied then "" else " Unresolved dependencies: " ++ show unsatisfied -testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo -> [InstalledPackageId]+testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo -> [UnitId] testDeps xs ys = map fst $ nub $ componentPackageDeps xs ++ componentPackageDeps ys
@@ -135,13 +135,13 @@ Running the integration tests is a little involved, you'll need to: ```bash-$ stack build --flag stack:integration-tests stack --interleaved-output --exec stack-integration-test+$ stack build --flag stack:integration-tests stack --exec stack-integration-test ``` Running an individual module works like this: ```bash-$ stack build --flag stack:integration-tests stack --interleaved-output --exec "stack-integration-test -m <PATTERN>"+$ stack build --flag stack:integration-tests stack --exec "stack-integration-test -m <PATTERN>" ``` Where `<PATTERN>` is the name of the folder listed in the
@@ -1,6 +1,101 @@ # Changelog +## v2.3.1 +**Changes since v2.1.3.1**++Release notes:+* We have reduced the number of platforms that we support with binary releases.+ The reason behind this is that we've been slowed down in our release process+ until now with issues trying to build binaries for less common platforms. In+ order to make sure we can address issues more quickly (like supporting new+ GHC versions), we're limiting support from the Stack team to:++ * Linux 64-bit (static)+ * MacOS+ * Windows 64-bit++ If others want to provide additional binaries, we will definitely be happy+ for the support. But since our CI system is currently able to produce these+ three bindists only, that's what we will be providing with the next release.++Major changes:+* `setup-info-locations` yaml configuration now allows overwriting the default locations of `stack-setup-2.yaml`.+ [#5031](https://github.com/commercialhaskell/stack/pull/5031)+ [#2983](https://github.com/commercialhaskell/stack/issues/2983)+ [#2913](https://github.com/commercialhaskell/stack/issues/2913)++* The `setup-info` configuration key now allows overwriting parts of the default `setup-info`++* The `--setup-info-yaml` command line flag now may be used in all stack commands such as `stack build`, and not only in `stack setup`++* The `--setup-info-yaml` may specify multiple locations for `stack-setup.yaml` files.++* The `stack upload` can read first reads environment Variable `$HACKAGE_USERNAME` and `$HACKAGE_PASSWORD` if they are missing only then asks for `username` or `password`++* Fully remove GHCJS support.++* Remove the `freeze` command. It has been replaced by lock files.++Behavior changes:+* Remove the deprecated `--stack-setup-yaml` command line argument in favor of `--setup-info-yaml`+ [#2647](https://github.com/commercialhaskell/stack/issues/2647)++* We now recommend checking in generated cabal files for repos. When generating lock files for+ extra-deps that only include `package.yaml` files, a deprecation warning will be generated.+ Also, those packages will no longer be included in the generated lock files.+ See [#5210](https://github.com/commercialhaskell/stack/issues/5210).++Other enhancements:+* Add `build-output-timestamps` flag in yaml. Setting it to true+ prefixes each build log output line with a timestamp.++* Show warning about `local-programs-path` with spaces on windows+ when running scripts. See + [#5013](https://github.com/commercialhaskell/stack/pull/5013)++* Add `ls dependencies json` which will print dependencies as JSON.+ `ls dependencies --tree` is now `ls dependencies tree`. See+ [#4424](https://github.com/commercialhaskell/stack/pull/4424)++* Remove warning for using Stack with GHC 8.8-8.10, and Cabal 3.0-3.2.++* Allow relative paths in `--setup-info-yaml` and tool paths+ [#3394](https://github.com/commercialhaskell/stack/issues/3394)++* Added the `--only-locals` flag. See+ [#5272](https://github.com/commercialhaskell/stack/issues/5272)++Bug fixes:++* Upgrade `pantry`: module mapping insertions into the database are now atomic.+ Previously, if you SIGTERMed at the wrong time while running a script, you+ could end up with an inconsistent database state.++* `--resolver global` doesn't retrieve snapshots list from the internet+ beause doesn't need it. See [#5103](https://github.com/commercialhaskell/stack/issues/5103)++* Fix using relative links in haddocks output. See+ [#4971](https://github.com/commercialhaskell/stack/issues/4971).+* Do not include generated cabal file information in lock files. See+ [#5045](https://github.com/commercialhaskell/stack/issues/5045).++* Use proper Hoogle executable path when installed automatically. See+ [#4905](https://github.com/commercialhaskell/stack/issues/4905)++* Fix GHC version for batched package unregistration. See+ [#4951](https://github.com/commercialhaskell/stack/issues/4951)++* Use Hoogle from the snapshot used and not the latest version. See+ [#4905](https://github.com/commercialhaskell/stack/issues/4905)++* Resolve "'stty' is not recognized". See+ [#4901](https://github.com/commercialhaskell/stack/issues/4901)++* Fix missing reconfigure check causing errors when a package gets+ used in multiple projects. See+ [#5147](https://github.com/commercialhaskell/stack/issues/5147)+ ## v2.1.3.1 Hackage-only release:@@ -9,6 +104,7 @@ * Support rio-0.1.11.0 * Add `stack.yaml` back to hackage sdist, and add `snapshot.yaml` + ## v2.1.3 **Changes since v2.1.1**@@ -59,7 +155,7 @@ * Expose package library when running tests. * Fix support for non-ASCII module names. See- [4938](https://github.com/commercialhaskell/stack/issues/4938)+ [#4938](https://github.com/commercialhaskell/stack/issues/4938) Other changes: @@ -202,7 +298,7 @@ use to avoid multiple runs of Stack from trampling each others' files. See [#2730](https://github.com/commercialhaskell/stack/issues/2730).-* Stack will check occassionally if there is a new version available and prompt+* Stack will check occasionally if there is a new version available and prompt the user to upgrade. This will not incur any additional network traffic, as it will piggy-back on the existing Hackage index updates. You can set `recommend-stack-upgrade: false` to bypass this. See@@ -233,7 +329,7 @@ * British English spelling of 'color' (colour) accepted as an alias for `--color`, `--stack-colors`, `stack ls stack-colors` at the command line and for `color:` and `stack-colors:` in yaml configuration files.-* New build option `--ddump-dir`. (See +* New build option `--ddump-dir`. (See [#4225](https://github.com/commercialhaskell/stack/issues/4225)) * Stack parses and respects the `preferred-versions` information from Hackage for choosing latest version of a package in some cases,@@ -678,7 +774,7 @@ conflicting versions of packages without issue. See [Stackage issue #3185](https://github.com/fpco/stackage/issues/3185). * When promoting packages from snapshot to local, we were- occassionally discarding the actual package location content and+ occasionally discarding the actual package location content and instead defaulting to pulling the package from the index. We now correctly retain this information. Note that if you were affected by this bug, you will likely need to delete the binary build cache
@@ -450,7 +450,7 @@ also known as *snapshots*. We mentioned the LTS resolvers, and you can get quite a bit of information about it at [https://www.stackage.org/lts](https://www.stackage.org/lts), including: -* The appropriate resolver value (`resolver: lts-11.22`, as is currently the latest LTS)+* The appropriate resolver value (`resolver: lts-14.27`, as is currently the latest LTS) * The GHC version used * A full list of all packages available in this snapshot * The ability to perform a Hoogle search on the packages in this snapshot@@ -467,15 +467,15 @@ ## Resolvers and changing your compiler version -Let's explore package sets a bit further. Instead of lts-11.22, let's change our+Let's explore package sets a bit further. Instead of lts-14.27, let's change our `stack.yaml` file to use [the latest nightly](https://www.stackage.org/nightly). Right now,-this is currently 2018-07-25 - please see the resolve from the link above to get the latest.+this is currently 2020-03-24 - please see the resolve from the link above to get the latest. Then, Rerunning `stack build` will produce: ``` michael@d30748af6d3d:~/helloworld$ stack build-Downloaded nightly-2018-07-31 build plan.+Downloaded nightly-2020-03-24 build plan. # build output ... ``` @@ -483,8 +483,8 @@ Continuous Integration (CI) setting, like on Travis. For example: ```-michael@d30748af6d3d:~/helloworld$ stack --resolver lts-11.22 build-Downloaded lts-11.22 build plan.+michael@d30748af6d3d:~/helloworld$ stack --resolver lts-14.27 build+Downloaded lts-14.27 build plan. # build output ... ``` @@ -520,7 +520,6 @@ At the time of writing: * `ghc-X.Y.Z`, for requiring a specific GHC version but no additional packages-* Experimental GHCJS support * Experimental custom snapshot support The most up-to-date information can always be found in the@@ -541,7 +540,7 @@ ``` Note that you can also unpack to the directory of your liking instead of-the current one by issueing:+the current one by issuing: ``` cueball:~$ stack unpack yackage-0.8.0 --to ~/work@@ -574,45 +573,6 @@ (Note: yackage does not currently support hpack, but you can also hpack-convert should you need to generate a package.yaml). -#### External Dependencies--Given that LTS Haskell and Stackage Nightly have ~1400 of the most common-Haskell packages, this will often be enough to build most packages. However,-at times, you may find that not all dependencies required may be available in-the Stackage snapshots.--Let's simulate an unsatisfied dependency by adding acme-missiles to the list of dependencies-the build requires. This is done by including it in the `Build-depends` section in the .cabal file-and then re-initing:--```-cueball:~/yackage-0.8.0$ stack init --force-# init failure output-```--stack has tested six different snapshots, and in every case discovered that-acme-missiles is not available. In the end it suggested that you use the-`--solver` command line switch if you want to use packages outside Stackage. So-let's give it a try:--```-cueball:~/yackage-0.8.0$ stack init --force --solver-# solver output ...-```--stack will complain that it needs a `cabal-install` installation. Let's get that:--```-cueball:~/yackage-0.8.0$ stack install cabal-install-```--Then run the above `stack init` command again and it will succeed.--As you can verify by viewing `stack.yaml`, three external dependencies were added-by stack init under the `extra-deps` field. Of course, you could have added the-external dependencies by manually editing `stack.yaml` but stack init does the-hard work for you.- #### Excluded Packages Sometimes multiple packages in your project may have conflicting requirements.@@ -626,10 +586,10 @@ To simulate a conflict we will use acme-missiles-0.3 in yackage and we will also copy `yackage.cabal` to another directory and change the name of the file and package to yackage-test. In this new package we will use acme-missiles-0.2-instead. Let's see what happens when we run solver:+instead. Let's see what happens when we re-run stack init: ```-cueball:~/yackage-0.8.0$ stack init --force --solver --omit-packages+cueball:~/yackage-0.8.0$ stack init --force --omit-packages # init failure output ... ``` @@ -697,70 +657,6 @@ Warning: Specified resolver could not satisfy all dependencies. Some external packages have been added as dependencies. You can suppress this message by removing it from stack.yaml ```-### stack solver--While `stack init` is used to create stack configuration file from existing-cabal files, `stack solver` can be used to fine tune or fix an existing stack-configuration file.--`stack solver` uses the existing file as a constraint. For example it will-use only those packages specified in the existing config file or use existing-external dependencies as constraints to figure out other dependencies.--Let's try `stack solver` to verify the config that we generated earlier with-`stack init`:--```-cueball:~/yackage-0.8.0$ stack solver-# solver output ...-```--It says there are no changes needed to your configuration. Notice that it also reports-`example/yackage-test.cabal` as missing from the config. It was purposely-omitted by `stack init` to resolve a conflict.--Sometimes `stack init` may not be able to give you a perfect configuration. In-that case, you can tweak the configuration file as per your requirements and then-run `stack solver`, it will check the file and suggest or apply any fixes-needed.--For example, if `stack init` ignored certain packages due to name conflicts or-dependency conflicts, the choice that `stack init` made may not be the correct-one. In that case you can revert the choice and use solver to fix things.--Let's try commenting out `.` and uncommenting `examples/` in our previously-generated `stack.yaml` and then run `stack solver`:--```-cueball:~/yackage-0.8.0$ stack solver-# solver failure output ...-```--Due to the change that we made, solver suggested some new dependencies.-By default it does not make changes to the config. As it suggested you can use-`--update-config` to make changes to the config.--NOTE: You should probably back up your `stack.yaml` before doing this, such as-committing to Git/Mercurial/Darcs.--Sometimes, you may want to use specific versions of certain packages for your-project. To do that you can fix those versions by specifying them in the-extra-deps section and then use `stack solver` to figure out whether it is-feasible to use those or what other dependencies are needed as a result.--If you want to change the resolver for your project, you can run-`stack solver --resolver <resolver name>` and it will figure out the changes needed for you.--Let's see what happens if we change the resolver to an older resolver - lts-2.22:--```-cueball:~/yackage-0.8.0$ stack solver --resolver lts-2.22-# solver failure output ...-```--As you can see, it automatically suggested changes in `extra-deps` due to the-change of resolver.- ## Different databases Time to take a short break from hands-on examples and discuss a little@@ -1247,7 +1143,7 @@ ``` michael@d30748af6d3d:~$ stack exec --package stm -- echo I installed the stm package via --package stm Run from outside a project, using implicit global project config-Using latest snapshot resolver: lts-3.2+Using latest snapshot resolver: lts-14.27 Writing global (non-project-specific) config file to: /home/michael/.stack/global/stack.yaml Note: You can change the snapshot via the resolver field there. I installed the stm package via --package stm@@ -1427,6 +1323,16 @@ project and want to access the package databases and configurations used by that project. See the next section for more information on configuration files. +### Platform-specific script issues++On Mac OSX:++- Avoid `{-# LANGUAGE CPP #-}` in stack scripts; it breaks the hashbang line+ ([GHC #6132](https://gitlab.haskell.org/ghc/ghc/issues/6132))++- Use a compiled executable, not another script, in the hashbang line.+ Eg `#!/usr/bin/env runhaskell` will work but `#!/usr/local/bin/runhaskell` would not.+ ### Loading scripts in ghci Sometimes you want to load your script in ghci REPL to play around with your@@ -1732,9 +1638,7 @@ * `stack update` will download the most recent set of packages from your package indices (e.g. Hackage). Generally, stack runs this for you automatically- when necessary, but it can be useful to do this manually sometimes (e.g.,- before running `stack solver`, to guarantee you have the most recent- upstream packages available).+ when necessary, but it can be useful to do this manually sometimes. * `stack unpack` is a command we've already used quite a bit for examples, but most users won't use it regularly. It does what you'd expect: downloads a tarball and unpacks it. It accept optional `--to` argument to specify@@ -1746,6 +1650,13 @@ per [our blog post](https://www.fpcomplete.com/blog/2016/05/stack-security-gnupg-keys). * `--no-signature` disables signing of packages+ * `username` and `password` can be read by environment++ ```bash+ export $HACKAGE_USERNAME="<username>"+ export $HACKAGE_PASSWORD="<password>"+ ```+ * `stack upgrade` will build a new version of stack from source. * `--git` is a convenient way to get the most recent version from master for those testing and living on the bleeding edge.@@ -1778,7 +1689,7 @@ To create a profiling report for an executable, e.g. `my-exe`, you can run - stack exec -- my-exe +RTS -p+ stack exec --profile -- my-exe +RTS -p For more fine-grained control of compilation options there are the `--library-profiling` and `--executable-profiling` flags which will turn on the@@ -1809,13 +1720,11 @@ use the `--trace` flag. Like `--profile` this compiles with profiling options, but adds the `+RTS -xc` runtime option. -### DWARF+### Debugging symbols -`stack` now supports debugging and profiling with-[DWARF information](https://ghc.haskell.org/trac/ghc/wiki/DWARF),-using the `--no-strip`, `--no-library-stripping`, and `--no-executable-stripping`-flags to disable the default behavior of removing such information from compiled-libraries and executables.+Building with debugging symbols in the [DWARF information](https://ghc.haskell.org/trac/ghc/wiki/DWARF) is supported by `stack`. This can be done by passing the flag `--ghc-options="-g"` and also to override the default behaviour of stripping executables of debugging symbols by passing either one of the following flags: `--no-strip`, `--no-library-stripping` or `--no-executable-stripping`.++In Windows GDB can be isntalled to debug an executable with `stack exec -- pacman -S gdb`. Windows visual studio compiler's debugging format PDB is not supported at the moment. This might be possible by [separating](https://stackoverflow.com/questions/866721/how-to-generate-gcc-debug-symbol-outside-the-build-target) debugging symbols and [converting](https://github.com/rainers/cv2pdb) their format. Or as an option when [using the LLVM backend](http://blog.llvm.org/2017/08/llvm-on-windows-now-supports-pdb-debug.html). ## More resources
@@ -2,7 +2,12 @@ # Signing key -Releases are signed with this key:+Releases are signed with the GPG key of the individual who builds+them. Authorized keys will always be signed by key ID 0x575159689BEFB442,+with the key and signature uploaded to the+[SKS keyserver pool](https://sks-keyservers.net/).++This is the public key block for 0x575159689BEFB442: ``` -----BEGIN PGP PUBLIC KEY BLOCK-----
@@ -15,9 +15,7 @@ [azure-simple](https://raw.githubusercontent.com/commercialhaskell/stack/stable/doc/azure/azure-simple.yml) file into `azure-pipelines.yml`. * For complex Azure configuration, you need to take the below linked- four files and put all of them into the `.azure` directory except- the `azure-pipelines.yml` file which should be put in the root of- the repository.+ four files and put all of them into the `.azure` directory. For a more detailed explanation, you can read further. @@ -32,14 +30,9 @@ with just the settings present in your `stack.yaml` file. * The complex Azure configuration is intended for projects that need to support multiple GHC versions and multiple OSes, such as open- source libraries to be released to Hackage. It tests against- cabal-install, as well as Stack on Linux and macOS. The- configuration is significantly more involved to allow for all of- this branching behavior. In the provided template, we use the Linux- build configuration to test against various combinations of- cabal-install and stack. The macOS and Windows configuration is used- only for testing Stack build configuration. These are the files for- the complex configuration:+ source libraries to be released to Hackage. It tests against Stack+ for different resolves on Linux, macOS and Windows. These are the+ files for the complex configuration: - [azure-pipelines.yml](https://raw.githubusercontent.com/commercialhaskell/stack/stable/doc/azure/azure-pipelines.yml) : This is the starter file used by the Azure CI. - [azure-linux-template.yml](https://raw.githubusercontent.com/commercialhaskell/stack/stable/doc/azure/azure-linux-template.yml) : Template for Azure Linux build - [azure-osx-template.yml](https://raw.githubusercontent.com/commercialhaskell/stack/stable/doc/azure/azure-osx-template.yml) : Template for Azure macOS build@@ -102,19 +95,14 @@ ``` yaml pool:- vmImage: ubuntu-16.04+ vmImage: ubuntu-latest ``` -The other popular options are `macOS-10.13`, `vs2017-win2016` for Mac+The other popular options are `macOS-latest`, `windows-latest` for Mac and Windows respectively. You can find the [complete list](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=vsts&tabs=yaml)-here.--Note that as of now, Azure CI doesn't offer any caching support. You-can use something like [cache-s3](https://github.com/fpco/cache-s3)-for explicit caching, although it may cost you. For a project with an-example usage of `cache-s3`, you can see the Azure configuration of-[stack](https://github.com/commercialhaskell/stack) repository.+here. You also have the option to select a specific supported ubuntu+version like `ubuntu-18.08`. ## Installing Stack @@ -136,19 +124,7 @@ - Install GHC using apt package manger. This method is only applicable for Debian based images. -See the [simple azure-script](https://raw.githubusercontent.com/commercialhaskell/stack/stable/doc/azure/azure-simple.yml)-for an example of the first option (letting Stack download GHC). Here,-we will show the second option:--```yaml-sudo add-apt-repository -y ppa:hvr/ghc-sudo apt-get update-sudo apt-get install cabal-install-$CABALVER ghc-$GHCVER-```--For the above commands to work, you need to set the `CABALVER` and-`GHCVER` environment variable properly.+But we only use the first method of using Stack to download GHC. ### Multiple GHC - parametrised builds @@ -156,34 +132,22 @@ `stack.yaml` files. If you don't want to put a specific `stack.yaml` for a particular resolver and still want to test it, you have specify your resolver argument in `ARGS` environment variable (you will see an-example below). For cabal based builds, you have to specify both-`GHCVER` and `CABALVER` environment variables.-+example below). ``` strategy: matrix:- stack-def:- BUILD: stack- STACK_YAML: stack.yaml- stack-lts-13:- BUILD: stack- STACK_YAML: stack-lts-13.yaml- cabal-8.4.4:- BUILD: cabal- GHCVER: 8.4.4- CABALVER: 2.4- cabal-8.6.5:- BUILD: cabal- GHCVER: 8.6.5- CABALVER: 2.4+ GHC 8.0:+ ARGS: "--resolver lts-9"+ GHC 8.2:+ ARGS: "--resolver lts-11"+ GHC 8.4:+ ARGS: "--resolver lts-12"+ GHC 8.6:+ ARGS: "--resolver lts-14"+ GHC 8.8:+ ARGS: "--resolver lts-15" nightly:- BUILD: stack ARGS: "--resolver nightly"- style:- BUILD: style- pedantic:- BUILD: pedantic- STACK_YAML: stack.yaml ``` ## Running tests@@ -191,8 +155,7 @@ After the environment setup, actual test running is simple: ```yaml-script:- - stack test+stack $ARGS test --bench --no-run-benchmarks --haddock --no-haddock-deps ``` ## Other details
@@ -184,19 +184,22 @@ ## Build output -When building a single target package (e.g., `stack build` in a project with-only one package, or `stack build package-name` in a multi-package project),-the build output from GHC will be hidden for building all dependencies, and-will be displayed for the one target package.+Starting with Stack 2.1, output of all packages being built scrolls by in a+streaming fashion. The output from each package built will be prefixed by the+package name, e.g. `mtl> Building ...`. This will include the output from+dependencies being built, not just targets. -By default, when building multiple target packages, the output from these will-end up in a log file instead of on the console unless it contains errors or-warnings, to avoid problems of interleaved output and decrease console noise.-If you would like to see this content instead, you can use the `--dump-logs`-command line option, or add `dump-logs: all` to your `stack.yaml` file.+To disable this behaviour, you can pass `--no-interleaved-output`, or add+`interleaved-output: false` to your `stack.yaml` file. When disabled: -Alternatively, starting with Stack 1.8, you can pass `--interleaved-output` to-see output of all packages being built scroll by in a streaming fashion. The-output from each package built will be prefixed by the package name, e.g. `mtl>-Building ...`. Note that, unlike the default output, this will include the-output from dependencies being built, not just targets.+ * When building a single target package (e.g., `stack build` in a project+ with only one package, or `stack build package-name` in a multi-package+ project), the build output from GHC will be hidden for building all+ dependencies, and will be displayed for the one target package.++ * By default, when building multiple target packages, the output from these+ will end up in a log file instead of on the console unless it contains+ errors or warnings, to avoid problems of interleaved output and decrease+ console noise. If you would like to see this content instead, you can use+ the `--dump-logs` command line option, or add `dump-logs: all` to your+ `stack.yaml` file.
@@ -81,7 +81,7 @@ the executable. When switching on this flag, it will usually cause all local packages to be- rebuilt (see [#1940](https://github.com/commercialhaskell/stack/issues/1940).+ rebuilt (see [#1940](https://github.com/commercialhaskell/stack/issues/1940)). 2. Before the build runs with `--coverage`, the contents of `stack path --local-hpc-root` gets deleted. This prevents old reports from getting mixed
@@ -5,6 +5,8 @@ You can use stack to visualize the dependencies between your packages and optionally also external dependencies. +First, you need [Graphviz](https://www.graphviz.org/). You can [get it here](https://www.graphviz.org/download/).+ As an example, let's look at `wreq`: ```
@@ -49,8 +49,8 @@ installed with the commands: ```-stack exec -- pacman -R mingw-w64-x86_64-make-stack exec -- pacman -R mingw-w64-x86_64-cmake+stack exec -- pacman -S mingw-w64-x86_64-make+stack exec -- pacman -S mingw-w64-x86_64-cmake ``` Even though make and cmake are then both installed into the same
@@ -47,8 +47,6 @@ * Cabal-the-library is used by stack to build your Haskell code. See the [Architecture: Plan Execution](architecture.md#plan-execution) section for more detail, including how the Cabal version is chosen.-* cabal-install (the executable) is used by stack for its dependency solver- functionality. * A .cabal file is provided for each package, and defines all package-level metadata just like it does in the cabal-install world: modules, executables, test suites, etc. No change at all on this front.@@ -76,39 +74,35 @@ ## I need to use a package (or version of a package) that is not available on hackage, what should I do? -Add it to the `packages` list in your project's `stack.yaml`, specifying the-package's source code location relative to the directory where your-`stack.yaml` file lives, e.g.+Add it to the +[`extra-deps`](yaml_configuration.md#extra-deps) list in your project's +`stack.yaml`, specifying the package's source code location relative to the +directory where your `stack.yaml` file lives, e.g. ```yaml resolver: lts-2.10 packages: - '.'+extra-deps: - third-party/proprietary-dep - github-version-of/conduit - patched/diagrams-extra-deps: [] ``` -The above example specifies that it should include the package at the root-directory (`'.'`), that the `proprietary-dep` package is found in the project's-`third-party` folder, that the `conduit` package is found in the project's-`github-version-of` folder, and that the `diagrams` package is found in the-project's `patched` folder. This autodetects changes and reinstalls the+The above example specifies that the `proprietary-dep` package is found in the +project's `third-party` folder, that the `conduit` package is found in the +project's `github-version-of` folder, and that the `diagrams` package is found +in the project's `patched` folder. This autodetects changes and reinstalls the package. To install packages directly from a Git repository, use e.g.: ```yaml-resolver: lts-2.10-packages:-- location:- git: https://github.com/githubuser/reponame.git+extra-deps:+ - git: https://github.com/githubuser/reponame.git commit: somecommitID ``` -Note that the `- '.'` line has been omitted, so the package in the root directory will not be used.- ## What is the meaning of the arguments given to stack build, test, etc? Those are the targets of the build, and can have one of three formats:@@ -129,13 +123,6 @@ Another would be to add the upstream package as a submodule to your project. -## Am I required to use a Stackage snapshot to use stack?--No, not at all. If you prefer dependency solving to curation, you can continue-with that workflow. Instead of describing the details of how that works here,-it's probably easiest to just say: run `stack init --solver` and look at the-generated stack.yaml.- ## How do I use this with sandboxes? Explicit sandboxing on the part of the user is not required by stack. All@@ -581,3 +568,19 @@ **Note that we're fixing `ghc-8.2.2` in this case; repeat for other versions as necessary.** You should apply this fix for the version of GHC that matches your resolver. Issue [#4009](https://github.com/commercialhaskell/stack/issues/4009) on GitHub goes into further detail.++## How do I install ghc in stack when it fails with the error: Missing ghc bindist for "linux64-ncurses6"?++Example Error:+```+No setup information found for ghc-8.6.4 on your platform.+This probably means a GHC bindist has not yet been added for OS key 'linux64-ncurses6'.+Supported versions: ghc-7.10.3, ghc-8.0.1, ghc-8.0.2, ghc-8.2.1, ghc-8.2.2+```++Most Linux distributions have standardized on providing libtinfo.so.6 (either directly or as a symlink to libncursesw.so.6). As such, there aren't GHC 8.6.* bindists that link to libncursesw.so.6 available. ++So creating a symlink to libncursesw.so.6 as libtinfo.so.6 can prevent this error (root privileges might be required).+```+ln -s /usr/lib/libncursesw.so.6 /usr/lib/libtinfo.so.6+```
@@ -1,164 +1,5 @@ <div class="hidden-warning"><a href="https://docs.haskellstack.org/"><img src="https://cdn.jsdelivr.net/gh/commercialhaskell/stack/doc/img/hidden-warning.svg"></a></div> -# GHCJS (experimental)--To use GHCJS with stack, place a GHCJS version in the [`compiler`](yaml_configuration.md#compiler) field of `stack.yaml`. After this, some stack commands should work with GHCJS. In particular:--* `stack setup` will install GHCJS from source and boot it, which takes a long time.--* `stack build` will compile your code to JavaScript. In particular, the generated code for an executable ends up in `$(stack path --local-install-root)/bin/EXECUTABLE.jsexe/all.js` (bash syntax, where `EXECUTABLE` is the name of your executable).--You can also build existing stack projects which target GHC, and instead build-them with GHCJS. For example: `stack build --compiler ghcjs-0.2.0.9006020_ghc-7.10.3`--There are advanced options for `stack setup`: `--ghcjs-boot-options` (one word at a time) and `--[no-]ghcjs-boot-clean`-which will pass your settings down to the `ghcjs-boot`. You will need to know exactly what you are doing with them. --Sidenote: If you receive a message like-`The program 'ghcjs' version >=0.1 is required but the version of .../ghcjs could not be determined.`,-then you may need to install a different version of `node`. See-[issue #1496](https://github.com/commercialhaskell/stack/issues/1496).--## Example Configurations--### GHCJS repacked for snapsnots lts-8 and lts-9--Please see the [ghcjs-stack-dist repository](https://github.com/matchwood/ghcjs-stack-dist) for `lts-8` and `lts-9` configurations and refer to the [README](https://github.com/matchwood/ghcjs-stack-dist/blob/master/README.md) for common issues.--Support for `> lts-9` snapshots (`GHC 8.2` and above) is currently [work in progress](https://github.com/matchwood/ghcjs-stack-dist/issues/10).--### GHCJS repacked for snapsnots < lts-8--These versions of GHCJS were created by-[Marcin Tolysz](https://github.com/tolysz), and were particularly crafted to-include package versions which match those expected by particular stackage-snapshots.--For `ghcjs` based on `ghc-7.10.3` one could try:-```yaml-resolver: lts-6.30-compiler: ghcjs-0.2.0.9006030_ghc-7.10.3-compiler-check: match-exact--setup-info:- ghcjs:- source:- ghcjs-0.2.0.9006030_ghc-7.10.3:- url: http://ghcjs.tolysz.org/lts-6.30-9006030.tar.gz- sha1: 2371e2ffe9e8781808b7a04313e6a0065b64ee51-```--Or for the latest one based on `ghc-8.0.1` (with more features):-```yaml-resolver: lts-7.19-compiler: ghcjs-0.2.1.9007019_ghc-8.0.1-compiler-check: match-exact--setup-info:- ghcjs:- source:- ghcjs-0.2.1.9007019_ghc-8.0.1:- url: http://ghcjs.tolysz.org/ghc-8.0-2017-02-05-lts-7.19-9007019.tar.gz- sha1: d2cfc25f9cda32a25a87d9af68891b2186ee52f9-```-The latter can be generated via: https://github.com/tolysz/prepare-ghcjs-the former is a bit more manual. Those bundles are only tested against the latest `node-7.4.0`.--In order to correctly boot and use ghcjs, one might need to install `alex` `happy` `hscolour` `hsc2hs` with the normal ghc.--Older resolvers:--|resolver|ghcjs|url|sha1|-|---|---|---|---|-| lts-7.19 |0.2.1| http://ghcjs.tolysz.org/ghc-8.0-2017-02-05-lts-7.19-9007019.tar.gz | d2cfc25f9cda32a25a87d9af68891b2186ee52f9 |-| lts-7.15 |0.2.1| http://ghcjs.tolysz.org/ghc-8.0-2017-01-11-lts-7.15-9007015.tar.gz | 30d34e9d704bdb799066387dfa1ba98b8884d932 |-| lts-7.14 |0.2.1| http://ghcjs.tolysz.org/ghc-8.0-2016-12-25-lts-7.14-9007014.tar.gz | 530c4ee5e19e2874e128431c7ad421e336df0303 |-| lts-7.13 |0.2.1| http://ghcjs.tolysz.org/ghc-8.0-2016-12-18-lts-7.13-9007013.tar.gz | 0d2ebe0931b29adca7cb9d9b9f77d60095bfb864 |-| lts-7.8 || http://ghcjs.tolysz.org/ghc-8.0-2016-11-07-lts-7.8-9007008.tar.gz | 190300a3725cde44b2a08be9ef829f2077bf8825 |-| lts-7.7 || http://ghcjs.tolysz.org/ghc-8.0-2016-11-03-lts-7.7-9007007.tar.gz | ce169f85f1c49ad613ae77fc494d5565452ff59a |-| lts-7.5 || http://ghcjs.tolysz.org/ghc-8.0-2016-10-24-lts-7.5-9007005.tar.gz | 450e81028d7f1eb82a16bc4b0809f30730c3e173 |-| lts-7.4 || http://ghcjs.tolysz.org/ghc-8.0-2016-10-22-lts-7.4-9007004.tar.gz | ed77b3c15fedbadad5ab0e0afe1bd42c0a8695b4 |-| lts-7.3 || http://ghcjs.tolysz.org/ghc-8.0-2016-10-11-lts-7.3-9007003.tar.gz | 3196fd5eaed670416083cf3678396d02c50096de |-| lts-7.2 || http://ghcjs.tolysz.org/ghc-8.0-2016-10-01-lts-7.2-9007002.tar.gz | a41ae415328e2b257d40724d13d1386390c26322 | -| lts-7.1 || http://ghcjs.tolysz.org/ghc-8.0-2016-09-26-lts-7.1-9007001-mem.tar.gz | e640724883238593e2d2f7f03991cb413ec0347b |-| lts-6.25 | 0.2.0 | http://ghcjs.tolysz.org/lts-6.25-9006025.tar.gz | 3c87228579b55c05e227a7876682c2a7d4c9c007 |-| lts-6.21 || http://ghcjs.tolysz.org/lts-6.21-9006021.tar.gz | 80b83f85dcec182093418e843979f4cee092fa85 |-| lts-6.20 || http://ghcjs.tolysz.org/lts-6.20-9006020.tar.gz | a6cea90cd8121eee3afb201183c6e9bd6bacd94a |-| lts-6.19 || http://ghcjs.tolysz.org/lts-6.19-9006019.tar.gz | ef4264d5a93b269ee4ec8f9d5139da030331d65a |-| lts-6.18 || http://ghcjs.tolysz.org/lts-6.18-9006018.tar.gz | 3e9f345116c851349a5a551ffd94f7e0b74bfabb |--If you do not use the same resolver, say, an older LTS snapshot, you will get-some warnings like this:--```-Ignoring that the GHCJS boot package "aeson" has a different version, 0.9.0.1, than the resolver's wanted version, 0.8.0.2-Ignoring that the GHCJS boot package "attoparsec" has a different version, 0.13.0.1, than the resolver's wanted version, 0.12.1.6-Ignoring that the GHCJS boot package "scientific" has a different version, 0.3.3.8, than the resolver's wanted version, 0.3.4.2-...-```--These warnings can usually be safely ignored, but they do indicate a divergence-between your snapshot's packages, and those that are being used to compile your-project. You will normally get these warnings when using a GHCJS tarball that-has not been packaged with a particular snapshot in mind.--### GHCJS (old base)--If you want to build some older GHCJS packages, you may need to use the "old-base" GHCJS. To do this, use the following compiler info:--```yaml-compiler: ghcjs-0.1.0.20150924_ghc-7.10.2-compiler-check: match-exact-```--### Custom installed GHCJS--In order to use a GHCJS installed on your PATH, just add the following to your `stack.yaml`:--```yaml-compiler: ghcjs-0.2.0_ghc-7.10.2-```--(Or, `ghcjs-0.1.0_ghc-7.10.2` if you are working with an older version)--This is particularly useful when you have built GHCJS from source.--## Project with both client and server--For projects with both a server and client, the recommended project-organization is to put one or both of your `stack.yaml` files in-sub-directories. This way, you can use the current working directory to-specify whether you're working on the client or server. This will also allow-more straightforward editor tooling, once projects like `ghc-mod` and-`haskell-ide-engine` support GHCJS.--For example, here's what a script for building both client and server looks-like:--```bash-#!/bin/bash--# Build the client-stack build --stack-yaml=client/stack.yaml--# Copy over the javascript-rm -f server/static/all.js-cp $(stack path --stack-yaml=client/stack.yaml --local-install-root)/bin/client.jsexe/all.js server/static/all.js--# Build the server-stack build --stack-yaml=server/stack.yaml-```--You can also put both the yaml files in the same directory, and have e.g.-`ghcjs-stack.yaml`, but this won't work well with editor integrations.--## Using stack without a snapshot--If you don't want to use a snapshot, instead place the ghcjs version in the `resolver` field of your `stack.yaml`. This is also necessary when using stack `< 0.1.8`.--## Setting up GHCJS on Windows+# GHCJS (removed) -If `stack setup` command fails to successfully complete with message: `commitBuffer: invalid argument (invalid character)`, it means you have a locale problem.-This problem is not exclusive to GHCJS, and might happen also during other builds. A workaround is to set _Language for non-Unicode programs_ to _English (US)_.-For details see [stack issue #1448](https://github.com/commercialhaskell/stack/issues/1448).+GHCJS support is no longer included in Stack as of version 2.3.
@@ -32,7 +32,6 @@ will make `stack install` and `stack upgrade` work correctly out of the box. * [Windows 64-bit Installer](https://get.haskellstack.org/stable/windows-x86_64-installer.exe)- * [Windows 32-bit Installer](https://get.haskellstack.org/stable/windows-i386-installer.exe) If in doubt: you should prefer the 64-bit installer. @@ -45,7 +44,6 @@ * Download the latest release: * [Windows 64-bit](https://get.haskellstack.org/stable/windows-x86_64.zip)- * [Windows 32-bit](https://get.haskellstack.org/stable/windows-i386.zip) * Unpack the archive and place `stack.exe` somewhere on your `%PATH%` (see [Path section below](#path)) and you can then run `stack` on the command line.@@ -141,8 +139,8 @@ There is also an unofficial-[Fedora Copr repo](https://copr.fedoraproject.org/coprs/petersen/stack/) which-can be enabled with: `sudo dnf copr enable petersen/stack`. Note that this Stack+[Fedora Copr repo](https://copr.fedoraproject.org/coprs/petersen/stack2/) which+can be enabled with: `sudo dnf copr enable petersen/stack2`. Note that this Stack version may lag behind, so we recommend running `stack upgrade` after installing it. @@ -244,7 +242,7 @@ (note: requires libgmp.so.10, and will not work on some older distributions that have libgmp.so.3, such as CentOS 6) - * [Linux ARMv7](https://get.haskellstack.org/stable/linux-arm.tar.gz)+ <!-- * [Linux ARMv7](https://get.haskellstack.org/stable/linux-arm.tar.gz) --> * [Linux AArch64](https://get.haskellstack.org/stable/linux-aarch64.tar.gz) @@ -313,21 +311,32 @@ If you're attempting to install stack from within China: -* As of 2018-10-24, the download link has limited connectivity from within mainland China. If this is the case, please proceed by manually downloading (ideally via a VPN) and installing stack per the instructions found on this page pertinent to your OS.+* As of 2020-02-24, the download link has limited connectivity from within mainland China. If this is the case, please proceed by manually downloading (ideally via a VPN) and installing stack per the instructions found on this page pertinent to your OS. * After install, your ~/.stack/config.yaml will need to be configured before stack can download large files consistently from within China (without reliance on a VPN). Please add the following to the bottom of the ~/.stack/config.yaml file (for Windows: use the %STACK_ROOT%\config.yaml): ``` ###ADD THIS IF YOU LIVE IN CHINA-setup-info: "http://mirrors.tuna.tsinghua.edu.cn/stackage/stack-setup.yaml"+setup-info-locations: +- "http://mirrors.tuna.tsinghua.edu.cn/stackage/stack-setup.yaml" urls: latest-snapshot: http://mirrors.tuna.tsinghua.edu.cn/stackage/snapshots.json- lts-build-plans: http://mirrors.tuna.tsinghua.edu.cn/stackage/lts-haskell/- nightly-build-plans: http://mirrors.tuna.tsinghua.edu.cn/stackage/stackage-nightly/+ package-indices:- - name: Tsinghua- download-prefix: http://mirrors.tuna.tsinghua.edu.cn/hackage/package/- http: http://mirrors.tuna.tsinghua.edu.cn/hackage/00-index.tar.gz+ - download-prefix: http://mirrors.tuna.tsinghua.edu.cn/hackage/+ hackage-security:+ keyids:+ - 0a5c7ea47cd1b15f01f5f51a33adda7e655bc0f0b0615baa8e271f4c3351e21d+ - 1ea9ba32c526d1cc91ab5e5bd364ec5e9e8cb67179a471872f6e26f0ae773d42+ - 280b10153a522681163658cb49f632cde3f38d768b736ddbc901d99a1a772833+ - 2a96b1889dc221c17296fcc2bb34b908ca9734376f0f361660200935916ef201+ - 2c6c3627bd6c982990239487f1abd02e08a02e6cf16edb105a8012d444d870c3+ - 51f0161b906011b52c6613376b1ae937670da69322113a246a09f807c62f6921+ - 772e9f4c7db33d251d5c6e357199c819e569d130857dc225549b40845ff0890d+ - aa315286e6ad281ad61182235533c41e806e5a787e0b6d1e7eef3f09d137d2e9+ - fe331502606802feac15e514d9b9ea83fee8b6ffef71335479a2e68d84adc6b0+ key-threshold: 3+ ignore-expiry: no ``` ## Using an http proxy@@ -358,3 +367,25 @@ wget -qO- https://get.haskellstack.org/ | sh -s - -f * Manually follow the steps above to download the newest binaries from the release page and replace the old binary.++## Install Older Versions++To install a specific version of stack, navigate to the desired version on +[the GitHub release page](https://github.com/fpco/stack/releases),+and click the appropriate link under its "Assets" drop-down menu.++Alternatively, use the URL +`https://github.com/commercialhaskell/stack/releases/download/vVERSION/stack-VERSION-PLATFORM.EXTENSION`.+For example, the tarball for stack 2.1.0.1, osx-x86_64 is at+`https://github.com/commercialhaskell/stack/releases/download/v2.1.0.1/stack-2.1.0.1-osx-x86_64.tar.gz`.++Here's a snippet for `appveyor.yml` files, borrowed from `dhall`'s +[`appveyor.yml`](https://github.com/dhall-lang/dhall-haskell/blob/1079b7a3a7a6922f72a373e47daf6f1b74f128b1/appveyor.yml).+Change the values of PATH and VERSION as needed.++ install:+ - set PATH=C:\Program Files\Git\mingw64\bin;%PATH%+ - curl --silent --show-error --output stack.zip --location "https://github.com/commercialhaskell/stack/releases/download/v%STACK_VERSION%/stack-%STACK_VERSION%-windows-x86_64.zip"+ - 7z x stack.zip stack.exe+ - stack setup > nul+ - git submodule update --init --recursive
@@ -67,9 +67,6 @@ extra-deps: - size: 1442 url: https://hackage.haskell.org/package/acme-missiles-0.3.tar.gz- cabal-file:- size: 613- sha256: 2ba66a092a32593880a87fb00f3213762d7bca65a687d45965778deb8694c5d1 name: acme-missiles version: '0.3' sha256: e563d8b524017a06b32768c4db8eff1f822f3fb22a90320b7e414402647b735b@@ -150,9 +147,6 @@ completed: size: 1442 url: https://hackage.haskell.org/package/acme-missiles-0.3.tar.gz- cabal-file:- size: 613- sha256: 2ba66a092a32593880a87fb00f3213762d7bca65a687d45965778deb8694c5d1 name: acme-missiles version: '0.3' sha256: e563d8b524017a06b32768c4db8eff1f822f3fb22a90320b7e414402647b735b
@@ -86,12 +86,11 @@ $ nix-instantiate --eval -E "with import <nixpkgs> {}; lib.attrNames haskell.compiler" ``` -Alternatively, install `nix-repl`, a convenient tool to explore+Alternatively, use `nix repl`, a convenient tool to explore nixpkgs: ```sh-$ nix-env -i nix-repl-$ nix-repl+$ nix repl ``` In the REPL, load nixpkgs and get the same information through@@ -102,7 +101,7 @@ nix-repl> haskell.compiler.ghc<Tab> ``` -You can type and evaluate any nix expression in the nix-repl, such as+You can type and evaluate any nix expression in the nix repl, such as the one we gave to `nix-instantiate` earlier. **Note:** currently, stack only discovers dynamic and static libraries
@@ -18,7 +18,7 @@ packages. ### Issues Referenced- - https://github.com/commercialhaskell/stack/issues/105+ - <https://github.com/commercialhaskell/stack/issues/105> ## Passing Flags to Cabal @@ -50,12 +50,12 @@ ### Issues Referenced- - https://github.com/commercialhaskell/stack/issues/191- - https://github.com/commercialhaskell/stack/issues/417- - https://github.com/commercialhaskell/stack/issues/335- - https://github.com/commercialhaskell/stack/issues/301- - https://github.com/commercialhaskell/stack/issues/365- - https://github.com/commercialhaskell/stack/issues/105+ - <https://github.com/commercialhaskell/stack/issues/191>+ - <https://github.com/commercialhaskell/stack/issues/417>+ - <https://github.com/commercialhaskell/stack/issues/335>+ - <https://github.com/commercialhaskell/stack/issues/301>+ - <https://github.com/commercialhaskell/stack/issues/365>+ - <https://github.com/commercialhaskell/stack/issues/105> ## Selecting a Resolver @@ -75,8 +75,8 @@ :TODO: Document `--solver` ### Issues Referenced- - https://github.com/commercialhaskell/stack/issues/468- - https://github.com/commercialhaskell/stack/issues/464+ - <https://github.com/commercialhaskell/stack/issues/468>+ - <https://github.com/commercialhaskell/stack/issues/464> ## Using git Repositories @@ -86,8 +86,8 @@ information. ### Issues Referenced- - https://github.com/commercialhaskell/stack/issues/254- - https://github.com/commercialhaskell/stack/issues/199+ - <https://github.com/commercialhaskell/stack/issues/254>+ - <https://github.com/commercialhaskell/stack/issues/199> ## Private Hackage Working with a private Hackage is currently supported in certain situations.@@ -105,16 +105,16 @@ For further information see [YAML configuration](yaml_configuration.md) ### Issues Referenced- - https://github.com/commercialhaskell/stack/issues/445- - https://github.com/commercialhaskell/stack/issues/565+ - <https://github.com/commercialhaskell/stack/issues/445>+ - <https://github.com/commercialhaskell/stack/issues/565> ## Custom Snapshots See [Custom Snapshots](custom_snapshot.md). ### Issues Referenced- - https://github.com/commercialhaskell/stack/issues/111- - https://github.com/commercialhaskell/stack/issues/253- - https://github.com/commercialhaskell/stack/issues/137+ - <https://github.com/commercialhaskell/stack/issues/111>+ - <https://github.com/commercialhaskell/stack/issues/253>+ - <https://github.com/commercialhaskell/stack/issues/137> ## Intra-package Targets Stack supports intra-package targets, similar to `cabal build COMPONENTS` for@@ -129,4 +129,4 @@ Note: this does require prefixing the component name with the package name. ### Issues referenced- - https://github.com/commercialhaskell/stack/issues/201+ - <https://github.com/commercialhaskell/stack/issues/201>
@@ -13,23 +13,6 @@ * Package location specification (in the `extra-deps` field and inside snapshots) * Snapshot specification, for creating custom snapshots -## Freeze command--As you'll see throughout this document, there is a lot of additional-information that can be provided to Stack to make the configuration-more reproducible and faster to parse. However, it's tedious to-specify these values manually. Therefore, the recommended workflow is:--* Manually write the simple version of a configuration value-* Use `stack freeze` to obtain the more reproducible version--The standard `stack freeze` will operate on your `stack.yaml` file, and provide-you with updated `resolver` and `extra-deps` values, if relevant. If you run-`stack freeze --snapshot`, it will provide you with an update snapshot file.--New contents will be printed to `stdout` instead of modifying your existing-files to avoid mutation of user-created files.- ## Snapshot location There are essentially four different ways of specifying a snapshot@@ -55,9 +38,9 @@ sha256: 781ea577595dff08b9c8794761ba1321020e3e1ec3297fb833fe951cce1bee11 ``` -Where the `size` is the number of bytes in the file, and `sha256` is-its SHA256 hash. This information can automatically be generated with-the [`stack freeze`](#freeze-command) command.+Where the `size` is the number of bytes in the file, and `sha256` is its SHA256+hash. If not provided, the information will automatically be generated and+stored in a lock file. ## Package location @@ -69,8 +52,7 @@ All three of these formats support optional tree metadata to be added, which can be used for reproducibility and faster downloads. This-information can automatically be generated with the [`stack-freeze`](#freeze-command) command.+information can automatically be generated in a lock file. ### Hackage @@ -111,7 +93,7 @@ equally reproducible build plans. Finally, you can include the Pantry tree information. The following-was generated with `stack freeze`:+would be generated and stored in the lock file: ```yaml - hackage: acme-missiles-0.3@sha256:2ba66a092a32593880a87fb00f3213762d7bca65a687d45965778deb8694c5d1,613@@ -172,48 +154,6 @@ explicitly specified if a required package is found in the top-level directory of the repository. -Using the `stack freeze` command will add in additional information,-including not only the Pantry tree hash, but also package metadata-which can allow Stack to work faster by bypassing cabal file-parses. For example, this:--```yaml-extra-deps:-- git: git@github.com:yesodweb/wai- commit: 2f8a8e1b771829f4a8a77c0111352ce45a14c30f- subdirs:- - auto-update- - wai-```--Would be converted into:--```yaml-extra-deps:-- subdir: auto-update- cabal-file:- size: 1219- sha256: c07b2b1a2df1199f83eef819ac9bb067567e100b60586a52f8b92fc733ae3a6d- name: auto-update- version: 0.1.2.1- git: git@github.com:yesodweb/wai- pantry-tree:- size: 687- sha256: 26377897f35ccd3890b4405d72523233717afb04d62f2d36031bf6b18dcef74f- commit: 2f8a8e1b771829f4a8a77c0111352ce45a14c30f-- subdir: wai- cabal-file:- size: 1717- sha256: 7b46e7a8b121d668351fa8a684810afadf58c39276125098485203ef274fd056- name: wai- version: 3.0.2.3- git: git@github.com:yesodweb/wai- pantry-tree:- size: 10299- sha256: ce33fddab13592c847fbd7acd1859dfcbb9aeb6c212db3cee27c909fa3f3ae44- commit: 2f8a8e1b771829f4a8a77c0111352ce45a14c30f-```- #### Limited [git-annex](https://git-annex.branchable.com) support Pantry does not support [git-annex](https://git-annex.branchable.com). This is@@ -254,58 +194,6 @@ sha256: e563d8b524017a06b32768c4db8eff1f822f3fb22a90320b7e414402647b735b ``` -With the `stack freeze` command, this would be replaced with:--```yaml-extra-deps:-- size: 1540- url: https://hackage.haskell.org/package/acme-dont-1.1.tar.gz- cabal-file:- size: 602- sha256: 8264ad3e5113d3e0417b46e71d5a9c0914a1f03b5b81319cc329f1dc0f49b96c- name: acme-dont- version: '1.1'- sha256: c32231ff8548bccd4f3bafcc9b1eb84947a2e5e0897c50c048e0e7609fc443ce- pantry-tree:- size: 206- sha256: 79dbeddaf0fd507611687cefe9511c8fda489849fb0cac3894925716936290b2-- size: 285152- subdir: wai- url: http://github.com/yesodweb/wai/archive/2f8a8e1b771829f4a8a77c0111352ce45a14c30f.zip- cabal-file:- size: 1717- sha256: 7b46e7a8b121d668351fa8a684810afadf58c39276125098485203ef274fd056- name: wai- version: 3.0.2.3- sha256: 3b6eb04f3763ca16432f3ab2135d239161fbe2c8811b8cd1778ffa67469289ba- pantry-tree:- size: 10296- sha256: ce431f1a22fcda89375ba5e35e53aee968eea23d1124fcba7cb9eae426daa2db-- size: 285152- subdir: warp- url: http://github.com/yesodweb/wai/archive/2f8a8e1b771829f4a8a77c0111352ce45a14c30f.zip- cabal-file:- size: 6648- sha256: e3f01fd7417af923fd30962e9e6a4fe4de41ebc5e02af9819067fed79c9c6575- name: warp- version: 3.0.13.1- sha256: 3b6eb04f3763ca16432f3ab2135d239161fbe2c8811b8cd1778ffa67469289ba- pantry-tree:- size: 4292- sha256: d6b1def306a042b5fc500930302533a3ea828e916c99cbd82c0b7e2c4e3a8e09-- size: 1442- filepath: acme-missiles-0.3.tar.gz- cabal-file:- size: 613- sha256: 2ba66a092a32593880a87fb00f3213762d7bca65a687d45965778deb8694c5d1- name: acme-missiles- version: '0.3'- sha256: e563d8b524017a06b32768c4db8eff1f822f3fb22a90320b7e414402647b735b- pantry-tree:- size: 226- sha256: 614bc0cca76937507ea0a5ccc17a504c997ce458d7f2f9e43b15a10c8eaeb033-```- ## Snapshots _NOTE_ Stack has supported custom snapshots properly since version@@ -366,41 +254,6 @@ identify the snapshot internally. It is often reasonably efficient to modify a custom snapshot, due to stack sharing snapshot packages whenever possible. -Running the `stack freeze --snapshot` command yields the following-output:--```yaml-flags:- unordered-containers:- debug: true-ghc-options:- warp:- - -O2-packages:-- hackage: unordered-containers-0.2.7.1@sha256:7a1ceb6d88c0f16ec417f28dac16f6dc7b10e88fbb536a74d84941ad2f57b74b,4367- pantry-tree:- size: 1286- sha256: 8a8f745cacae3c11a9c6e6c2fcefc95a13d0c153a8e14b4d28485db1b59d9ef3-- hackage: hashable-1.2.4.0@sha256:33a49b3ea87cc4a0c89a4fd48f19e4807d8c620aff710a048a28cf7d9c9b4620,4271- pantry-tree:- size: 1325- sha256: cb05c31a8ec43f727004e5a6c8e35ff92e0515855a85cb01fa73623683ee4b33-- hackage: text-1.2.2.1@sha256:1c6ffad395d1674915cc9fda1d3b8f202ddcbfda7c341eb8bd99de67d3283bf9,5724- pantry-tree:- size: 7376- sha256: ac2601c49cf7bc0f5d66b2793eddc8352f51a6ee989980827a0d0d8169700a03-hidden:- warp: false- wai: true-drop-packages:-- wai-extra-compiler: ghc-8.0.1-resolver:- size: 515969- url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/8/21.yaml- sha256: 2ec73d520d3e55cb753eaca11a72a9ce95bd9ba7ccaf16de1150d0130a50a5a1-```- ### Overriding the compiler The following snapshot specification will be identical to `lts-7.1`, but instead@@ -462,13 +315,3 @@ text: developer: true ```--## Updating frozen information--Suppose you're depending on `foo-1.2.3` from Hackage, and have used `stack-freeze` on your file. Now you'd like to upgrade to `foo-1.2.4`. Doing so-requires you to:--* Change the version number specified to `1.2.4`-* Remove any freeze information that may conflict, like cabal file info, pantry tree, etc-* Rerun the `stack freeze` command to generate the new freeze information
@@ -104,7 +104,7 @@ the interim, the build plan generated should be the same. \* There's at least one hole in this theory today, which is Hackage revisions.-When you specify `extra-deps: [acme-missiles-0.3]`, it doesnt' specify which+When you specify `extra-deps: [acme-missiles-0.3]`, it doesn't specify which revision of the cabal file to use, and Stack will just choose the latest. Stack version 1.6 added the ability to specify exact revisions of cabal files, but this isn't enforced as a requirement as it's so different from the way most@@ -134,3 +134,7 @@ need to add it explicitly to your `stack.yaml` file: it's already there implicitly via the `resolver` setting. This is what you do the majority of the time, such as when you add `vector` or `mtl` as a `build-depends` value.++## Should I check in generated cabal files?++Yes, you should. This recommendation was changed in [issue #5210](https://github.com/commercialhaskell/stack/issues/5210), please see the discussion there.
@@ -61,7 +61,6 @@ * Stackage Nightly snapshot, e.g. `resolver: nightly-2015-06-16` * No snapshot, just use packages shipped with the compiler * For GHC this looks like `resolver: ghc-7.10.2`- * For GHCJS this looks like `resolver: ghcjs-0.1.0_ghc-7.10.2`. * Custom snapshot, via a URL or relative file path. (See [pantry docs](pantry.md) for more information.) Each of these resolvers will also determine what constraints are placed on the@@ -345,8 +344,8 @@ snapshots failing to work. Note: since Stack v2.1.3, `ignore-expiry` was changed to `true` by-default. For more information on this change, see [issue-#4928](https://github.com/commercialhaskell/stack/issues/4928).+default. For more information on this change, see+[issue #4928](https://github.com/commercialhaskell/stack/issues/4928). ### system-ghc @@ -443,14 +442,12 @@ Overrides the compiler version in the resolver. Note that the `compiler-check` flag also applies to the version numbers. This uses the same syntax as compiler-resolvers like `ghc-7.10.2` or `ghcjs-0.1.0.20150924_ghc-7.10.2` (version used-for the 'old-base' version of GHCJS). While it's useful to override the-compiler for a variety of reasons, the main usecase is to use GHCJS with a-stackage snapshot, like this:+resolvers like `ghc-8.6.5`. This can be used to override the+compiler for a Stackage snapshot, like this: ```yaml-resolver: lts-3.10-compiler: ghcjs-0.1.0.20150924_ghc-7.10.2+resolver: lts-14.20+compiler: ghc-8.6.4 compiler-check: match-exact ``` @@ -617,8 +614,9 @@ * `integersimple`: Use a GHC bindist that uses [integer-simple instead of GMP](https://ghc.haskell.org/trac/ghc/wiki/ReplacingGMPNotes) * any other value: Use a custom GHC bindist. You should specify- [setup-info](#setup-info) so `stack setup` knows where to download it, or- pass the `stack setup --ghc-bindist` argument on the command-line+ [setup-info](#setup-info) or [setup-info-locations](#setup-info-locations) + so `stack setup` knows where to download it,+ or pass the `stack setup --ghc-bindist` argument on the command-line This option is incompatible with `system-ghc: true`. @@ -630,14 +628,92 @@ determined automatically, but you can override the autodetected value here. Possible arguments include `standard`, `gmp4`, `tinfo6`, and `nopie`. +### setup-info-locations++(Since 2.3)++Possible usages of this config are:+1. Using `stack` offline or behind a firewall+2. Extending the tools known to `stack` such as cutting-edge versions of `ghc` or builds for custom linux distributions.++The `setup-info` dictionary specifies locations for installation of Haskell-related tooling - it maps `(Tool, Platform, Version)` to the location where it can be obtained, such as `(GHC, Windows64, 8.6.5)` to the url hosting the `*.tar.xz` for GHC's installation.++By default, it's obtained from [stack-setup-2.yaml](https://github.com/commercialhaskell/stackage-content/raw/master/stack/stack-setup-2.yaml).++The `setup-info` dictionary is constructed in the following order:+1. `setup-info` yaml configuration - inline config+2. `--setup-info-yaml` command line arguments - urls or paths, multiple locations may be specified.+3. `setup-info-locations` yaml configuration - urls or paths++The first location which specifies the location of a tool `(Tool, Platform, Version)` takes precedence, so one can extend the default tools with a fallback to the default `setup-info` location:++```yaml+setup-info-locations:+- C:/stack-offline/my-stack-setup.yaml+- relative/inside/my/project/setup-info.yaml+- \\smbShare\stack\my-stack-setup.yaml+- http://stack-mirror.com/stack-setup.yaml+- https://github.com/commercialhaskell/stackage-content/raw/master/stack/stack-setup-2.yaml+```++The default `setup-info` location is included only if no locations in the `setup-info-locations` config or the `--setup-info-yaml` command line argument were specified.++Thus the following will cause `stack setup` not to consult github for the `setup-info`:+```yaml+setup-info-locations:+- C:/stack-offline/my-stack-setup.yaml+```++```yaml+setup-info-locations: []+```++Relative paths are resolved relative to the `stack.yaml` file - either in the local project or the global `stack.yaml` in the stack directory.++Relative paths may also be used inside paths to tool installs - such as for ghc or 7z, which allows vendoring the tools inside a monorepo.+For example:++Directory structure:+```+- src/+- installs/+ - my-stack-setup.yaml+ - 7z.exe+ - 7z.dll+ - ghc-8.2.2.tar.xz+- stack.yaml+```++In the project's `stack.yaml`:+```yaml+setup-info-locations:+- installs/my-stack-setup.yaml+```++In `installs/my-stack-setup.yaml`:+```yaml+sevenzexe-info:+ url: "installs/7z.exe"++sevenzdll-info:+ url: "installs/7z.dll"++ghc:+ windows64:+ 8.2.2:+ url: "installs/ghc-8.2.2.tar.xz"+```+ ### setup-info (Since 0.1.5) Allows augmenting from where tools like GHC and msys2 (on Windows) are downloaded. Most useful for specifying locations of custom GHC binary-distributions (for use with the [ghc-variant](#ghc-variant) option):+distributions (for use with the [ghc-variant](#ghc-variant) option). +The format of this field is the same as in the default [stack-setup-2.yaml](https://github.com/commercialhaskell/stackage-content/raw/master/stack/stack-setup-2.yaml):+ ```yaml setup-info: ghc:@@ -646,18 +722,14 @@ url: "https://example.com/ghc-7.10.2-i386-unknown-mingw32-foo.tar.xz" ``` -Or you can point to external setup-info:+This configuration **adds** the specified setup info metadata to the default;+Specifying this config **does not** prevent the default `stack-setup-2.yaml` from being consulted as a fallback. +If you need to **replace** the default setup-info, add the following:+ ```yaml-setup-info: "https://example.com/my-stack-setup-info.yaml"+setup-info-locations: [] ```--This may be either URL or (since 1.2.0) absolute file path.--Note that this **adds** the specified setup info metadata to the default.-If you need to **replace** it, use the `stack --setup-info-yaml` command-line-argument instead. The default setup metadata is in-[stack-setup-2.yaml](https://github.com/commercialhaskell/stackage-content/raw/master/stack/stack-setup-2.yaml). ### pvp-bounds
@@ -1,35 +0,0 @@-resolver: lts-11.22-name: snapshot-for-building-stack-with-ghc-8.2.2--packages:-- ansi-terminal-0.9@rev:0-- Cabal-2.4.0.1@rev:0-- infer-license-0.2.0@rev:0 #for hpack-0.31-- hpack-0.31.2@rev:0-- githash-0.1.3.0@rev:0-- rio-orphans-0.1.1.0@sha256:15600084c56ef4e1f22ac2091d10fa6ed62f01f531d819c6a5a19492212a76c9-- yaml-0.10.4.0@rev:0 #for hpack-0.31-- tar-conduit-0.3.0@sha256:c220b7a74b986445d08706aed77f17f82807d0133a5f3a760f53d587d20865b2,2928-- hackage-security-0.5.3.0@rev:2-- http-api-data-0.3.8.1@rev:1-- cabal-doctest-1.0.6@rev:2-- unliftio-0.2.12@rev:0 #for rio-0.1.11.0-- happy-1.19.9@sha256:f8c774230735a390c287b2980cfcd2703d24d8dde85a01ea721b7b4b4c82944f,4667-- fsnotify-0.3.0.1@rev:1-- process-1.6.3.0@sha256:fc77cfe75a9653b8c54ae455ead8c06cb8adc4d7a340984d84d8ca880b579919,2370 #because of https://github.com/haskell/process/pull/101-- persistent-2.9.2@rev:0-- persistent-sqlite-2.9.3@rev:0-- rio-0.1.11.0@rev:0-- ansi-wl-pprint-0.6.8.2@rev:1 # for ansi-terminal-0.9-- hedgehog-0.6.1@rev:4 # for ansi-terminal-0.9-- typed-process-0.2.6.0@rev:0 # for rio-0.1.10.0-- rio-prettyprint-0.1.0.0-- hi-file-parser-0.1.0.0-- http-download-0.1.0.0-- pantry-0.1.1.1-- git: https://github.com/snoyberg/filelock.git- commit: 97e83ecc133cd60a99df8e1fa5a3c2739ad007dc--drop-packages:-# See https://github.com/commercialhaskell/stack/pull/4712-- cabal-install
@@ -63,7 +63,7 @@ import Data.Text (pack) import Stack.Prelude import System.FilePath (takeExtension)-import System.IO (stderr, hPutStrLn)+import System.IO (hPutStrLn) -- | Parser to extract the stack command line embedded inside a comment -- after validating the placement and formatting rules for a valid
@@ -1,6 +1,6 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-}-+{-# LANGUAGE LambdaCase #-} -- | -- Wrapper functions of 'Network.HTTP.Simple' and 'Network.HTTP.Client' to -- add the 'User-Agent' HTTP request header to each request.@@ -43,17 +43,28 @@ , download , redownload , verifiedDownload+ , verifiedDownloadWithProgress , CheckHexDigest (..)- , DownloadRequest (..)+ , DownloadRequest , drRetryPolicyDefault- , DownloadException (..)+ , VerifiedDownloadException (..) , HashCheck (..)+ , mkDownloadRequest+ , setHashChecks+ , setLengthCheck+ , setRetryPolicy+ , setForceDownload ) where +import Control.Monad.State (get, put, modify) import Data.Aeson (FromJSON) import qualified Data.ByteString as Strict-import Data.Conduit (ConduitM)-import Data.Void (Void)+import Data.Conduit (ConduitM, ConduitT, awaitForever, (.|), yield, await)+import Data.Conduit.Lift (evalStateC)+import qualified Data.Conduit.List as CL+import Data.Monoid (Sum (..))+import qualified Data.Text as T+import Data.Time.Clock (NominalDiffTime, diffUTCTime, getCurrentTime) import Network.HTTP.Client (Request, RequestBody(..), Response, parseRequest, getUri, path, checkResponse, parseUrlThrow) import Network.HTTP.Simple (setRequestMethod, setRequestBody, setRequestHeader, addRequestHeader, HttpException(..), getResponseBody, getResponseStatusCode, getResponseHeaders) import Network.HTTP.Types (hAccept, hContentLength, hContentMD5, methodPut)@@ -64,8 +75,10 @@ import qualified Network.HTTP.Simple import Network.HTTP.Client.MultipartFormData (formDataBody, partFileRequestBody, partBS, partLBS) import Path+import Prelude (until, (!!)) import RIO import RIO.PrettyPrint+import Text.Printf (printf) setUserAgent :: Request -> Request@@ -144,4 +157,97 @@ verifiedDownload dr destpath progressSink = Download.verifiedDownload dr' destpath progressSink where- dr' = dr {drRequest = setUserAgent (drRequest dr)}+ dr' = modifyRequest setUserAgent dr++verifiedDownloadWithProgress+ :: HasTerm env+ => DownloadRequest+ -> Path Abs File+ -> Text+ -> Maybe Int+ -> RIO env Bool+verifiedDownloadWithProgress req destpath lbl msize =+ verifiedDownload req destpath (chattyDownloadProgress lbl msize)++chattyDownloadProgress+ :: ( HasLogFunc env+ , MonadIO m+ , MonadReader env m+ )+ => Text+ -> Maybe Int+ -> f+ -> ConduitT ByteString c m ()+chattyDownloadProgress label mtotalSize _ = do+ _ <- logSticky $ RIO.display label <> ": download has begun"+ CL.map (Sum . Strict.length)+ .| chunksOverTime 1+ .| go+ where+ go = evalStateC 0 $ awaitForever $ \(Sum size) -> do+ modify (+ size)+ totalSoFar <- get+ logSticky $ fromString $+ case mtotalSize of+ Nothing -> chattyProgressNoTotal totalSoFar+ Just 0 -> chattyProgressNoTotal totalSoFar+ Just totalSize -> chattyProgressWithTotal totalSoFar totalSize++ -- Example: ghc: 42.13 KiB downloaded...+ chattyProgressNoTotal totalSoFar =+ printf ("%s: " <> bytesfmt "%7.2f" totalSoFar <> " downloaded...")+ (T.unpack label)++ -- Example: ghc: 50.00 MiB / 100.00 MiB (50.00%) downloaded...+ chattyProgressWithTotal totalSoFar total =+ printf ("%s: " <>+ bytesfmt "%7.2f" totalSoFar <> " / " <>+ bytesfmt "%.2f" total <>+ " (%6.2f%%) downloaded...")+ (T.unpack label)+ percentage+ where percentage :: Double+ percentage = fromIntegral totalSoFar / fromIntegral total * 100++-- | Given a printf format string for the decimal part and a number of+-- bytes, formats the bytes using an appropriate unit and returns the+-- formatted string.+--+-- >>> bytesfmt "%.2" 512368+-- "500.359375 KiB"+bytesfmt :: Integral a => String -> a -> String+bytesfmt formatter bs = printf (formatter <> " %s")+ (fromIntegral (signum bs) * dec :: Double)+ (bytesSuffixes !! i)+ where+ (dec,i) = getSuffix (abs bs)+ getSuffix n = until p (\(x,y) -> (x / 1024, y+1)) (fromIntegral n,0)+ where p (n',numDivs) = n' < 1024 || numDivs == (length bytesSuffixes - 1)+ bytesSuffixes :: [String]+ bytesSuffixes = ["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]++-- Await eagerly (collect with monoidal append),+-- but space out yields by at least the given amount of time.+-- The final yield may come sooner, and may be a superfluous mempty.+-- Note that Integer and Float literals can be turned into NominalDiffTime+-- (these literals are interpreted as "seconds")+chunksOverTime :: (Monoid a, Semigroup a, MonadIO m) => NominalDiffTime -> ConduitM a a m ()+chunksOverTime diff = do+ currentTime <- liftIO getCurrentTime+ evalStateC (currentTime, mempty) go+ where+ -- State is a tuple of:+ -- * the last time a yield happened (or the beginning of the sink)+ -- * the accumulated awaits since the last yield+ go = await >>= \case+ Nothing -> do+ (_, acc) <- get+ yield acc+ Just a -> do+ (lastTime, acc) <- get+ let acc' = acc <> a+ currentTime <- liftIO getCurrentTime+ if diff < diffUTCTime currentTime lastTime+ then put (currentTime, mempty) >> yield acc'+ else put (lastTime, acc')+ go
@@ -0,0 +1,40 @@+{-# LANGUAGE CPP #-}++module Path.Extended + ( fileExtension+ , addExtension+ , replaceExtension+ ) where++import Control.Monad.Catch+import qualified Path+import Path (Path, File)++fileExtension :: MonadThrow m => Path b File -> m String+fileExtension = +#if MIN_VERSION_path(0,7,0)+ Path.fileExtension+#else+ pure . Path.fileExtension+#endif++addExtension :: MonadThrow m+ => String+ -> Path b File+ -> m (Path b File)+addExtension =+#if MIN_VERSION_path(0,7,0)+ Path.addExtension+#else+ Path.addFileExtension+#endif++replaceExtension :: MonadThrow m+ => String+ -> Path b File+ -> m (Path b File)+#if MIN_VERSION_path(0,7,0)+replaceExtension ext = Path.replaceExtension ('.' : ext)+#else+replaceExtension = flip (Path.-<.>)+#endif
@@ -17,7 +17,6 @@ ,tryGetModificationTime ) where -import Data.Bool (bool) import Data.Time (UTCTime) import Path import Path.IO
@@ -21,7 +21,6 @@ import qualified Data.HashMap.Strict as HM import Data.List ((\\), isPrefixOf) import Data.List.Extra (groupSort)-import Data.List.NonEmpty (NonEmpty(..)) import qualified Data.List.NonEmpty as NE import qualified Data.Map as Map import qualified Data.Set as Set@@ -31,6 +30,8 @@ import Data.Text.Read (decimal) import qualified Data.Vector as V import qualified Data.Yaml as Yaml+import qualified Distribution.PackageDescription as C+import Distribution.Types.Dependency (depLibraries) import Distribution.Version (mkVersion) import Path (parent) import Stack.Build.ConstructPlan@@ -65,6 +66,8 @@ depsLocals <- localDependencies let allLocals = locals <> depsLocals + checkSubLibraryDependencies (Map.elems $ smProject sourceMap)+ -- Set local files, necessary for file watching stackYaml <- view stackYamlL for_ msetLocalFiles $ \setLocalFiles -> do@@ -334,3 +337,28 @@ | lp <- lps , c <- Set.toList (lpUnbuildable lp) ]++-- | Find if sublibrary dependency exist in each project+checkSubLibraryDependencies :: HasLogFunc env => [ProjectPackage] -> RIO env ()+checkSubLibraryDependencies proj = do+ forM_ proj $ \p -> do+ C.GenericPackageDescription _ _ lib subLibs foreignLibs exes tests benches <- liftIO $ cpGPD . ppCommon $ p++ let dependencies = concatMap getDeps subLibs <>+ concatMap getDeps foreignLibs <>+ concatMap getDeps exes <>+ concatMap getDeps tests <>+ concatMap getDeps benches <>+ maybe [] C.condTreeConstraints lib+ libraries = concatMap (toList . depLibraries) dependencies++ when (subLibDepExist libraries)+ (logWarn "SubLibrary dependency is not supported, this will almost certainly fail")+ where+ getDeps (_, C.CondNode _ dep _) = dep+ subLibDepExist lib = + any (\x ->+ case x of+ C.LSubLibName _ -> True+ C.LMainLibName -> False+ ) lib
@@ -11,6 +11,7 @@ ( tryGetBuildCache , tryGetConfigCache , tryGetCabalMod+ , tryGetSetupConfigMod , getInstalledExes , tryGetFlagCache , deleteCaches@@ -138,6 +139,17 @@ => Path Abs Dir -> RIO env (Maybe CTime) tryGetCabalMod dir = do fp <- toFilePath <$> configCabalMod dir+ tryGetFileMod fp++-- | Try to read the mod time of setup-config file from the last build+tryGetSetupConfigMod :: HasEnvConfig env+ => Path Abs Dir -> RIO env (Maybe CTime)+tryGetSetupConfigMod dir = do+ fp <- toFilePath <$> configSetupConfigMod dir+ tryGetFileMod fp++tryGetFileMod :: MonadIO m => FilePath -> m (Maybe CTime)+tryGetFileMod fp = liftIO $ either (const Nothing) (Just . modificationTime) <$> tryIO (getFileStatus fp)
@@ -22,12 +22,9 @@ import Data.Monoid.Map (MonoidMap(..)) import qualified Data.Set as Set import qualified Data.Text as T-import Data.Text.Encoding (encodeUtf8, decodeUtf8With)-import Data.Text.Encoding.Error (lenientDecode) import qualified Distribution.Text as Cabal import qualified Distribution.Version as Cabal import Distribution.Types.BuildType (BuildType (Configure))-import Distribution.Types.PackageId (pkgVersion) import Distribution.Types.PackageName (mkPackageName) import Distribution.Version (mkVersion) import Generics.Deriving.Monoid (memptydefault, mappenddefault)@@ -206,10 +203,11 @@ tasks = M.fromList $ mapMaybe toTask adrs takeSubset = case boptsCLIBuildSubset $ bcoBuildOptsCLI baseConfigOpts0 of- BSAll -> id- BSOnlySnapshot -> stripLocals- BSOnlyDependencies -> stripNonDeps (M.keysSet $ smDeps sourceMap)- return $ takeSubset Plan+ BSAll -> pure+ BSOnlySnapshot -> pure . stripLocals+ BSOnlyDependencies -> pure . stripNonDeps (M.keysSet $ smDeps sourceMap)+ BSOnlyLocals -> errorOnSnapshot+ takeSubset Plan { planTasks = tasks , planFinals = M.fromList finals , planUnregisterLocal = mkUnregisterLocal tasks dirtyReason localDumpPkgs initialBuildSteps@@ -270,6 +268,33 @@ return $ PSFilePath lp return $ pPackages <> deps +-- | Throw an exception if there are any snapshot packages in the plan.+errorOnSnapshot :: Plan -> RIO env Plan+errorOnSnapshot plan@(Plan tasks _finals _unregister installExes) = do+ let snapTasks = Map.keys $ Map.filter (\t -> taskLocation t == Snap) tasks+ let snapExes = Map.keys $ Map.filter (== Snap) installExes+ unless (null snapTasks && null snapExes) $ throwIO $+ NotOnlyLocal snapTasks snapExes+ pure plan++data NotOnlyLocal = NotOnlyLocal [PackageName] [Text]++instance Show NotOnlyLocal where+ show (NotOnlyLocal packages exes) = concat+ [ "Specified only-locals, but I need to build snapshot contents:\n"+ , if null packages then "" else concat+ [ "Packages: "+ , intercalate ", " (map packageNameString packages)+ , "\n"+ ]+ , if null exes then "" else concat+ [ "Executables: "+ , intercalate ", " (map T.unpack exes)+ , "\n"+ ]+ ]+instance Exception NotOnlyLocal+ -- | State to be maintained during the calculation of local packages -- to unregister. data UnregisterState = UnregisterState@@ -842,10 +867,6 @@ go ("--ghc-options":x:xs) = go' Ghc x xs go ((T.stripPrefix "--ghc-option=" -> Just x):xs) = go' Ghc x xs go ((T.stripPrefix "--ghc-options=" -> Just x):xs) = go' Ghc x xs- go ("--ghcjs-option":x:xs) = go' Ghcjs x xs- go ("--ghcjs-options":x:xs) = go' Ghcjs x xs- go ((T.stripPrefix "--ghcjs-option=" -> Just x):xs) = go' Ghcjs x xs- go ((T.stripPrefix "--ghcjs-options=" -> Just x):xs) = go' Ghcjs x xs go (x:xs) = x : go xs go' wc x xs = checkKeepers wc x $ go xs@@ -1109,7 +1130,7 @@ let prunedDeps = map (style Current . fromString . packageNameString) pruned in Just $ flow "Can't use GHC boot package" <+> (style Current . fromString . packageNameString $ name) <+>- flow "when it has an overriden dependency, " <+>+ flow "when it has an overridden dependency (issue #4510);" <+> flow "you need to add the following as explicit dependencies to the project:" <+> line <+> encloseSep "" "" ", " prunedDeps | otherwise = Just $ flow "Unknown package:" <+> (style Current . fromString . packageNameString $ name)@@ -1121,13 +1142,22 @@ pprintFlag (name, False) = "-" <> fromString (flagNameString name) pprintDep (name, (range, mlatestApplicable, badDep)) = case badDep of- NotInBuildPlan -> Just $- style Error (fromString $ packageNameString name) <+>- align ((if range == Cabal.anyVersion- then flow "needed"- else flow "must match" <+> goodRange) <> "," <> softline <>- flow "but the stack configuration has no specified version" <+>- latestApplicable Nothing)+ NotInBuildPlan+ | name `elem` fold prunedGlobalDeps -> Just $+ style Error (fromString $ packageNameString name) <+>+ align ((if range == Cabal.anyVersion+ then flow "needed"+ else flow "must match" <+> goodRange) <> "," <> softline <>+ flow "but this GHC boot package has been pruned (issue #4510);" <+>+ flow "you need to add the package explicitly to extra-deps" <+>+ latestApplicable Nothing)+ | otherwise -> Just $+ style Error (fromString $ packageNameString name) <+>+ align ((if range == Cabal.anyVersion+ then flow "needed"+ else flow "must match" <+> goodRange) <> "," <> softline <>+ flow "but the stack configuration has no specified version" <+>+ latestApplicable Nothing) -- TODO: For local packages, suggest editing constraints DependencyMismatch version -> Just $ (style Error . fromString . packageIdentifierString) (PackageIdentifier name version) <+>
@@ -40,15 +40,17 @@ import Data.Conduit.Process.Typed (createSource) import qualified Data.Conduit.Text as CT import Data.List hiding (any)-import Data.List.NonEmpty (NonEmpty(..), nonEmpty)+import Data.List.NonEmpty (nonEmpty) import qualified Data.List.NonEmpty as NonEmpty (toList) import Data.List.Split (chunksOf) import qualified Data.Map.Strict as M import qualified Data.Map.Strict as Map import qualified Data.Set as Set import qualified Data.Text as T-import Data.Text.Encoding (decodeUtf8, encodeUtf8)+import Data.Text.Encoding (decodeUtf8) import Data.Tuple+import Data.Time (ZonedTime, getZonedTime, formatTime, defaultTimeLocale)+import qualified Data.ByteString.Char8 as S8 import qualified Distribution.PackageDescription as C import qualified Distribution.Simple.Build.Macros as C import Distribution.System (OS (Windows),@@ -87,7 +89,7 @@ import System.Environment (getExecutablePath, lookupEnv) import System.FileLock (withTryFileLock, SharedExclusive (Exclusive), withFileLock) import qualified System.FilePath as FP-import System.IO (stderr, stdout)+import System.IO.Error (isDoesNotExistError) import System.PosixCompat.Files (createLink, modificationTime, getFileStatus) import System.PosixCompat.Time (epochTime) import RIO.PrettyPrint@@ -267,16 +269,12 @@ outputNameS = case wc of Ghc -> exeNameS- Ghcjs -> baseNameS ++ ".jsexe"- jsExeNameS =- baseNameS ++ ".jsexe" setupDir = view stackRootL config </> relDirSetupExeCache </> platformDir exePath <- (setupDir </>) <$> parseRelFile exeNameS- jsExePath <- (setupDir </>) <$> parseRelDir jsExeNameS exists <- liftIO $ D.doesFileExist $ toFilePath exePath @@ -285,7 +283,6 @@ else do tmpExePath <- fmap (setupDir </>) $ parseRelFile $ "tmp-" ++ exeNameS tmpOutputPath <- fmap (setupDir </>) $ parseRelFile $ "tmp-" ++ outputNameS- tmpJsExePath <- fmap (setupDir </>) $ parseRelDir $ "tmp-" ++ jsExeNameS ensureDir setupDir let args = buildSetupArgs ++ [ "-package"@@ -294,15 +291,13 @@ , toFilePath setupShimHs , "-o" , toFilePath tmpOutputPath- ] ++- ["-build-runner" | wc == Ghcjs]+ ] compilerPath <- getCompilerPath withWorkingDir (toFilePath tmpdir) (proc (toFilePath compilerPath) args $ \pc0 -> do let pc = setStdout (useHandleOpen stderr) pc0 runProcess_ pc) `catch` \ece -> throwM $ SetupHsBuildFailure (eceExitCode ece) Nothing compilerPath args Nothing []- when (wc == Ghcjs) $ renameDir tmpJsExePath jsExePath renameFile tmpExePath exePath return $ Just exePath @@ -687,9 +682,9 @@ unregisterGhcPkgIds pkg localDB $ select ident gid :| [] case cv of- -- GHC versions >= 8.0.1 support batch unregistering of packages. See- -- https://github.com/commercialhaskell/stack/pull/4554- ACGhc v | v >= mkVersion [8, 0, 1] -> do+ -- GHC versions >= 8.2.1 support batch unregistering of packages. See+ -- https://gitlab.haskell.org/ghc/ghc/issues/12637+ ACGhc v | v >= mkVersion [8, 2, 1] -> do platform <- view platformL -- According to https://support.microsoft.com/en-us/help/830473/command-prompt-cmd-exe-command-line-string-limitation -- the maximum command line length on Windows since XP is 8191 characters.@@ -851,6 +846,9 @@ -> RIO env Bool ensureConfig newConfigCache pkgDir ExecuteEnv {..} announce cabal cabalfp task = do newCabalMod <- liftIO $ modificationTime <$> getFileStatus (toFilePath cabalfp)+ setupConfigfp <- setupConfigFromDir pkgDir+ newSetupConfigMod <- liftIO $ either (const Nothing) (Just . modificationTime) <$>+ tryJust (guard . isDoesNotExistError) (getFileStatus (toFilePath setupConfigfp)) -- See https://github.com/commercialhaskell/stack/issues/3554 taskAnyMissingHack <- view $ actualCompilerVersionL.to getGhcVersion.to (< mkVersion [8, 4]) needConfig <-@@ -869,8 +867,13 @@ mOldCabalMod <- tryGetCabalMod pkgDir + -- Cabal's setup-config is created per OS/Cabal version, multiple+ -- projects using the same package could get a conflict because of this+ mOldSetupConfigMod <- tryGetSetupConfigMod pkgDir+ return $ fmap ignoreComponents mOldConfigCache /= Just (ignoreComponents newConfigCache) || mOldCabalMod /= Just newCabalMod+ || mOldSetupConfigMod /= newSetupConfigMod let ConfigureOpts dirs nodirs = configCacheOpts newConfigCache when (taskBuildTypeConfig task) ensureConfigureScript@@ -886,7 +889,6 @@ [ "--with-ghc=" ++ toFilePath (cpCompiler cp) , "--with-ghc-pkg=" ++ toFilePath pkgPath ]- Ghcjs -> [] exes <- forM programNames $ \name -> do mpath <- findExecutable name return $ case mpath of@@ -923,7 +925,7 @@ -- On Windows 10, an upstream issue with the `sh autoreconf -i` -- command means that command clears, but does not then restore, the -- ENABLE_VIRTUAL_TERMINAL_PROCESSING flag for native terminals. The- -- folowing hack re-enables the lost ANSI-capability.+ -- following hack re-enables the lost ANSI-capability. fixupOnWindows = when osIsWindows (void $ liftIO defaultColorWhen) withWorkingDir (toFilePath pkgDir) $ autoreconf `catchAny` \ex -> do fixupOnWindows@@ -1292,15 +1294,14 @@ where runAndOutput :: ActualCompiler -> RIO env () runAndOutput compilerVer = withWorkingDir (toFilePath pkgDir) $ withProcessContext menv $ case outputType of- OTLogFile _ h ->- proc (toFilePath exeName) fullArgs- $ runProcess_- -- Don't use closed, since that can break- -- ./configure scripts. See:- -- https://github.com/commercialhaskell/stack/pull/4722- . setStdin (byteStringInput "")- . setStdout (useHandleOpen h)- . setStderr (useHandleOpen h)+ OTLogFile _ h -> do+ let prefixWithTimestamps =+ if configPrefixTimestamps config+ then PrefixWithTimestamps+ else WithoutTimestamps+ void $ sinkProcessStderrStdout (toFilePath exeName) fullArgs+ (sinkWithTimestamps prefixWithTimestamps h)+ (sinkWithTimestamps prefixWithTimestamps h) OTConsole mprefix -> let prefix = fold mprefix in void $ sinkProcessStderrStdout (toFilePath exeName) fullArgs@@ -1334,7 +1335,6 @@ then return outputFile else do ensureDir setupDir- compiler <- view $ actualCompilerVersionL.whichCompilerL compilerPath <- view $ compilerPathsL.to cpCompiler packageArgs <- getPackageArgs setupDir runExe compilerPath $@@ -1350,9 +1350,6 @@ , "-o", toFilePath outputFile , "-threaded" ] ++- (case compiler of- Ghc -> []- Ghcjs -> ["-build-runner"]) ++ -- Apply GHC options -- https://github.com/commercialhaskell/stack/issues/4526@@ -1557,7 +1554,6 @@ "' once. After a successful build of all of them, only specified executables will be rebuilt.")) _neededConfig <- ensureConfig cache pkgDir ee (announce ("configure" <> RIO.display (annSuffix executableBuildStatuses))) cabal cabalfp task- let installedMapHasThisPkg :: Bool installedMapHasThisPkg = case Map.lookup (packageName package) installedMap of@@ -1787,7 +1783,7 @@ [dp] -> do liftIO $ atomically $ modifyTVar' tvar (Map.insert (dpGhcPkgId dp) dp) return $ Just (dpGhcPkgId dp)- _ -> error "singleBuild: invariant violated: multiple results when describing installed package"+ _ -> error $ "singleBuild: invariant violated: multiple results when describing installed package " ++ show (name, dps) -- | Get the build status of all the package executables. Do so by -- testing whether their expected output file exists, e.g.@@ -1799,22 +1795,20 @@ :: HasEnvConfig env => Package -> Path Abs Dir -> RIO env (Map Text ExecutableBuildStatus) getExecutableBuildStatuses package pkgDir = do- compiler <- view $ actualCompilerVersionL.whichCompilerL distDir <- distDirFromDir pkgDir platform <- view platformL fmap M.fromList- (mapM (checkExeStatus compiler platform distDir) (Set.toList (packageExes package)))+ (mapM (checkExeStatus platform distDir) (Set.toList (packageExes package))) -- | Check whether the given executable is defined in the given dist directory. checkExeStatus :: HasLogFunc env- => WhichCompiler- -> Platform+ => Platform -> Path b Dir -> Text -> RIO env (Text, ExecutableBuildStatus)-checkExeStatus compiler platform distDir name = do+checkExeStatus platform distDir name = do exename <- parseRelDir (T.unpack name) exists <- checkPath (distDir </> relDirBuild </> exename) pure@@ -1824,18 +1818,13 @@ else ExecutableNotBuilt) where checkPath base =- case compiler of- Ghcjs -> do- dir <- parseRelDir (file ++ ".jsexe")- doesDirExist (base </> dir)- _ ->- case platform of- Platform _ Windows -> do- fileandext <- parseRelFile (file ++ ".exe")- doesFileExist (base </> fileandext)- _ -> do- fileandext <- parseRelFile file- doesFileExist (base </> fileandext)+ case platform of+ Platform _ Windows -> do+ fileandext <- parseRelFile (file ++ ".exe")+ doesFileExist (base </> fileandext)+ _ -> do+ fileandext <- parseRelFile file+ doesFileExist (base </> fileandext) where file = T.unpack name @@ -2192,6 +2181,28 @@ >> char ':' >> return () where num = some digit++-- | Whether to prefix log lines with timestamps.+data PrefixWithTimestamps = PrefixWithTimestamps | WithoutTimestamps++-- | Write stream of lines to handle, but adding timestamps.+sinkWithTimestamps :: MonadIO m => PrefixWithTimestamps -> Handle -> ConduitT ByteString Void m ()+sinkWithTimestamps prefixWithTimestamps h =+ case prefixWithTimestamps of+ PrefixWithTimestamps ->+ CB.lines .| CL.mapM addTimestamp .| CL.map (<> "\n") .| sinkHandle h+ WithoutTimestamps -> sinkHandle h+ where+ addTimestamp theLine = do+ now <- liftIO getZonedTime+ pure (formatZonedTimeForLog now <> " " <> theLine)++-- | Format a time in ISO8601 format. We choose ZonedTime over UTCTime+-- because a user expects to see logs in their local time, and would+-- be confused to see UTC time. Stack's debug logs also use the local+-- time zone.+formatZonedTimeForLog :: ZonedTime -> ByteString+formatZonedTimeForLog = S8.pack . formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%S%6Q" -- | Find the Setup.hs or Setup.lhs in the given directory. If none exists, -- throw an exception.
@@ -229,8 +229,10 @@ docRelFP FP.</> packageIdentifierString dpPackageIdent FP.</> (packageNameString name FP.<.> "haddock")+ docPathRelFP =+ fmap ((docRelFP FP.</>) . FP.takeFileName) dpHaddockHtml interfaces = intercalate "," $- maybeToList dpHaddockHtml ++ [srcInterfaceFP]+ maybeToList docPathRelFP ++ [srcInterfaceFP] destInterfaceAbsFile <- parseCollapsedAbsFile (toFilePath destDir FP.</> destInterfaceRelFP) esrcInterfaceModTime <- tryGetModificationTime srcInterfaceAbsFile
@@ -24,7 +24,6 @@ import Stack.Prelude import Stack.SourceMap (getPLIVersion, loadVersion) import Stack.Types.Build-import Stack.Types.Compiler import Stack.Types.Config import Stack.Types.GhcPkgId import Stack.Types.Package@@ -116,12 +115,10 @@ -> [LoadHelper] -- ^ from parent databases -> RIO env ([LoadHelper], [DumpPackage]) loadDatabase installMap mdb lhs0 = do- wc <- view $ actualCompilerVersionL.to whichCompiler pkgexe <- getGhcPkgExe (lhs1', dps) <- ghcPkgDump pkgexe (fmap snd (maybeToList mdb)) $ conduitDumpPackage .| sink- let ghcjsHack = wc == Ghcjs && isNothing mdb- lhs1 <- mapMaybeM (processLoadResult mdb ghcjsHack) lhs1'+ lhs1 <- mapMaybeM (processLoadResult mdb) lhs1' let lhs = pruneDeps id lhId@@ -139,23 +136,10 @@ processLoadResult :: HasLogFunc env => Maybe (InstalledPackageLocation, Path Abs Dir)- -> Bool -> (Allowed, LoadHelper) -> RIO env (Maybe LoadHelper)-processLoadResult _ _ (Allowed, lh) = return (Just lh)-processLoadResult _ True (WrongVersion actual wanted, lh)- -- Allow some packages in the ghcjs global DB to have the wrong- -- versions. Treat them as wired-ins by setting deps to [].- | fst (lhPair lh) `Set.member` ghcjsBootPackages = do- logWarn $- "Ignoring that the GHCJS boot package \"" <>- fromString (packageNameString (fst (lhPair lh))) <>- "\" has a different version, " <>- fromString (versionString actual) <>- ", than the resolver's wanted version, " <>- fromString (versionString wanted)- return (Just lh)-processLoadResult mdb _ (reason, lh) = do+processLoadResult _ (Allowed, lh) = return (Just lh)+processLoadResult mdb (reason, lh) = do logDebug $ "Ignoring package " <> fromString (packageNameString (fst (lhPair lh))) <>
@@ -25,7 +25,6 @@ import qualified Data.Foldable as F import qualified Data.Set as Set import Data.List (intercalate)-import Data.List.NonEmpty (NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Map as Map import qualified Data.Text as T@@ -372,7 +371,6 @@ where compilerErrors compiler errs | whichCompiler compiler == Ghc = ghcErrors errs- -- FIXME not sure how to handle ghcjs boot packages | otherwise = Map.empty isGhcWiredIn p _ = p `Set.member` wiredInPackages
@@ -44,7 +44,6 @@ import qualified Data.Monoid import Data.Monoid.Map (MonoidMap(..)) import qualified Data.Text as T-import Data.Text.Encoding (encodeUtf8) import qualified Data.Yaml as Yaml import Distribution.System (OS (..), Platform (..), buildPlatform, Arch(OtherArch)) import qualified Distribution.Text@@ -146,7 +145,6 @@ -> RIO env RawSnapshotLocation makeConcreteResolver (ARResolver r) = pure r makeConcreteResolver ar = do- snapshots <- getSnapshots r <- case ar of ARResolver r -> assert False $ makeConcreteResolver (ARResolver r)@@ -157,16 +155,18 @@ iopc <- loadConfigYaml (parseProjectAndConfigMonoid (parent fp)) fp ProjectAndConfigMonoid project _ <- liftIO iopc return $ projectResolver project- ARLatestNightly -> return $ nightlySnapshotLocation $ snapshotsNightly snapshots- ARLatestLTSMajor x ->+ ARLatestNightly -> nightlySnapshotLocation . snapshotsNightly <$> getSnapshots+ ARLatestLTSMajor x -> do+ snapshots <- getSnapshots case IntMap.lookup x $ snapshotsLts snapshots of Nothing -> throwString $ "No LTS release found with major version " ++ show x Just y -> return $ ltsSnapshotLocation x y- ARLatestLTS- | IntMap.null $ snapshotsLts snapshots -> throwString "No LTS releases found"- | otherwise ->- let (x, y) = IntMap.findMax $ snapshotsLts snapshots- in return $ ltsSnapshotLocation x y+ ARLatestLTS -> do+ snapshots <- getSnapshots+ if IntMap.null $ snapshotsLts snapshots+ then throwString "No LTS releases found"+ else let (x, y) = IntMap.findMax $ snapshotsLts snapshots+ in return $ ltsSnapshotLocation x y logInfo $ "Selected resolver: " <> display r return r @@ -211,6 +211,7 @@ configMonoidLatestSnapshot clConnectionCount = fromFirst 8 configMonoidConnectionCount configHideTHLoading = fromFirstTrue configMonoidHideTHLoading+ configPrefixTimestamps = fromFirst False configMonoidPrefixTimestamps configGHCVariant = getFirst configMonoidGHCVariant configCompilerRepository = fromFirst@@ -281,12 +282,12 @@ shortLocalProgramsFilePath <- liftIO $ getShortPathName localProgramsFilePath when (' ' `elem` shortLocalProgramsFilePath) $ do- logWarn $ "Stack's 'programs' path contains a space character and " <>+ logError $ "Stack's 'programs' path contains a space character and " <> "has no alternative short ('8 dot 3') name. This will cause " <> "problems with packages that use the GNU project's 'configure' " <>- "shell script. Use the 'local-programs-path' configuation option " <>- "to specify an alternative path. The current 'shortest' path is: " <>- display (T.pack shortLocalProgramsFilePath)+ "shell script. Use the 'local-programs-path' configuration option " <>+ "to specify an alternative path. The current path is: " <>+ display (T.pack localProgramsFilePath) platformOnlyDir <- runReaderT platformOnlyRelDir (configPlatform, configPlatformVariant) let configLocalPrograms = configLocalProgramsBase </> platformOnlyDir @@ -319,6 +320,7 @@ configGhcOptionsByName = coerce configMonoidGhcOptionsByName configGhcOptionsByCat = coerce configMonoidGhcOptionsByCat configSetupInfoLocations = configMonoidSetupInfoLocations+ configSetupInfoInline = configMonoidSetupInfoInline configPvpBounds = fromFirst (PvpBounds PvpBoundsNone False) configMonoidPvpBounds configModifyCodePage = fromFirstTrue configMonoidModifyCodePage configExplicitSetupDeps = configMonoidExplicitSetupDeps@@ -374,6 +376,8 @@ hsc (maybe HpackBundled HpackCommand $ getFirst configMonoidOverrideHpack) clConnectionCount+ (fromFirst defaultCasaRepoPrefix configMonoidCasaRepoPrefix)+ defaultCasaMaxPerRequest (\configPantryConfig -> initUserStorage (configStackRoot </> relFileStorage) (\configUserStorage -> inner Config {..}))@@ -587,8 +591,17 @@ (deps0, mcompleted) <- fmap unzip . forM (projectDependencies project) $ \rpl -> do (pl, mCompleted) <- case rpl of RPLImmutable rpli -> do- compl <- maybe (completePackageLocation rpli) pure (Map.lookup rpli locCache)- pure (PLImmutable compl, Just (CompletedPLI rpli compl))+ (compl, mcompl) <-+ case Map.lookup rpli locCache of+ Just compl -> pure (compl, Just compl)+ Nothing -> do+ cpl <- completePackageLocation rpli+ if cplHasCabalFile cpl+ then pure (cplComplete cpl, Just $ cplComplete cpl)+ else do+ warnMissingCabalFile rpli+ pure (cplComplete cpl, Nothing)+ pure (PLImmutable compl, CompletedPLI rpli <$> mcompl) RPLMutable p -> pure (PLMutable p, Nothing) dp <- additionalDepPackage (shouldHaddockDeps bopts) pl
@@ -25,7 +25,7 @@ import qualified Options.Applicative as OA import qualified Options.Applicative.Types as OA import Options.Applicative.Builder.Extra-import Pantry (completeSnapshotLocation, loadSnapshot)+import Pantry (loadSnapshot) import Path import qualified RIO.Map as Map import RIO.Process (envVarsL)
@@ -19,7 +19,6 @@ ,inNixShellEnvVar ,stackProgNameUpper ,wiredInPackages- ,ghcjsBootPackages ,cabalPackageName ,implicitGlobalProjectDirDeprecated ,implicitGlobalProjectDir@@ -169,7 +168,7 @@ -- -- Deprecated since stack-1.1.0. ----- TODO: Remove occurences of this variable and use 'stackRootOptionName' only+-- TODO: Remove occurrences of this variable and use 'stackRootOptionName' only -- after an appropriate deprecation period. deprecatedStackRootOptionName :: String deprecatedStackRootOptionName = "global-stack-root"@@ -202,53 +201,6 @@ , "interactive" ] --- TODO: Get this unwieldy list out of here and into a datafile--- generated by GHCJS! See https://github.com/ghcjs/ghcjs/issues/434-ghcjsBootPackages :: Set PackageName-ghcjsBootPackages =- maybe (error "Parse error in ghcjsBootPackages") Set.fromList mparsed- where- mparsed = mapM parsePackageName- -- stage1a- [ "array"- , "base"- , "binary"- , "bytestring"- , "containers"- , "deepseq"- , "integer-gmp"- , "pretty"- , "primitive"- , "integer-gmp"- , "pretty"- , "primitive"- , "template-haskell"- , "transformers"- -- stage1b- , "directory"- , "filepath"- , "old-locale"- , "process"- , "time"- -- stage2- , "async"- , "aeson"- , "attoparsec"- , "case-insensitive"- , "dlist"- , "extensible-exceptions"- , "hashable"- , "mtl"- , "old-time"- , "parallel"- , "scientific"- , "stm"- , "syb"- , "text"- , "unordered-containers"- , "vector"- ]- -- | Just to avoid repetition and magic strings. cabalPackageName :: PackageName cabalPackageName =@@ -305,11 +257,9 @@ platformVariantEnvVar :: String platformVariantEnvVar = stackProgNameUpper ++ "_PLATFORM_VARIANT" --- | Provides --ghc-options for 'Ghc', and similarly, --ghcjs-options--- for 'Ghcjs'.+-- | Provides --ghc-options for 'Ghc' compilerOptionsCabalFlag :: WhichCompiler -> String compilerOptionsCabalFlag Ghc = "--ghc-options"-compilerOptionsCabalFlag Ghcjs = "--ghcjs-options" -- | The flag to pass to GHC when we want to force its output to be -- colorized.
@@ -4,11 +4,13 @@ module Stack.Constants.Config ( distDirFromDir , rootDistDirFromDir+ , setupConfigFromDir , workDirFromDir , distRelativeDir , imageStagingDir , projectDockerSandboxDir , configCabalMod+ , configSetupConfigMod , buildCachesDir , testSuccessFile , testBuiltFile@@ -21,7 +23,6 @@ import Stack.Prelude import Stack.Constants-import Stack.Types.Compiler import Stack.Types.Config import Path @@ -75,6 +76,15 @@ (</> $(mkRelFile "stack-cabal-mod")) (distDirFromDir dir) +-- | The filename used for modification check of setup-config+configSetupConfigMod :: (MonadThrow m, MonadReader env m, HasEnvConfig env)+ => Path Abs Dir -- ^ Package directory.+ -> m (Path Abs File)+configSetupConfigMod dir =+ liftM+ (</> $(mkRelFile "stack-setup-config-mod"))+ (distDirFromDir dir)+ -- | Directory for HPC work. hpcDirFromDir :: (MonadThrow m, MonadReader env m, HasEnvConfig env)@@ -89,6 +99,14 @@ hpcRelativeDir = liftM (</> $(mkRelDir "hpc")) distRelativeDir +-- | Package's setup-config storing Cabal configuration+setupConfigFromDir :: (MonadThrow m, MonadReader env m, HasEnvConfig env)+ => Path Abs Dir+ -> m (Path Abs File)+setupConfigFromDir fp = do+ dist <- distDirFromDir fp+ return $ dist </> $(mkRelFile "setup-config")+ -- | Package's build artifacts directory. distDirFromDir :: (MonadThrow m, MonadReader env m, HasEnvConfig env) => Path Abs Dir@@ -130,11 +148,9 @@ distRelativeDir = do cabalPkgVer <- view cabalVersionL platform <- platformGhcRelDir- wc <- view $ actualCompilerVersionL.to whichCompiler- -- Cabal version, suffixed with "_ghcjs" if we're using GHCJS.+ -- Cabal version envDir <- parseRelDir $- (if wc == Ghcjs then (++ "_ghcjs") else id) $ packageIdentifierString $ PackageIdentifier cabalPackageName cabalPkgVer platformAndCabal <- useShaPathOnWindows (platform </> envDir)
@@ -46,6 +46,15 @@ import Trace.Hpc.Tix import Web.Browser (openBrowser) +newtype CoverageException = NonTestSuiteTarget PackageName deriving Typeable++instance Exception CoverageException+instance Show CoverageException where+ show (NonTestSuiteTarget name) = + "Can't specify anything except test-suites as hpc report targets (" +++ packageNameString name +++ " is used with a non test-suite target)"+ -- | Invoked at the beginning of running with "--coverage" deleteHpcReports :: HasEnvConfig env => RIO env () deleteHpcReports = do@@ -235,10 +244,8 @@ case nc of CTest testName -> liftM (pkgPath </>) $ parseRelFile (T.unpack testName ++ "/" ++ T.unpack testName ++ ".tix")- _ -> fail $- "Can't specify anything except test-suites as hpc report targets (" ++- packageNameString name ++- " is used with a non test-suite target)"+ _ -> throwIO $ NonTestSuiteTarget name+ TargetAll PTProject -> do pkgPath <- hpcPkgPath name exists <- doesDirExist pkgPath
@@ -39,8 +39,8 @@ import qualified Data.Text as T import qualified Data.Text.Encoding as T import Data.Time (UTCTime)-import Data.Version (showVersion)-import Distribution.Version (mkVersion)+import qualified Data.Version (showVersion, parseVersion)+import Distribution.Version (mkVersion, mkVersion') import Path import Path.Extra (toFilePathNoTrailingSep) import Path.IO hiding (canonicalizePath)@@ -55,12 +55,12 @@ import Stack.Types.Docker import System.Environment (getEnv,getEnvironment,getProgName,getArgs,getExecutablePath) import qualified System.FilePath as FP-import System.IO (stderr,stdin) import System.IO.Error (isDoesNotExistError) import System.IO.Unsafe (unsafePerformIO) import qualified System.PosixCompat.User as User import qualified System.PosixCompat.Files as Files import System.Terminal (hIsTerminalDeviceOrMinTTY)+import Text.ParserCombinators.ReadP (readP_to_S) import RIO.Process #ifndef WINDOWS@@ -90,7 +90,7 @@ else return Nothing args <- fmap- (["--" ++ reExecArgName ++ "=" ++ showVersion Meta.version+ (["--" ++ reExecArgName ++ "=" ++ Data.Version.showVersion Meta.version ,"--" ++ dockerEntrypointArgName ,show DockerEntrypoint{..}] ++) (liftIO getArgs)@@ -151,7 +151,17 @@ exePath <- ensureDockerStackExe dockerContainerPlatform cmdArgs args exePath cmdArgs args exePath = do+ -- MSS 2020-04-21 previously used replaceExtension, but semantics changed in path 0.7+ -- In any event, I'm not even sure _why_ we need to drop a file extension here+ -- Originally introduced here: https://github.com/commercialhaskell/stack/commit/6218dadaf5fd7bf312bb1bd0db63b4784ba78cb2+#if MIN_VERSION_path(0, 7, 0)+ let exeBase =+ case splitExtension exePath of+ Left _ -> exePath+ Right (x, _) -> x+#else exeBase <- exePath -<.> ""+#endif let mountPath = hostBinDir FP.</> toFilePath (filename exeBase) return (mountPath, args, [], [Mount (toFilePath exePath) mountPath]) @@ -181,6 +191,7 @@ bamboo = lookup "bamboo_buildKey" env jenkins = lookup "JENKINS_HOME" env msshAuthSock = lookup "SSH_AUTH_SOCK" env+ mstackYaml = lookup "STACK_YAML" env muserEnv = lookup "USER" env isRemoteDocker = maybe False (isPrefixOf "tcp://") dockerHost image <- either throwIO pure (dockerImage docker)@@ -262,6 +273,11 @@ Just sshAuthSock -> ["-e","SSH_AUTH_SOCK=" ++ sshAuthSock ,"-v",sshAuthSock ++ ":" ++ sshAuthSock]+ ,case mstackYaml of+ Nothing -> []+ Just stackYaml ->+ ["-e","STACK_YAML=" ++ stackYaml+ ,"-v",stackYaml++ ":" ++ stackYaml ++ ":ro"] -- Disable the deprecated entrypoint in FP Complete-generated images ,["--entrypoint=/usr/bin/env" | isJust (lookupImageEnv oldSandboxIdEnvVar imageEnvVars) &&@@ -399,7 +415,7 @@ dockerVersionOut <- readDockerProcess ["--version"] case words (decodeUtf8 dockerVersionOut) of (_:_:v:_) ->- case parseVersion (stripVersion v) of+ case fmap mkVersion' $ parseVersion' $ stripVersion v of Just v' | v' < minimumDockerVersion -> throwIO (DockerTooOldException minimumDockerVersion v')@@ -414,6 +430,9 @@ where minimumDockerVersion = mkVersion [1, 6, 0] prohibitedDockerVersions = [] stripVersion v = takeWhile (/= '-') (dropWhileEnd (not . isDigit) v)+ -- version is parsed by Data.Version provided code to avoid+ -- Cabal's Distribution.Version lack of support for leading zeros in version+ parseVersion' = fmap fst . listToMaybe . reverse . readP_to_S Data.Version.parseVersion -- | Remove the project's Docker sandbox. reset :: HasConfig env => Bool -> RIO env ()
@@ -9,11 +9,15 @@ ,DotOpts(..) ,DotPayload(..) ,ListDepsOpts(..)+ ,ListDepsFormat(..)+ ,ListDepsFormatOpts(..) ,resolveDependencies ,printGraph ,pruneGraph ) where +import Data.Aeson+import qualified Data.ByteString.Lazy.Char8 as LBC8 import qualified Data.Foldable as F import qualified Data.Sequence as Seq import qualified Data.Set as Set@@ -26,6 +30,7 @@ import qualified Distribution.SPDX.License as SPDX import Distribution.License (License(BSD3), licenseFromSPDX) import Distribution.Types.PackageName (mkPackageName)+import qualified Path import RIO.PrettyPrint (HasTerm (..), HasStylesUpdate (..)) import RIO.Process (HasProcessContext (..)) import Stack.Build (loadPackage)@@ -33,7 +38,6 @@ import Stack.Build.Source import Stack.Constants import Stack.Package-import Stack.PackageDump (DumpPackage(..)) import Stack.Prelude hiding (Display (..), pkgName, loadPackage) import qualified Stack.Prelude (pkgName) import Stack.Runners@@ -67,15 +71,21 @@ -- ^ Use global hints instead of relying on an actual GHC installation. } +data ListDepsFormatOpts = ListDepsFormatOpts { listDepsSep :: !Text+ -- ^ Separator between the package name and details.+ , listDepsLicense :: !Bool+ -- ^ Print dependency licenses instead of versions.+ }++data ListDepsFormat = ListDepsText ListDepsFormatOpts+ | ListDepsTree ListDepsFormatOpts+ | ListDepsJSON+ data ListDepsOpts = ListDepsOpts- { listDepsDotOpts :: !DotOpts+ { listDepsFormat :: !ListDepsFormat+ -- ^ Format of printing dependencies+ , listDepsDotOpts :: !DotOpts -- ^ The normal dot options.- , listDepsSep :: !Text- -- ^ Separator between the package name and details.- , listDepsLicense :: !Bool- -- ^ Print dependency licenses instead of versions.- , listDepsTree :: !Bool- -- ^ Print dependency tree. } -- | Visualize the project's dependencies as a graphviz graph@@ -90,6 +100,8 @@ -- ^ The package version. , payloadLicense :: Maybe (Either SPDX.License License) -- ^ The license the package was released under.+ , payloadLocation :: Maybe PackageLocation+ -- ^ The location of the package. } deriving (Eq, Show) -- | Create the dependency graph and also prune it as specified in the dot@@ -131,10 +143,11 @@ -- Skip packages that can't be loaded - see -- https://github.com/commercialhaskell/stack/issues/2967 | name `elem` [mkPackageName "rts", mkPackageName "ghc"] =- return (Set.empty, DotPayload (Just version) (Just $ Right BSD3))- | otherwise = fmap (packageAllDeps &&& makePayload) (loadPackage loc flags ghcOptions cabalConfigOpts)+ return (Set.empty, DotPayload (Just version) (Just $ Right BSD3) Nothing)+ | otherwise =+ fmap (packageAllDeps &&& makePayload loc) (loadPackage loc flags ghcOptions cabalConfigOpts) resolveDependencies (dotDependencyDepth dotOpts) graph depLoader- where makePayload pkg = DotPayload (Just $ packageVersion pkg) (Just $ packageLicense pkg)+ where makePayload loc pkg = DotPayload (Just $ packageVersion pkg) (Just $ packageLicense pkg) (Just $ PLImmutable loc) listDependencies :: ListDepsOpts@@ -142,14 +155,53 @@ listDependencies opts = do let dotOpts = listDepsDotOpts opts (pkgs, resultGraph) <- createPrunedDependencyGraph dotOpts- if listDepsTree opts then- do- liftIO $ Text.putStrLn "Packages"- liftIO $ printTree opts 0 [] (treeRoots opts pkgs) resultGraph- else- void (Map.traverseWithKey go (snd <$> resultGraph))- where go name payload = liftIO $ Text.putStrLn $ listDepsLine opts name payload+ liftIO $ case listDepsFormat opts of+ ListDepsTree treeOpts -> Text.putStrLn "Packages" >> printTree treeOpts dotOpts 0 [] (treeRoots opts pkgs) resultGraph+ ListDepsJSON -> printJSON pkgs resultGraph+ ListDepsText textOpts -> void (Map.traverseWithKey go (snd <$> resultGraph))+ where go name payload = Text.putStrLn $ listDepsLine textOpts name payload +data DependencyTree = DependencyTree (Set PackageName) (Map PackageName (Set PackageName, DotPayload))++instance ToJSON DependencyTree where+ toJSON (DependencyTree _ dependencyMap) =+ toJSON $ foldToList dependencyToJSON dependencyMap++foldToList :: (k -> a -> b) -> Map k a -> [b]+foldToList f = Map.foldrWithKey (\k a bs -> bs ++ [f k a]) []++dependencyToJSON :: PackageName -> (Set PackageName, DotPayload) -> Value+dependencyToJSON pkg (deps, payload) = let fieldsAlwaysPresent = [ "name" .= packageNameString pkg+ , "license" .= licenseText payload+ , "version" .= versionText payload+ , "dependencies" .= Set.map packageNameString deps+ ]+ loc = catMaybes [("location" .=) . pkgLocToJSON <$> payloadLocation payload]+ in object $ fieldsAlwaysPresent ++ loc++pkgLocToJSON :: PackageLocation -> Value+pkgLocToJSON (PLMutable (ResolvedPath _ dir)) = object [ "type" .= ("project package" :: Text)+ , "url" .= ("file://" ++ Path.toFilePath dir)]+pkgLocToJSON (PLImmutable (PLIHackage pkgid _ _)) = object [ "type" .= ("hackage" :: Text)+ , "url" .= ("https://hackage.haskell.org/package/" ++ display pkgid)]+pkgLocToJSON (PLImmutable (PLIArchive archive _)) = let url = case archiveLocation archive of+ ALUrl u -> u+ ALFilePath (ResolvedPath _ path) -> Text.pack $ "file://" ++ Path.toFilePath path+ in object [ "type" .= ("archive" :: Text)+ , "url" .= url ]+pkgLocToJSON (PLImmutable (PLIRepo repo _)) = object [ "type" .= case repoType repo of+ RepoGit -> "git" :: Text+ RepoHg -> "hg" :: Text+ , "url" .= repoUrl repo+ , "commit" .= repoCommit repo+ , "subdir" .= repoSubdir repo+ ]++printJSON :: Set PackageName+ -> Map PackageName (Set PackageName, DotPayload)+ -> IO ()+printJSON pkgs dependencyMap = LBC8.putStrLn $ encode $ DependencyTree pkgs dependencyMap+ treeRoots :: ListDepsOpts -> Set PackageName -> Set PackageName treeRoots opts projectPackages' = let targets = dotTargets $ listDepsDotOpts opts@@ -157,13 +209,14 @@ then projectPackages' else Set.fromList $ map (mkPackageName . Text.unpack) targets -printTree :: ListDepsOpts+printTree :: ListDepsFormatOpts+ -> DotOpts -> Int -> [Int] -> Set PackageName -> Map PackageName (Set PackageName, DotPayload) -> IO ()-printTree opts depth remainingDepsCounts packages dependencyMap =+printTree opts dotOpts depth remainingDepsCounts packages dependencyMap = F.sequence_ $ Seq.mapWithIndex go (toSeq packages) where toSeq = Seq.fromList . Set.toList@@ -171,22 +224,23 @@ in case Map.lookup name dependencyMap of Just (deps, payload) -> do- printTreeNode opts depth newDepsCounts deps payload name- if Just depth == dotDependencyDepth (listDepsDotOpts opts)+ printTreeNode opts dotOpts depth newDepsCounts deps payload name+ if Just depth == dotDependencyDepth dotOpts then return ()- else printTree opts (depth + 1) newDepsCounts deps dependencyMap+ else printTree opts dotOpts (depth + 1) newDepsCounts deps dependencyMap -- TODO: Define this behaviour, maybe return an error? Nothing -> return () -printTreeNode :: ListDepsOpts+printTreeNode :: ListDepsFormatOpts+ -> DotOpts -> Int -> [Int] -> Set PackageName -> DotPayload -> PackageName -> IO ()-printTreeNode opts depth remainingDepsCounts deps payload name =- let remainingDepth = fromMaybe 999 (dotDependencyDepth (listDepsDotOpts opts)) - depth+printTreeNode opts dotOpts depth remainingDepsCounts deps payload name =+ let remainingDepth = fromMaybe 999 (dotDependencyDepth dotOpts) - depth hasDeps = not $ null deps in Text.putStrLn $ treeNodePrefix "" remainingDepsCounts hasDeps remainingDepth <> " " <> listDepsLine opts name payload @@ -201,15 +255,21 @@ treeNodePrefix t (0:ns) d remainingDepth = treeNodePrefix (t <> " ") ns d remainingDepth treeNodePrefix t (_:ns) d remainingDepth = treeNodePrefix (t <> "│ ") ns d remainingDepth -listDepsLine :: ListDepsOpts -> PackageName -> DotPayload -> Text+listDepsLine :: ListDepsFormatOpts -> PackageName -> DotPayload -> Text listDepsLine opts name payload = Text.pack (packageNameString name) <> listDepsSep opts <> payloadText opts payload -payloadText :: ListDepsOpts -> DotPayload -> Text+payloadText :: ListDepsFormatOpts -> DotPayload -> Text payloadText opts payload = if listDepsLicense opts- then maybe "<unknown>" (Text.pack . display . either licenseFromSPDX id) (payloadLicense payload)- else maybe "<unknown>" (Text.pack . display) (payloadVersion payload)+ then licenseText payload+ else versionText payload +licenseText :: DotPayload -> Text+licenseText payload = maybe "<unknown>" (Text.pack . display . either licenseFromSPDX id) (payloadLicense payload)++versionText :: DotPayload -> Text+versionText payload = maybe "<unknown>" (Text.pack . display) (payloadVersion payload)+ -- | @pruneGraph dontPrune toPrune graph@ prunes all packages in -- @graph@ with a name in @toPrune@ and removes resulting orphans -- unless they are in @dontPrune@@@ -277,7 +337,7 @@ where loadDeps pp = do pkg <- loadCommonPackage (ppCommon pp)- pure (packageAllDeps pkg, payloadFromLocal pkg)+ pure (packageAllDeps pkg, payloadFromLocal pkg Nothing) dependencyDeps = loadDeps <$> Map.lookup pkgName (smDeps sourceMap)@@ -285,7 +345,7 @@ loadDeps DepPackage{dpLocation=PLMutable dir} = do pp <- mkProjectPackage YesPrintWarnings dir False pkg <- loadCommonPackage (ppCommon pp)- pure (packageAllDeps pkg, payloadFromLocal pkg)+ pure (packageAllDeps pkg, payloadFromLocal pkg (Just $ PLMutable dir)) loadDeps dp@DepPackage{dpLocation=PLImmutable loc} = do let common = dpCommon dp@@ -313,21 +373,23 @@ noDepsErr = error ("Invariant violated: The '" ++ packageNameString pkgName ++ "' package was not found in any of the dependency sources") - payloadFromLocal pkg = DotPayload (Just $ packageVersion pkg) (Just $ packageLicense pkg)- payloadFromDump dp = DotPayload (Just $ pkgVersion $ dpPackageIdent dp) (Right <$> dpLicense dp)+ payloadFromLocal pkg loc = DotPayload (Just $ packageVersion pkg) (Just $ packageLicense pkg) loc+ payloadFromDump dp = DotPayload (Just $ pkgVersion $ dpPackageIdent dp) (Right <$> dpLicense dp) Nothing -- | Resolve the direct (depth 0) external dependencies of the given local packages (assumed to come from project packages) projectPackageDependencies :: DotOpts -> [LocalPackage] -> [(PackageName, (Set PackageName, DotPayload))] projectPackageDependencies dotOpts locals = map (\lp -> let pkg = localPackageToPackage lp- in (packageName pkg, (deps pkg, lpPayload pkg)))+ pkgDir = Path.parent $ lpCabalFile lp+ loc = PLMutable $ ResolvedPath (RelFilePath "N/A") pkgDir+ in (packageName pkg, (deps pkg, lpPayload pkg loc))) locals where deps pkg = if dotIncludeExternal dotOpts then Set.delete (packageName pkg) (packageAllDeps pkg) else Set.intersection localNames (packageAllDeps pkg) localNames = Set.fromList $ map (packageName . lpPackage) locals- lpPayload pkg = DotPayload (Just $ packageVersion pkg) (Just $ packageLicense pkg)+ lpPayload pkg loc = DotPayload (Just $ packageVersion pkg) (Just $ packageLicense pkg) (Just loc) -- | Print a graphviz graph of the edges in the Map and highlight the given local packages printGraph :: (Applicative m, MonadIO m)@@ -405,8 +467,11 @@ bconfig <- view buildConfigL globals <- globalsFromHints $ smwCompiler $ bcSMWanted bconfig fakeGhcPkgId <- parseGhcPkgId "ignored"+ actual <- either throwIO pure $+ wantedToActual $ smwCompiler $+ bcSMWanted bconfig let smActual = SMActual- { smaCompiler = wantedToActual $ smwCompiler $ bcSMWanted bconfig+ { smaCompiler = actual , smaProject = smwProject $ bcSMWanted bconfig , smaDeps = smwDeps $ bcSMWanted bconfig , smaGlobal = Map.mapWithKey toDump globals
@@ -13,18 +13,18 @@ import GHC.IO.Exception import Path import System.FSNotify-import System.IO (hPutStrLn, getLine)-import System.Terminal+import System.IO (getLine)+import RIO.PrettyPrint hiding (line) fileWatch- :: Handle- -> ((Set (Path Abs File) -> IO ()) -> RIO env ())+ :: (HasLogFunc env, HasTerm env)+ => ((Set (Path Abs File) -> IO ()) -> RIO env ()) -> RIO env () fileWatch = fileWatchConf defaultConfig fileWatchPoll- :: Handle- -> ((Set (Path Abs File) -> IO ()) -> RIO env ())+ :: (HasLogFunc env, HasTerm env)+ => ((Set (Path Abs File) -> IO ()) -> RIO env ()) -> RIO env () fileWatchPoll = fileWatchConf $ defaultConfig { confUsePolling = True } @@ -33,18 +33,11 @@ -- The action provided takes a callback that is used to set the files to be -- watched. When any of those files are changed, we rerun the action again. fileWatchConf- :: WatchConfig- -> Handle+ :: (HasLogFunc env, HasTerm env)+ => WatchConfig -> ((Set (Path Abs File) -> IO ()) -> RIO env ()) -> RIO env ()-fileWatchConf cfg out inner = withRunInIO $ \run -> withManagerConf cfg $ \manager -> do- let putLn = hPutStrLn out -- FIXME- outputIsTerminal <- hIsTerminalDeviceOrMinTTY out- let withColor color str = putLn $ do- if outputIsTerminal- then concat [color, str, reset]- else str-+fileWatchConf cfg inner = withRunInIO $ \run -> withManagerConf cfg $ \manager -> do allFiles <- newTVarIO Set.empty dirtyVar <- newTVarIO True watchVar <- newTVarIO Map.empty@@ -92,32 +85,31 @@ let watchInput = do line <- getLine unless (line == "quit") $ do- case line of+ run $ case line of "help" -> do- putLn ""- putLn "help: display this help"- putLn "quit: exit"- putLn "build: force a rebuild"- putLn "watched: display watched files"+ logInfo ""+ logInfo "help: display this help"+ logInfo "quit: exit"+ logInfo "build: force a rebuild"+ logInfo "watched: display watched files" "build" -> atomically $ writeTVar dirtyVar True "watched" -> do watch <- readTVarIO allFiles- mapM_ putLn (Set.toList watch)+ mapM_ (logInfo . fromString) (Set.toList watch) "" -> atomically $ writeTVar dirtyVar True- _ -> putLn $ concat- [ "Unknown command: "- , show line- , ". Try 'help'"- ]+ _ -> logInfo $+ "Unknown command: " <>+ displayShow line <>+ ". Try 'help'" watchInput - race_ watchInput $ forever $ do+ race_ watchInput $ run $ forever $ do atomically $ do dirty <- readTVar dirtyVar check dirty - eres <- tryAny $ run $ inner setWatched+ eres <- tryAny $ inner setWatched -- Clear dirtiness flag after the build to avoid an infinite -- loop caused by the build itself triggering dirtiness. This@@ -127,17 +119,13 @@ -- https://github.com/commercialhaskell/stack/issues/822 atomically $ writeTVar dirtyVar False - case eres of- Left e -> do- let color = case fromException e of- Just ExitSuccess -> green- _ -> red- withColor color $ show e- _ -> withColor green "Success! Waiting for next file change."-- putLn "Type help for available commands. Press enter to force a rebuild."+ prettyInfo $+ case eres of+ Left e ->+ let theStyle = case fromException e of+ Just ExitSuccess -> Good+ _ -> Error+ in style theStyle $ fromString $ show e+ _ -> style Good "Success! Waiting for next file change." -green, red, reset :: String-green = "\ESC[32m"-red = "\ESC[31m"-reset = "\ESC[0m"+ logInfo "Type help for available commands. Press enter to force a rebuild."
@@ -1,79 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE OverloadedStrings #-}--module Stack.Freeze- ( freeze- , FreezeOpts (..)- , FreezeMode (..)- ) where--import Data.Aeson ((.=), object)-import qualified Data.Yaml as Yaml-import RIO.Process-import qualified RIO.ByteString as B-import Stack.Prelude-import Stack.Types.Config--data FreezeMode = FreezeProject | FreezeSnapshot--newtype FreezeOpts = FreezeOpts- { freezeMode :: FreezeMode- }--freeze :: HasEnvConfig env => FreezeOpts -> RIO env ()-freeze (FreezeOpts mode) = do- mproject <- view $ configL.to configProject- let warn = logWarn "No project was found: nothing to freeze"- case mproject of- PCProject (p, _) -> doFreeze p mode- PCGlobalProject -> warn- PCNoProject _ -> warn--doFreeze ::- (HasProcessContext env, HasLogFunc env, HasPantryConfig env)- => Project- -> FreezeMode- -> RIO env ()-doFreeze p FreezeProject = do- let deps = projectDependencies p- resolver = projectResolver p- completePackageLocation' pl =- case pl of- RPLImmutable pli -> PLImmutable <$> completePackageLocation pli- RPLMutable m -> pure $ PLMutable m- resolver' <- completeSnapshotLocation resolver- deps' <- mapM completePackageLocation' deps- let rawCompleted = map toRawPL deps'- rawResolver = toRawSL resolver'- if rawCompleted == deps && rawResolver == resolver- then- logInfo "No freezing is required for this project"- else do- logInfo "# Fields not mentioned below do not need to be updated"-- if rawResolver == resolver- then logInfo "# No update to resolver is needed"- else do- logInfo "# Frozen version of resolver"- B.putStr $ Yaml.encode $ object ["resolver" .= rawResolver]-- if rawCompleted == deps- then logInfo "# No update to extra-deps is needed"- else do- logInfo "# Frozen version of extra-deps"- B.putStr $ Yaml.encode $ object ["extra-deps" .= rawCompleted]--doFreeze p FreezeSnapshot = do- resolver <- completeSnapshotLocation $ projectResolver p- result <- loadSnapshotLayer resolver- case result of- Left _wc ->- logInfo "No freezing is required for compiler resolver"- Right snap -> do- snap' <- completeSnapshotLayer snap- let rawCompleted = toRawSnapshotLayer snap'- if rawCompleted == snap- then- logInfo "No freezing is required for the snapshot of this project"- else- liftIO $ B.putStr $ Yaml.encode snap'
@@ -18,7 +18,6 @@ import qualified Data.ByteString.Char8 as S8 import qualified Data.ByteString.Lazy as BL import Data.List-import Data.List.NonEmpty (NonEmpty(..)) import qualified Data.Text as T import qualified Data.Text.Encoding as T import Path (parent, (</>))@@ -103,7 +102,6 @@ -- | Get the environment variable to use for the package DB paths. ghcPkgPathEnvVar :: WhichCompiler -> Text ghcPkgPathEnvVar Ghc = "GHC_PACKAGE_PATH"-ghcPkgPathEnvVar Ghcjs = "GHCJS_PACKAGE_PATH" -- | Get the necessary ghc-pkg flags for setting up the given package database packageDbFlags :: [Path Abs Dir] -> [String]@@ -131,7 +129,8 @@ Right bs -> fmap (stripCR . T.decodeUtf8) $ listToMaybe $ S8.lines bs --- | unregister list of package ghcids, batching available from GHC 8.0.1,+-- | unregister list of package ghcids, batching available from GHC 8.2.1,+-- see https://github.com/commercialhaskell/stack/issues/2662#issuecomment-460342402 -- using GHC package id where available (from GHC 7.9) unregisterGhcPkgIds :: (HasProcessContext env, HasLogFunc env)@@ -145,11 +144,10 @@ Left e -> logWarn $ displayShow e Right _ -> return () where+ (idents, gids) = partitionEithers $ toList epgids args = "unregister" : "--user" : "--force" :- concatMap (either- (\ident -> [packageIdentifierString ident])- (\gid -> ["--ipid", ghcPkgIdString gid]))- epgids+ map packageIdentifierString idents +++ if null gids then [] else "--ipid" : map ghcPkgIdString gids -- | Get the value for GHC_PACKAGE_PATH mkGhcPackagePath :: Bool -> Path Abs Dir -> Path Abs Dir -> [Path Abs Dir] -> Path Abs Dir -> Text
@@ -19,7 +19,7 @@ import qualified Data.Set as S import Path import Stack.Prelude-import System.IO (BufferMode (..), hSetBinaryMode)+import System.IO (hSetBinaryMode) import Distribution.ModuleName hiding (toFilePath)
@@ -11,6 +11,7 @@ import qualified Data.ByteString.Lazy.Char8 as BL8 import Data.Char (isSpace) import qualified Data.Text as T+import Distribution.PackageDescription (packageDescription, package) import Distribution.Types.PackageName (mkPackageName) import Distribution.Version (mkVersion) import Lens.Micro ((?~))@@ -20,8 +21,13 @@ import Stack.Build.Target (NeedTargets(NeedTargets)) import Stack.Runners import Stack.Types.Config+import Stack.Types.SourceMap+import qualified RIO.Map as Map import RIO.Process +-- | Helper type to duplicate log messages+data Muted = Muted | NotMuted+ -- | Hoogle command. hoogleCmd :: ([String],Bool,Bool,Bool) -> RIO Runner () hoogleCmd (args,setup,rebuild,startServer) =@@ -74,52 +80,67 @@ hoogleMinVersion = mkVersion [5, 0] hoogleMinIdent = PackageIdentifier hooglePackageName hoogleMinVersion- installHoogle :: RIO EnvConfig ()- installHoogle = do- hooglePackageIdentifier <- do- mversion <- getLatestHackageVersion YesRequireHackageIndex hooglePackageName UsePreferredVersions-- -- FIXME For a while, we've been following the logic of- -- taking the latest Hoogle version available. However, we- -- may want to instead grab the version of Hoogle present in- -- the snapshot current being used instead.- pure $ fromMaybe (Left hoogleMinIdent) $ do- pir@(PackageIdentifierRevision _ ver _) <- mversion- guard $ ver >= hoogleMinVersion- Just $ Right pir-- case hooglePackageIdentifier of- Left{} -> logInfo $- "Minimum " <>- fromString (packageIdentifierString hoogleMinIdent) <>- " is not in your index. Installing the minimum version."- Right ident -> logInfo $- "Minimum version is " <>- fromString (packageIdentifierString hoogleMinIdent) <>- ". Found acceptable " <>- display ident <>- " in your index, installing it."+ installHoogle :: RIO EnvConfig (Path Abs File)+ installHoogle = requiringHoogle Muted $ do+ Stack.Build.build Nothing+ mhooglePath' <- findExecutable "hoogle"+ case mhooglePath' of+ Right hooglePath -> parseAbsFile hooglePath+ Left _ -> do+ logWarn "Couldn't find hoogle in path after installing. This shouldn't happen, may be a bug."+ bail+ requiringHoogle :: Muted -> RIO EnvConfig x -> RIO EnvConfig x+ requiringHoogle muted f = do+ hoogleTarget <- do+ sourceMap <- view $ sourceMapL . to smDeps+ case Map.lookup hooglePackageName sourceMap of+ Just hoogleDep ->+ case dpLocation hoogleDep of+ PLImmutable pli ->+ T.pack . packageIdentifierString <$>+ restrictMinHoogleVersion muted (packageLocationIdent pli)+ plm@(PLMutable _) -> do+ T.pack . packageIdentifierString . package . packageDescription+ <$> loadCabalFile plm+ Nothing -> do+ -- not muted because this should happen only once+ logWarn "No hoogle version was found, trying to install the latest version"+ mpir <- getLatestHackageVersion YesRequireHackageIndex hooglePackageName UsePreferredVersions+ let hoogleIdent = case mpir of+ Nothing -> hoogleMinIdent+ Just (PackageIdentifierRevision _ ver _) ->+ PackageIdentifier hooglePackageName ver+ T.pack . packageIdentifierString <$>+ restrictMinHoogleVersion muted hoogleIdent config <- view configL- menv <- liftIO $ configProcessContextSettings config envSettings let boptsCLI = defaultBuildOptsCLI- { boptsCLITargets =- pure $- T.pack . packageIdentifierString $- either- id- (\(PackageIdentifierRevision n v _) -> PackageIdentifier n v)- hooglePackageIdentifier+ { boptsCLITargets = [hoogleTarget] }- runRIO config $ catch -- Also a bit weird- (withEnvConfig- NeedTargets- boptsCLI $- Stack.Build.build Nothing- )- (\(e :: ExitCode) ->- case e of- ExitSuccess -> runRIO menv resetExeCache- _ -> throwIO e)+ runRIO config $ withEnvConfig NeedTargets boptsCLI f+ restrictMinHoogleVersion+ :: HasLogFunc env+ => Muted -> PackageIdentifier -> RIO env PackageIdentifier+ restrictMinHoogleVersion muted ident = do+ if ident < hoogleMinIdent+ then do+ muteableLog LevelWarn muted $+ "Minimum " <>+ fromString (packageIdentifierString hoogleMinIdent) <>+ " is not in your index. Installing the minimum version."+ pure hoogleMinIdent+ else do+ muteableLog LevelInfo muted $+ "Minimum version is " <>+ fromString (packageIdentifierString hoogleMinIdent) <>+ ". Found acceptable " <>+ fromString (packageIdentifierString ident) <>+ " in your index, requiring its installation."+ pure ident+ muteableLog :: HasLogFunc env => LogLevel -> Muted -> Utf8Builder -> RIO env ()+ muteableLog logLevel muted msg =+ case muted of+ Muted -> pure ()+ NotMuted -> logGeneric "" logLevel msg runHoogle :: Path Abs File -> [String] -> RIO EnvConfig () runHoogle hooglePath hoogleArgs = do config <- view configL@@ -139,7 +160,8 @@ ensureHoogleInPath = do config <- view configL menv <- liftIO $ configProcessContextSettings config envSettings- mhooglePath <- runRIO menv $ findExecutable "hoogle"+ mhooglePath <- runRIO menv (findExecutable "hoogle") <>+ requiringHoogle NotMuted (findExecutable "hoogle") eres <- case mhooglePath of Left _ -> return $ Left "Hoogle isn't installed." Right hooglePath -> do@@ -171,12 +193,6 @@ | setup -> do logWarn $ display err <> " Automatically installing (use --no-setup to disable) ..." installHoogle- mhooglePath' <- runRIO menv $ findExecutable "hoogle"- case mhooglePath' of- Right hooglePath -> parseAbsFile hooglePath- Left _ -> do- logWarn "Couldn't find hoogle in path after installing. This shouldn't happen, may be a bug."- bail | otherwise -> do logWarn $ display err <> " Not installing it due to --no-setup." bail
@@ -17,7 +17,6 @@ import qualified Data.HashMap.Strict as HM import qualified Data.IntMap as IntMap import Data.List.Extra (groupSortOn)-import Data.List.NonEmpty (NonEmpty (..)) import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Map.Strict as Map import qualified Data.Set as Set@@ -116,7 +115,8 @@ Map.mapMaybe (flip Map.lookup gpdByDir . resolvedAbsolute) rbundle deps <- for (Map.toList extraDeps) $ \(n, v) ->- PLImmutable <$> completePackageLocation (RPLIHackage (PackageIdentifierRevision n v CFILatest) Nothing)+ PLImmutable . cplComplete <$>+ completePackageLocation (RPLIHackage (PackageIdentifierRevision n v CFILatest) Nothing) let p = Project { projectUserMsg = if userMsg == "" then Nothing else Just userMsg
@@ -13,11 +13,11 @@ import Pantry.Internal.AesonExtended import Data.ByteString.Builder (byteString) import qualified Data.List.NonEmpty as NE-import Data.Map (Map) import qualified Data.Map as Map import qualified Data.Yaml as Yaml import Pantry-import Path (addFileExtension, parent)+import Path (parent)+import Path.Extended (addExtension) import Path.IO (doesFileExist) import Stack.Prelude import Stack.SourceMap@@ -95,7 +95,7 @@ -> RIO env ( SMWanted, [CompletedPLI])) -> RIO env SMWanted lockCachedWanted stackFile resolver fillWanted = do- lockFile <- liftIO $ addFileExtension "lock" stackFile+ lockFile <- liftIO $ addExtension ".lock" stackFile let getLockExists = doesFileExist lockFile lfb <- view lockFileBehaviorL readLockFile <-
@@ -9,8 +9,7 @@ , listDependenciesCmd ) where -import Control.Exception (Exception, throw)-import Control.Monad (when)+import Control.Exception (throw) import Data.Aeson import Data.Array.IArray ((//), elems) import Stack.Prelude hiding (Snapshot (..))@@ -19,11 +18,10 @@ import Data.Text hiding (pack, intercalate) import qualified Data.Text as T import qualified Data.Text.IO as T-import Data.Typeable (Typeable) import qualified Data.Vector as V import Network.HTTP.StackClient (httpJSON, addRequestHeader, getResponseBody, parseRequest, hAccept) import qualified Options.Applicative as OA-import Options.Applicative ((<|>), idm)+import Options.Applicative (idm) import Options.Applicative.Builder.Extra (boolFlags) import Path import RIO.PrettyPrint (useColorL)
@@ -17,7 +17,6 @@ import Stack.Prelude import Control.Monad.Trans.Writer.Strict-import Control.Monad (void) import Data.ByteString.Builder (lazyByteString) import qualified Data.ByteString.Lazy as LB import Data.Conduit@@ -30,9 +29,9 @@ import qualified Data.Text.Lazy.Encoding as TLE import Data.Time.Calendar import Data.Time.Clock-import Network.HTTP.StackClient (DownloadException (..), Request, HttpException,- getResponseStatusCode, getResponseBody, httpLbs,- parseRequest, parseUrlThrow, redownload, setGithubHeaders)+import Network.HTTP.StackClient (VerifiedDownloadException (..), Request, HttpException,+ getResponseBody, httpLbs, mkDownloadRequest, parseRequest, parseUrlThrow,+ setForceDownload, setGithubHeaders, verifiedDownloadWithProgress) import Path import Path.IO import Stack.Constants@@ -155,13 +154,16 @@ downloadTemplate req (templateDir </> rel) downloadTemplate :: Request -> Path Abs File -> RIO env Text downloadTemplate req path = do+ let dReq = setForceDownload True $ mkDownloadRequest req logIt RemoteTemp catch- (void $ redownload req path)+ (void $ do+ verifiedDownloadWithProgress dReq path (T.pack $ toFilePath path) Nothing+ ) (useCachedVersionOrThrow path) loadLocalFile path- useCachedVersionOrThrow :: Path Abs File -> DownloadException -> RIO env ()+ useCachedVersionOrThrow :: Path Abs File -> VerifiedDownloadException -> RIO env () useCachedVersionOrThrow path exception = do exists <- doesFileExist path @@ -318,7 +320,7 @@ = FailedToLoadTemplate !TemplateName !FilePath | FailedToDownloadTemplate !TemplateName- !DownloadException+ !VerifiedDownloadException | AlreadyExists !(Path Abs Dir) | MissingParameters !PackageName !TemplateName !(Set String) !(Path Abs File) | InvalidTemplate !TemplateName !String@@ -337,18 +339,13 @@ "Failed to load download template " <> T.unpack (templateName name) <> " from " <> path- show (FailedToDownloadTemplate name (RedownloadInvalidResponse _ _ resp)) =- case getResponseStatusCode resp of- 404 ->- "That template doesn't exist. Run `stack templates' to discover available templates."- code ->- "Failed to download template " <> T.unpack (templateName name) <>- ": unknown reason, status code was: " <>- show code-- show (FailedToDownloadTemplate name (RedownloadHttpError httpError)) =+ show (FailedToDownloadTemplate name (DownloadHttpError httpError)) = "There was an unexpected HTTP error while downloading template " <> T.unpack (templateName name) <> ": " <> show httpError+ show (FailedToDownloadTemplate name _) =+ "Failed to download template " <> T.unpack (templateName name) <>+ ": unknown reason"+ show (AlreadyExists path) = "Directory " <> toFilePath path <> " already exists. Aborting." show (MissingParameters name template missingKeys userConfigPath) =
@@ -15,7 +15,6 @@ import Stack.Prelude import qualified Data.Text as T import Data.Version (showVersion)-import Lens.Micro (set) import Path.IO import qualified Paths_stack as Meta import Stack.Config (getInContainer, withBuildConfig)
@@ -54,6 +54,11 @@ (long "only-dependencies" <> help "Only build packages that are dependencies of targets on the command line") <|>+ flag'+ BSOnlyLocals+ (long "only-locals" <>+ help+ "Only build packages in the local database, fail if the build plan includes the snapshot database") <|> pure BSAll) <*> (flag' FileWatch
@@ -21,8 +21,8 @@ configOptsParser currentDir hide0 = (\stackRoot workDir buildOpts dockerOpts nixOpts systemGHC installGHC arch ghcVariant ghcBuild jobs includes libs overrideGccPath overrideHpack- skipGHCCheck skipMsys localBin modifyCodePage allowDifferentUser- dumpLogs colorWhen -> mempty+ skipGHCCheck skipMsys localBin setupInfoLocations modifyCodePage+ allowDifferentUser dumpLogs colorWhen -> mempty { configMonoidStackRoot = stackRoot , configMonoidWorkDir = workDir , configMonoidBuildOpts = buildOpts@@ -41,6 +41,7 @@ , configMonoidOverrideHpack = overrideHpack , configMonoidSkipMsys = skipMsys , configMonoidLocalBinPath = localBin+ , configMonoidSetupInfoLocations = setupInfoLocations , configMonoidModifyCodePage = modifyCodePage , configMonoidAllowDifferentUser = allowDifferentUser , configMonoidDumpLogs = dumpLogs@@ -128,6 +129,11 @@ <> help "Install binaries to DIR" <> hide ))+ <*> many (+ strOption+ ( long "setup-info-yaml"+ <> help "Alternate URL or relative / absolute path for stack dependencies"+ <> metavar "URL" )) <*> firstBoolFlagsTrue "modify-code-page" "setting the codepage to support UTF-8 (Windows only)"
@@ -7,7 +7,7 @@ import Data.List.Split (splitOn) import qualified Data.Set as Set import qualified Data.Text as T-import Distribution.Types.PackageName(PackageName, mkPackageName)+import Distribution.Types.PackageName(mkPackageName) import Options.Applicative import Options.Applicative.Builder.Extra import Stack.Dot@@ -57,23 +57,49 @@ globalHints = switch (long "global-hints" <> help "Do not require an install GHC; instead, use a hints file for global packages") +separatorParser :: Parser Text+separatorParser =+ fmap escapeSep+ (textOption (long "separator" <>+ metavar "SEP" <>+ help ("Separator between package name " <>+ "and package version.") <>+ value " " <>+ showDefault))+ where escapeSep sep = T.replace "\\t" "\t" (T.replace "\\n" "\n" sep)++licenseParser :: Parser Bool+licenseParser = boolFlags False+ "license"+ "printing of dependency licenses instead of versions"+ idm++listDepsFormatOptsParser :: Parser ListDepsFormatOpts+listDepsFormatOptsParser = ListDepsFormatOpts <$> separatorParser <*> licenseParser++listDepsTreeParser :: Parser ListDepsFormat+listDepsTreeParser = ListDepsTree <$> listDepsFormatOptsParser++listDepsTextParser :: Parser ListDepsFormat+listDepsTextParser = ListDepsText <$> listDepsFormatOptsParser++listDepsJsonParser :: Parser ListDepsFormat+listDepsJsonParser = pure ListDepsJSON++toListDepsOptsParser :: Parser ListDepsFormat -> Parser ListDepsOpts+toListDepsOptsParser formatParser = ListDepsOpts+ <$> formatParser+ <*> dotOptsParser True++formatSubCommand :: String -> String -> Parser ListDepsFormat -> Mod CommandFields ListDepsOpts+formatSubCommand cmd desc formatParser =+ command cmd (info (toListDepsOptsParser formatParser)+ (progDesc desc))+ -- | Parser for arguments to `stack ls dependencies`. listDepsOptsParser :: Parser ListDepsOpts-listDepsOptsParser = ListDepsOpts- <$> dotOptsParser True -- Default for --external is True.- <*> fmap escapeSep- (textOption (long "separator" <>- metavar "SEP" <>- help ("Separator between package name " <>- "and package version.") <>- value " " <>- showDefault))- <*> boolFlags False- "license"- "printing of dependency licenses instead of versions"- idm- <*> boolFlags False- "tree"- "printing of dependencies as a tree"- idm- where escapeSep sep = T.replace "\\t" "\t" (T.replace "\\n" "\n" sep)+listDepsOptsParser = subparser+ ( formatSubCommand "text" "Print dependencies as text (default)" listDepsTextParser+ <> formatSubCommand "tree" "Print dependencies as tree" listDepsTreeParser+ <> formatSubCommand "json" "Print dependencies as JSON" listDepsJsonParser+ ) <|> toListDepsOptsParser listDepsTextParser
@@ -1,16 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}--module Stack.Options.FreezeParser where--import Data.Semigroup ((<>))-import Options.Applicative-import Stack.Freeze----- | Parser for arguments to `stack freeze`-freezeOptsParser :: Parser FreezeOpts-freezeOptsParser =- FreezeOpts <$> flag FreezeProject FreezeSnapshot- ( long "snapshot"- <> short 's'- <> help "Freeze snapshot definition instead of project's stack.yaml" )
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE ScopedTypeVariables #-}@@ -28,7 +29,6 @@ ) where import Data.List (find, isPrefixOf, unzip)-import Data.Maybe (maybe) import qualified Data.Map.Strict as M import qualified Data.Set as S import qualified Data.Text as T@@ -40,6 +40,7 @@ import qualified Distribution.PackageDescription as D import Distribution.PackageDescription hiding (FlagName) import Distribution.PackageDescription.Parsec+import Distribution.Pretty (prettyShow) import Distribution.Simple.Glob (matchDirFileGlob) import Distribution.System (OS (..), Arch, Platform (..)) import qualified Distribution.Text as D@@ -47,12 +48,17 @@ import qualified Distribution.Types.ExeDependency as Cabal import Distribution.Types.ForeignLib import qualified Distribution.Types.LegacyExeDependency as Cabal+import Distribution.Types.LibraryName (libraryNameString, maybeToLibraryName) import Distribution.Types.MungedPackageName import qualified Distribution.Types.UnqualComponentName as Cabal import qualified Distribution.Verbosity as D import Distribution.Version (mkVersion, orLaterVersion, anyVersion) import qualified HiFileParser as Iface+#if MIN_VERSION_path(0,7,0)+import Path as FL hiding (replaceExtension)+#else import Path as FL+#endif import Path.Extra import Path.IO hiding (findFiles) import Stack.Build.Installed@@ -191,7 +197,7 @@ subLibNames = S.fromList $ map (T.pack . Cabal.unUnqualComponentName)- $ mapMaybe libName -- this is a design bug in the Cabal API: this should statically be known to exist+ $ mapMaybe (libraryNameString . libName) -- this is a design bug in the Cabal API: this should statically be known to exist $ filter (buildable . libBuildInfo) $ subLibraries pkg @@ -202,8 +208,8 @@ $ foreignLibs pkg toInternalPackageMungedName- = T.pack . unMungedPackageName . computeCompatPackageName (pkgName pkgId)- . Just . Cabal.mkUnqualComponentName . T.unpack+ = T.pack . prettyShow . MungedPackageName (pkgName pkgId)+ . maybeToLibraryName . Just . Cabal.mkUnqualComponentName . T.unpack -- Gets all of the modules, files, build files, and data files that -- constitute the package. This is primarily used for dirtiness@@ -248,7 +254,7 @@ , knownTools ]) msetupDeps = fmap- (M.fromList . map (depName &&& depRange) . setupDepends)+ (M.fromList . map (depPkgName &&& depVerRange) . setupDepends) (setupBuildInfo pkg) asLibrary range = DepValue@@ -303,7 +309,7 @@ (library pkg) , mapMaybe (\sublib -> do- let maybeLib = CInternalLib . T.pack . Cabal.unUnqualComponentName <$> libName sublib+ let maybeLib = CInternalLib . T.pack . Cabal.unUnqualComponentName <$> (libraryNameString . libName) sublib flip generate (libBuildInfo sublib) <$> maybeLib ) (subLibraries pkg)@@ -383,12 +389,9 @@ pkgs = biAddPackages ++ [ name- | Dependency name _ <- targetBuildDepends biBuildInfo+ | Dependency name _ _ <- targetBuildDepends biBuildInfo -- TODO: cabal 3 introduced multiple public libraries in a single dependency , name `notElem` biOmitPackages]- ghcOpts = concatMap snd . filter (isGhc . fst) $ options biBuildInfo- where- isGhc GHC = True- isGhc _ = False+ PerCompilerFlavor ghcOpts _ = options biBuildInfo extOpts = map (("-X" ++) . D.display) (usedExtensions biBuildInfo) srcOpts = map (("-i" <>) . toFilePathNoTrailingSep)@@ -528,7 +531,7 @@ -> Map PackageName VersionRange packageDependencies pkgConfig pkg' = M.fromListWith intersectVersionRanges $- map (depName &&& depRange) $+ map (depPkgName &&& depVerRange) $ concatMap targetBuildDepends (allBuildInfo' pkg) ++ maybe [] setupDepends (setupBuildInfo pkg) where@@ -680,7 +683,7 @@ return (modules, files, dfiles, warnings) where libComponent = const CLib- internalLibComponent = CInternalLib . T.pack . maybe "" Cabal.unUnqualComponentName . libName+ internalLibComponent = CInternalLib . T.pack . maybe "" Cabal.unUnqualComponentName . libraryNameString . libName exeComponent = CExe . T.pack . Cabal.unUnqualComponentName . exeName testComponent = CTest . T.pack . Cabal.unUnqualComponentName . testName benchComponent = CBench . T.pack . Cabal.unUnqualComponentName . benchmarkName@@ -859,7 +862,7 @@ desc {library = fmap (resolveConditions rc updateLibDeps) mlib ,subLibraries =- map (\(n, v) -> (resolveConditions rc updateLibDeps v){libName=Just n})+ map (\(n, v) -> (resolveConditions rc updateLibDeps v){libName=LSubLibName n}) subLibs ,foreignLibs = map (\(n, v) -> (resolveConditions rc updateForeignLibDeps v){foreignLibName=n})@@ -981,18 +984,7 @@ Impl flavor range -> case (flavor, rcCompilerVersion rc) of (GHC, ACGhc vghc) -> vghc `withinRange` range- (GHC, ACGhcjs _ vghc) -> vghc `withinRange` range- (GHCJS, ACGhcjs vghcjs _) ->- vghcjs `withinRange` range _ -> False---- | Get the name of a dependency.-depName :: Dependency -> PackageName-depName (Dependency n _) = n---- | Get the version range of a dependency.-depRange :: Dependency -> VersionRange-depRange (Dependency _ r) = r -- | Try to resolve the list of base names in the given directory by -- looking for unique instances of base names applied with the given
@@ -13,9 +13,7 @@ import Data.List (intercalate) import qualified Data.Text as T import qualified Data.Text.IO as T-import Lens.Micro (lens) import qualified Options.Applicative as OA-import Pantry (HasPantryConfig (..)) import Path import Path.Extra import Stack.Constants
@@ -41,8 +41,6 @@ import qualified Data.Conduit.List as CL import Data.Conduit.Process.Typed (withLoggedProcess_, createSource, byteStringInput) import RIO.Process (HasProcessContext (..), ProcessContext, setStdin, closed, getStderr, getStdout, proc, withProcessWait_, setStdout, setStderr, ProcessConfig, readProcess_, workingDirL, waitExitCode)-import Data.Text.Encoding (decodeUtf8With)-import Data.Text.Encoding.Error (lenientDecode) import qualified Data.Text.IO as T import qualified RIO.Text as T@@ -216,4 +214,4 @@ writeBinaryFileAtomic :: MonadIO m => Path absrel File -> Builder -> m () writeBinaryFileAtomic fp builder = liftIO $- withBinaryFileAtomic (toFilePath fp) WriteMode (\h -> hPutBuilder h builder)+ withBinaryFileAtomic (toFilePath fp) WriteMode (`hPutBuilder` builder)
@@ -33,9 +33,9 @@ import Stack.Types.Config import Stack.Types.Docker (dockerEnable) import Stack.Types.Nix (nixEnable)-import Stack.Types.Version (stackMinorVersion, stackVersion, minorVersion)+import Stack.Types.Version (stackMinorVersion, minorVersion) import System.Console.ANSI (hSupportsANSIWithoutEmulation)-import System.Console.Terminal.Size (size, width)+import System.Terminal (getTerminalWidth) -- | Ensure that no project settings are used when running 'withConfig'. withGlobalProject :: RIO Runner a -> RIO Runner a@@ -137,16 +137,15 @@ withRunnerGlobal :: GlobalOpts -> RIO Runner a -> IO a withRunnerGlobal go inner = do colorWhen <-- case getFirst $ configMonoidColorWhen $ globalConfigMonoid go of- Nothing -> defaultColorWhen- Just colorWhen -> pure colorWhen+ maybe defaultColorWhen pure $+ getFirst $ configMonoidColorWhen $ globalConfigMonoid go useColor <- case colorWhen of ColorNever -> return False ColorAlways -> return True ColorAuto -> fromMaybe True <$> hSupportsANSIWithoutEmulation stderr termWidth <- clipWidth <$> maybe (fromMaybe defaultTerminalWidth- <$> fmap (fmap width) size)+ <$> getTerminalWidth) pure (globalTermWidth go) menv <- mkDefaultProcessContext logOptions0 <- logOptionsHandle stderr False
@@ -19,14 +19,12 @@ import Control.Applicative import Control.Concurrent.Execute (ActionContext(..), Concurrency(..)) import Stack.Prelude hiding (Display (..))-import Control.Monad.Reader.Class (local) import qualified Data.ByteString as S import qualified Data.ByteString.Char8 as S8 import qualified Data.ByteString.Lazy as L import Data.Char (toLower) import Data.Data (cast) import Data.List-import Data.List.NonEmpty (NonEmpty) import qualified Data.List.NonEmpty as NE import qualified Data.Map.Strict as Map import qualified Data.Set as Set@@ -43,7 +41,6 @@ import Distribution.PackageDescription.PrettyPrint (showGenericPackageDescription) import qualified Distribution.Types.UnqualComponentName as Cabal import Distribution.Version (simplifyVersionRange, orLaterVersion, earlierVersion, hasUpperBound, hasLowerBound)-import Lens.Micro (set) import Path import Path.IO hiding (getModificationTime, getPermissions, withSystemTempDir) import RIO.PrettyPrint@@ -244,15 +241,16 @@ ) where addBounds :: Set PackageName -> InstallMap -> InstalledMap -> Dependency -> Dependency- addBounds internalPackages installMap installedMap dep@(Dependency name range) =+ -- FIXME+ addBounds internalPackages installMap installedMap dep@(Dependency name range _) = if name `Set.member` internalPackages then dep else case foundVersion of Nothing -> dep- Just version -> Dependency name $ simplifyVersionRange+ Just version -> Dependency name (simplifyVersionRange $ (if toAddUpper && not (hasUpperBound range) then addUpper version else id) $ (if toAddLower && not (hasLowerBound range) then addLower version else id)- range+ range) Set.empty where foundVersion = case Map.lookup name installMap of
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-}@@ -21,7 +22,11 @@ import Distribution.Types.VersionRange (withinRange) import Distribution.System (Platform (..)) import qualified Pantry.SHA256 as SHA256+#if MIN_VERSION_path(0,7,0)+import Path hiding (replaceExtension)+#else import Path+#endif import Path.IO import qualified Stack.Build import Stack.Build.Installed@@ -256,8 +261,6 @@ pure $ compiler == GHC && version `withinRange` range ACGhcGit {} -> pure $ compiler == GHC- ACGhcjs version _ghcVersion ->- pure $ compiler == GHCJS && version `withinRange` range -- currently we don't do flag checking here checkCond other = Left other mlibrary = snd . C.simplifyCondTree checkCond <$> PD.condLibrary gpd
@@ -31,14 +31,12 @@ import qualified Codec.Archive.Tar as Tar import Conduit import Control.Applicative (empty)-import Control.Monad.State (get, put, modify) import "cryptonite" Crypto.Hash (SHA1(..), SHA256(..)) import Pantry.Internal.AesonExtended import qualified Data.ByteString as S import qualified Data.ByteString.Lazy as LBS import qualified Data.Conduit.Binary as CB import Data.Conduit.Lazy (lazyConsume)-import Data.Conduit.Lift (evalStateC) import qualified Data.Conduit.List as CL import Data.Conduit.Process.Typed (createSource) import Data.Conduit.Zlib (ungzip)@@ -50,23 +48,21 @@ import qualified Data.Text as T import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding.Error as T-import Data.Time.Clock (NominalDiffTime, diffUTCTime, getCurrentTime) import qualified Data.Yaml as Yaml import Distribution.System (OS, Arch (..), Platform (..)) import qualified Distribution.System as Cabal import Distribution.Text (simpleParse) import Distribution.Types.PackageName (mkPackageName) import Distribution.Version (mkVersion)-import Lens.Micro (set)-import Network.HTTP.StackClient (CheckHexDigest (..), DownloadRequest (..), HashCheck (..),- drRetryPolicyDefault, getResponseBody, getResponseStatusCode,- httpLbs, httpJSON, parseRequest, parseUrlThrow, setGithubHeaders,- verifiedDownload, withResponse)-import Path+import Network.HTTP.StackClient (CheckHexDigest (..), HashCheck (..),+ getResponseBody, getResponseStatusCode, httpLbs, httpJSON,+ mkDownloadRequest, parseRequest, parseUrlThrow, setGithubHeaders,+ setHashChecks, setLengthCheck, verifiedDownloadWithProgress, withResponse)+import Path hiding (fileExtension) import Path.CheckInstall (warnInstallSearchPathIssues)+import Path.Extended (fileExtension) import Path.Extra (toFilePathNoTrailingSep) import Path.IO hiding (findExecutable, withSystemTempDir)-import Prelude (until) import qualified Pantry import qualified RIO import RIO.List@@ -95,7 +91,6 @@ import System.FilePath (searchPathSeparator) import qualified System.FilePath as FP import System.Permissions (setFileExecutable)-import Text.Printf (printf) import System.Uname (getRelease) import Data.List.Split (splitOn) @@ -121,12 +116,8 @@ -- ^ Do not use a custom msys installation on Windows , soptsResolveMissingGHC :: !(Maybe Text) -- ^ Message shown to user for how to resolve the missing GHC- , soptsSetupInfoYaml :: !FilePath- -- ^ Location of the main stack-setup.yaml file , soptsGHCBindistURL :: !(Maybe String) -- ^ Alternate GHC binary distribution (requires custom GHCVariant)- , soptsGHCJSBootOpts :: [String]- -- ^ Additional ghcjs-boot options, the default is "--clean" } deriving Show data SetupException = UnsupportedSetupCombo OS Arch@@ -138,12 +129,9 @@ | RequireCustomGHCVariant | ProblemWhileDecompressing (Path Abs File) | SetupInfoMissingSevenz- | GHCJSRequiresStandardVariant- | GHCJSNotBooted | DockerStackExeNotFound Version Text | UnsupportedSetupConfiguration | InvalidGhcAt (Path Abs File) SomeException- | NoLongerBuildGhcjs deriving Typeable instance Exception SetupException instance Show SetupException where@@ -182,10 +170,6 @@ "Problem while decompressing " ++ toFilePath archive show SetupInfoMissingSevenz = "SetupInfo missing Sevenz EXE/DLL"- show GHCJSRequiresStandardVariant =- "stack does not yet support using --ghc-variant with GHCJS"- show GHCJSNotBooted =- "GHCJS does not yet have its boot packages installed. Use \"stack setup\" to attempt to run ghcjs-boot." show (DockerStackExeNotFound stackVersion' osKey) = concat [ stackProgName , "-"@@ -199,8 +183,6 @@ "I don't know how to install GHC on your system configuration, please install manually" show (InvalidGhcAt compiler e) = "Found an invalid compiler at " ++ show (toFilePath compiler) ++ ": " ++ displayException e- show NoLongerBuildGhcjs =- "Since Stack 2.0, Stack does not support building GHCJS itself" -- | Modify the environment variables (like PATH) appropriately, possibly doing installation too setupEnv :: NeedTargets@@ -213,7 +195,9 @@ let stackYaml = bcStackYaml bc platform <- view platformL wcVersion <- view wantedCompilerVersionL- wc <- view $ wantedCompilerVersionL.to wantedToActual.whichCompilerL+ wanted <- view wantedCompilerVersionL+ actual <- either throwIO pure $ wantedToActual wanted+ let wc = actual^.whichCompilerL let sopts = SetupOpts { soptsInstallIfMissing = configInstallGHC config , soptsUseSystem = configSystemGHC config@@ -225,9 +209,7 @@ , soptsSkipGhcCheck = configSkipGHCCheck config , soptsSkipMsys = configSkipMsys config , soptsResolveMissingGHC = mResolveMissingGHC- , soptsSetupInfoYaml = defaultSetupInfoYaml , soptsGHCBindistURL = Nothing- , soptsGHCJSBootOpts = ["--clean"] } (compilerPaths, ghcBin) <- ensureCompilerAndMsys sopts@@ -450,13 +432,14 @@ -- | Ensure both the compiler and the msys toolchain are installed and -- provide the PATHs to add if necessary ensureCompilerAndMsys- :: (HasConfig env, HasGHCVariant env)+ :: (HasBuildConfig env, HasGHCVariant env) => SetupOpts -> RIO env (CompilerPaths, ExtraDirs) ensureCompilerAndMsys sopts = do- didWarn <- warnUnsupportedCompiler $ getGhcVersion $ wantedToActual $ soptsWantedCompiler sopts+ actual <- either throwIO pure $ wantedToActual $ soptsWantedCompiler sopts+ didWarn <- warnUnsupportedCompiler $ getGhcVersion actual - getSetupInfo' <- memoizeRef (getSetupInfo (soptsSetupInfoYaml sopts))+ getSetupInfo' <- memoizeRef getSetupInfo (cp, ghcPaths) <- ensureCompiler sopts getSetupInfo' warnUnsupportedCompilerCabal cp didWarn@@ -482,9 +465,9 @@ logWarn "For more information, see: https://github.com/commercialhaskell/stack/issues/648" logWarn "" pure True- | ghcVersion >= mkVersion [8, 7] -> do+ | ghcVersion >= mkVersion [8, 11] -> do logWarn $- "Stack has not been tested with GHC versions above 8.6, and using " <>+ "Stack has not been tested with GHC versions above 8.10, and using " <> fromString (versionString ghcVersion) <> ", this may fail" pure True@@ -509,9 +492,9 @@ logWarn "This invocation will most likely fail." logWarn "To fix this, either use an older version of Stack or a newer resolver" logWarn "Acceptable resolvers: lts-3.0/nightly-2015-05-05 or later"- | cabalVersion >= mkVersion [2, 5] ->+ | cabalVersion >= mkVersion [3, 3] -> logWarn $- "Stack has not been tested with Cabal versions above 2.4, but version " <>+ "Stack has not been tested with Cabal versions above 3.2, but version " <> fromString (versionString cabalVersion) <> " was found, this may fail" | otherwise -> pure ()@@ -519,7 +502,7 @@ -- | Ensure that the msys toolchain is installed if necessary and -- provide the PATHs to add if necessary ensureMsys- :: HasConfig env+ :: HasBuildConfig env => SetupOpts -> Memoized SetupInfo -> RIO env (Maybe Tool)@@ -549,7 +532,7 @@ _ -> return Nothing installGhcBindist- :: HasConfig env+ :: HasBuildConfig env => SetupOpts -> Memoized SetupInfo -> [Tool]@@ -560,14 +543,14 @@ isWanted = isWantedCompiler (soptsCompilerCheck sopts) (soptsWantedCompiler sopts) config <- view configL ghcVariant <- view ghcVariantL+ wc <- either throwIO (pure . whichCompiler) $ wantedToActual wanted possibleCompilers <-- case whichCompiler $ wantedToActual wanted of+ case wc of Ghc -> do ghcBuilds <- getGhcBuilds forM ghcBuilds $ \ghcBuild -> do ghcPkgName <- parsePackageNameThrowing ("ghc" ++ ghcVariantSuffix ghcVariant ++ compilerBuildSuffix ghcBuild) return (getInstalledTool installed ghcPkgName (isWanted . ACGhc), ghcBuild)- Ghcjs -> return [] let existingCompilers = concatMap (\(installedCompiler, compilerBuild) -> case (installedCompiler, soptsForceReinstall sopts) of@@ -608,15 +591,15 @@ (soptsStackYaml sopts) suggestion --- | Ensure compiler (ghc or ghcjs) is installed, without worrying about msys+-- | Ensure compiler is installed, without worrying about msys ensureCompiler- :: forall env. (HasConfig env, HasGHCVariant env)+ :: forall env. (HasBuildConfig env, HasGHCVariant env) => SetupOpts -> Memoized SetupInfo -> RIO env (CompilerPaths, ExtraDirs) ensureCompiler sopts getSetupInfo' = do let wanted = soptsWantedCompiler sopts- wc = whichCompiler $ wantedToActual wanted+ wc <- either throwIO (pure . whichCompiler) $ wantedToActual wanted Platform expectedArch _ <- view platformL @@ -652,7 +635,7 @@ pure (cp, paths) ensureSandboxedCompiler- :: HasConfig env+ :: HasBuildConfig env => SetupOpts -> Memoized SetupInfo -> RIO env (CompilerPaths, ExtraDirs)@@ -670,18 +653,18 @@ _ -> installGhcBindist sopts getSetupInfo' installed paths <- extraDirs compilerTool - let wc = whichCompiler $ wantedToActual wanted+ wc <- either throwIO (pure . whichCompiler) $ wantedToActual wanted menv0 <- view processContextL m <- either throwM return $ augmentPathMap (toFilePath <$> edBins paths) (view envVarsL menv0) menv <- mkProcessContext (removeHaskellEnvVars m) - let names =- case wanted of- WCGhc version -> ["ghc-" ++ versionString version, "ghc"]- WCGhcGit{} -> ["ghc"]- WCGhcjs{} -> ["ghcjs"]- loop [] = do+ names <-+ case wanted of+ WCGhc version -> pure ["ghc-" ++ versionString version, "ghc"]+ WCGhcGit{} -> pure ["ghc"]+ WCGhcjs{} -> throwIO GhcjsNotSupported+ let loop [] = do logError $ "Looked for sandboxed compiler named one of: " <> displayShow names logError $ "Could not find it on the paths " <> displayShow (edBins paths) throwString "Could not find sandboxed compiler"@@ -712,7 +695,6 @@ let prefix = case wc of Ghc -> "ghc-"- Ghcjs -> "ghcjs-" fmap ("-" ++) $ stripPrefix prefix $ toFilePath $ filename compiler suffixes = maybe id (:) msuffixWithVersion [suffixNoVersion] findHelper :: (WhichCompiler -> [String]) -> RIO env (Path Abs File)@@ -729,7 +711,6 @@ loop toTry pkg <- fmap GhcPkgExe $ findHelper $ \case Ghc -> ["ghc-pkg"]- Ghcjs -> ["ghcjs-pkg"] menv0 <- view processContextL menv <- mkProcessContext (removeHaskellEnvVars (view envVarsL menv0))@@ -737,11 +718,9 @@ interpreter <- findHelper $ \case Ghc -> ["runghc"]- Ghcjs -> ["runghcjs"] haddock <- findHelper $ \case Ghc -> ["haddock", "haddock-ghc"]- Ghcjs -> ["haddock-ghcjs"] infobs <- proc (toFilePath compiler) ["--info"] $ fmap (toStrictBytes . fst) . readProcess_ infotext <-@@ -774,7 +753,6 @@ logWarn "Key 'Project version' not found in GHC info" getCompilerVersion wc compiler Just versionString' -> ACGhc <$> parseVersionThrowing versionString'- Ghcjs -> getCompilerVersion wc compiler globaldb <- case eglobaldb of Left e -> do@@ -826,7 +804,7 @@ buildGhcFromSource :: forall env. ( HasTerm env , HasProcessContext env- , HasConfig env+ , HasBuildConfig env ) => Memoized SetupInfo -> [Tool] -> CompilerRepository -> Text -> Text -> RIO env (Tool, CompilerBuild) buildGhcFromSource getSetupInfo' installed (CompilerRepository url) commitId flavour = do@@ -875,9 +853,13 @@ bindistPath <- parseRelDir "_build/bindist" (_,files) <- listDir (cwd </> bindistPath) let- isBindist p = "ghc-" `isPrefixOf` (toFilePath (filename p))- && fileExtension (filename p) == ".xz"- mbindist = filter isBindist files+ isBindist p = do+ extension <- fileExtension (filename p)++ return $ "ghc-" `isPrefixOf` (toFilePath (filename p))+ && extension == ".xz"++ mbindist <- filterM isBindist files case mbindist of [bindist] -> do let bindist' = T.pack (toFilePath bindist)@@ -1052,44 +1034,43 @@ -> ConduitT i (Path Abs File) (RIO env) () sourceSystemCompilers wanted = do searchPath <- view exeSearchPathL+ names <-+ case wanted of+ WCGhc version -> pure+ [ "ghc-" ++ versionString version+ , "ghc"+ ]+ WCGhcjs{} -> throwIO GhcjsNotSupported+ WCGhcGit{} -> pure [] -- only use sandboxed versions for_ names $ \name -> for_ searchPath $ \dir -> do fp <- resolveFile' $ addExe $ dir FP.</> name exists <- doesFileExist fp when exists $ yield fp where- names =- case wanted of- WCGhc version ->- [ "ghc-" ++ versionString version- , "ghc"- ]- WCGhcjs{} -> ["ghcjs"]- WCGhcGit{} -> [] -- only use sandboxed versions addExe | osIsWindows = (++ ".exe") | otherwise = id -- | Download the most recent SetupInfo-getSetupInfo :: HasConfig env => String -> RIO env SetupInfo-getSetupInfo stackSetupYaml = do+getSetupInfo :: HasConfig env => RIO env SetupInfo+getSetupInfo = do config <- view configL- setupInfos <-- mapM- loadSetupInfo- (SetupInfoFileOrURL stackSetupYaml :- configSetupInfoLocations config)- return (mconcat setupInfos)+ let inlineSetupInfo = configSetupInfoInline config+ locations' = configSetupInfoLocations config+ locations = if null locations' then [defaultSetupInfoYaml] else locations'++ resolvedSetupInfos <- mapM loadSetupInfo locations+ return (inlineSetupInfo <> mconcat resolvedSetupInfos) where- loadSetupInfo (SetupInfoInline si) = return si- loadSetupInfo (SetupInfoFileOrURL urlOrFile) = do- bs <-- case parseUrlThrow urlOrFile of- Just req -> liftM (LBS.toStrict . getResponseBody) $ httpLbs req- Nothing -> liftIO $ S.readFile urlOrFile- WithJSONWarnings si warnings <- either throwM return (Yaml.decodeEither' bs)- when (urlOrFile /= defaultSetupInfoYaml) $- logJSONWarnings urlOrFile warnings- return si+ loadSetupInfo urlOrFile = do+ bs <-+ case parseUrlThrow urlOrFile of+ Just req -> liftM (LBS.toStrict . getResponseBody) $ httpLbs req+ Nothing -> liftIO $ S.readFile urlOrFile+ WithJSONWarnings si warnings <- either throwM return (Yaml.decodeEither' bs)+ when (urlOrFile /= defaultSetupInfoYaml) $+ logJSONWarnings urlOrFile warnings+ return si getInstalledTool :: [Tool] -- ^ already installed -> PackageName -- ^ package to find@@ -1108,7 +1089,7 @@ else Nothing goodPackage _ = Nothing -downloadAndInstallTool :: HasTerm env+downloadAndInstallTool :: (HasTerm env, HasBuildConfig env) => Path Abs Dir -> DownloadInfo -> Tool@@ -1127,7 +1108,7 @@ liftIO $ ignoringAbsence (removeDirRecur tempDir) return tool -downloadAndInstallCompiler :: (HasConfig env, HasGHCVariant env)+downloadAndInstallCompiler :: (HasBuildConfig env, HasGHCVariant env) => CompilerBuild -> SetupInfo -> WantedCompiler@@ -1175,7 +1156,7 @@ let tool = Tool $ PackageIdentifier ghcPkgName selectedVersion downloadAndInstallTool (configLocalPrograms config) (gdiDownloadInfo downloadInfo) tool (installer si) -downloadAndInstallCompiler _ _ WCGhcjs{} _ _ = throwIO NoLongerBuildGhcjs+downloadAndInstallCompiler _ _ WCGhcjs{} _ _ = throwIO GhcjsNotSupported downloadAndInstallCompiler _ _ WCGhcGit{} _ _ = error "downloadAndInstallCompiler: shouldn't be reached with ghc-git"@@ -1199,7 +1180,7 @@ -- | Download and install the first available compiler build. downloadAndInstallPossibleCompilers- :: (HasGHCVariant env, HasConfig env)+ :: (HasGHCVariant env, HasBuildConfig env) => [CompilerBuild] -> SetupInfo -> WantedCompiler@@ -1266,41 +1247,53 @@ Platform AArch64 Cabal.Linux -> return "linux-aarch64" Platform arch os -> throwM $ UnsupportedSetupCombo os arch +downloadOrUseLocal+ :: (HasTerm env, HasBuildConfig env)+ => Text -> DownloadInfo -> Path Abs File -> RIO env (Path Abs File)+downloadOrUseLocal downloadLabel downloadInfo destination =+ case url of+ (parseUrlThrow -> Just _) -> do+ ensureDir (parent destination)+ chattyDownload downloadLabel downloadInfo destination+ return destination+ (parseAbsFile -> Just path) -> do+ warnOnIgnoredChecks+ return path+ (parseRelFile -> Just path) -> do+ warnOnIgnoredChecks+ root <- view projectRootL+ return (root </> path)+ _ ->+ throwString $ "Error: `url` must be either an HTTP URL or a file path: " ++ url+ where+ url = T.unpack $ downloadInfoUrl downloadInfo+ warnOnIgnoredChecks = do+ let DownloadInfo{downloadInfoContentLength=contentLength, downloadInfoSha1=sha1,+ downloadInfoSha256=sha256} = downloadInfo+ when (isJust contentLength) $+ logWarn "`content-length` is not checked and should not be specified when `url` is a file path"+ when (isJust sha1) $+ logWarn "`sha1` is not checked and should not be specified when `url` is a file path"+ when (isJust sha256) $+ logWarn "`sha256` is not checked and should not be specified when `url` is a file path"+ downloadFromInfo- :: HasTerm env+ :: (HasTerm env, HasBuildConfig env) => Path Abs Dir -> DownloadInfo -> Tool -> RIO env (Path Abs File, ArchiveType) downloadFromInfo programsDir downloadInfo tool = do- at <-+ archiveType <- case extension of ".tar.xz" -> return TarXz ".tar.bz2" -> return TarBz2 ".tar.gz" -> return TarGz ".7z.exe" -> return SevenZ _ -> throwString $ "Error: Unknown extension for url: " ++ url+ relativeFile <- parseRelFile $ toolString tool ++ extension- path <- case url of- (parseUrlThrow -> Just _) -> do- let path = programsDir </> relativeFile- ensureDir programsDir- chattyDownload (T.pack (toolString tool)) downloadInfo path- return path- (parseAbsFile -> Just path) -> do- let DownloadInfo{downloadInfoContentLength=contentLength, downloadInfoSha1=sha1,- downloadInfoSha256=sha256} =- downloadInfo- when (isJust contentLength) $- logWarn ("`content-length` in not checked \n" <>- "and should not be specified when `url` is a file path")- when (isJust sha1) $- logWarn ("`sha1` is not checked and \n" <>- "should not be specified when `url` is a file path")- when (isJust sha256) $- logWarn ("`sha256` is not checked and \n" <>- "should not be specified when `url` is a file path")- return path- _ ->- throwString $ "Error: `url` must be either an HTTP URL or absolute file path: " ++ url- return (path, at)+ let destinationPath = programsDir </> relativeFile+ localPath <- downloadOrUseLocal (T.pack (toolString tool)) downloadInfo destinationPath+ return (localPath, archiveType)+ where url = T.unpack $ downloadInfoUrl downloadInfo extension = loop url@@ -1311,6 +1304,7 @@ where (fp', ext) = FP.splitExtension fp + data ArchiveType = TarBz2 | TarXz@@ -1438,7 +1432,7 @@ Left _ -> y Right x' -> return $ Right x' -installGHCWindows :: HasConfig env+installGHCWindows :: HasBuildConfig env => Maybe Version -> SetupInfo -> Path Abs File@@ -1451,7 +1445,7 @@ withUnpackedTarball7z "GHC" si archiveFile archiveType tarComponent destDir logInfo $ "GHC installed to " <> fromString (toFilePath destDir) -installMsys2Windows :: HasConfig env+installMsys2Windows :: HasBuildConfig env => Text -- ^ OS Key -> SetupInfo -> Path Abs File@@ -1492,7 +1486,7 @@ -- | Unpack a compressed tarball using 7zip. Expects a single directory in -- the unpacked results, which is renamed to the destination directory.-withUnpackedTarball7z :: HasConfig env+withUnpackedTarball7z :: HasBuildConfig env => String -- ^ Name of tool, used in error messages -> SetupInfo -> Path Abs File -- ^ Path to archive file@@ -1533,20 +1527,20 @@ -- | Download 7z as necessary, and get a function for unpacking things. -- -- Returned function takes an unpack directory and archive.-setup7z :: (HasConfig env, MonadIO m)+setup7z :: (HasBuildConfig env, MonadIO m) => SetupInfo -> RIO env (Path Abs Dir -> Path Abs File -> m ()) setup7z si = do dir <- view $ configL.to configLocalPrograms ensureDir dir- let exe = dir </> relFile7zexe- dll = dir </> relFile7zdll+ let exeDestination = dir </> relFile7zexe+ dllDestination = dir </> relFile7zdll case (siSevenzDll si, siSevenzExe si) of (Just sevenzDll, Just sevenzExe) -> do- chattyDownload "7z.dll" sevenzDll dll- chattyDownload "7z.exe" sevenzExe exe+ _ <- downloadOrUseLocal "7z.dll" sevenzDll dllDestination+ exePath <- downloadOrUseLocal "7z.exe" sevenzExe exeDestination withRunInIO $ \run -> return $ \outdir archive -> liftIO $ run $ do- let cmd = toFilePath exe+ let cmd = toFilePath exePath args = [ "x" , "-o" ++ toFilePath outdir@@ -1618,92 +1612,16 @@ when (null hashChecks) $ logWarn $ "No sha1 or sha256 found in metadata," <> " download hash won't be checked."- let dReq = DownloadRequest- { drRequest = req- , drHashChecks = hashChecks- , drLengthCheck = mtotalSize- , drRetryPolicy = drRetryPolicyDefault- }- x <- verifiedDownload dReq path chattyDownloadProgress+ let dReq = setHashChecks hashChecks $+ setLengthCheck mtotalSize $+ mkDownloadRequest req+ x <- verifiedDownloadWithProgress dReq path label mtotalSize if x then logStickyDone ("Downloaded " <> RIO.display label <> ".") else logStickyDone "Already downloaded." where mtotalSize = downloadInfoContentLength downloadInfo- chattyDownloadProgress _ = do- _ <- logSticky $ RIO.display label <> ": download has begun"- CL.map (Sum . S.length)- .| chunksOverTime 1- .| go- where- go = evalStateC 0 $ awaitForever $ \(Sum size) -> do- modify (+ size)- totalSoFar <- get- logSticky $ fromString $- case mtotalSize of- Nothing -> chattyProgressNoTotal totalSoFar- Just 0 -> chattyProgressNoTotal totalSoFar- Just totalSize -> chattyProgressWithTotal totalSoFar totalSize - -- Example: ghc: 42.13 KiB downloaded...- chattyProgressNoTotal totalSoFar =- printf ("%s: " <> bytesfmt "%7.2f" totalSoFar <> " downloaded...")- (T.unpack label)-- -- Example: ghc: 50.00 MiB / 100.00 MiB (50.00%) downloaded...- chattyProgressWithTotal totalSoFar total =- printf ("%s: " <>- bytesfmt "%7.2f" totalSoFar <> " / " <>- bytesfmt "%.2f" total <>- " (%6.2f%%) downloaded...")- (T.unpack label)- percentage- where percentage :: Double- percentage = fromIntegral totalSoFar / fromIntegral total * 100---- | Given a printf format string for the decimal part and a number of--- bytes, formats the bytes using an appropiate unit and returns the--- formatted string.------ >>> bytesfmt "%.2" 512368--- "500.359375 KiB"-bytesfmt :: Integral a => String -> a -> String-bytesfmt formatter bs = printf (formatter <> " %s")- (fromIntegral (signum bs) * dec :: Double)- (bytesSuffixes !! i)- where- (dec,i) = getSuffix (abs bs)- getSuffix n = until p (\(x,y) -> (x / 1024, y+1)) (fromIntegral n,0)- where p (n',numDivs) = n' < 1024 || numDivs == (length bytesSuffixes - 1)- bytesSuffixes :: [String]- bytesSuffixes = ["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]---- Await eagerly (collect with monoidal append),--- but space out yields by at least the given amount of time.--- The final yield may come sooner, and may be a superfluous mempty.--- Note that Integer and Float literals can be turned into NominalDiffTime--- (these literals are interpreted as "seconds")-chunksOverTime :: (Monoid a, Semigroup a, MonadIO m) => NominalDiffTime -> ConduitM a a m ()-chunksOverTime diff = do- currentTime <- liftIO getCurrentTime- evalStateC (currentTime, mempty) go- where- -- State is a tuple of:- -- * the last time a yield happened (or the beginning of the sink)- -- * the accumulated awaits since the last yield- go = await >>= \case- Nothing -> do- (_, acc) <- get- yield acc- Just a -> do- (lastTime, acc) <- get- let acc' = acc <> a- currentTime <- liftIO getCurrentTime- if diff < diffUTCTime currentTime lastTime- then put (currentTime, mempty) >> yield acc'- else put (lastTime, acc')- go- -- | Perform a basic sanity check of GHC sanityCheck :: (HasProcessContext env, HasLogFunc env) => Path Abs File -> RIO env ()@@ -1725,7 +1643,6 @@ -- Remove potentially confusing environment variables removeHaskellEnvVars :: Map Text Text -> Map Text Text removeHaskellEnvVars =- Map.delete "GHCJS_PACKAGE_PATH" . Map.delete "GHC_PACKAGE_PATH" . Map.delete "GHC_ENVIRONMENT" . Map.delete "HASKELL_PACKAGE_SANDBOX" .
@@ -83,16 +83,6 @@ x <- T.stripSuffix ".installed" $ T.pack $ toFilePath $ filename fp parseToolText x --- | See https://github.com/commercialhaskell/stack/issues/4086.-warnAboutGHCJS :: HasLogFunc env => RIO env ()-warnAboutGHCJS =- logWarn $ "Building a GHCJS project. " <> fromString ghcjsWarning--ghcjsWarning :: String-ghcjsWarning = unwords- [ "Note that GHCJS support in Stack is EXPERIMENTAL"- ]- getCompilerVersion :: (HasProcessContext env, HasLogFunc env) => WhichCompiler@@ -107,16 +97,6 @@ x <- ACGhc <$> parseVersionThrowing (T.unpack $ T.decodeUtf8 ghcVersion) logDebug $ "GHC version is: " <> display x return x- Ghcjs -> do- warnAboutGHCJS- logDebug "Asking GHCJS for its version"- -- Output looks like- --- -- The Glorious Glasgow Haskell Compilation System for JavaScript, version 0.1.0 (GHC 7.10.2)- bs <- fst <$> proc (toFilePath exe) ["--version"] readProcess_- let (rest, ghcVersion) = T.unpack . T.decodeUtf8 <$> versionFromEnd (BL.toStrict bs)- (_, ghcjsVersion) = T.unpack . T.decodeUtf8 <$> versionFromEnd rest- ACGhcjs <$> parseVersionThrowing ghcjsVersion <*> parseVersionThrowing ghcVersion where versionFromEnd = S8.spanEnd isValid . fst . S8.breakEnd isValid isValid c = c == '.' || ('0' <= c && c <= '9')
@@ -27,25 +27,11 @@ data SetupCmdOpts = SetupCmdOpts { scoCompilerVersion :: !(Maybe WantedCompiler) , scoForceReinstall :: !Bool- , scoSetupInfoYaml :: !String , scoGHCBindistURL :: !(Maybe String) , scoGHCJSBootOpts :: ![String] , scoGHCJSBootClean :: !Bool } -setupYamlCompatParser :: OA.Parser String-setupYamlCompatParser = stackSetupYaml <|> setupInfoYaml- where stackSetupYaml = OA.strOption (- OA.long "stack-setup-yaml"- <> OA.help "DEPRECATED: Use 'setup-info-yaml' instead"- <> OA.metavar "URL"- <> OA.hidden )- setupInfoYaml = OA.strOption (- OA.long "setup-info-yaml"- <> OA.help "Alternate URL or absolute path for stack dependencies"- <> OA.metavar "URL"- <> OA.value defaultSetupInfoYaml )- setupParser :: OA.Parser SetupCmdOpts setupParser = SetupCmdOpts <$> OA.optional (OA.argument readVersion@@ -56,7 +42,6 @@ "reinstall" "reinstalling GHC, even if available (incompatible with --system-ghc)" OA.idm- <*> setupYamlCompatParser <*> OA.optional (OA.strOption (OA.long "ghc-bindist" <> OA.metavar "URL"@@ -80,7 +65,7 @@ Right x -> return x setup- :: (HasConfig env, HasGHCVariant env)+ :: (HasBuildConfig env, HasGHCVariant env) => SetupCmdOpts -> WantedCompiler -> VersionCheck@@ -99,9 +84,7 @@ , soptsSkipGhcCheck = False , soptsSkipMsys = configSkipMsys , soptsResolveMissingGHC = Nothing- , soptsSetupInfoYaml = scoSetupInfoYaml , soptsGHCBindistURL = scoGHCBindistURL- , soptsGHCJSBootOpts = scoGHCJSBootOpts ++ ["--clean" | scoGHCJSBootClean] } let compiler = case wantedCompiler of WCGhc _ -> "GHC"
@@ -270,8 +270,10 @@ prjPkgs <- fmap Map.fromList . for projectPackages $ \resolved -> do pp <- mkProjectPackage printWarnings resolved buildHaddocks pure (cpName $ ppCommon pp, pp)+ compiler <- either throwIO pure $ wantedToActual+ $ snapshotCompiler snapshot return SMActual- { smaCompiler = wantedToActual $ snapshotCompiler snapshot+ { smaCompiler = compiler , smaProject = prjPkgs , smaDeps = Map.difference deps prjPkgs , smaGlobal = globals
@@ -1,3 +1,4 @@+{-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}@@ -6,6 +7,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-}@@ -24,7 +26,6 @@ import qualified Data.ByteString as S import qualified Data.Set as Set-import Database.Persist.Sql (SqlBackend) import Database.Persist.Sqlite import Database.Persist.TH import qualified Pantry.Internal as SQLite
@@ -1,3 +1,4 @@+{-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}@@ -6,6 +7,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-}@@ -30,7 +32,6 @@ import qualified Data.Set as Set import qualified Data.Text as T import Data.Time.Clock (UTCTime)-import Database.Persist.Sql (SqlBackend) import Database.Persist.Sqlite import Database.Persist.TH import Distribution.Text (simpleParse, display)
@@ -53,8 +53,6 @@ import qualified Data.Map as Map import qualified Data.Set as Set import qualified Data.Text as T-import Data.Text.Encoding (decodeUtf8With)-import Data.Text.Encoding.Error (lenientDecode) import Database.Persist.Sql (PersistField(..) ,PersistFieldSql(..) ,PersistValue(PersistText)@@ -635,7 +633,6 @@ , map ("--extra-include-dirs=" ++) (configExtraIncludeDirs config) , map ("--extra-lib-dirs=" ++) (configExtraLibDirs config) , maybe [] (\customGcc -> ["--with-gcc=" ++ toFilePath customGcc]) (configOverrideGccPath config)- , ["--ghcjs" | wc == Ghcjs] , ["--exact-configuration"] , ["--ghc-option=-fhide-source-paths" | hideSourcePaths cv] ]
@@ -10,6 +10,7 @@ ( ActualCompiler (..) , WhichCompiler (..) , CompilerRepository (..)+ , CompilerException (..) , defaultCompilerRepository , getGhcVersion , whichCompiler@@ -25,7 +26,6 @@ import Database.Persist import Database.Persist.Sql import qualified Data.Text as T-import Data.Text (Text) import Stack.Prelude import Stack.Types.Version import Distribution.Version (mkVersion)@@ -33,7 +33,6 @@ -- | Variety of compiler to use. data WhichCompiler = Ghc- | Ghcjs deriving (Show, Eq, Ord) -- | Specifies a compiler and its version number(s).@@ -43,14 +42,10 @@ data ActualCompiler = ACGhc !Version | ACGhcGit !Text !Text- | ACGhcjs- !Version -- GHCJS version- !Version -- GHC version deriving (Generic, Show, Eq, Ord, Data, Typeable) instance NFData ActualCompiler instance Display ActualCompiler where display (ACGhc x) = display (WCGhc x)- display (ACGhcjs x y) = display (WCGhcjs x y) display (ACGhcGit x y) = display (WCGhcGit x y) instance ToJSON ActualCompiler where toJSON = toJSON . compilerVersionText@@ -68,18 +63,28 @@ instance PersistFieldSql ActualCompiler where sqlType _ = SqlString -wantedToActual :: WantedCompiler -> ActualCompiler-wantedToActual (WCGhc x) = ACGhc x-wantedToActual (WCGhcjs x y) = ACGhcjs x y-wantedToActual (WCGhcGit x y) = ACGhcGit x y+data CompilerException+ = GhcjsNotSupported+ | PantryException PantryException +instance Show CompilerException where+ show GhcjsNotSupported = "GHCJS is no longer supported by Stack"+ show (PantryException p) = displayException p+instance Exception CompilerException++wantedToActual :: WantedCompiler -> Either CompilerException ActualCompiler+wantedToActual (WCGhc x) = Right $ ACGhc x+wantedToActual (WCGhcjs _ _) = Left GhcjsNotSupported+wantedToActual (WCGhcGit x y) = Right $ ACGhcGit x y+ actualToWanted :: ActualCompiler -> WantedCompiler actualToWanted (ACGhc x) = WCGhc x-actualToWanted (ACGhcjs x y) = WCGhcjs x y actualToWanted (ACGhcGit x y) = WCGhcGit x y -parseActualCompiler :: T.Text -> Either PantryException ActualCompiler-parseActualCompiler = fmap wantedToActual . parseWantedCompiler+parseActualCompiler :: T.Text -> Either CompilerException ActualCompiler+parseActualCompiler =+ either (Left . PantryException) wantedToActual .+ parseWantedCompiler compilerVersionText :: ActualCompiler -> T.Text compilerVersionText = utf8BuilderToText . display@@ -90,20 +95,16 @@ whichCompiler :: ActualCompiler -> WhichCompiler whichCompiler ACGhc{} = Ghc whichCompiler ACGhcGit{} = Ghc-whichCompiler ACGhcjs{} = Ghcjs isWantedCompiler :: VersionCheck -> WantedCompiler -> ActualCompiler -> Bool isWantedCompiler check (WCGhc wanted) (ACGhc actual) = checkVersion check wanted actual-isWantedCompiler check (WCGhcjs wanted wantedGhc) (ACGhcjs actual actualGhc) =- checkVersion check wanted actual && checkVersion check wantedGhc actualGhc isWantedCompiler _check (WCGhcGit wCommit wFlavour) (ACGhcGit aCommit aFlavour) = wCommit == aCommit && wFlavour == aFlavour isWantedCompiler _ _ _ = False getGhcVersion :: ActualCompiler -> Version getGhcVersion (ACGhc v) = v-getGhcVersion (ACGhcjs _ v) = v getGhcVersion (ACGhcGit _ _) = -- We can't return the actual version without running the installed ghc. -- For now we assume that users of ghc-git use it with a recent commit so we
@@ -140,7 +140,6 @@ ,VersionedDownloadInfo(..) ,GHCDownloadInfo(..) ,SetupInfo(..)- ,SetupInfoLocation(..) -- ** Docker entrypoint ,DockerEntrypoint(..) ,DockerUser(..)@@ -182,14 +181,13 @@ (ToJSON, toJSON, FromJSON, FromJSONKey (..), parseJSON, withText, object, (.=), (..:), (...:), (..:?), (..!=), Value(Bool), withObjectWarnings, WarningParser, Object, jsonSubWarnings,- jsonSubWarningsT, jsonSubWarningsTT, WithJSONWarnings(..), noJSONWarnings,+ jsonSubWarningsT, jsonSubWarningsTT, WithJSONWarnings(..), FromJSONKeyFunction (FromJSONKeyTextParser)) import Data.Attoparsec.Args (parseArgs, EscapingMode (Escaping)) import qualified Data.ByteArray.Encoding as Mem (convertToBase, Base(Base16)) import qualified Data.ByteString.Char8 as S8 import Data.Coerce (coerce) import Data.List (stripPrefix)-import Data.List.NonEmpty (NonEmpty) import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Map as Map import qualified Data.Map.Strict as M@@ -197,7 +195,6 @@ import Data.Monoid.Map (MonoidMap(..)) import qualified Data.Set as Set import qualified Data.Text as T-import Data.Text.Encoding (encodeUtf8) import Data.Yaml (ParseException) import qualified Data.Yaml as Yaml import qualified Distribution.License as C@@ -209,7 +206,7 @@ import qualified Distribution.Types.UnqualComponentName as C import Distribution.Version (anyVersion, mkVersion', mkVersion) import Generics.Deriving.Monoid (memptydefault, mappenddefault)-import Lens.Micro (Lens', lens, _1, _2, to)+import Lens.Micro import Options.Applicative (ReadM) import qualified Options.Applicative as OA import qualified Options.Applicative.Types as OA@@ -234,6 +231,7 @@ import qualified System.FilePath as FilePath import System.PosixCompat.Types (UserID, GroupID, FileMode) import RIO.Process (ProcessContext, HasProcessContext (..))+import Casa.Client (CasaRepoPrefix) -- Re-exports import Stack.Types.Config.Build as X@@ -283,6 +281,8 @@ ,configHideTHLoading :: !Bool -- ^ Hide the Template Haskell "Loading package ..." messages from the -- console+ ,configPrefixTimestamps :: !Bool+ -- ^ Prefix build output with timestamps for each line. ,configPlatform :: !Platform -- ^ The platform we're building for, used in many directory names ,configPlatformVariant :: !PlatformVariant@@ -331,8 +331,11 @@ -- ^ Additional GHC options to apply to categories of packages ,configCabalConfigOpts :: !(Map CabalConfigKey [Text]) -- ^ Additional options to be passed to ./Setup.hs configure- ,configSetupInfoLocations :: ![SetupInfoLocation]- -- ^ Additional SetupInfo (inline or remote) to use to find tools.+ ,configSetupInfoLocations :: ![String]+ -- ^ URLs or paths to stack-setup.yaml files, for finding tools.+ -- If none present, the default setup-info is used.+ ,configSetupInfoInline :: !SetupInfo+ -- ^ Additional SetupInfo to use to find tools. ,configPvpBounds :: !PvpBounds -- ^ How PVP upper bounds should be added to packages ,configModifyCodePage :: !Bool@@ -406,7 +409,7 @@ instance FromJSONKey CabalConfigKey where fromJSONKey = FromJSONKeyTextParser parseCabalConfigKey -parseCabalConfigKey :: Monad m => Text -> m CabalConfigKey+parseCabalConfigKey :: (Monad m, MonadFail m) => Text -> m CabalConfigKey parseCabalConfigKey "$targets" = pure CCKTargets parseCabalConfigKey "$locals" = pure CCKLocals parseCabalConfigKey "$everything" = pure CCKEverything@@ -762,6 +765,8 @@ -- ^ See: 'configConnectionCount' , configMonoidHideTHLoading :: !FirstTrue -- ^ See: 'configHideTHLoading'+ , configMonoidPrefixTimestamps :: !(First Bool)+ -- ^ See: 'configPrefixTimestamps' , configMonoidLatestSnapshot :: !(First Text) -- ^ See: 'configLatestSnapshot' , configMonoidPackageIndices :: !(First [HackageSecurityConfig])@@ -816,8 +821,10 @@ -- ^ See 'configCabalConfigOpts'. ,configMonoidExtraPath :: ![Path Abs Dir] -- ^ Additional paths to search for executables in- ,configMonoidSetupInfoLocations :: ![SetupInfoLocation]- -- ^ Additional setup info (inline or remote) to use for installing tools+ ,configMonoidSetupInfoLocations :: ![String]+ -- ^ See 'configSetupInfoLocations'+ ,configMonoidSetupInfoInline :: !SetupInfo+ -- ^ See 'configSetupInfoInline' ,configMonoidLocalProgramsBase :: !(First (Path Abs Dir)) -- ^ Override the default local programs dir, where e.g. GHC is installed. ,configMonoidPvpBounds :: !(First PvpBounds)@@ -851,6 +858,7 @@ -- ^ See 'configHideSourcePaths' , configMonoidRecommendUpgrade :: !FirstTrue -- ^ See 'configRecommendUpgrade'+ , configMonoidCasaRepoPrefix :: !(First CasaRepoPrefix) } deriving (Show, Generic) @@ -877,6 +885,7 @@ configMonoidNixOpts <- jsonSubWarnings (obj ..:? configMonoidNixOptsName ..!= mempty) configMonoidConnectionCount <- First <$> obj ..:? configMonoidConnectionCountName configMonoidHideTHLoading <- FirstTrue <$> obj ..:? configMonoidHideTHLoadingName+ configMonoidPrefixTimestamps <- First <$> obj ..:? configMonoidPrefixTimestampsName murls :: Maybe Value <- obj ..:? configMonoidUrlsName configMonoidLatestSnapshot <-@@ -942,8 +951,8 @@ let configMonoidCabalConfigOpts = coerce (configMonoidCabalConfigOpts' :: Map CabalConfigKey [Text]) configMonoidExtraPath <- obj ..:? configMonoidExtraPathName ..!= []- configMonoidSetupInfoLocations <-- maybeToList <$> jsonSubWarningsT (obj ..:? configMonoidSetupInfoLocationsName)+ configMonoidSetupInfoLocations <- obj ..:? configMonoidSetupInfoLocationsName ..!= []+ configMonoidSetupInfoInline <- jsonSubWarningsT (obj ..:? configMonoidSetupInfoInlineName) ..!= mempty configMonoidLocalProgramsBase <- First <$> obj ..:? configMonoidLocalProgramsBaseName configMonoidPvpBounds <- First <$> obj ..:? configMonoidPvpBoundsName configMonoidModifyCodePage <- FirstTrue <$> obj ..:? configMonoidModifyCodePageName@@ -972,9 +981,11 @@ configMonoidHideSourcePaths <- FirstTrue <$> obj ..:? configMonoidHideSourcePathsName configMonoidRecommendUpgrade <- FirstTrue <$> obj ..:? configMonoidRecommendUpgradeName + configMonoidCasaRepoPrefix <- First <$> obj ..:? configMonoidCasaRepoPrefixName+ return ConfigMonoid {..} where- handleExplicitSetupDep :: Monad m => (Text, Bool) -> m (Maybe PackageName, Bool)+ handleExplicitSetupDep :: (Monad m, MonadFail m) => (Text, Bool) -> m (Maybe PackageName, Bool) handleExplicitSetupDep (name', b) = do name <- if name' == "*"@@ -1002,6 +1013,9 @@ configMonoidHideTHLoadingName :: Text configMonoidHideTHLoadingName = "hide-th-loading" +configMonoidPrefixTimestampsName :: Text+configMonoidPrefixTimestampsName = "build-output-timestamps"+ configMonoidUrlsName :: Text configMonoidUrlsName = "urls" @@ -1072,8 +1086,11 @@ configMonoidExtraPathName = "extra-path" configMonoidSetupInfoLocationsName :: Text-configMonoidSetupInfoLocationsName = "setup-info"+configMonoidSetupInfoLocationsName = "setup-info-locations" +configMonoidSetupInfoInlineName :: Text+configMonoidSetupInfoInlineName = "setup-info"+ configMonoidLocalProgramsBaseName :: Text configMonoidLocalProgramsBaseName = "local-programs-path" @@ -1128,6 +1145,9 @@ configMonoidRecommendUpgradeName :: Text configMonoidRecommendUpgradeName = "recommend-stack-upgrade" +configMonoidCasaRepoPrefixName :: Text+configMonoidCasaRepoPrefixName = "casa-repo-prefix"+ data ConfigException = ParseConfigFileException (Path Abs File) ParseException | ParseCustomSnapshotException Text ParseException@@ -1414,7 +1434,6 @@ compilerVersion <- view actualCompilerVersionL parseRelDir $ case compilerVersion of ACGhc version -> versionString version- ACGhcjs {} -> compilerVersionString compilerVersion ACGhcGit {} -> compilerVersionString compilerVersion -- | Package database for installing dependencies into@@ -1663,7 +1682,6 @@ , siSevenzDll :: Maybe DownloadInfo , siMsys2 :: Map Text VersionedDownloadInfo , siGHCs :: Map Text (Map Version GHCDownloadInfo)- , siGHCJSs :: Map Text (Map ActualCompiler DownloadInfo) , siStack :: Map Text (Map Version DownloadInfo) } deriving Show@@ -1674,20 +1692,18 @@ siSevenzDll <- jsonSubWarningsT (o ..:? "sevenzdll-info") siMsys2 <- jsonSubWarningsT (o ..:? "msys2" ..!= mempty) (fmap unCabalStringMap -> siGHCs) <- jsonSubWarningsTT (o ..:? "ghc" ..!= mempty)- siGHCJSs <- jsonSubWarningsTT (o ..:? "ghcjs" ..!= mempty) (fmap unCabalStringMap -> siStack) <- jsonSubWarningsTT (o ..:? "stack" ..!= mempty) return SetupInfo {..} --- | For @siGHCs@ and @siGHCJSs@ fields maps are deeply merged.--- For all fields the values from the last @SetupInfo@ win.+-- | For the @siGHCs@ field maps are deeply merged.+-- For all fields the values from the first @SetupInfo@ win. instance Semigroup SetupInfo where l <> r = SetupInfo- { siSevenzExe = siSevenzExe r <|> siSevenzExe l- , siSevenzDll = siSevenzDll r <|> siSevenzDll l- , siMsys2 = siMsys2 r <> siMsys2 l- , siGHCs = Map.unionWith (<>) (siGHCs r) (siGHCs l)- , siGHCJSs = Map.unionWith (<>) (siGHCJSs r) (siGHCJSs l)+ { siSevenzExe = siSevenzExe l <|> siSevenzExe r+ , siSevenzDll = siSevenzDll l <|> siSevenzDll r+ , siMsys2 = siMsys2 l <> siMsys2 r+ , siGHCs = Map.unionWith (<>) (siGHCs l) (siGHCs r) , siStack = Map.unionWith (<>) (siStack l) (siStack r) } instance Monoid SetupInfo where@@ -1697,26 +1713,9 @@ , siSevenzDll = Nothing , siMsys2 = Map.empty , siGHCs = Map.empty- , siGHCJSs = Map.empty , siStack = Map.empty } mappend = (<>)---- | Remote or inline 'SetupInfo'-data SetupInfoLocation- = SetupInfoFileOrURL String- | SetupInfoInline SetupInfo- deriving (Show)--instance FromJSON (WithJSONWarnings SetupInfoLocation) where- parseJSON v =- (noJSONWarnings <$>- withText "SetupInfoFileOrURL" (pure . SetupInfoFileOrURL . T.unpack) v) <|>- inline- where- inline = do- WithJSONWarnings si w <- parseJSON v- return $ WithJSONWarnings (SetupInfoInline si) w -- | How PVP bounds should be added to .cabal files data PvpBoundsType
@@ -339,6 +339,9 @@ -- ^ Only install packages in the snapshot database, skipping -- packages intended for the local database. | BSOnlyDependencies+ | BSOnlyLocals+ -- ^ Refuse to build anything in the snapshot database, see+ -- https://github.com/commercialhaskell/stack/issues/5272 deriving (Show, Eq) -- | Options for the 'FinalAction' 'DoTests'
@@ -16,7 +16,7 @@ import Data.Aeson (ToJSON (..), FromJSON (..), (.=), (.:), object, withObject) import qualified Data.Map as M import qualified Data.Set as Set-import Distribution.Parsec.Common (PError (..), PWarning (..), showPos)+import Distribution.Parsec (PError (..), PWarning (..), showPos) import qualified Distribution.SPDX.License as SPDX import Distribution.License (License) import Distribution.ModuleName (ModuleName)
@@ -11,7 +11,7 @@ ,IntersectingVersionRange(..) ,VersionCheck(..) ,versionRangeText- ,withinRange+ ,Cabal.withinRange ,Stack.Types.Version.intersectVersionRanges ,toMajorVersion ,latestApplicableVersion@@ -24,11 +24,11 @@ import Stack.Prelude hiding (Vector) import Pantry.Internal.AesonExtended+import Data.List (find) import qualified Data.Set as Set import qualified Data.Text as T-import Distribution.Text (disp)+import Distribution.Pretty (pretty) import qualified Distribution.Version as Cabal-import Distribution.Version (Version, versionNumbers, withinRange) import qualified Paths_stack as Meta import Text.PrettyPrint (render) @@ -46,7 +46,7 @@ -- | Display a version range versionRangeText :: Cabal.VersionRange -> Text-versionRangeText = T.pack . render . disp+versionRangeText = T.pack . render . pretty -- | A modified intersection which also simplifies, for better display. intersectVersionRanges :: Cabal.VersionRange -> Cabal.VersionRange -> Cabal.VersionRange@@ -55,7 +55,7 @@ -- | Returns the first two components, defaulting to 0 if not present toMajorVersion :: Version -> Version toMajorVersion v =- case versionNumbers v of+ case Cabal.versionNumbers v of [] -> Cabal.mkVersion [0, 0] [a] -> Cabal.mkVersion [a, 0] a:b:_ -> Cabal.mkVersion [a, b]@@ -63,12 +63,12 @@ -- | Given a version range and a set of versions, find the latest version from -- the set that is within the range. latestApplicableVersion :: Cabal.VersionRange -> Set Version -> Maybe Version-latestApplicableVersion r = listToMaybe . filter (`withinRange` r) . Set.toDescList+latestApplicableVersion r = find (`Cabal.withinRange` r) . Set.toDescList -- | Get the next major version number for the given version nextMajorVersion :: Version -> Version nextMajorVersion v =- case versionNumbers v of+ case Cabal.versionNumbers v of [] -> Cabal.mkVersion [0, 1] [a] -> Cabal.mkVersion [a, 1] a:b:_ -> Cabal.mkVersion [a, b + 1]@@ -93,7 +93,7 @@ expected = "VersionCheck value (match-minor, match-exact, or newer-minor)" checkVersion :: VersionCheck -> Version -> Version -> Bool-checkVersion check (versionNumbers -> wanted) (versionNumbers -> actual) =+checkVersion check (Cabal.versionNumbers -> wanted) (Cabal.versionNumbers -> actual) = case check of MatchMinor -> and (take 3 matching) MatchExact -> length wanted == length actual && and matching@@ -112,7 +112,7 @@ -- | Get minor version (excludes any patchlevel) minorVersion :: Version -> Version-minorVersion = Cabal.mkVersion . take 3 . versionNumbers+minorVersion = Cabal.mkVersion . take 3 . Cabal.versionNumbers -- | Current Stack version stackVersion :: Version
@@ -38,7 +38,7 @@ let (errs1, (names, pirs1)) = fmap partitionEithers $ partitionEithers $ map parse input locs1 <- forM pirs1 $ \pir -> do- loc <- completePackageLocation $ RPLIHackage pir Nothing+ loc <- fmap cplComplete $ completePackageLocation $ RPLIHackage pir Nothing pure (loc, packageLocationIdent loc) (errs2, locs2) <- partitionEithers <$> traverse toLoc names case errs1 ++ errs2 of@@ -97,7 +97,7 @@ Nothing -> pure $ Left $ "Package does not appear in snapshot: " ++ packageNameString name Just sp -> do- loc <- completePackageLocation (rspLocation sp)+ loc <- cplComplete <$> completePackageLocation (rspLocation sp) pure $ Right (loc, packageLocationIdent loc) -- Possible future enhancement: parse names as name + version range
@@ -12,7 +12,6 @@ import Stack.Prelude hiding (force, Display (..)) import qualified Data.Text as T import Distribution.Version (mkVersion')-import Lens.Micro (set) import Options.Applicative import Path import qualified Paths_stack as Paths@@ -198,7 +197,7 @@ -- On Windows 10, an upstream issue with the `git clone` command -- means that command clears, but does not then restore, the -- ENABLE_VIRTUAL_TERMINAL_PROCESSING flag for native terminals.- -- The folowing hack re-enables the lost ANSI-capability.+ -- The following hack re-enables the lost ANSI-capability. when osIsWindows $ void $ liftIO $ hSupportsANSIWithoutEmulation stdout return $ Just $ tmp </> relDirStackProgName
@@ -27,7 +27,6 @@ import qualified Data.ByteString.Lazy as L import qualified Data.Conduit.Binary as CB import qualified Data.Text as T-import Data.Text.Encoding (encodeUtf8) import Network.HTTP.StackClient (Request, RequestBody(RequestBodyLBS), Response, withResponse, httpNoBody, getGlobalManager, getResponseStatusCode, getResponseBody, setRequestHeader,@@ -39,8 +38,9 @@ import Stack.Types.Config import System.Directory (createDirectoryIfMissing, removeFile, renameFile)+import System.Environment (lookupEnv) import System.FilePath ((</>), takeFileName, takeDirectory)-import System.IO (stdout, putStrLn, putStr, print) -- TODO remove putStrLn, use logInfo+import System.IO (putStrLn, putStr, print) -- TODO remove putStrLn, use logInfo import System.PosixCompat.Files (setFileMode) -- | Username and password to log into Hackage.@@ -63,6 +63,9 @@ <$> o .: "username" <*> o .: "password" +withEnvVariable :: Text -> IO Text -> IO Text+withEnvVariable varName fromPrompt = lookupEnv (T.unpack varName) >>= maybe fromPrompt (pure . T.pack)+ -- | Load Hackage credentials, either from a save file or the command -- line. --@@ -85,8 +88,8 @@ return $ mkCreds fp where fromPrompt fp = do- username <- prompt "Hackage username: "- password <- promptPassword "Hackage password: "+ username <- withEnvVariable "HACKAGE_USERNAME" (prompt "Hackage username: ")+ password <- withEnvVariable "HACKAGE_PASSWORD" (promptPassword "Hackage password: ") let hc = HackageCreds { hcUsername = username , hcPassword = password
@@ -3,49 +3,61 @@ -- | Run external pagers (@$PAGER@, @less@, @more@). module System.Process.Pager- (pageWriter- ,pageText- ,PagerException(..))- where+ ( pageWriter+ , pageText+ , PagerException (..)+ ) where import Stack.Prelude import System.Directory (findExecutable) import System.Environment (lookupEnv)-import System.Process (createProcess,shell,waitForProcess,StdStream (CreatePipe)- ,CreateProcess(std_in, close_fds, delegate_ctlc))-import System.IO (stdout)+import System.Process ( createProcess, cmdspec, shell, proc, waitForProcess+ , CmdSpec (ShellCommand, RawCommand)+ , StdStream (CreatePipe)+ , CreateProcess (std_in, close_fds, delegate_ctlc)+ )+import Control.Monad.Trans.Maybe (MaybeT (runMaybeT, MaybeT)) import qualified Data.Text.IO as T -- | Run pager, providing a function that writes to the pager's input. pageWriter :: (Handle -> IO ()) -> IO () pageWriter writer =- do mpager <- lookupEnv "PAGER" `orElse`- findExecutable "less" `orElse`- findExecutable "more"+ do mpager <- runMaybeT $ cmdspecFromEnvVar+ <|> cmdspecFromExeName "less"+ <|> cmdspecFromExeName "more" case mpager of Just pager ->- do (Just h,_,_,procHandle) <- createProcess (shell pager)- {std_in = CreatePipe- ,close_fds = True- ,delegate_ctlc = True}- (_::Either IOException ()) <- try (do writer h- hClose h)+ do (Just h,_,_,procHandle) <- createProcess pager+ { std_in = CreatePipe+ , close_fds = True+ , delegate_ctlc = True+ }+ (_ :: Either IOException ()) <- try (do writer h+ hClose h) exit <- waitForProcess procHandle case exit of ExitSuccess -> return ()- ExitFailure n -> throwIO (PagerExitFailure pager n)+ ExitFailure n -> throwIO (PagerExitFailure (cmdspec pager) n) return () Nothing -> writer stdout where- orElse a b = maybe b (return . Just) =<< a+ cmdspecFromEnvVar = shell <$> MaybeT (lookupEnv "PAGER")+ cmdspecFromExeName =+ fmap (\path -> proc path []) . MaybeT . findExecutable -- | Run pager to display a 'Text' pageText :: Text -> IO () pageText = pageWriter . flip T.hPutStr -- | Exception running pager.-data PagerException = PagerExitFailure FilePath Int+data PagerException = PagerExitFailure CmdSpec Int deriving Typeable instance Show PagerException where- show (PagerExitFailure p n) = "Pager (`" ++ p ++ "') exited with non-zero status: " ++ show n+ show (PagerExitFailure cmd n) =+ let+ getStr (ShellCommand c) = c+ getStr (RawCommand exePath _) = exePath+ in+ "Pager (`" ++ getStr cmd ++ "') exited with non-zero status: " ++ show n+ instance Exception PagerException
@@ -13,7 +13,6 @@ import BuildInfo import Stack.Prelude hiding (Display (..)) import Conduit (runConduitRes, sourceLazy, sinkFileCautious)-import Control.Monad.Reader (local) import Control.Monad.Trans.Except (ExceptT) import Control.Monad.Writer.Lazy (Writer) import Data.Attoparsec.Args (parseArgs, EscapingMode (Escaping))@@ -30,7 +29,6 @@ import Options.Applicative.Help (errorHelp, stringChunk, vcatChunks) import Options.Applicative.Builder.Extra import Options.Applicative.Complicated-import Options.Applicative.Types (ParserHelp(..)) import Pantry (loadSnapshot) import Path import Path.IO@@ -50,7 +48,6 @@ import Stack.GhcPkg (findGhcPkgField) import qualified Stack.Nix as Nix import Stack.FileWatch-import Stack.Freeze import Stack.Ghci import Stack.Hoogle import Stack.Ls@@ -64,7 +61,6 @@ import Stack.Options.ExecParser import Stack.Options.GhciParser import Stack.Options.GlobalParser-import Stack.Options.FreezeParser import Stack.Options.HpcReportParser import Stack.Options.NewParser@@ -89,7 +85,7 @@ import System.Environment (getProgName, getArgs, withArgs) import System.FilePath (isValid, pathSeparator, takeDirectory) import qualified System.FilePath as FP-import System.IO (stderr, stdin, stdout, BufferMode(..), hPutStrLn, hGetEncoding, hSetEncoding)+import System.IO (hPutStrLn, hGetEncoding, hSetEncoding) import System.Terminal (hIsTerminalDeviceOrMinTTY) -- | Change the character encoding of the given Handle to transliterate@@ -334,10 +330,6 @@ }) (globalOpts OtherCmdGlobalOpts) scriptOptsParser- addCommand' "freeze"- "Show project or snapshot with pinned dependencies if there are any such (experimental, may be removed)"- freezeCmd- freezeOptsParser unless isInterpreter (do addCommand' "eval"@@ -539,11 +531,11 @@ return (a,(b,mempty)) setupCmd :: SetupCmdOpts -> RIO Runner ()-setupCmd sco@SetupCmdOpts{..} = withConfig YesReexec $ do+setupCmd sco@SetupCmdOpts{..} = withConfig YesReexec $ withBuildConfig $ do (wantedCompiler, compilerCheck, mstack) <- case scoCompilerVersion of Just v -> return (v, MatchMinor, Nothing)- Nothing -> withBuildConfig $ (,,)+ Nothing -> (,,) <$> view wantedCompilerVersionL <*> view (configL.to configCompilerCheck) <*> (Just <$> view stackYamlL)@@ -562,8 +554,8 @@ exitFailure local (over globalOptsL modifyGO) $ case boptsCLIFileWatch opts of- FileWatchPoll -> fileWatchPoll stderr (inner . Just)- FileWatch -> fileWatch stderr (inner . Just)+ FileWatchPoll -> fileWatchPoll (inner . Just)+ FileWatch -> fileWatch (inner . Just) NoFileWatch -> inner Nothing where inner@@ -726,8 +718,6 @@ (ExecCmd cmd, args) -> return (cmd, args) (ExecRun, args) -> getRunCmd args (ExecGhc, args) -> getGhcCmd eoPackages args- -- NOTE: This doesn't work for GHCJS, because it doesn't have- -- a runghcjs binary. (ExecRunGhc, args) -> getRunGhcCmd eoPackages args runWithPath eoCwd $ exec cmd args@@ -759,7 +749,7 @@ let executables = filter isCExe $ concatMap Set.toList pkgComponents let (exe, args') = case args of [] -> (firstExe, args)- x:xs -> case find (\y -> y == (CExe $ T.pack x)) executables of+ x:xs -> case find (\y -> y == CExe (T.pack x)) executables of Nothing -> (firstExe, args) argExe -> (argExe, xs) where@@ -867,9 +857,6 @@ { boptsCLITargets = if hroptsAll hropts then [] else targetNames } withConfig YesReexec $ withEnvConfig AllowNoTargets boptsCLI $ generateHpcReportForTargets hropts tixFiles targetNames--freezeCmd :: FreezeOpts -> RIO Runner ()-freezeCmd freezeOpts = withConfig YesReexec $ withDefaultEnvConfig $ freeze freezeOpts data MainException = InvalidReExecVersion String String | InvalidPathForExec FilePath
@@ -19,7 +19,7 @@ import Stack.Dot dummyPayload :: DotPayload-dummyPayload = DotPayload (parseVersion "0.0.0.0") (Just (Right BSD3))+dummyPayload = DotPayload (parseVersion "0.0.0.0") (Just (Right BSD3)) Nothing spec :: Spec spec = do@@ -53,14 +53,14 @@ prop "requested packages are pruned" $ do let resolvedGraph = runIdentity (resolveDependencies Nothing graph stubLoader)- allPackages g = Map.keysSet g `Set.union` fold (fmap fst g)+ allPackages g = Map.keysSet g `Set.union` foldMap fst g forAll (sublistOf (Set.toList (allPackages resolvedGraph))) $ \toPrune -> let pruned = pruneGraph [pkgName "one", pkgName "two"] toPrune resolvedGraph in Set.null (allPackages pruned `Set.intersection` Set.fromList toPrune) prop "pruning removes orhpans" $ do let resolvedGraph = runIdentity (resolveDependencies Nothing graph stubLoader)- allPackages g = Map.keysSet g `Set.union` fold (fmap fst g)+ allPackages g = Map.keysSet g `Set.union` foldMap fst g orphans g = Map.filterWithKey (\k _ -> not (graphElem k g)) g forAll (sublistOf (Set.toList (allPackages resolvedGraph))) $ \toPrune -> let pruned = pruneGraph [pkgName "one", pkgName "two"] toPrune resolvedGraph
@@ -5,7 +5,6 @@ module Stack.LockSpec where import Pantry.Internal.AesonExtended (WithJSONWarnings(..))-import Data.ByteString (ByteString) import qualified Data.Yaml as Yaml import Distribution.Types.PackageName (mkPackageName) import Distribution.Types.Version (mkVersion)@@ -44,9 +43,9 @@ [r|#some snapshots: - completed:- compiler: ghc-8.2.2+ compiler: ghc-8.6.5 original:- compiler: ghc-8.2.2+ compiler: ghc-8.6.5 packages: [] |] pkgImm <- lckPkgImmutableLocations <$> decodeLocked lockFile@@ -60,11 +59,11 @@ size: 527801 url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/11/22.yaml sha256: 7c8b1853da784bd7beb8728168bf4e879d8a2f6daf408ca0fa7933451864a96a- original: lts-11.22+ original: lts-14.27 - completed:- compiler: ghc-8.2.2+ compiler: ghc-8.6.5 original:- compiler: ghc-8.2.2+ compiler: ghc-8.6.5 packages: [] |] pkgImm <- lckPkgImmutableLocations <$> decodeLocked lockFile@@ -78,11 +77,11 @@ size: 527801 url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/11/22.yaml sha256: 7c8b1853da784bd7beb8728168bf4e879d8a2f6daf408ca0fa7933451864a96a- original: lts-11.22+ original: lts-14.27 - completed:- compiler: ghc-8.2.2+ compiler: ghc-8.6.5 original:- compiler: ghc-8.2.2+ compiler: ghc-8.6.5 packages: - original: subdir: wai@@ -90,9 +89,6 @@ commit: d11d63f1a6a92db8c637a8d33e7953ce6194a3e0 completed: subdir: wai- cabal-file:- size: 1765- sha256: eea52c4967d8609c2f79213d6dffe6d6601034f1471776208404781de7051410 name: wai version: 3.2.1.2 git: https://github.com/yesodweb/wai.git@@ -106,9 +102,6 @@ commit: d11d63f1a6a92db8c637a8d33e7953ce6194a3e0 completed: subdir: warp- cabal-file:- size: 10725- sha256: cfec5336260bb4b1ecbd833f7d6948fd1ee373770471fe79796cf9c389c71758 name: warp version: 3.2.25 git: https://github.com/yesodweb/wai.git@@ -128,7 +121,6 @@ emptyRPM = RawPackageMetadata { rpmName = Nothing , rpmVersion = Nothing , rpmTreeKey = Nothing- , rpmCabal = Nothing } pkgImm `shouldBe` [ LockedLocation@@ -145,10 +137,6 @@ (decodeSHA "ecfd0b4b75f435a3f362394807b35e5ef0647b1a25005d44a3632c49db4833d2") (FileSize 714))- , pmCabal =- toBlobKey- "eea52c4967d8609c2f79213d6dffe6d6601034f1471776208404781de7051410"- 1765 })) , LockedLocation (RPLIRepo (waiSubdirRepo "warp") emptyRPM)@@ -164,9 +152,5 @@ (decodeSHA "f808e075811b002563d24c393ce115be826bb66a317d38da22c513ee42b7443a") (FileSize 5103))- , pmCabal =- toBlobKey- "cfec5336260bb4b1ecbd833f7d6948fd1ee373770471fe79796cf9c389c71758"- 10725 })) ]
@@ -1,9 +1,40 @@+{-# LANGUAGE ForeignFunctionInterface #-} module System.Terminal ( fixCodePage+, getTerminalWidth , hIsTerminalDeviceOrMinTTY ) where +import Foreign+import Foreign.C.Types import RIO (MonadIO, Handle, hIsTerminalDevice)++#include <sys/ioctl.h>+#include <unistd.h>+++newtype WindowWidth = WindowWidth CUShort+ deriving (Eq, Ord, Show)++instance Storable WindowWidth where+ sizeOf _ = (#size struct winsize)+ alignment _ = (#alignment struct winsize)+ peek p = WindowWidth <$> (#peek struct winsize, ws_col) p+ poke p (WindowWidth w) = do+ (#poke struct winsize, ws_col) p w++foreign import ccall "sys/ioctl.h ioctl"+ ioctl :: CInt -> CInt -> Ptr WindowWidth -> IO CInt++getTerminalWidth :: IO (Maybe Int)+getTerminalWidth =+ alloca $ \p -> do+ errno <- ioctl (#const STDOUT_FILENO) (#const TIOCGWINSZ) p+ if errno < 0+ then return Nothing+ else do+ WindowWidth w <- peek p+ return . Just . fromIntegral $ w fixCodePage :: x -> y -> a -> a fixCodePage _ _ = id
@@ -1,14 +1,73 @@+{-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} module System.Terminal ( fixCodePage+, getTerminalWidth , hIsTerminalDeviceOrMinTTY ) where import Distribution.Types.Version (mkVersion)+import Foreign.Ptr+import Foreign.Storable+import Foreign.Marshal.Alloc import Stack.Prelude+import System.IO hiding (hIsTerminalDevice)+import System.Process import System.Win32 (isMinTTYHandle, withHandleToHANDLE) import System.Win32.Console (setConsoleCP, setConsoleOutputCP, getConsoleCP, getConsoleOutputCP)+import RIO.Partial (read)++type HANDLE = Ptr ()++data CONSOLE_SCREEN_BUFFER_INFO++sizeCONSOLE_SCREEN_BUFFER_INFO :: Int+sizeCONSOLE_SCREEN_BUFFER_INFO = 22++posCONSOLE_SCREEN_BUFFER_INFO_srWindow :: Int+posCONSOLE_SCREEN_BUFFER_INFO_srWindow = 10 -- 4 x Word16 Left,Top,Right,Bottom++c_STD_OUTPUT_HANDLE :: Int+c_STD_OUTPUT_HANDLE = -11++foreign import ccall unsafe "windows.h GetConsoleScreenBufferInfo"+ c_GetConsoleScreenBufferInfo :: HANDLE -> Ptr CONSOLE_SCREEN_BUFFER_INFO -> IO Bool++foreign import ccall unsafe "windows.h GetStdHandle"+ c_GetStdHandle :: Int -> IO HANDLE+++getTerminalWidth :: IO (Maybe Int)+getTerminalWidth = do+ hdl <- c_GetStdHandle c_STD_OUTPUT_HANDLE+ allocaBytes sizeCONSOLE_SCREEN_BUFFER_INFO $ \p -> do+ b <- c_GetConsoleScreenBufferInfo hdl p+ if not b+ then do -- This could happen on Cygwin or MSYS+ let stty = (shell "stty size") { + std_in = UseHandle stdin+ , std_out = CreatePipe+ , std_err = CreatePipe+ }+ (_, mbStdout, _, rStty) <- createProcess stty+ exStty <- waitForProcess rStty+ case exStty of+ ExitFailure _ -> return Nothing+ ExitSuccess ->+ maybe (return Nothing)+ (\hSize -> do+ sizeStr <- hGetContents hSize+ case map read $ words sizeStr :: [Int] of+ [_r, c] -> return $ Just c+ _ -> return Nothing+ )+ mbStdout+ else do+ [left,_top,right,_bottom] <- forM [0..3] $ \i -> do+ v <- peekByteOff p ((i*2) + posCONSOLE_SCREEN_BUFFER_INFO_srWindow)+ return $ fromIntegral (v :: Word16)+ return $ Just (1+right-left) -- | Set the code page for this process as necessary. Only applies to Windows. -- See: https://github.com/commercialhaskell/stack/issues/738
@@ -1,6 +1,6 @@ cabal-version: 2.0 name: stack-version: 2.1.3.1+version: 2.3.1 license: BSD3 license-file: LICENSE maintainer: manny@fpcomplete.com@@ -28,7 +28,6 @@ ChangeLog.md README.md stack.yaml- snapshot.yaml doc/azure_ci.md doc/build_command.md doc/build_overview.md@@ -67,9 +66,9 @@ location: https://github.com/commercialhaskell/stack custom-setup- setup-depends: Cabal >=2.4.0.1,+ setup-depends: Cabal >=3.0.0.0, base >=4.10 && <5,- filepath >=1.4.1.2+ filepath >=1.4.2.1 flag disable-git-info description:@@ -137,7 +136,6 @@ Stack.Docker Stack.Dot Stack.FileWatch- Stack.Freeze Stack.GhcPkg Stack.Ghci Stack.Ghci.Script@@ -157,7 +155,6 @@ Stack.Options.DockerParser Stack.Options.DotParser Stack.Options.ExecParser- Stack.Options.FreezeParser Stack.Options.GhcBuildParser Stack.Options.GhciParser Stack.Options.GhcVariantParser@@ -213,6 +210,7 @@ Paths_stack hs-source-dirs: src/ other-modules:+ Path.Extended Stack.Types.Cache autogen-modules: Paths_stack@@ -221,96 +219,95 @@ -fwarn-incomplete-record-updates -optP-Wno-nonportable-include-path -fwarn-identities build-depends:- Cabal >=2.4.0.1,- aeson >=1.2.4.0,+ Cabal >=3.0.0.0,+ aeson >=1.4.6.0, annotated-wl-pprint >=0.7.0,- ansi-terminal >=0.9,- array >=0.5.2.0,- async >=2.1.1.1,- attoparsec >=0.13.2.2,+ ansi-terminal >=0.9.1,+ array >=0.5.3.0,+ async >=2.2.2,+ attoparsec >=0.13.2.3, base >=4.10 && <5,- base64-bytestring >=1.0.0.1,+ base64-bytestring >=1.0.0.3, bytestring >=0.10.8.2,- colour >=2.3.4,- conduit >=1.3.0.3,- conduit-extra >=1.3.0,- containers >=0.5.10.2,+ casa-client >=0.0.1,+ casa-types >=0.0.1,+ colour >=2.3.5,+ conduit >=1.3.1.2,+ conduit-extra >=1.3.4,+ containers >=0.6.0.1, cryptonite >=0.25, cryptonite-conduit >=0.2.2,- deepseq >=1.4.3.0,- directory >=1.3.0.2,+ deepseq >=1.4.4.0,+ directory >=1.3.3.0, echo >=0.1.3,- exceptions >=0.8.3,- extra >=1.6.9,- file-embed >=0.0.10.1,- filelock >=0.1.1.2,- filepath >=1.4.1.2,+ exceptions >=0.10.4,+ extra >=1.6.19,+ file-embed >=0.0.11.1,+ filelock >=0.1.1.4,+ filepath >=1.4.2.1, fsnotify >=0.3.0.1,- generic-deriving >=1.12.2,+ generic-deriving >=1.12.4, hackage-security >=0.5.3.0, hashable >=1.2.7.0, hi-file-parser >=0.1.0.0,- hpack >=0.31.2,+ hpack >=0.33.0, hpc >=0.6.0.3,- http-client >=0.5.13.1,+ http-client >=0.6.4, http-client-tls >=0.3.5.3,- http-conduit >=2.3.2,- http-download >=0.1.0.0,- http-types >=0.12.1,- memory >=0.14.16,- microlens >=0.4.8.3,+ http-conduit >=2.3.7.3,+ http-download >=0.2.0.0,+ http-types >=0.12.3,+ memory >=0.14.18,+ microlens >=0.4.10, mintty >=0.1.2,- mono-traversable >=1.0.9.0,+ mono-traversable >=1.0.15.1, mtl >=2.2.2,- mustache >=2.3.0,- neat-interpolation >=0.3.2.1,- network-uri >=2.6.1.0,+ mustache >=2.3.1,+ neat-interpolation >=0.3.2.6,+ network-uri >=2.6.2.0, open-browser >=0.2.1.0,- optparse-applicative >=0.14.2.0,- pantry >=0.1.1.1,+ optparse-applicative >=0.14.3.0,+ pantry >=0.4.0.1, path >=0.6.1,- path-io >=1.3.3,+ path-io >=1.4.2, persistent >=2.9.2, persistent-sqlite >=2.9.3,- persistent-template >=2.5.4,- pretty >=1.1.3.3,+ persistent-template >=2.6.0,+ pretty >=1.1.3.6, primitive >=0.6.4.0,- process >=1.6.3.0,+ process >=1.6.5.0, project-template >=0.2.0.1, regex-applicative-text >=0.1.0.1,- resource-pool >=0.2.3.2,- resourcet >=1.2.1,- retry >=0.7.6.3,- rio >=0.1.11.0,+ retry >=0.8.1.0,+ rio >=0.1.14.0, rio-prettyprint >=0.1.0.0, semigroups >=0.18.5, split >=0.2.3.3,- stm >=2.4.5.0,- streaming-commons >=0.1.19,- tar >=0.5.1.0,- template-haskell >=2.12.0.0,- temporary >=1.2.1.1,- terminal-size >=0.3.2.1,- text >=1.2.3.0,+ stm >=2.5.0.0,+ streaming-commons >=0.2.1.2,+ tar >=0.5.1.1,+ template-haskell >=2.14.0.0,+ temporary >=1.3,+ text >=1.2.3.1, text-metrics >=0.3.0,- th-reify-many >=0.1.8,+ th-reify-many >=0.1.9, time >=1.8.0.2, tls >=1.4.1,- transformers >=0.5.2.0,+ transformers >=0.5.6.2, typed-process >=0.2.6.0,- unicode-transforms >=0.3.4,- unix-compat >=0.5.0.1,+ unicode-transforms >=0.3.6,+ unix-compat >=0.5.2, unliftio >=0.2.12,- unordered-containers >=0.2.9.0,- vector >=0.12.0.1,- yaml >=0.10.4.0,- zip-archive >=0.3.3,- zlib >=0.6.2+ unordered-containers >=0.2.10.0,+ vector >=0.12.1.2,+ yaml >=0.11.2.0,+ zip-archive >=0.4.1,+ zlib >=0.6.2.1 if os(windows) cpp-options: -DWINDOWS build-depends:- Win32 -any+ Win32 >=2.6.1.0 else build-tools: hsc2hs -any build-depends:@@ -342,97 +339,96 @@ -fwarn-incomplete-record-updates -optP-Wno-nonportable-include-path -threaded -rtsopts build-depends:- Cabal >=2.4.0.1,- aeson >=1.2.4.0,+ Cabal >=3.0.0.0,+ aeson >=1.4.6.0, annotated-wl-pprint >=0.7.0,- ansi-terminal >=0.9,- array >=0.5.2.0,- async >=2.1.1.1,- attoparsec >=0.13.2.2,+ ansi-terminal >=0.9.1,+ array >=0.5.3.0,+ async >=2.2.2,+ attoparsec >=0.13.2.3, base >=4.10 && <5,- base64-bytestring >=1.0.0.1,+ base64-bytestring >=1.0.0.3, bytestring >=0.10.8.2,- colour >=2.3.4,- conduit >=1.3.0.3,- conduit-extra >=1.3.0,- containers >=0.5.10.2,+ casa-client >=0.0.1,+ casa-types >=0.0.1,+ colour >=2.3.5,+ conduit >=1.3.1.2,+ conduit-extra >=1.3.4,+ containers >=0.6.0.1, cryptonite >=0.25, cryptonite-conduit >=0.2.2,- deepseq >=1.4.3.0,- directory >=1.3.0.2,+ deepseq >=1.4.4.0,+ directory >=1.3.3.0, echo >=0.1.3,- exceptions >=0.8.3,- extra >=1.6.9,- file-embed >=0.0.10.1,- filelock >=0.1.1.2,- filepath >=1.4.1.2,+ exceptions >=0.10.4,+ extra >=1.6.19,+ file-embed >=0.0.11.1,+ filelock >=0.1.1.4,+ filepath >=1.4.2.1, fsnotify >=0.3.0.1,- generic-deriving >=1.12.2,+ generic-deriving >=1.12.4, hackage-security >=0.5.3.0, hashable >=1.2.7.0, hi-file-parser >=0.1.0.0,- hpack >=0.31.2,+ hpack >=0.33.0, hpc >=0.6.0.3,- http-client >=0.5.13.1,+ http-client >=0.6.4, http-client-tls >=0.3.5.3,- http-conduit >=2.3.2,- http-download >=0.1.0.0,- http-types >=0.12.1,- memory >=0.14.16,- microlens >=0.4.8.3,+ http-conduit >=2.3.7.3,+ http-download >=0.2.0.0,+ http-types >=0.12.3,+ memory >=0.14.18,+ microlens >=0.4.10, mintty >=0.1.2,- mono-traversable >=1.0.9.0,+ mono-traversable >=1.0.15.1, mtl >=2.2.2,- mustache >=2.3.0,- neat-interpolation >=0.3.2.1,- network-uri >=2.6.1.0,+ mustache >=2.3.1,+ neat-interpolation >=0.3.2.6,+ network-uri >=2.6.2.0, open-browser >=0.2.1.0,- optparse-applicative >=0.14.2.0,- pantry >=0.1.1.1,+ optparse-applicative >=0.14.3.0,+ pantry >=0.4.0.1, path >=0.6.1,- path-io >=1.3.3,+ path-io >=1.4.2, persistent >=2.9.2, persistent-sqlite >=2.9.3,- persistent-template >=2.5.4,- pretty >=1.1.3.3,+ persistent-template >=2.6.0,+ pretty >=1.1.3.6, primitive >=0.6.4.0,- process >=1.6.3.0,+ process >=1.6.5.0, project-template >=0.2.0.1, regex-applicative-text >=0.1.0.1,- resource-pool >=0.2.3.2,- resourcet >=1.2.1,- retry >=0.7.6.3,- rio >=0.1.11.0,+ retry >=0.8.1.0,+ rio >=0.1.14.0, rio-prettyprint >=0.1.0.0, semigroups >=0.18.5, split >=0.2.3.3, stack -any,- stm >=2.4.5.0,- streaming-commons >=0.1.19,- tar >=0.5.1.0,- template-haskell >=2.12.0.0,- temporary >=1.2.1.1,- terminal-size >=0.3.2.1,- text >=1.2.3.0,+ stm >=2.5.0.0,+ streaming-commons >=0.2.1.2,+ tar >=0.5.1.1,+ template-haskell >=2.14.0.0,+ temporary >=1.3,+ text >=1.2.3.1, text-metrics >=0.3.0,- th-reify-many >=0.1.8,+ th-reify-many >=0.1.9, time >=1.8.0.2, tls >=1.4.1,- transformers >=0.5.2.0,+ transformers >=0.5.6.2, typed-process >=0.2.6.0,- unicode-transforms >=0.3.4,- unix-compat >=0.5.0.1,+ unicode-transforms >=0.3.6,+ unix-compat >=0.5.2, unliftio >=0.2.12,- unordered-containers >=0.2.9.0,- vector >=0.12.0.1,- yaml >=0.10.4.0,- zip-archive >=0.3.3,- zlib >=0.6.2+ unordered-containers >=0.2.10.0,+ vector >=0.12.1.2,+ yaml >=0.11.2.0,+ zip-archive >=0.4.1,+ zlib >=0.6.2.1 if os(windows) cpp-options: -DWINDOWS build-depends:- Win32 -any+ Win32 >=2.6.1.0 else build-tools: hsc2hs -any build-depends:@@ -444,8 +440,8 @@ if !flag(disable-git-info) cpp-options: -DUSE_GIT_INFO build-depends:- githash >=0.1.3.0,- optparse-simple >=0.1.0+ githash >=0.1.3.3,+ optparse-simple >=0.1.1.2 if flag(hide-dependency-versions) cpp-options: -DHIDE_DEP_VERSIONS@@ -464,98 +460,97 @@ -fwarn-incomplete-record-updates -optP-Wno-nonportable-include-path -threaded -rtsopts -with-rtsopts=-N build-depends:- Cabal >=2.4.0.1,- aeson >=1.2.4.0,+ Cabal >=3.0.0.0,+ aeson >=1.4.6.0, annotated-wl-pprint >=0.7.0,- ansi-terminal >=0.9,- array >=0.5.2.0,- async >=2.1.1.1,- attoparsec >=0.13.2.2,+ ansi-terminal >=0.9.1,+ array >=0.5.3.0,+ async >=2.2.2,+ attoparsec >=0.13.2.3, base >=4.10 && <5,- base64-bytestring >=1.0.0.1,+ base64-bytestring >=1.0.0.3, bytestring >=0.10.8.2,- colour >=2.3.4,- conduit >=1.3.0.3,- conduit-extra >=1.3.0,- containers >=0.5.10.2,+ casa-client >=0.0.1,+ casa-types >=0.0.1,+ colour >=2.3.5,+ conduit >=1.3.1.2,+ conduit-extra >=1.3.4,+ containers >=0.6.0.1, cryptonite >=0.25, cryptonite-conduit >=0.2.2,- deepseq >=1.4.3.0,- directory >=1.3.0.2,+ deepseq >=1.4.4.0,+ directory >=1.3.3.0, echo >=0.1.3,- exceptions >=0.8.3,- extra >=1.6.9,- file-embed >=0.0.10.1,- filelock >=0.1.1.2,- filepath >=1.4.1.2,+ exceptions >=0.10.4,+ extra >=1.6.19,+ file-embed >=0.0.11.1,+ filelock >=0.1.1.4,+ filepath >=1.4.2.1, fsnotify >=0.3.0.1,- generic-deriving >=1.12.2,+ generic-deriving >=1.12.4, hackage-security >=0.5.3.0, hashable >=1.2.7.0, hi-file-parser >=0.1.0.0,- hpack >=0.31.2,+ hpack >=0.33.0, hpc >=0.6.0.3,- hspec >=2.4.8,- http-client >=0.5.13.1,+ hspec >=2.7.1,+ http-client >=0.6.4, http-client-tls >=0.3.5.3,- http-conduit >=2.3.2,- http-download >=0.1.0.0,- http-types >=0.12.1,- memory >=0.14.16,- microlens >=0.4.8.3,+ http-conduit >=2.3.7.3,+ http-download >=0.2.0.0,+ http-types >=0.12.3,+ memory >=0.14.18,+ microlens >=0.4.10, mintty >=0.1.2,- mono-traversable >=1.0.9.0,+ mono-traversable >=1.0.15.1, mtl >=2.2.2,- mustache >=2.3.0,- neat-interpolation >=0.3.2.1,- network-uri >=2.6.1.0,+ mustache >=2.3.1,+ neat-interpolation >=0.3.2.6,+ network-uri >=2.6.2.0, open-browser >=0.2.1.0,- optparse-applicative >=0.14.2.0,- optparse-generic >=1.3.0,- pantry >=0.1.1.1,+ optparse-applicative >=0.14.3.0,+ optparse-generic >=1.3.1,+ pantry >=0.4.0.1, path >=0.6.1,- path-io >=1.3.3,+ path-io >=1.4.2, persistent >=2.9.2, persistent-sqlite >=2.9.3,- persistent-template >=2.5.4,- pretty >=1.1.3.3,+ persistent-template >=2.6.0,+ pretty >=1.1.3.6, primitive >=0.6.4.0,- process >=1.6.3.0,+ process >=1.6.5.0, project-template >=0.2.0.1, regex-applicative-text >=0.1.0.1,- resource-pool >=0.2.3.2,- resourcet >=1.2.1,- retry >=0.7.6.3,- rio >=0.1.11.0,+ retry >=0.8.1.0,+ rio >=0.1.14.0, rio-prettyprint >=0.1.0.0, semigroups >=0.18.5, split >=0.2.3.3,- stm >=2.4.5.0,- streaming-commons >=0.1.19,- tar >=0.5.1.0,- template-haskell >=2.12.0.0,- temporary >=1.2.1.1,- terminal-size >=0.3.2.1,- text >=1.2.3.0,+ stm >=2.5.0.0,+ streaming-commons >=0.2.1.2,+ tar >=0.5.1.1,+ template-haskell >=2.14.0.0,+ temporary >=1.3,+ text >=1.2.3.1, text-metrics >=0.3.0,- th-reify-many >=0.1.8,+ th-reify-many >=0.1.9, time >=1.8.0.2, tls >=1.4.1,- transformers >=0.5.2.0,+ transformers >=0.5.6.2, typed-process >=0.2.6.0,- unicode-transforms >=0.3.4,- unix-compat >=0.5.0.1,+ unicode-transforms >=0.3.6,+ unix-compat >=0.5.2, unliftio >=0.2.12,- unordered-containers >=0.2.9.0,- vector >=0.12.0.1,- yaml >=0.10.4.0,- zip-archive >=0.3.3,- zlib >=0.6.2+ unordered-containers >=0.2.10.0,+ vector >=0.12.1.2,+ yaml >=0.11.2.0,+ zip-archive >=0.4.1,+ zlib >=0.6.2.1 if os(windows) cpp-options: -DWINDOWS build-depends:- Win32 -any+ Win32 >=2.6.1.0 else build-tools: hsc2hs -any build-depends:@@ -563,6 +558,9 @@ if !flag(integration-tests) buildable: False+ + if flag(static)+ ld-options: -static -pthread test-suite stack-test type: exitcode-stdio-1.0@@ -589,101 +587,100 @@ -fwarn-incomplete-record-updates -optP-Wno-nonportable-include-path -threaded build-depends:- Cabal >=2.4.0.1,- QuickCheck >=2.10.1,- aeson >=1.2.4.0,+ Cabal >=3.0.0.0,+ QuickCheck >=2.13.2,+ aeson >=1.4.6.0, annotated-wl-pprint >=0.7.0,- ansi-terminal >=0.9,- array >=0.5.2.0,- async >=2.1.1.1,- attoparsec >=0.13.2.2,+ ansi-terminal >=0.9.1,+ array >=0.5.3.0,+ async >=2.2.2,+ attoparsec >=0.13.2.3, base >=4.10 && <5,- base64-bytestring >=1.0.0.1,+ base64-bytestring >=1.0.0.3, bytestring >=0.10.8.2,- colour >=2.3.4,- conduit >=1.3.0.3,- conduit-extra >=1.3.0,- containers >=0.5.10.2,+ casa-client >=0.0.1,+ casa-types >=0.0.1,+ colour >=2.3.5,+ conduit >=1.3.1.2,+ conduit-extra >=1.3.4,+ containers >=0.6.0.1, cryptonite >=0.25, cryptonite-conduit >=0.2.2,- deepseq >=1.4.3.0,- directory >=1.3.0.2,+ deepseq >=1.4.4.0,+ directory >=1.3.3.0, echo >=0.1.3,- exceptions >=0.8.3,- extra >=1.6.9,- file-embed >=0.0.10.1,- filelock >=0.1.1.2,- filepath >=1.4.1.2,+ exceptions >=0.10.4,+ extra >=1.6.19,+ file-embed >=0.0.11.1,+ filelock >=0.1.1.4,+ filepath >=1.4.2.1, fsnotify >=0.3.0.1,- generic-deriving >=1.12.2,+ generic-deriving >=1.12.4, hackage-security >=0.5.3.0, hashable >=1.2.7.0, hi-file-parser >=0.1.0.0,- hpack >=0.31.2,+ hpack >=0.33.0, hpc >=0.6.0.3,- hspec >=2.4.8,- http-client >=0.5.13.1,+ hspec >=2.7.1,+ http-client >=0.6.4, http-client-tls >=0.3.5.3,- http-conduit >=2.3.2,- http-download >=0.1.0.0,- http-types >=0.12.1,- memory >=0.14.16,- microlens >=0.4.8.3,+ http-conduit >=2.3.7.3,+ http-download >=0.2.0.0,+ http-types >=0.12.3,+ memory >=0.14.18,+ microlens >=0.4.10, mintty >=0.1.2,- mono-traversable >=1.0.9.0,+ mono-traversable >=1.0.15.1, mtl >=2.2.2,- mustache >=2.3.0,- neat-interpolation >=0.3.2.1,- network-uri >=2.6.1.0,+ mustache >=2.3.1,+ neat-interpolation >=0.3.2.6,+ network-uri >=2.6.2.0, open-browser >=0.2.1.0,- optparse-applicative >=0.14.2.0,- pantry >=0.1.1.1,+ optparse-applicative >=0.14.3.0,+ pantry >=0.4.0.1, path >=0.6.1,- path-io >=1.3.3,+ path-io >=1.4.2, persistent >=2.9.2, persistent-sqlite >=2.9.3,- persistent-template >=2.5.4,- pretty >=1.1.3.3,+ persistent-template >=2.6.0,+ pretty >=1.1.3.6, primitive >=0.6.4.0,- process >=1.6.3.0,+ process >=1.6.5.0, project-template >=0.2.0.1, raw-strings-qq >=1.1, regex-applicative-text >=0.1.0.1,- resource-pool >=0.2.3.2,- resourcet >=1.2.1,- retry >=0.7.6.3,- rio >=0.1.11.0,+ retry >=0.8.1.0,+ rio >=0.1.14.0, rio-prettyprint >=0.1.0.0, semigroups >=0.18.5, smallcheck >=1.1.5, split >=0.2.3.3, stack -any,- stm >=2.4.5.0,- streaming-commons >=0.1.19,- tar >=0.5.1.0,- template-haskell >=2.12.0.0,- temporary >=1.2.1.1,- terminal-size >=0.3.2.1,- text >=1.2.3.0,+ stm >=2.5.0.0,+ streaming-commons >=0.2.1.2,+ tar >=0.5.1.1,+ template-haskell >=2.14.0.0,+ temporary >=1.3,+ text >=1.2.3.1, text-metrics >=0.3.0,- th-reify-many >=0.1.8,+ th-reify-many >=0.1.9, time >=1.8.0.2, tls >=1.4.1,- transformers >=0.5.2.0,+ transformers >=0.5.6.2, typed-process >=0.2.6.0,- unicode-transforms >=0.3.4,- unix-compat >=0.5.0.1,+ unicode-transforms >=0.3.6,+ unix-compat >=0.5.2, unliftio >=0.2.12,- unordered-containers >=0.2.9.0,- vector >=0.12.0.1,- yaml >=0.10.4.0,- zip-archive >=0.3.3,- zlib >=0.6.2+ unordered-containers >=0.2.10.0,+ vector >=0.12.1.2,+ yaml >=0.11.2.0,+ zip-archive >=0.4.1,+ zlib >=0.6.2.1 if os(windows) cpp-options: -DWINDOWS build-depends:- Win32 -any+ Win32 >=2.6.1.0 else build-tools: hsc2hs -any build-depends:
@@ -1,12 +1,14 @@-resolver: snapshot.yaml+resolver: lts-14.27 packages: - . docker: enable: false- repo: fpco/stack-build:lts-11.22 + #image: fpco/alpine-haskell-stack:8.6.5+ image: fpco/alpine-haskell-stack@sha256:49e7e15f3b1d3f882ba5bb701463b1d508fbf40e5aafce6ea31acd210da570ba+ nix: # --nix on the command-line to enable. packages:@@ -19,3 +21,16 @@ ghc-options: "$locals": -fhide-source-paths++extra-deps:+- Cabal-3.0.0.0@rev:0+- hpack-0.33.0@rev:0+- http-download-0.2.0.0@rev:0+- filelock-0.1.1.4@rev:0+- pantry-0.4.0.1@rev:0+- casa-client-0.0.1@rev:0+- casa-types-0.0.1@rev:0++drop-packages:+# See https://github.com/commercialhaskell/stack/pull/4712+- cabal-install
@@ -270,7 +270,7 @@ -- the main @stack.yaml@. -- defaultResolverArg :: String-defaultResolverArg = "--resolver=lts-11.22"+defaultResolverArg = "--resolver=lts-14.27" -- | Remove a file and ignore any warnings about missing files. removeFileIgnore :: HasCallStack => FilePath -> IO ()