on master help sign in
17 files changed+740
since splitsnapshots
unifiedsplit
.gitignore+4 .hext.yaml+16 .hlint.yaml+60 .stylish-haskell.yaml+229 ChangeLog.md+3 README.md+30 Setup.hs+5 UNLICENSE+24 app/Main.hs+17 beforebuild+2 package.yaml+57 src/Control/Hext/Arguments.hs+50 src/Control/Hext/Config.hs+51 src/Control/Hext/Processor.hs+69 src/Data/Haskell/Parser.hs+40 stack.yaml+78 test/Spec.hs+5
.gitignorenew file+4
@@ -0,0 +1,4 @@
1+.stack-work/
2+hext.cabal
3+*~
4+stack.yaml.lock
.hext.yamlnew file+16
@@ -0,0 +1,16 @@
1+- src:
2+ - src
3+ - tests
4+ - app
5+
6+ line_limit: 100
7+
8+ extensions:
9+ - OverloadedStrings
10+ - NoImplicitPrelude
11+ - TypeApplications
12+ - DeriveGeneric
13+ - DeriveAnyClass
14+ - RecordWildCards
15+ - ScopedTypeVariables
16+ - LambdaCase
.hlint.yamlnew file+60
@@ -0,0 +1,60 @@
1+# HLint configuration file
2+# https://github.com/ndmitchell/hlint
3+##########################
4+
5+# This file contains a template configuration file, which is typically
6+# placed as .hlint.yaml in the root of your project
7+
8+
9+# Specify additional command line arguments
10+#
11+# - arguments: [--color, --cpp-simple, -XQuasiQuotes]
12+
13+
14+# Control which extensions/flags/modules/functions can be used
15+#
16+# - extensions:
17+# - default: false # all extension are banned by default
18+# - name: [PatternGuards, ViewPatterns] # only these listed extensions can be used
19+# - {name: CPP, within: CrossPlatform} # CPP can only be used in a given module
20+#
21+# - flags:
22+# - {name: -w, within: []} # -w is allowed nowhere
23+#
24+# - modules:
25+# - {name: [Data.Set, Data.HashSet], as: Set} # if you import Data.Set qualified, it must be as 'Set'
26+# - {name: Control.Arrow, within: []} # Certain modules are banned entirely
27+#
28+# - functions:
29+# - {name: unsafePerformIO, within: []} # unsafePerformIO can only appear in no modules
30+
31+
32+# Add custom hints for this project
33+#
34+# Will suggest replacing "wibbleMany [myvar]" with "wibbleOne myvar"
35+# - error: {lhs: "wibbleMany [x]", rhs: wibbleOne x}
36+
37+
38+# Turn on hints that are off by default
39+#
40+# Ban "module X(module X) where", to require a real export list
41+# - warn: {name: Use explicit module export list}
42+#
43+# Replace a $ b $ c with a . b $ c
44+# - group: {name: dollar, enabled: true}
45+#
46+# Generalise map to fmap, ++ to <>
47+# - group: {name: generalise, enabled: true}
48+
49+
50+# Ignore some builtin hints
51+- ignore: {name: Unused LANGUAGE pragma}
52+# - ignore: {name: Use let}
53+# - ignore: {name: Use const, within: SpecialModule} # Only within certain modules
54+
55+# Define some custom infix operators
56+# - fixity: infixr 3 ~^#^~
57+
58+
59+# To generate a suitable file for HLint do:
60+# $ hlint --default > .hlint.yaml
.stylish-haskell.yamlnew file+229
@@ -0,0 +1,229 @@
1+# stylish-haskell configuration file
2+# ==================================
3+
4+# The stylish-haskell tool is mainly configured by specifying steps. These steps
5+# are a list, so they have an order, and one specific step may appear more than
6+# once (if needed). Each file is processed by these steps in the given order.
7+steps:
8+ # Convert some ASCII sequences to their Unicode equivalents. This is disabled
9+ # by default.
10+ # - unicode_syntax:
11+ # # In order to make this work, we also need to insert the UnicodeSyntax
12+ # # language pragma. If this flag is set to true, we insert it when it's
13+ # # not already present. You may want to disable it if you configure
14+ # # language extensions using some other method than pragmas. Default:
15+ # # true.
16+ # add_language_pragma: true
17+
18+ # Align the right hand side of some elements. This is quite conservative
19+ # and only applies to statements where each element occupies a single
20+ # line.
21+# - simple_align:
22+# cases: true
23+# top_level_patterns: true
24+# records: true
25+
26+ # Import cleanup
27+ - imports:
28+ # There are different ways we can align names and lists.
29+ #
30+ # - global: Align the import names and import list throughout the entire
31+ # file.
32+ #
33+ # - file: Like global, but don't add padding when there are no qualified
34+ # imports in the file.
35+ #
36+ # - group: Only align the imports per group (a group is formed by adjacent
37+ # import lines).
38+ #
39+ # - none: Do not perform any alignment.
40+ #
41+ # Default: global.
42+ align: none
43+
44+ # The following options affect only import list alignment.
45+ #
46+ # List align has following options:
47+ #
48+ # - after_alias: Import list is aligned with end of import including
49+ # 'as' and 'hiding' keywords.
50+ #
51+ # > import qualified Data.List as List (concat, foldl, foldr, head,
52+ # > init, last, length)
53+ #
54+ # - with_alias: Import list is aligned with start of alias or hiding.
55+ #
56+ # > import qualified Data.List as List (concat, foldl, foldr, head,
57+ # > init, last, length)
58+ #
59+ # - new_line: Import list starts always on new line.
60+ #
61+ # > import qualified Data.List as List
62+ # > (concat, foldl, foldr, head, init, last, length)
63+ #
64+ # Default: after_alias
65+ list_align: after_alias
66+
67+ # Right-pad the module names to align imports in a group:
68+ #
69+ # - true: a little more readable
70+ #
71+ # > import qualified Data.List as List (concat, foldl, foldr,
72+ # > init, last, length)
73+ # > import qualified Data.List.Extra as List (concat, foldl, foldr,
74+ # > init, last, length)
75+ #
76+ # - false: diff-safe
77+ #
78+ # > import qualified Data.List as List (concat, foldl, foldr, init,
79+ # > last, length)
80+ # > import qualified Data.List.Extra as List (concat, foldl, foldr,
81+ # > init, last, length)
82+ #
83+ # Default: true
84+ pad_module_names: false
85+
86+ # Long list align style takes effect when import is too long. This is
87+ # determined by 'columns' setting.
88+ #
89+ # - inline: This option will put as much specs on same line as possible.
90+ #
91+ # - new_line: Import list will start on new line.
92+ #
93+ # - new_line_multiline: Import list will start on new line when it's
94+ # short enough to fit to single line. Otherwise it'll be multiline.
95+ #
96+ # - multiline: One line per import list entry.
97+ # Type with constructor list acts like single import.
98+ #
99+ # > import qualified Data.Map as M
100+ # > ( empty
101+ # > , singleton
102+ # > , ...
103+ # > , delete
104+ # > )
105+ #
106+ # Default: inline
107+ long_list_align: inline
108+
109+ # Align empty list (importing instances)
110+ #
111+ # Empty list align has following options
112+ #
113+ # - inherit: inherit list_align setting
114+ #
115+ # - right_after: () is right after the module name:
116+ #
117+ # > import Vector.Instances ()
118+ #
119+ # Default: inherit
120+ empty_list_align: inherit
121+
122+ # List padding determines indentation of import list on lines after import.
123+ # This option affects 'long_list_align'.
124+ #
125+ # - <integer>: constant value
126+ #
127+ # - module_name: align under start of module name.
128+ # Useful for 'file' and 'group' align settings.
129+ list_padding: 4
130+
131+ # Separate lists option affects formatting of import list for type
132+ # or class. The only difference is single space between type and list
133+ # of constructors, selectors and class functions.
134+ #
135+ # - true: There is single space between Foldable type and list of it's
136+ # functions.
137+ #
138+ # > import Data.Foldable (Foldable (fold, foldl, foldMap))
139+ #
140+ # - false: There is no space between Foldable type and list of it's
141+ # functions.
142+ #
143+ # > import Data.Foldable (Foldable(fold, foldl, foldMap))
144+ #
145+ # Default: true
146+ separate_lists: true
147+
148+ # Space surround option affects formatting of import lists on a single
149+ # line. The only difference is single space after the initial
150+ # parenthesis and a single space before the terminal parenthesis.
151+ #
152+ # - true: There is single space associated with the enclosing
153+ # parenthesis.
154+ #
155+ # > import Data.Foo ( foo )
156+ #
157+ # - false: There is no space associated with the enclosing parenthesis
158+ #
159+ # > import Data.Foo (foo)
160+ #
161+ # Default: false
162+ space_surround: false
163+
164+ # Language pragmas
165+# - language_pragmas:
166+# # We can generate different styles of language pragma lists.
167+# #
168+# # - vertical: Vertical-spaced language pragmas, one per line.
169+# #
170+# # - compact: A more compact style.
171+# #
172+# # - compact_line: Similar to compact, but wrap each line with
173+# # `{-#LANGUAGE #-}'.
174+# #
175+# # Default: vertical.
176+# style: vertical
177+
178+# # Align affects alignment of closing pragma brackets.
179+# #
180+# # - true: Brackets are aligned in same column.
181+# #
182+# # - false: Brackets are not aligned together. There is only one space
183+# # between actual import and closing bracket.
184+# #
185+# # Default: true
186+# align: true
187+
188+# # stylish-haskell can detect redundancy of some language pragmas. If this
189+# # is set to true, it will remove those redundant pragmas. Default: true.
190+# remove_redundant: true
191+
192+ # Replace tabs by spaces. This is disabled by default.
193+ # - tabs:
194+ # # Number of spaces to use for each tab. Default: 8, as specified by the
195+ # # Haskell report.
196+ # spaces: 8
197+
198+ # Remove trailing whitespace
199+# - trailing_whitespace: {}
200+
201+ # Squash multiple spaces between the left and right hand sides of some
202+ # elements into single spaces. Basically, this undoes the effect of
203+ # simple_align but is a bit less conservative.
204+ # - squash: {}
205+
206+# A common setting is the number of columns (parts of) code will be wrapped
207+# to. Different steps take this into account. Default: 80.
208+columns: 100
209+
210+# By default, line endings are converted according to the OS. You can override
211+# preferred format here.
212+#
213+# - native: Native newline format. CRLF on Windows, LF on other OSes.
214+#
215+# - lf: Convert to LF ("\n").
216+#
217+# - crlf: Convert to CRLF ("\r\n").
218+#
219+# Default: native.
220+# newline: native
221+
222+# Sometimes, language extensions are specified in a cabal file or from the
223+# command line instead of using language pragmas in the file. stylish-haskell
224+# needs to be aware of these, so it can parse the file correctly.
225+#
226+# No language extensions are enabled by default.
227+# language_extensions:
228+ # - TemplateHaskell
229+ # - QuasiQuotes
ChangeLog.mdnew file+3
@@ -0,0 +1,3 @@
1+# Changelog for hext
2+
3+## Unreleased changes
README.mdnew file+30
@@ -0,0 +1,30 @@
1+# hext
2+
3+It can be tempting to keep all GHC extensions in your stack.yaml or cabal file but many haskell tools don't have integrations with build tools like stack and cabal, and thus would break if they don't see an explicit language pragma at the start of the file.
4+
5+Hext alows you to mainain a single list of GHC extensions and automatically apply them to every file.
6+
7+Create a `.hext.yaml` file and put it into your project directory:
8+
9+```yaml
10+- src:
11+ - src
12+ - tests
13+ - app
14+
15+ line_limit: 100
16+
17+ extensions:
18+ - OverloadedStrings
19+ - NoImplicitPrelude
20+ - TypeApplications
21+ - DeriveGeneric
22+ - DeriveAnyClass
23+ - RecordWildCards
24+ - ScopedTypeVariables
25+ - LambdaCase
26+```
27+
28+You can create multiple groups with different GHC extensions.
29+
30+`line_limit` can be abset, indicating that every extensions should be on its own line, a positive int or `none`, indicating that all extensions should be placed on one lines.
Setup.hsnew file+5
@@ -0,0 +1,5 @@
1+{-# LANGUAGE DeriveAnyClass, DeriveGeneric, LambdaCase, NoImplicitPrelude, OverloadedStrings #-}
2+{-# LANGUAGE RecordWildCards, ScopedTypeVariables, TypeApplications #-}
3+
4+import Distribution.Simple
5+main = defaultMain
UNLICENSEnew file+24
@@ -0,0 +1,24 @@
1+This is free and unencumbered software released into the public domain.
2+
3+Anyone is free to copy, modify, publish, use, compile, sell, or
4+distribute this software, either in source code form or as a compiled
5+binary, for any purpose, commercial or non-commercial, and by any
6+means.
7+
8+In jurisdictions that recognize copyright laws, the author or authors
9+of this software dedicate any and all copyright interest in the
10+software to the public domain. We make this dedication for the benefit
11+of the public at large and to the detriment of our heirs and
12+successors. We intend this dedication to be an overt act of
13+relinquishment in perpetuity of all present and future rights to this
14+software under copyright law.
15+
16+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+OTHER DEALINGS IN THE SOFTWARE.
23+
24+For more information, please refer to <http://unlicense.org>
app/Main.hsnew file+17
@@ -0,0 +1,17 @@
1+{-# LANGUAGE DeriveAnyClass, DeriveGeneric, LambdaCase, NoImplicitPrelude, OverloadedStrings #-}
2+{-# LANGUAGE RecordWildCards, ScopedTypeVariables, TypeApplications #-}
3+
4+module Main where
5+
6+import Relude
7+
8+import Control.Hext.Arguments
9+import Control.Hext.Config
10+import Control.Hext.Processor
11+
12+main :: IO ()
13+main = do
14+ Options{..} <- parseOptions
15+ configs <- getConfigs extensionsPath
16+ forM_ configs $ \Config{..} ->
17+ mapM_ (processFiles lineLimit extensions) $ maybe src pure activeDirectory
beforebuildnew file+2
@@ -0,0 +1,2 @@
1+#!/bin/sh
2+hext
package.yamlnew file+57
@@ -0,0 +1,57 @@
1+name: hext
2+version: 0.1.0.0
3+github: "ilyakooo0/hext"
4+license: Unlicense
5+author: "iko"
6+maintainer: "ilyakooo0@gmail.com"
7+copyright: "2019 Ilya Kostyuchenko"
8+
9+extra-source-files:
10+- README.md
11+- ChangeLog.md
12+
13+# Metadata used when publishing your package
14+# synopsis: Short description of your package
15+# category: Web
16+
17+# To avoid duplicated efforts in documentation and dealing with the
18+# complications of embedding Haddock markup inside cabal files, it is
19+# common to point users to the README.md file.
20+description: Please see the README on GitHub at <https://github.com/ilyakooo0/hext#readme>
21+
22+dependencies:
23+- base >= 4.7 && < 5
24+- megaparsec
25+- relude
26+- yaml
27+- aeson
28+- aeson-casing
29+- optparse-applicative
30+- directory-tree
31+- scientific
32+- text
33+
34+library:
35+ source-dirs: src
36+
37+executables:
38+ hext:
39+ main: Main.hs
40+ source-dirs: app
41+ ghc-options:
42+ - -threaded
43+ - -rtsopts
44+ - -with-rtsopts=-N
45+ dependencies:
46+ - hext
47+
48+tests:
49+ hext-test:
50+ main: Spec.hs
51+ source-dirs: test
52+ ghc-options:
53+ - -threaded
54+ - -rtsopts
55+ - -with-rtsopts=-N
56+ dependencies:
57+ - hext
src/Control/Hext/Arguments.hsnew file+50
@@ -0,0 +1,50 @@
1+{-# LANGUAGE DeriveAnyClass #-}
2+{-# LANGUAGE DeriveGeneric #-}
3+{-# LANGUAGE LambdaCase #-}
4+{-# LANGUAGE NoImplicitPrelude #-}
5+{-# LANGUAGE OverloadedStrings #-}
6+{-# LANGUAGE RecordWildCards #-}
7+{-# LANGUAGE ScopedTypeVariables #-}
8+{-# LANGUAGE TypeApplications #-}
9+
10+module Control.Hext.Arguments
11+ ( parseOptions,
12+ Options (..),
13+ )
14+where
15+
16+import Options.Applicative
17+import Relude
18+
19+parseOptions :: IO Options
20+parseOptions =
21+ execParser $
22+ info
23+ (Options <$> activeDirectoryArgument <*> extensionsFilePath)
24+ ( fullDesc
25+ <> progDesc "Add GHC extensions to source files automatically."
26+ )
27+
28+data Options
29+ = Options
30+ { activeDirectory :: Maybe FilePath,
31+ extensionsPath :: FilePath
32+ }
33+
34+activeDirectoryArgument :: Parser (Maybe FilePath)
35+activeDirectoryArgument =
36+ argument
37+ (maybeReader $ (Just . Just))
38+ ( help "The directiry to scan for .hs files."
39+ <> value Nothing
40+ )
41+
42+extensionsFilePath :: Parser FilePath
43+extensionsFilePath =
44+ option
45+ auto
46+ ( short 'i'
47+ <> long "input"
48+ <> help "The input yaml file with extensions."
49+ <> value ".hext.yaml"
50+ )
src/Control/Hext/Config.hsnew file+51
@@ -0,0 +1,51 @@
1+{-# LANGUAGE DeriveAnyClass #-}
2+{-# LANGUAGE DeriveGeneric #-}
3+{-# LANGUAGE LambdaCase #-}
4+{-# LANGUAGE NoImplicitPrelude #-}
5+{-# LANGUAGE OverloadedStrings #-}
6+{-# LANGUAGE RecordWildCards #-}
7+{-# LANGUAGE ScopedTypeVariables #-}
8+{-# LANGUAGE TypeApplications #-}
9+
10+module Control.Hext.Config
11+ ( getConfigs,
12+ Config (..),
13+ LineLimit (..),
14+ )
15+where
16+
17+import Data.Aeson as A
18+import Data.Aeson.Casing
19+import Data.Scientific
20+import Data.Yaml
21+import Relude
22+import System.Exit as SE
23+
24+data Config
25+ = Config
26+ { extensions :: [Text],
27+ src :: [FilePath],
28+ lineLimit :: Maybe LineLimit
29+ }
30+ deriving (Show, Eq, Ord, Generic)
31+
32+instance FromJSON Config where
33+ parseJSON = genericParseJSON $ defaultOptions {fieldLabelModifier = snakeCase}
34+
35+data LineLimit
36+ = Limited Int
37+ | Unlimited
38+ deriving (Show, Generic, Eq, Ord)
39+
40+instance FromJSON LineLimit where
41+ parseJSON (A.Number n)
42+ | Right n' <- floatingOrInteger @Double n,
43+ n' > 0 =
44+ return $ Limited n'
45+ parseJSON (A.String "none") = return Unlimited
46+ parseJSON _ = fail "invalid line-limit value"
47+
48+getConfigs :: FilePath -> IO [Config]
49+getConfigs f =
50+ (fmap . fmap) (\c@Config {..} -> c {extensions = sort extensions}) $
51+ decodeFileEither f >>= either (SE.die . prettyPrintParseException) return
src/Control/Hext/Processor.hsnew file+69
@@ -0,0 +1,69 @@
1+{-# LANGUAGE DeriveAnyClass, DeriveGeneric, LambdaCase, NoImplicitPrelude, OverloadedStrings #-}
2+{-# LANGUAGE RecordWildCards, ScopedTypeVariables, TypeApplications #-}
3+
4+module Control.Hext.Processor
5+ ( processFiles,
6+ )
7+where
8+
9+import Control.Hext.Config
10+import Data.Haskell.Parser
11+import Data.List hiding (head, unlines)
12+import qualified Data.Text as T
13+import Relude
14+import System.Directory.Tree
15+
16+getFiles :: FilePath -> IO [FilePath]
17+getFiles dir = do
18+ (_ :/ tree) <- readDirectoryWith return dir
19+ return . (>>= getHs) . unwrapDir $ tree
20+ where
21+ unwrapDir :: DirTree a -> [DirTree a]
22+ unwrapDir (Dir _ paths) = paths
23+ unwrapDir _ = []
24+ getHs :: DirTree FilePath -> [FilePath]
25+ getHs (File _ path) | ".hs" `isSuffixOf` path = pure path
26+ getHs (Dir name paths) | not $ "." `isPrefixOf` name = paths >>= getHs
27+ getHs _ = []
28+
29+processFile :: Text -> Text -> Text
30+processFile extensions file =
31+ extensions
32+ <> "\n"
33+ <> withoutExtensions file
34+
35+wrapExtension :: Text -> Text
36+wrapExtension ee = "{-# LANGUAGE " <> ee <> " #-}"
37+
38+baseLength :: Int
39+baseLength = T.length $ wrapExtension ""
40+
41+processFiles :: Maybe LineLimit -> [Text] -> FilePath -> IO ()
42+processFiles limit allExtensions dir = do
43+ files <- getFiles dir
44+ forM_ files $ \file -> do
45+ contents <- readFileText file
46+ writeFileText file . processFile (wrapExtensions allExtensions) $ contents
47+ where
48+ wrapExtensions :: [Text] -> Text
49+ wrapExtensions [] = ""
50+ wrapExtensions extensions@(e : ee) = case limit of
51+ Nothing -> unlines . fmap wrapExtension $ extensions
52+ Just Unlimited -> unlines . pure . wrapExtension . mconcat . intersperse ", " $ extensions
53+ Just (Limited n) ->
54+ let emptyExtra = ([], ee, baseLength + T.length e)
55+ ee' =
56+ unfoldr
57+ ( \case
58+ Nothing -> Nothing
59+ (Just current@(_, [], _)) -> Just (current, Nothing)
60+ (Just current@(soFar, ne : next, l)) ->
61+ let thing = (ne : soFar, next, l + T.length ne + 2)
62+ in Just (current, Just thing)
63+ )
64+ (Just emptyExtra)
65+ (extraExtensions, eLeft, _) =
66+ fromMaybe emptyExtra . viaNonEmpty head . reverse . filter (\(_, _, n') -> n' <= n) $ ee'
67+ in (wrapExtension . mconcat . intersperse ", " $ e : reverse extraExtensions)
68+ <> "\n"
69+ <> wrapExtensions eLeft
src/Data/Haskell/Parser.hsnew file+40
@@ -0,0 +1,40 @@
1+{-# LANGUAGE DeriveAnyClass, DeriveGeneric, LambdaCase, NoImplicitPrelude, OverloadedStrings #-}
2+{-# LANGUAGE RecordWildCards, ScopedTypeVariables, TypeApplications #-}
3+
4+module Data.Haskell.Parser
5+ ( withoutExtensions
6+ , withoutExtensionsParser
7+ ) where
8+
9+import Relude hiding (many, some)
10+
11+import Text.Megaparsec
12+import Text.Megaparsec.Char
13+
14+withoutExtensions :: Text -> Text
15+withoutExtensions t = fromMaybe t $ (parseMaybe @()) withoutExtensionsParser t
16+
17+withoutExtensionsParser :: (Ord e) => ParsecT e Text m Text
18+withoutExtensionsParser = do
19+ _ <- many extensionExpr
20+ takeRest
21+ where
22+ extensionExpr = do
23+ space
24+ chunk "{-#"
25+ space
26+ chunk "LANGUAGE"
27+ space
28+ some extensions
29+ space
30+ chunk "#-}"
31+ space
32+
33+ extensions = do
34+ some letterChar
35+ space
36+ optional $ do
37+ single ','
38+ space
39+ extensions
40+ return ()
stack.yamlnew file+78
@@ -0,0 +1,78 @@
1+# This file was automatically generated by 'stack init'
2+#
3+# Some commonly used options have been documented as comments in this file.
4+# For advanced use and comprehensive documentation of the format, please see:
5+# https://docs.haskellstack.org/en/stable/yaml_configuration/
6+
7+# Resolver to choose a 'specific' stackage snapshot or a compiler version.
8+# A snapshot resolver dictates the compiler version and the set of packages
9+# to be used for project dependencies. For example:
10+#
11+# resolver: lts-3.5
12+# resolver: nightly-2015-09-21
13+# resolver: ghc-7.10.2
14+#
15+# The location of a snapshot can be provided as a file or url. Stack assumes
16+# a snapshot provided as a file might change, whereas a url resource does not.
17+#
18+# resolver: ./custom-snapshot.yaml
19+# resolver: https://example.com/snapshots/2018-01-01.yaml
20+resolver: lts-14.0
21+
22+# User packages to be built.
23+# Various formats can be used as shown in the example below.
24+#
25+# packages:
26+# - some-directory
27+# - https://example.com/foo/bar/baz-0.0.2.tar.gz
28+# subdirs:
29+# - auto-update
30+# - wai
31+packages:
32+- .
33+# Dependency packages to be pulled from upstream that are not in the resolver.
34+# These entries can reference officially published versions as well as
35+# forks / in-progress versions pinned to a git hash. For example:
36+#
37+# extra-deps:
38+# - acme-missiles-0.3
39+# - git: https://github.com/commercialhaskell/stack.git
40+# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
41+#
42+# extra-deps: []
43+
44+# Override default flag values for local packages and extra-deps
45+# flags: {}
46+
47+# Extra package databases containing global packages
48+# extra-package-dbs: []
49+
50+# Control whether we use the GHC we find on the path
51+# system-ghc: true
52+#
53+# Require a specific version of stack, using version ranges
54+# require-stack-version: -any # Default
55+# require-stack-version: ">=2.1"
56+#
57+# Override the architecture used by stack, especially useful on Windows
58+# arch: i386
59+# arch: x86_64
60+#
61+# Extra directories used by stack for building
62+# extra-include-dirs: [/path/to/dir]
63+# extra-lib-dirs: [/path/to/dir]
64+#
65+# Allow a newer minor version of GHC than the snapshot specifies
66+# compiler-check: newer-minor
67+
68+ghc-options:
69+ "$locals":
70+ -Wall
71+ -Wincomplete-uni-patterns
72+ -Wincomplete-record-updates
73+ -Wmissing-exported-signatures
74+ -Wmissing-home-modules
75+ -Widentities
76+ -Wmissed-specialisations
77+ -Wall-missed-specialisations
78+ -Wno-unused-do-bind
test/Spec.hsnew file+5
@@ -0,0 +1,5 @@
1+{-# LANGUAGE DeriveAnyClass, DeriveGeneric, LambdaCase, NoImplicitPrelude, OverloadedStrings #-}
2+{-# LANGUAGE RecordWildCards, ScopedTypeVariables, TypeApplications #-}
3+
4+main :: IO ()
5+main = putStrLn "Test suite not yet implemented"