diff --git a/.hlint.yaml b/.hlint.yaml index deb0f0d0c6..1eba17f0eb 100644 --- a/.hlint.yaml +++ b/.hlint.yaml @@ -16,6 +16,10 @@ - ignore: {name: "Use &&&"} - ignore: {name: "Redundant compare"} +# Added in hlint-2.0.10, ignoring for now +- ignore: {name: "Unnecessary hiding"} +- ignore: {name: "Use lambda-case"} + - ignore: {name: "Use fewer imports", within: [ "System.Process.Read", # Related to 'Hide post-AMP warnings' comment "Stack.Exec" # ifdef for System.Process.Read diff --git a/ChangeLog.md b/ChangeLog.md index 4d33f706c5..5a3c2e4606 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -48,6 +48,9 @@ Behavior changes: * `ghc-options:` for specific packages will now come after the options specified for all packages / particular sets of packages. See [#3573](https://github.com/commercialhaskell/stack/issues/3573). +* The `pvp-bounds` feature is no longer fully functional, due to some + issues with the Cabal library's printer. See + [#3550](https://github.com/commercialhaskell/stack/issues/3550). Other enhancements: @@ -118,6 +121,17 @@ Other enhancements: be optimal yet. The terminal width can be overriden with the new `--terminal-width` command-line option (this works even on non-POSIX). +* Passing non local packages as targets to `stack ghci` will now + cause them to be used as `-package` args along with package + hiding. +* Detect when user changed .cabal file instead of package.yaml. This + was implemented upstream in hpack. See + [#3383](https://github.com/commercialhaskell/stack/issues/3383). +* Automatically run `autoreconf -i` as necessary when a `configure` + script is missing. See + [#3534](https://github.com/commercialhaskell/stack/issues/3534) +* GHC bindists can now be identified by their SHA256 checksum in addition to + their SHA1 checksum, allowing for more security in download. Bug fixes: @@ -179,6 +193,9 @@ Bug fixes: * Fixes a bug that has existed since 1.5.0, where `stack setup --upgrade-cabal` would say that Cabal is already the latest version, when it wasn't. +* Ensure that an `extra-dep` from a local directory is not treated as + a `$locals` for GHC options purposes. See + [#3574](https://github.com/commercialhaskell/stack/issues/3574). ## 1.5.1 diff --git a/doc/GUIDE.md b/doc/GUIDE.md index c741338bcc..11797790da 100644 --- a/doc/GUIDE.md +++ b/doc/GUIDE.md @@ -1085,7 +1085,7 @@ The following changes will be made to stack.yaml: - aeson-0.10.0.0 - aeson-compat-0.3.0.0 - attoparsec-0.13.0.1 - - conduit-extra-1.1.9.2 + - conduit-extra-1.2.0 - email-validate-2.2.0 - hex-0.1.2 - http-api-data-0.2.2 @@ -1579,8 +1579,9 @@ what needs to be removed: We've already used `stack exec` used multiple times in this guide. As you've likely already guessed, it allows you to run executables, but with a slightly modified environment. In particular: `stack exec` looks for executables on -stack's bin paths, and sets a few additional environment variables (like -`GHC_PACKAGE_PATH`, which tells GHC which package databases to use). +stack's bin paths, and sets a few additional environment variables (like adding +those paths to `PATH`, and setting `GHC_PACKAGE_PATH`, which tells GHC which +package databases to use). If you want to see exactly what the modified environment looks like, try: @@ -1789,7 +1790,7 @@ it. Here is an example: -} ``` -## Finding project configs, and the implicit global +## Finding project configs, and the implicit global project Whenever you run something with stack, it needs a `stack.yaml` project file. The algorithm stack uses to find this is: @@ -1820,6 +1821,15 @@ configuration. It has no impact on projects at all. Every package you install with it is put into isolated databases just like everywhere else. The only magic is that it's the catch-all project whenever you're running stack somewhere else. +## Setting stack root location + +`stack path --stack-root` will tell you the location of the "stack root". Among +other things, this is where stack stores downloaded programs and snapshot +packages. This location can be configured by setting the STACK_ROOT environment +variable or passing the `--stack-root` commandline option. It is particularly +useful to do this on Windows, where filepaths are limited (MAX_PATH), and things +can break when this limit is exceeded. + ## `stack.yaml` vs `.cabal` files Now that we've covered a lot of stack use cases, this quick summary of @@ -1899,21 +1909,6 @@ __Other tools for comparison (including active and historical)__ * [cabal-src](https://hackage.haskell.org/package/cabal-src) is mostly irrelevant in the presence of both stack and cabal sandboxes, both of which make it easier to add additional package sources easily. The mega-sdist executable that ships with cabal-src is, however, still relevant. Its functionality may some day be folded into stack * [stackage-cli](https://hackage.haskell.org/package/stackage-cli) was an initial attempt to make cabal-install work more easily with curated snapshots, but due to a slight impedance mismatch between cabal.config constraints and snapshots, it did not work as well as hoped. It is deprecated in favor of stack. -## More resources - -There are lots of resources available for learning more about stack: - -* `stack --help` -* `stack --version` — identify the version and Git hash of the stack executable -* `--verbose` (or `-v`) — much more info about internal operations (useful for bug reports) -* The [home page](http://haskellstack.org) -* The [stack mailing list](https://groups.google.com/d/forum/haskell-stack) -* The [the FAQ](faq.md) -* The [stack wiki](https://github.com/commercialhaskell/stack/wiki) -* The [haskell-stack tag on Stack Overflow](http://stackoverflow.com/questions/tagged/haskell-stack) -* [Another getting started with stack tutorial](http://seanhess.github.io/2015/08/04/practical-haskell-getting-started.html) -* [Why is stack not cabal?](https://www.fpcomplete.com/blog/2015/06/why-is-stack-not-cabal) - ## Fun features @@ -1962,11 +1957,11 @@ As a starting point you can use [the "simple" template](https://github.com/comme An introduction into template-writing and a place for submitting official templates, you will find at [the stack-templates repository](https://github.com/commercialhaskell/stack-templates#readme). -### IDE +### Editor integration -stack has a work-in-progress suite of editor integrations, to do things like -getting type information in Emacs. For more information, see -[stack-ide](https://github.com/commercialhaskell/stack-ide#readme). +For editor integration, stack has a related project called +[intero](https://github.com/commercialhaskell/intero). It is particularly well +supported by emacs, but some other editors have integration for it as well. ### Visualizing dependencies @@ -2039,11 +2034,11 @@ image: and then run `stack image container` and then `docker images` to list the images. -Note that the executable will be built in the development environment -and copied to the container, so the dev OS must match that of the +Note that the executable will be built in the development environment +and copied to the container, so the dev OS must match that of the container OS. This is easily accomplished using [Docker integration](docker_integration.md), -under which the exe emitted by `stack build` will be built on the -Docker container, not the local OS. +under which the exe emitted by `stack build` will be built on the +Docker container, not the local OS. The executable will be stored under `/usr/local/bin/-exe` in the running container. @@ -2159,6 +2154,14 @@ build: executable-profiling: true ``` +### Further reading + +For more commands and uses, see [the official GHC chapter on +profiling](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html), +[the Haskell wiki](https://wiki.haskell.org/How_to_profile_a_Haskell_program), +and [the chapter on profiling in Real World +Haskell](http://book.realworldhaskell.org/read/profiling-and-optimization.html). + ### Tracing To generate a backtrace in case of exceptions during a test or benchmarks run, @@ -2173,10 +2176,17 @@ 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. -### Further reading +## More resources -For more commands and uses, see [the official GHC chapter on -profiling](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html), -[the Haskell wiki](https://wiki.haskell.org/How_to_profile_a_Haskell_program), -and [the chapter on profiling in Real World -Haskell](http://book.realworldhaskell.org/read/profiling-and-optimization.html). +There are lots of resources available for learning more about stack: + +* `stack --help` +* `stack --version` — identify the version and Git hash of the stack executable +* `--verbose` (or `-v`) — much more info about internal operations (useful for bug reports) +* The [home page](http://haskellstack.org) +* The [stack mailing list](https://groups.google.com/d/forum/haskell-stack) +* The [the FAQ](faq.md) +* The [stack wiki](https://github.com/commercialhaskell/stack/wiki) +* The [haskell-stack tag on Stack Overflow](http://stackoverflow.com/questions/tagged/haskell-stack) +* [Another getting started with stack tutorial](http://seanhess.github.io/2015/08/04/practical-haskell-getting-started.html) +* [Why is stack not cabal?](https://www.fpcomplete.com/blog/2015/06/why-is-stack-not-cabal) diff --git a/doc/yaml_configuration.md b/doc/yaml_configuration.md index a25c358dce..c16c584451 100644 --- a/doc/yaml_configuration.md +++ b/doc/yaml_configuration.md @@ -208,6 +208,9 @@ __NOTE__ It is highly recommended that you only use SHA1 values for a Git or Mercurial commit. Other values may work, but they are not officially supported, and may result in unexpected behavior (namely, Stack will not automatically pull to update to new versions). +Another problem with this is that your build will not be deterministic, +because when someone else tries to build the project they can get a +different checkout of the package. A common practice in the Haskell world is to use "megarepos", or repositories with multiple packages in various subdirectories. Some @@ -619,6 +622,13 @@ setup-info: "https://raw.githubusercontent.com/fpco/stackage-content/master/stac (Since 0.1.5) +__NOTE__ As of Stack 1.6.0, this feature does not reliably work, due +to issues with the Cabal library's printer. Stack will generate a +warning when a lossy conversion occurs, in which case you may need to +disable this setting. See +[#3550](https://github.com/commercialhaskell/stack/issues/3550) for +more information. + When using the `sdist` and `upload` commands, this setting determines whether the cabal file's dependencies should be modified to reflect PVP lower and upper bounds. Values are `none` (unchanged), `upper` (add upper bounds), `lower` (add @@ -797,7 +807,7 @@ The 5 parameters are: `author-email`, `author-name`, `category`, `copyright` and set per project by passing `-p "category:value"` to the `stack new` command. * _copyright_ - sets the `copyright` property in cabal. It is typically the name of the holder of the copyright on the package and the year(s) from which - copyright is claimed. For example: `Copyright: (c) 2006-2007 Joe Bloggs` + copyright is claimed. For example: `Copyright (c) 2006-2007 Joe Bloggs` * _github-username_ - used to generate `homepage` and `source-repository` in cabal. For instance `github-username: myusername` and `stack new my-project new-template` would result: @@ -817,7 +827,7 @@ templates: author-name: Your Name author-email: youremail@example.com category: Your Projects Category - copyright: 'Copyright: (c) 2017 Your Name' + copyright: 'Copyright (c) 2017 Your Name' github-username: yourusername ``` @@ -859,7 +869,7 @@ For more information, see Since 1.6.0 -# urls +### urls Customize the URLs where `stack` looks for snapshot build plans. @@ -874,3 +884,91 @@ urls: **Note:** The `latest-snapshot-url` field has been deprecated in favor of `latest-snapshot` and will be removed in a future version of `stack`. + +### jobs + +Specifies how many build tasks should be run in parallel. This can be overloaded +on the commandline via `-jN`, for example `-j2`. The default is to use the +number of processors reported by your CPU. One usage for this might be to avoid +running out of memory by setting it to 1, like this: + +```yaml +jobs: 1 +``` + +### work-dir + +Specifies relative path of work directory (default is `.stack-work`. This can +also be specified by env var or cli flag, in particular, the earlier items in +this list take precedence: + +1. `--work-dir DIR` passed on the commandline +2. `work-dir` in stack.yaml +3. `STACK_WORK` environment variable + +Since 0.1.10.0 + +### skip-msys + +Skips checking for and installing msys2 when stack is setting up the +environment. This is only useful on Windows machines, and usually doesn't make +sense in project configurations, just in `config.yaml`. Defaults to `false`, so +if this is used, it only really makes sense to use it like this: + +```yaml +skip-msys: true +``` + +Since 0.1.2.0 + +### concurrent-tests + +This option specifies whether test-suites should be executed concurrently with +each-other. The default for this is true, since this is usually fine and it +often means that tests can complete earlier. However, if some test-suites +require exclusive access to some resource, or require a great deal of CPU or +memory resources, then it makes sense to set this to `false` (the default is +`true`). + +```yaml +concurrent-tests: false +``` + +Since 0.1.2.0 + +### extra-path + +This option specifies additional directories to prepend to the PATH environment +variable. These will be used when resolving the location of executables, and +will also be visible in the `PATH` variable of processes run by stack. + +For example, to prepend `/path-to-some-dep/bin` to your PATh: + +```yaml +extra-path: +- /path-to-some-dep/bin +``` + +One thing to note is that other paths added by stack - things like the project's +bin dir and the compiler's bin dir - will take precedence over those specified +here (the automatic paths get prepended). + +Since 0.1.4.0 + +### local-programs-path + +This overrides the location of the programs directory, where tools like ghc and +msys get installed. + +On most systems, this defaults to a folder called `programs` +within the stack root directory. On windows, if the `LOCALAPPDATA` environment +variable exists, then it defaults to `$LOCALAPPDATA/Programs/stack/`, which +follows windows conventions. + +Since 1.3.0 + +### default-template + +This option specifies which template to use with `stack new`, when none is +specified. The default is called `new-template`. The other templates are listed +in [the stack-templates repo](https://github.com/commercialhaskell/stack-templates/). diff --git a/hlint.sh b/etc/scripts/hlint.sh similarity index 78% rename from hlint.sh rename to etc/scripts/hlint.sh index 65ed62e9e1..9a23b39acd 100755 --- a/hlint.sh +++ b/etc/scripts/hlint.sh @@ -2,6 +2,7 @@ set -eux +cd "$(dirname "$0")/../.." hlint src/ hlint src/ --cpp-define=WINDOWS=1 hlint test/ --cpp-simple diff --git a/package.yaml b/package.yaml index 207a3104a9..526d4e86e6 100644 --- a/package.yaml +++ b/package.yaml @@ -263,9 +263,9 @@ library: when: - condition: 'os(windows)' then: - source-dirs: windows/ + source-dirs: src/windows/ else: - source-dirs: unix/ + source-dirs: src/unix/ executables: stack: main: Main.hs diff --git a/src/Data/Attoparsec/Interpreter.hs b/src/Data/Attoparsec/Interpreter.hs index ca9285e148..9c29a8a1f1 100644 --- a/src/Data/Attoparsec/Interpreter.hs +++ b/src/Data/Attoparsec/Interpreter.hs @@ -1,5 +1,6 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE CPP #-} {- | This module implements parsing of additional arguments embedded in a comment when stack is invoked as a script interpreter @@ -139,14 +140,18 @@ getInterpreterArgs file = do parseArgStr str = case P.parseOnly (argsParser Escaping) (pack str) of - Left err -> handleFailure ("Error parsing command specified in the \ - \stack options comment: " ++ err) + Left err -> handleFailure ("Error parsing command specified in the " + ++ "stack options comment: " ++ err) Right [] -> handleFailure "Empty argument list in stack options comment" Right args -> return args decodeError e = case e of +#if MIN_VERSION_conduit_extra(1,2,0) + ParseError ctxs _ (Position line col _) -> +#else ParseError ctxs _ (Position line col) -> +#endif if null ctxs then "Parse error" else ("Expecting " ++ intercalate " or " ctxs) diff --git a/src/Stack/Build/ConstructPlan.hs b/src/Stack/Build/ConstructPlan.hs index c6e7587570..4a4b99404e 100644 --- a/src/Stack/Build/ConstructPlan.hs +++ b/src/Stack/Build/ConstructPlan.hs @@ -32,6 +32,7 @@ import Data.Text.Encoding (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 Generics.Deriving.Monoid (memptydefault, mappenddefault) import Lens.Micro (lens) import Stack.Build.Cache @@ -355,6 +356,7 @@ addFinal lp package isAllInOne = do , taskAllInOne = isAllInOne , taskCachePkgSrc = CacheSrcLocal (toFilePath (lpDir lp)) , taskAnyMissing = not $ Set.null missing + , taskBuildTypeConfig = packageBuildTypeConfig package } tell mempty { wFinals = Map.singleton (packageName package) res } @@ -571,8 +573,13 @@ installPackageGivenDeps isAllInOne ps package minstalled (missing, present, minL , taskAllInOne = isAllInOne , taskCachePkgSrc = toCachePkgSrc ps , taskAnyMissing = not $ Set.null missing + , taskBuildTypeConfig = packageBuildTypeConfig package } +-- | Is the build type of the package Configure +packageBuildTypeConfig :: Package -> Bool +packageBuildTypeConfig pkg = packageBuildType pkg == Just Configure + -- Update response in the lib map. If it is an error, and there's -- already an error about cyclic dependencies, prefer the cyclic error. updateLibMap :: PackageName -> Either ConstructPlanException AddDepRes -> M () @@ -1000,7 +1007,7 @@ pprintExceptions exceptions stackYaml parentMap wanted = case getShortestDepsPath parentMap wanted (packageName pkg) of Nothing -> line <> flow "needed for unknown reason - stack invariant violated." Just [] -> line <> flow "needed since" <+> pkgName <+> flow "is a build target." - Just (target:path) -> line <> flow "needed due to " <> encloseSep "" "" " -> " pathElems + Just (target:path) -> line <> flow "needed due to" <+> encloseSep "" "" " -> " pathElems where pathElems = [styleTarget . display $ target] ++ diff --git a/src/Stack/Build/Execute.hs b/src/Stack/Build/Execute.hs index 337722402e..e25008fccb 100644 --- a/src/Stack/Build/Execute.hs +++ b/src/Stack/Build/Execute.hs @@ -813,6 +813,9 @@ ensureConfig newConfigCache pkgDir ExecuteEnv {..} announce cabal cabalfp task = return $ fmap ignoreComponents mOldConfigCache /= Just (ignoreComponents newConfigCache) || mOldCabalMod /= Just newCabalMod let ConfigureOpts dirs nodirs = configCacheOpts newConfigCache + + when (taskBuildTypeConfig task) ensureConfigureScript + when needConfig $ withMVar eeConfigureLock $ \_ -> do deleteCaches pkgDir announce @@ -837,6 +840,19 @@ ensureConfig newConfigCache pkgDir ExecuteEnv {..} announce cabal cabalfp task = writeCabalMod pkgDir newCabalMod return needConfig + where + -- When build-type is Configure, we need to have a configure + -- script in the local directory. If it doesn't exist, build it + -- with autoreconf -i. See: + -- https://github.com/commercialhaskell/stack/issues/3534 + ensureConfigureScript = do + let fp = pkgDir $(mkRelFile "configure") + exists <- doesFileExist fp + unless exists $ do + logInfo $ "Trying to generate configure with autoreconf in " <> T.pack (toFilePath pkgDir) + menv <- getMinimalEnvOverride + readProcessNull (Just pkgDir) menv "autoreconf" ["-i"] `catchAny` \ex -> + logWarn $ "Unable to run autoreconf: " <> T.pack (show ex) announceTask :: MonadLogger m => Task -> Text -> m () announceTask task x = logInfo $ T.concat @@ -991,7 +1007,7 @@ withSingleContext runInBase ActionContext {..} ExecuteEnv {..} task@Task {..} md -- should simply use all of them. (Just customSetupDeps, _) -> do unless (Map.member $(mkPackageName "Cabal") customSetupDeps) $ - prettyWarnL $ + prettyWarnL [ display $ packageName package , "has a setup-depends field, but it does not mention a Cabal dependency. This is likely to cause build errors." ] diff --git a/src/Stack/Build/Source.hs b/src/Stack/Build/Source.hs index 6d2aab5fad..6317e16546 100644 --- a/src/Stack/Build/Source.hs +++ b/src/Stack/Build/Source.hs @@ -79,7 +79,7 @@ loadSourceMapFull needTargets boptsCli = do bconfig <- view buildConfigL (ls, localDeps, targets) <- parseTargets needTargets boptsCli lp <- getLocalPackages - locals <- mapM (loadLocalPackage boptsCli targets) $ Map.toList $ lpProject lp + locals <- mapM (loadLocalPackage True boptsCli targets) $ Map.toList $ lpProject lp checkFlagsUsed boptsCli locals localDeps (lsPackages ls) checkComponentsBuildable locals @@ -105,7 +105,7 @@ loadSourceMapFull needTargets boptsCli = do Left e -> throwM $ InvalidCabalFileInLocal (PLOther pl) e bs Right x -> return x mapM_ (printCabalFileWarning cabalfp) warnings - lp' <- loadLocalPackage boptsCli targets (n, LocalPackageView + lp' <- loadLocalPackage False boptsCli targets (n, LocalPackageView { lpvVersion = lpiVersion lpi , lpvRoot = dir , lpvCabalFP = cabalfp @@ -191,18 +191,22 @@ splitComponents = -- based on the selected components loadLocalPackage :: forall env. HasEnvConfig env - => BuildOptsCLI + => Bool + -- ^ Should this be treated as part of $locals? False for extra-deps. + -- + -- See: https://github.com/commercialhaskell/stack/issues/3574#issuecomment-346512821 + -> BuildOptsCLI -> Map PackageName Target -> (PackageName, LocalPackageView) -> RIO env LocalPackage -loadLocalPackage boptsCli targets (name, lpv) = do +loadLocalPackage isLocal boptsCli targets (name, lpv) = do let mtarget = Map.lookup name targets - config <- getPackageConfig boptsCli name (isJust mtarget) True + config <- getPackageConfig boptsCli name (isJust mtarget) isLocal bopts <- view buildOptsL let (exeCandidates, testCandidates, benchCandidates) = case mtarget of Just (TargetComps comps) -> splitComponents $ Set.toList comps - Just (TargetAll packageType) -> assert (packageType == ProjectPackage) + Just (TargetAll _packageType) -> ( packageExes pkg , if boptsTests bopts then Map.keysSet (packageTests pkg) diff --git a/src/Stack/Build/Target.hs b/src/Stack/Build/Target.hs index c1a4329fae..fd45ab727b 100644 --- a/src/Stack/Build/Target.hs +++ b/src/Stack/Build/Target.hs @@ -205,18 +205,6 @@ parseRawTarget t = -- Resolve the raw targets --------------------------------------------------------------------------------- --- | Simplified target information, after we've done a bunch of --- resolving. -data SimpleTarget - = STComponent !NamedComponent - -- ^ Targets a project package (non-dependency) with an explicit - -- component to be built. - | STDefaultComponents - -- ^ Targets a package with the default set of components (library - -- and all executables, plus test/bench for project packages if - -- the relevant flags are turned on). - deriving (Show, Eq, Ord) - data ResolveResult = ResolveResult { rrName :: !PackageName , rrRaw :: !RawInput diff --git a/src/Stack/Constants.hs b/src/Stack/Constants.hs index 1a4ac22914..a762eef143 100644 --- a/src/Stack/Constants.hs +++ b/src/Stack/Constants.hs @@ -6,6 +6,7 @@ module Stack.Constants (buildPlanDir + ,buildPlanCacheDir ,haskellModuleExts ,stackDotYaml ,stackWorkEnvVar @@ -206,6 +207,12 @@ buildPlanDir :: Path Abs Dir -- ^ Stack root -> Path Abs Dir buildPlanDir = ( $(mkRelDir "build-plan")) +-- | Path where binary caches of the build plans are stored. +buildPlanCacheDir + :: Path Abs Dir -- ^ Stack root + -> Path Abs Dir +buildPlanCacheDir = ( $(mkRelDir "build-plan-cache")) + -- | Environment variable that stores a variant to append to platform-specific directory -- names. Used to ensure incompatible binaries aren't shared between Docker builds and host platformVariantEnvVar :: String diff --git a/src/Stack/Ghci.hs b/src/Stack/Ghci.hs index e59518f1a9..65358fd91f 100644 --- a/src/Stack/Ghci.hs +++ b/src/Stack/Ghci.hs @@ -66,7 +66,7 @@ data GhciOpts = GhciOpts , ghciMainIs :: !(Maybe Text) , ghciLoadLocalDeps :: !Bool , ghciSkipIntermediate :: !Bool - , ghciHidePackages :: !Bool + , ghciHidePackages :: !(Maybe Bool) , ghciNoBuild :: !Bool , ghciOnlyMain :: !Bool } deriving Show @@ -138,31 +138,19 @@ ghci opts@GhciOpts{..} = do return (targetMap, Just (fileInfo, extraFiles)) -- Get a list of all the local target packages. localTargets <- getAllLocalTargets opts inputTargets mainIsTargets sourceMap + -- Get a list of all the non-local target packages. + nonLocalTargets <- getAllNonLocalTargets inputTargets -- Check if additional package arguments are sensible. addPkgs <- checkAdditionalPackages ghciAdditionalPackages -- Build required dependencies and setup local packages. stackYaml <- view stackYamlL buildDepsAndInitialSteps opts (map (packageNameText . fst) localTargets) - when (M.null inputTargets && isNothing mfileTargets) $ - prettyWarn $ vsep - [ flow "No targets specified, so ghci will not use any options from your package.yaml / *.cabal files." - , "" - , flow "Potential ways to resolve this:" - , bulletedList - [ fillSep - [ flow "If you want to use the package.yaml / *.cabal package in the current directory, use" - , styleShell "stack init" - , flow "to create a new stack.yaml." - ] - , flow "Add to the 'packages' field of" <+> display stackYaml - ] - , "" - ] + targetWarnings stackYaml localTargets nonLocalTargets mfileTargets -- Load the list of modules _after_ building, to catch changes in unlisted dependencies (#1180) pkgs <- getGhciPkgInfos buildOptsCLI sourceMap addPkgs (fmap fst mfileTargets) localTargets checkForIssues pkgs -- Finally, do the invocation of ghci - runGhci opts localTargets mainIsTargets pkgs (maybe [] snd mfileTargets) + runGhci opts localTargets mainIsTargets pkgs (maybe [] snd mfileTargets) (nonLocalTargets ++ addPkgs) preprocessTargets :: HasEnvConfig env => BuildOptsCLI -> [Text] -> RIO env (Either [Path Abs File] (Map PackageName Target)) preprocessTargets buildOptsCLI rawTargets = do @@ -286,6 +274,14 @@ getAllLocalTargets GhciOpts{..} targets0 mainIsTargets sourceMap = do ] return (directlyWanted ++ extraLoadDeps) +getAllNonLocalTargets + :: Map PackageName Target + -> RIO env [PackageName] +getAllNonLocalTargets targets = do + let isNonLocal (TargetAll Dependency) = True + isNonLocal _ = False + return $ map fst $ filter (isNonLocal . snd) (M.toList targets) + buildDepsAndInitialSteps :: HasEnvConfig env => GhciOpts -> [Text] -> RIO env () buildDepsAndInitialSteps GhciOpts{..} targets0 = do let targets = targets0 ++ map T.pack ghciAdditionalPackages @@ -317,14 +313,26 @@ runGhci -> Maybe (Map PackageName Target) -> [GhciPkgInfo] -> [Path Abs File] + -> [PackageName] -> RIO env () -runGhci GhciOpts{..} targets mainIsTargets pkgs extraFiles = do +runGhci GhciOpts{..} targets mainIsTargets pkgs extraFiles exposePackages = do config <- view configL wc <- view $ actualCompilerVersionL.whichCompilerL - let pkgopts = hidePkgOpt ++ genOpts ++ ghcOpts - hidePkgOpt = if null pkgs || not ghciHidePackages then [] else ["-hide-all-packages"] + let pkgopts = hidePkgOpts ++ genOpts ++ ghcOpts + shouldHidePackages = + fromMaybe (not (null pkgs && null exposePackages)) ghciHidePackages + hidePkgOpts = + if shouldHidePackages + then "-hide-all-packages" : + -- This is necessary, because current versions of ghci + -- will entirely fail to start if base isn't visible. This + -- is because it tries to use the interpreter to set + -- buffering options on standard IO. + "-package" : "base" : + concatMap (\n -> ["-package", packageNameString n]) exposePackages + else [] oneWordOpts bio - | ghciHidePackages = bioOneWordOpts bio ++ bioPackageFlags bio + | shouldHidePackages = bioOneWordOpts bio ++ bioPackageFlags bio | otherwise = bioOneWordOpts bio genOpts = nubOrd (concatMap (concatMap (oneWordOpts . snd) . ghciPkgOpts) pkgs) (omittedOpts, ghcOpts) = partition badForGhci $ @@ -700,6 +708,40 @@ checkForDuplicateModules pkgs = do M.toList $ M.fromListWith (++) $ concatMap (\pkg -> map ((, [ghciPkgName pkg]) . C.display) (S.toList (ghciPkgModules pkg))) pkgs +targetWarnings + :: HasRunner env + => Path Abs File + -> [(PackageName, (Path Abs File, Target))] + -> [PackageName] + -> Maybe (Map PackageName (Set (Path Abs File)), [Path Abs File]) + -> RIO env () +targetWarnings stackYaml localTargets nonLocalTargets mfileTargets = do + unless (null nonLocalTargets) $ + prettyWarnL + [ flow "Some targets" + , parens $ fillSep $ punctuate "," $ map (styleGood . display) nonLocalTargets + , flow "are not local packages, and so cannot be directly loaded." + , flow "In future versions of stack, this might be supported - see" + , styleUrl "https://github.com/commercialhaskell/stack/issues/1441" + , "." + , flow "It can still be useful to specify these, as they will be passed to ghci via -package flags." + ] + when (null localTargets && isNothing mfileTargets) $ + prettyWarn $ vsep + [ flow "No local targets specified, so ghci will not use any options from your package.yaml / *.cabal files." + , "" + , flow "Potential ways to resolve this:" + , bulletedList + [ fillSep + [ flow "If you want to use the package.yaml / *.cabal package in the current directory, use" + , styleShell "stack init" + , flow "to create a new stack.yaml." + ] + , flow "Add to the 'packages' field of" <+> display stackYaml + ] + , "" + ] + -- Adds in intermediate dependencies between ghci targets. Note that it -- will return a Lib component for these intermediate dependencies even -- if they don't have a library (but that's fine for the usage within diff --git a/src/Stack/Options/GhciParser.hs b/src/Stack/Options/GhciParser.hs index a142cca6f0..3ef558064e 100644 --- a/src/Stack/Options/GhciParser.hs +++ b/src/Stack/Options/GhciParser.hs @@ -52,6 +52,6 @@ ghciOptsParser = GhciOpts <*> switch (long "load-local-deps" <> help "Load all local dependencies of your targets") -- TODO: deprecate this? probably useless. <*> switch (long "skip-intermediate-deps" <> help "Skip loading intermediate target dependencies" <> internal) - <*> boolFlags True "package-hiding" "package hiding" idm + <*> optional (boolFlagsNoDefault "package-hiding" "package hiding" idm) <*> switch (long "no-build" <> help "Don't build before launching GHCi" <> internal) <*> switch (long "only-main" <> help "Only load and import the main module. If no main module, no modules will be loaded.") diff --git a/src/Stack/Package.hs b/src/Stack/Package.hs index 2e0555417a..fc81b5f1a0 100644 --- a/src/Stack/Package.hs +++ b/src/Stack/Package.hs @@ -45,6 +45,7 @@ module Stack.Package import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as C8 +import qualified Data.HashSet as HashSet import Data.List (isSuffixOf, partition, isPrefixOf) import Data.List.Extra (nubOrd) import qualified Data.Map.Strict as M @@ -195,22 +196,28 @@ readDotBuildinfo buildinfofp = -- | Print cabal file warnings. printCabalFileWarning - :: (MonadLogger m, HasRunner env, MonadReader env m) - => Path Abs File -> PWarning -> m () -printCabalFileWarning cabalfp = - \case - (PWarning x) -> - prettyWarnL - [ flow "Cabal file warning in" - , display cabalfp <> ":" - , flow x - ] - (UTFWarning ln msg) -> - prettyWarnL - [ flow "Cabal file warning in" - , display cabalfp <> ":" <> fromString (show ln) <> ":" - , flow msg - ] + :: HasRunner env + => Path Abs File + -> PWarning + -> RIO env () +printCabalFileWarning cabalfp warning' = do + let fp = toFilePath cabalfp + ref <- view $ runnerL.to runnerWarnedCabalFiles + join $ atomicModifyIORef' ref $ \hs -> + if fp `HashSet.member` hs + then (hs, return ()) + else (HashSet.insert fp hs, prettyWarnL (toPretty warning')) + where + toPretty (PWarning x) = + [ flow "Cabal file warning in" + , display cabalfp <> ":" + , flow x + ] + toPretty (UTFWarning ln msg) = + [ flow "Cabal file warning in" + , display cabalfp <> ":" <> fromString (show ln) <> ":" + , flow msg + ] -- | Check if the given name in the @Package@ matches the name of the .cabal file checkCabalFileName :: MonadThrow m => PackageName -> Path Abs File -> m () @@ -1321,11 +1328,7 @@ hpack pkgDir = do config <- view configL case configOverrideHpack config of HpackBundled -> do -#if MIN_VERSION_hpack(0,18,0) - r <- liftIO $ Hpack.hpackResult (Just $ toFilePath pkgDir) -#else - r <- liftIO $ Hpack.hpackResult (toFilePath pkgDir) -#endif + r <- liftIO $ Hpack.hpackResult (Just $ toFilePath pkgDir) Hpack.NoForce forM_ (Hpack.resultWarnings r) prettyWarnS let cabalFile = styleFile . fromString . Hpack.resultCabalFile $ r case Hpack.resultStatus r of @@ -1338,6 +1341,13 @@ hpack pkgDir = do , flow "was generated with a newer version of hpack," , flow "please upgrade and try again." ] + Hpack.ExistingCabalFileWasModifiedManually -> prettyWarnL + [ flow "WARNING: " + , cabalFile + , flow " was modified manually. Ignoring package.yaml in favor of cabal file." + , flow "If you want to use package.yaml instead of the cabal file, " + , flow "then please delete the cabal file." + ] HpackCommand command -> do envOverride <- getMinimalEnvOverride let cmd = Cmd (Just pkgDir) command envOverride [] diff --git a/src/Stack/SDist.hs b/src/Stack/SDist.hs index a2b55cd656..f5358984cc 100644 --- a/src/Stack/SDist.hs +++ b/src/Stack/SDist.hs @@ -113,13 +113,13 @@ getSDistTarball getSDistTarball mpvpBounds pkgDir = do config <- view configL let PvpBounds pvpBounds asRevision = fromMaybe (configPvpBounds config) mpvpBounds - tweakCabal = True -- pvpBounds /= PvpBoundsNone + tweakCabal = pvpBounds /= PvpBoundsNone pkgFp = toFilePath pkgDir lp <- readLocalPackage pkgDir logInfo $ "Getting file list for " <> T.pack pkgFp (fileList, cabalfp) <- getSDistFileList lp logInfo $ "Building sdist tarball for " <> T.pack pkgFp - files <- normalizeTarballPaths (lines fileList) + files <- normalizeTarballPaths (map (T.unpack . stripCR . T.pack) (lines fileList)) -- We're going to loop below and eventually find the cabal -- file. When we do, we'll upload this reference, if the @@ -349,6 +349,7 @@ getSDistFileList lp = , taskAllInOne = True , taskCachePkgSrc = CacheSrcLocal (toFilePath (lpDir lp)) , taskAnyMissing = True + , taskBuildTypeConfig = False } normalizeTarballPaths :: HasRunner env => [FilePath] -> RIO env [FilePath] diff --git a/src/Stack/Setup.hs b/src/Stack/Setup.hs index 473bde841b..524b7a9b8f 100644 --- a/src/Stack/Setup.hs +++ b/src/Stack/Setup.hs @@ -36,7 +36,7 @@ module Stack.Setup import qualified Codec.Archive.Tar as Tar import Control.Applicative (empty) import Control.Monad.State (get, put, modify) -import "cryptonite" Crypto.Hash (SHA1(..)) +import "cryptonite" Crypto.Hash (SHA1(..), SHA256(..)) import Data.Aeson.Extended import qualified Data.ByteString as S import qualified Data.ByteString.Char8 as S8 @@ -51,7 +51,6 @@ import Data.Foldable (maximumBy) import qualified Data.HashMap.Strict as HashMap import Data.IORef.RunOnce (runOnce) import Data.List hiding (concat, elem, maximumBy, any) -import Data.List.Split (splitOn) import qualified Data.Map as Map import qualified Data.Set as Set import qualified Data.Text as T @@ -107,6 +106,7 @@ import Text.Printf (printf) #if !WINDOWS import Bindings.Uname (uname, release) +import Data.List.Split (splitOn) import Foreign.C (throwErrnoIfMinus1_, peekCString) import Foreign.Marshal (alloca) import System.Posix.Files (setFileMode) @@ -616,6 +616,7 @@ getGhcBuild menv = do logDebug ("Using " <> T.pack s <> " GHC build") return (CompilerBuildSpecialized s) +#if !WINDOWS -- | Encode an OpenBSD version (like "6.1") into a valid argument for -- CompilerBuildSpecialized, so "maj6-min1". Later version numbers are prefixed -- with "r". @@ -629,7 +630,6 @@ mungeRelease = intercalate "-" . prefixMaj . splitOn "." prefixMaj = prefixFst "maj" prefixMin prefixMin = prefixFst "min" (map ('r':)) -#if !WINDOWS sysRelease :: (MonadUnliftIO m, MonadLogger m) => m String sysRelease = handleIO (\e -> do @@ -852,7 +852,12 @@ downloadAndInstallCompiler ghcBuild si wanted@GhcVersion{} versionCheck mbindist _ -> throwM RequireCustomGHCVariant case wanted of GhcVersion version -> - return (version, GHCDownloadInfo mempty mempty (DownloadInfo (T.pack bindistURL) Nothing Nothing)) + return (version, GHCDownloadInfo mempty mempty DownloadInfo + { downloadInfoUrl = T.pack bindistURL + , downloadInfoContentLength = Nothing + , downloadInfoSha1 = Nothing + , downloadInfoSha256 = Nothing + }) _ -> throwM WantedMustBeGHC _ -> do @@ -953,7 +958,8 @@ downloadFromInfo programsDir downloadInfo tool = do chattyDownload (T.pack (toolString tool)) downloadInfo path return path (parseAbsFile -> Just path) -> do - let DownloadInfo{downloadInfoContentLength=contentLength, downloadInfoSha1=sha1} = + let DownloadInfo{downloadInfoContentLength=contentLength, downloadInfoSha1=sha1, + downloadInfoSha256=sha256} = downloadInfo when (isJust contentLength) $ logWarn ("`content-length` in not checked \n" <> @@ -961,6 +967,9 @@ downloadFromInfo programsDir downloadInfo tool = do 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 @@ -1427,7 +1436,7 @@ setup7z si = do chattyDownload :: HasRunner env => Text -- ^ label - -> DownloadInfo -- ^ URL, content-length, and sha1 + -> DownloadInfo -- ^ URL, content-length, sha1, and sha256 -> Path Abs File -- ^ destination -> RIO env () chattyDownload label downloadInfo path = do @@ -1445,20 +1454,25 @@ chattyDownload label downloadInfo path = do , T.pack $ toFilePath path , " ..." ] - hashChecks <- case downloadInfoSha1 downloadInfo of - Just sha1ByteString -> do - let sha1 = CheckHexDigestByteString sha1ByteString + hashChecks <- fmap catMaybes $ forM + [ ("sha1", HashCheck SHA1, downloadInfoSha1) + , ("sha256", HashCheck SHA256, downloadInfoSha256) + ] + $ \(name, constr, getter) -> + case getter downloadInfo of + Just bs -> do logDebug $ T.concat - [ "Will check against sha1 hash: " - , T.decodeUtf8With T.lenientDecode sha1ByteString - ] - return [HashCheck SHA1 sha1] - Nothing -> do - logWarn $ T.concat - [ "No sha1 found in metadata," - , " download hash won't be checked." + [ "Will check against " + , name + , " hash: " + , T.decodeUtf8With T.lenientDecode bs ] - return [] + return $ Just $ constr $ CheckHexDigestByteString bs + Nothing -> return Nothing + when (null hashChecks) $ logWarn $ T.concat + [ "No sha1 or sha256 found in metadata," + , " download hash won't be checked." + ] let dReq = DownloadRequest { drRequest = req , drHashChecks = hashChecks diff --git a/src/Stack/Snapshot.hs b/src/Stack/Snapshot.hs index 50929e9711..1d6b35a299 100644 --- a/src/Stack/Snapshot.hs +++ b/src/Stack/Snapshot.hs @@ -138,16 +138,16 @@ loadResolver loadResolver (ResolverSnapshot name) = do stackage <- view stackRootL file' <- parseRelFile $ T.unpack file + cachePath <- (buildPlanCacheDir stackage ) <$> parseRelFile (T.unpack (renderSnapName name <> ".cache")) let fp = buildPlanDir stackage file' - tryDecode = liftIO $ do + tryDecode = tryAny $ $(versionedDecodeOrLoad snapshotDefVC) cachePath $ liftIO $ do evalue <- decodeFileEither $ toFilePath fp - return $ - case evalue of - Left e -> Left e - Right value -> - case parseEither parseStackageSnapshot value of - Left s -> Left $ AesonException s - Right x -> Right x + case evalue of + Left e -> throwIO e + Right value -> + case parseEither parseStackageSnapshot value of + Left s -> throwIO $ AesonException s + Right x -> return x logDebug $ "Decoding build plan from: " <> T.pack (toFilePath fp) eres <- tryDecode case eres of diff --git a/src/Stack/Types/Build.hs b/src/Stack/Types/Build.hs index f6254f06c7..bd69475683 100644 --- a/src/Stack/Types/Build.hs +++ b/src/Stack/Types/Build.hs @@ -442,6 +442,9 @@ data Task = Task -- unnecessary, when in fact we _do_ need to reconfigure. The -- details here suck. We really need proper hashes for package -- identifiers. + , taskBuildTypeConfig :: !Bool + -- ^ Is the build type of this package Configure. Check out + -- ensureConfigureScript in Stack.Build.Execute for the motivation } deriving Show diff --git a/src/Stack/Types/BuildPlan.hs b/src/Stack/Types/BuildPlan.hs index af0ba5d63c..d0c6540f76 100644 --- a/src/Stack/Types/BuildPlan.hs +++ b/src/Stack/Types/BuildPlan.hs @@ -13,6 +13,7 @@ module Stack.Types.BuildPlan ( -- * Types SnapshotDef (..) + , snapshotDefVC , sdRawPathName , PackageLocation (..) , PackageLocationIndex (..) @@ -96,7 +97,12 @@ data SnapshotDef = SnapshotDef -- of a snapshot with some codebase without installing GHC (e.g., -- during stack init), we would use this field. } - deriving (Show, Eq) + deriving (Show, Eq, Data, Generic, Typeable) +instance Store SnapshotDef +instance NFData SnapshotDef + +snapshotDefVC :: VersionConfig SnapshotDef +snapshotDefVC = storeVersionConfig "sd-v1" "tnwWSSLerZ2XeR6XpVwj5Uh0eF4=" -- | A relative file path including a unique string for the given -- snapshot. diff --git a/src/Stack/Types/Config.hs b/src/Stack/Types/Config.hs index 832845045e..52a2a8fca2 100644 --- a/src/Stack/Types/Config.hs +++ b/src/Stack/Types/Config.hs @@ -1602,6 +1602,7 @@ data DownloadInfo = DownloadInfo -- ^ URL or absolute file path , downloadInfoContentLength :: Maybe Int , downloadInfoSha1 :: Maybe ByteString + , downloadInfoSha256 :: Maybe ByteString } deriving (Show) instance FromJSON (WithJSONWarnings DownloadInfo) where @@ -1613,11 +1614,13 @@ parseDownloadInfoFromObject o = do url <- o ..: "url" contentLength <- o ..:? "content-length" sha1TextMay <- o ..:? "sha1" + sha256TextMay <- o ..:? "sha256" return DownloadInfo { downloadInfoUrl = url , downloadInfoContentLength = contentLength , downloadInfoSha1 = fmap encodeUtf8 sha1TextMay + , downloadInfoSha256 = fmap encodeUtf8 sha256TextMay } data VersionedDownloadInfo = VersionedDownloadInfo diff --git a/src/Stack/Types/Runner.hs b/src/Stack/Types/Runner.hs index 7fefff1f1c..2f8098044f 100644 --- a/src/Stack/Types/Runner.hs +++ b/src/Stack/Types/Runner.hs @@ -54,6 +54,14 @@ data Runner = Runner , runnerLogOptions :: !LogOptions , runnerTerminal :: !Bool , runnerSticky :: !Sticky + , runnerWarnedCabalFiles :: !(IORef (HashSet FilePath)) + -- ^ Set of all cabal files that have already been warned about. + -- + -- TODO: This is really an ugly hack to avoid spamming the user with + -- warnings when we parse cabal files multiple times. Ideally: we + -- would just design the system such that it only ever parses a + -- cabal file once. But for now, this is a decent workaround. See: + -- . } class HasLogFunc env => HasRunner env where @@ -259,6 +267,7 @@ withRunner logLevel useTime terminal colorWhen widthOverride reExec inner = do <$> liftIO getTerminalWidth) pure widthOverride canUseUnicode <- liftIO getCanUseUnicode + ref <- newIORef mempty withSticky terminal $ \sticky -> inner Runner { runnerReExec = reExec , runnerLogOptions = LogOptions @@ -271,6 +280,7 @@ withRunner logLevel useTime terminal colorWhen widthOverride reExec inner = do } , runnerTerminal = terminal , runnerSticky = sticky + , runnerWarnedCabalFiles = ref } where clipWidth w | w < minTerminalWidth = minTerminalWidth diff --git a/src/main/Main.hs b/src/main/Main.hs index 270ca21e7a..30bd9bf7a2 100644 --- a/src/main/Main.hs +++ b/src/main/Main.hs @@ -268,11 +268,20 @@ commandLineHandler currentDir progName isInterpreter = complicatedOptions buildCmd (buildOptsParser Haddock) addCommand' "new" - "Create a new project from a template. Run `stack templates' to see available templates." + (unwords [ "Create a new project from a template." + , "Run `stack templates' to see available templates." + , "Note: you can also specify a local file or a" + , "remote URL as a template." + ] ) newCmd newOptsParser addCommand' "templates" - "List the templates available for `stack new'." + (unwords [ "List the templates available for `stack new'." + , "Templates are drawn from" + , "https://github.com/commercialhaskell/stack-templates" + , "Note: `stack new' can also accept a template from a" + , "local file or a remote URL." + ] ) templatesCmd (pure ()) addCommand' "init" diff --git a/unix/System/Terminal.hsc b/src/unix/System/Terminal.hsc similarity index 100% rename from unix/System/Terminal.hsc rename to src/unix/System/Terminal.hsc diff --git a/windows/System/Terminal.hs b/src/windows/System/Terminal.hs similarity index 100% rename from windows/System/Terminal.hs rename to src/windows/System/Terminal.hs diff --git a/stack-nightly.yaml b/stack-nightly.yaml index 685d11fede..976ded566f 100644 --- a/stack-nightly.yaml +++ b/stack-nightly.yaml @@ -1,4 +1,4 @@ -resolver: nightly-2017-10-17 +resolver: nightly-2017-11-25 nix: # --nix on the command-line to enable. enable: false diff --git a/stack.yaml b/stack.yaml index 75783118c8..19c05fbc14 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,4 +1,4 @@ -resolver: lts-9.9 +resolver: lts-9.14 # docker: # enable: true # repo: fpco/stack-full @@ -18,10 +18,11 @@ flags: mintty: win32-2-5: false extra-deps: -- Cabal-2.0.0.2 +- Cabal-2.0.1.0 - mintty-0.1.1 - bindings-uname-0.1 - path-0.6.1 - path-io-1.3.3 - extra-1.6 - hsc2hs-0.68.2 +- hpack-0.20.0 diff --git a/test/integration/tests/3396-package-indices/Main.hs b/test/integration/tests/3396-package-indices/Main.hs index c66949955d..91115a6e82 100644 --- a/test/integration/tests/3396-package-indices/Main.hs +++ b/test/integration/tests/3396-package-indices/Main.hs @@ -1,11 +1,12 @@ import StackTest -import System.Directory (createDirectory) -import System.Environment (getEnv) +import System.Directory (createDirectoryIfMissing) +import System.Environment (getEnv, setEnv) import System.FilePath (()) main :: IO () main = do home <- getEnv "HOME" - createDirectory (home ".stack" "indices" "CustomIndex") + setEnv "STACK_ROOT" (home ".stack") -- Needed for Windows + createDirectoryIfMissing True (home ".stack" "indices" "CustomIndex") copy "CustomIndex/01-index.tar" (home ".stack" "indices" "CustomIndex" "01-index.tar") stack ["build"] diff --git a/test/integration/tests/3574-extra-dep-local/Main.hs b/test/integration/tests/3574-extra-dep-local/Main.hs new file mode 100644 index 0000000000..b1b93683df --- /dev/null +++ b/test/integration/tests/3574-extra-dep-local/Main.hs @@ -0,0 +1,4 @@ +import StackTest + +main :: IO () +main = stack ["build", "foo"] diff --git a/test/integration/tests/3574-extra-dep-local/files/foo/Foo.hs b/test/integration/tests/3574-extra-dep-local/files/foo/Foo.hs new file mode 100644 index 0000000000..a23b501b27 --- /dev/null +++ b/test/integration/tests/3574-extra-dep-local/files/foo/Foo.hs @@ -0,0 +1,3 @@ +module Foo(foo) where + +foo = "foo" diff --git a/test/integration/tests/3574-extra-dep-local/files/foo/foo.cabal b/test/integration/tests/3574-extra-dep-local/files/foo/foo.cabal new file mode 100644 index 0000000000..b37e615a97 --- /dev/null +++ b/test/integration/tests/3574-extra-dep-local/files/foo/foo.cabal @@ -0,0 +1,8 @@ +cabal-version: >= 1.2 +build-type: Simple +name: foo +version: 0 + +library + build-depends: base + exposed-modules: Foo diff --git a/test/integration/tests/3574-extra-dep-local/files/stack.yaml b/test/integration/tests/3574-extra-dep-local/files/stack.yaml new file mode 100644 index 0000000000..681e43c173 --- /dev/null +++ b/test/integration/tests/3574-extra-dep-local/files/stack.yaml @@ -0,0 +1,8 @@ +resolver: ghc-8.0.2 + +packages: +- location: foo + extra-dep: true + +ghc-options: + $locals: -bob diff --git a/test/integration/tests/3591-cabal-warnings-once/Main.hs b/test/integration/tests/3591-cabal-warnings-once/Main.hs new file mode 100644 index 0000000000..71a35c1e1a --- /dev/null +++ b/test/integration/tests/3591-cabal-warnings-once/Main.hs @@ -0,0 +1,10 @@ +import StackTest +import Data.List (isInfixOf) + +main :: IO () +main = do + stackCheckStderr ["build", "--dry-run"] $ \str -> + case filter ("unknown-field-name" `isInfixOf`) (lines str) of + [] -> error "unknown-field-name didn't appear once" + [_] -> return () + _:_:_ -> error "unknown-field-name appeared multiple times" diff --git a/test/integration/tests/3591-cabal-warnings-once/files/foo.cabal b/test/integration/tests/3591-cabal-warnings-once/files/foo.cabal new file mode 100644 index 0000000000..411bd8742d --- /dev/null +++ b/test/integration/tests/3591-cabal-warnings-once/files/foo.cabal @@ -0,0 +1,16 @@ +-- This file has been generated from package.yaml by hpack version 0.20.0. +-- +-- see: https://github.com/sol/hpack +-- +-- hash: 43a4e1612fc5dee2ab88c588fee639840be01569a600ab2955961c341b89058d + +name: foo +version: 0.1.0.0 +build-type: Simple +cabal-version: >= 1.10 + +unknown-field-name: makes a warning! + +library + hs-source-dirs: src + exposed-modules: Lib diff --git a/test/integration/tests/3591-cabal-warnings-once/files/src/Lib.hs b/test/integration/tests/3591-cabal-warnings-once/files/src/Lib.hs new file mode 100644 index 0000000000..6d85a26fe1 --- /dev/null +++ b/test/integration/tests/3591-cabal-warnings-once/files/src/Lib.hs @@ -0,0 +1 @@ +module Lib where diff --git a/test/integration/tests/3591-cabal-warnings-once/files/stack.yaml b/test/integration/tests/3591-cabal-warnings-once/files/stack.yaml new file mode 100644 index 0000000000..010450bf7b --- /dev/null +++ b/test/integration/tests/3591-cabal-warnings-once/files/stack.yaml @@ -0,0 +1 @@ +resolver: lts-9.0 diff --git a/test/integration/tests/internal-libraries/files/files.cabal b/test/integration/tests/internal-libraries/files/files.cabal index 61a1d1cd3d..9391e63a57 100644 --- a/test/integration/tests/internal-libraries/files/files.cabal +++ b/test/integration/tests/internal-libraries/files/files.cabal @@ -27,3 +27,5 @@ foreign-library baz build-depends: base, files, foo, mtl hs-source-dirs: src-baz default-language: Haskell2010 + if os(Windows) + options: standalone