diff options
author | Sean Whitton <spwhitton@spwhitton.name> | 2018-05-13 10:42:46 -0700 |
---|---|---|
committer | Sean Whitton <spwhitton@spwhitton.name> | 2018-05-13 10:42:46 -0700 |
commit | b3102087ce4cfceb395ce981c4ac167a9d6b7642 (patch) | |
tree | 1feb8e3fd4a877a765afa6efa6c2a3be35dcbd7a | |
parent | 01298b15d95aec5945be8c5839045763d57657fc (diff) | |
parent | 7fac380bd83d51191e223560449d808e323d7ca6 (diff) | |
download | stylish-haskell-b3102087ce4cfceb395ce981c4ac167a9d6b7642.tar.gz |
Merge tag 'v0.9.2.0'
v0.9.2.0
-rw-r--r-- | .circleci/config.yml | 37 | ||||
-rwxr-xr-x | .circleci/release.sh | 44 | ||||
-rw-r--r-- | .travis.yml | 19 | ||||
-rw-r--r-- | CHANGELOG | 27 | ||||
-rw-r--r-- | README.markdown | 17 | ||||
-rw-r--r-- | data/stylish-haskell.yaml | 5 | ||||
-rw-r--r-- | lib/Language/Haskell/Stylish/Align.hs | 4 | ||||
-rw-r--r-- | lib/Language/Haskell/Stylish/Config.hs | 48 | ||||
-rw-r--r-- | lib/Language/Haskell/Stylish/Parse.hs | 8 | ||||
-rw-r--r-- | lib/Language/Haskell/Stylish/Step/Imports.hs | 15 | ||||
-rw-r--r-- | lib/Language/Haskell/Stylish/Step/SimpleAlign.hs | 41 | ||||
-rw-r--r-- | lib/Language/Haskell/Stylish/Step/Squash.hs | 62 | ||||
-rw-r--r-- | lib/Language/Haskell/Stylish/Util.hs | 14 | ||||
-rwxr-xr-x | scripts/latest.sh | 21 | ||||
-rwxr-xr-x | scripts/stylish-haskell.sh | 4 | ||||
-rw-r--r-- | src/Main.hs | 9 | ||||
-rw-r--r-- | stack.yaml | 7 | ||||
-rw-r--r-- | stylish-haskell.cabal | 76 | ||||
-rw-r--r-- | tests/Language/Haskell/Stylish/Parse/Tests.hs | 11 | ||||
-rw-r--r-- | tests/Language/Haskell/Stylish/Step/Imports/Tests.hs | 15 | ||||
-rw-r--r-- | tests/Language/Haskell/Stylish/Step/SimpleAlign/Tests.hs | 18 | ||||
-rw-r--r-- | tests/Language/Haskell/Stylish/Step/Squash/Tests.hs | 121 | ||||
-rw-r--r-- | tests/TestSuite.hs | 2 |
23 files changed, 513 insertions, 112 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..3845c0e --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,37 @@ +version: 2 + +workflows: + version: 2 + simple-workflow: + jobs: + - build: + filters: + tags: + only: /.*/ + +jobs: + build: + docker: + - image: 'fpco/stack-build:latest' + + steps: + - checkout + - restore_cache: + key: 'v1-stylish-haskell-{{ arch }}-{{ .Branch }}' + - run: + name: 'Update cabal indices' + command: 'cabal update' + - run: + name: 'Build and install' + command: 'cabal install --enable-tests --jobs=1' + - run: + name: 'Run tests' + command: 'cabal test' + - save_cache: + key: 'v1-stylish-haskell-{{ arch }}-{{ .Branch }}-{{ .Revision }}' + paths: + - '~/.cabal' + - '~/.ghc' + - run: + name: 'Upload release' + command: '.circleci/release.sh "$CIRCLE_TAG"' diff --git a/.circleci/release.sh b/.circleci/release.sh new file mode 100755 index 0000000..5586d24 --- /dev/null +++ b/.circleci/release.sh @@ -0,0 +1,44 @@ +#!/bin/bash +set -o nounset -o errexit -o pipefail + +TAG="$1" +SUFFIX="linux-$(uname -m)" +USER="jaspervdj" +REPOSITORY="$(basename -- *.cabal ".cabal")" +BINARY="$REPOSITORY" + +echo "Tag: $TAG" +echo "Suffix: $SUFFIX" +echo "Repository: $REPOSITORY" + +$BINARY --version + +if [[ -z "$TAG" ]]; then + echo "Not a tagged build, skipping release..." + exit 0 +fi + +# Install ghr +GHR_VERSION="v0.5.4" +wget --quiet \ + "https://github.com/tcnksm/ghr/releases/download/${GHR_VERSION}/ghr_${GHR_VERSION}_linux_386.zip" +unzip ghr_${GHR_VERSION}_linux_386.zip + +# Install upx +UPX_VERSION="3.94" +wget --quiet \ + "https://github.com/upx/upx/releases/download/v${UPX_VERSION}/upx-${UPX_VERSION}-amd64_linux.tar.xz" +tar xf upx-${UPX_VERSION}-amd64_linux.tar.xz +mv upx-${UPX_VERSION}-amd64_linux/upx . + +# Create tarball +PACKAGE="$REPOSITORY-$TAG-$SUFFIX" +mkdir -p "$PACKAGE" +cp "$(which "$BINARY")" "$PACKAGE" +./upx -q "$PACKAGE/$BINARY" +cp CHANGELOG* LICENSE* README* "$PACKAGE" +tar -czf "$PACKAGE.tar.gz" "$PACKAGE" +rm -r "$PACKAGE" + +# Actually upload +./ghr -u "$USER" -r "$REPOSITORY" "$TAG" "$PACKAGE.tar.gz" diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5e5c816..0000000 --- a/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -sudo: false -language: c # Choose a lightweight base image - -cache: - directories: - - $HOME/.stack - -addons: - apt: - packages: - - libgmp-dev - -before_install: -- mkdir -p ~/.local/bin -- export PATH=$HOME/.local/bin:$PATH -- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack' - -script: -- stack --no-terminal test @@ -1,5 +1,32 @@ # CHANGELOG +- 0.9.2.0 (2018-05-01) + * Support alignment of case expressions with a single guard + * Add a new step to squash multiple spaces between some elements (by Martin + Huschenbett) + +- 0.9.1.1 (2018-04-26) + * Bump `aeson` to 1.3 for tests as well + +- 0.9.1.0 (2018-04-26) + * Support GHC 8.4.1 by adding instance SemiGroup ImportPortion (by George + Wilson) + * Bump `aeson` to 1.3 + +- 0.9.0.2 (2018-01-03) + * Bump lower bound of `directory` to `1.2.3` for `getXdgDirectory` + +- 0.9.0.1 (2017-12-29) + * Fix missing Extra-source-file in cabal file + +- 0.9.0.0 (2017-12-26) + * Embed the default configuration + * Add platform-specific configuration paths (by Jan Tojnar) + * Bump `haskell-src-exts` to 0.20 + * Avoid unpaired parenthesis when import doesn't specify any items (by + Matthew Kennerly) + * Remove shebang lines at the beginning of file (by Vaibhav Sagar) + - 0.8.1.0 (2017-06-19) * Add `pad_module_names` option (by Yuriy Syrovetskiy) * Add `space_surround` option to import styling (by Linus Arver) diff --git a/README.markdown b/README.markdown index 335d8c6..88df2b7 100644 --- a/README.markdown +++ b/README.markdown @@ -83,9 +83,13 @@ following order: settings) 3. `.stylish-haskell.yaml` in the nearest ancestor directory (useful for per-project settings) -4. `.stylish-haskell.yaml` in your home directory (useful for user-wide +4. `stylish-haskell/config.yaml` in the platform’s configuration directory + (on Windows, it is %APPDATA%, elsewhere it defaults to `~/.config` and + can be overridden by the `XDG_CONFIG_HOME` environment variable; + useful for user-wide settings) +5. `.stylish-haskell.yaml` in your home directory (useful for user-wide settings) -5. The default settings. +6. The default settings. Use `stylish-haskell --defaults > .stylish-haskell.yaml` to dump a well-documented default configuration to a file, this way you can get started @@ -133,6 +137,15 @@ Atom integration [ide-haskell]: https://atom.io/packages/ide-haskell [atom-beautify]: Https://atom.io/packages/atom-beautify +Using with Continuous Integration +--------------------------------- + +You can quickly grab the latest binary and run `stylish-haskell` like so: + + curl -sL https://raw.github.com/jaspervdj/stylish-haskell/master/scripts/latest.sh | sh -s . + +Where the `.` can be replaced with the arguments you pass to `stylish-haskell`. + Credits ------- diff --git a/data/stylish-haskell.yaml b/data/stylish-haskell.yaml index 10301be..c1d822d 100644 --- a/data/stylish-haskell.yaml +++ b/data/stylish-haskell.yaml @@ -198,6 +198,11 @@ steps: # Remove trailing whitespace - trailing_whitespace: {} + # Squash multiple spaces between the left and right hand sides of some + # elements into single spaces. Basically, this undoes the effect of + # simple_align but is a bit less conservative. + # - squash: {} + # A common setting is the number of columns (parts of) code will be wrapped # to. Different steps take this into account. Default: 80. columns: 80 diff --git a/lib/Language/Haskell/Stylish/Align.hs b/lib/Language/Haskell/Stylish/Align.hs index 8e6665f..53549b9 100644 --- a/lib/Language/Haskell/Stylish/Align.hs +++ b/lib/Language/Haskell/Stylish/Align.hs @@ -7,7 +7,6 @@ module Language.Haskell.Stylish.Align -------------------------------------------------------------------------------- -import Data.Char (isSpace) import Data.List (nub) import qualified Language.Haskell.Exts as H @@ -81,9 +80,6 @@ align maxColumns alignment (pre, post) = splitAt column str in [padRight longestLeft (trimRight pre) ++ trimLeft post] - trimLeft = dropWhile isSpace - trimRight = reverse . trimLeft . reverse - -------------------------------------------------------------------------------- -- | Checks that all the alignables appear on a single line, and that they do diff --git a/lib/Language/Haskell/Stylish/Config.hs b/lib/Language/Haskell/Stylish/Config.hs index 9fddbb5..19588b7 100644 --- a/lib/Language/Haskell/Stylish/Config.hs +++ b/lib/Language/Haskell/Stylish/Config.hs @@ -1,9 +1,10 @@ -------------------------------------------------------------------------------- {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TemplateHaskell #-} module Language.Haskell.Stylish.Config ( Extensions , Config (..) - , defaultConfigFilePath + , defaultConfigBytes , configFilePath , loadConfig ) where @@ -14,12 +15,13 @@ import Control.Monad (forM, mzero) import Data.Aeson (FromJSON (..)) import qualified Data.Aeson as A import qualified Data.Aeson.Types as A -import Data.Maybe (fromMaybe) import qualified Data.ByteString as B +import qualified Data.FileEmbed as FileEmbed import Data.List (inits, intercalate) import Data.Map (Map) import qualified Data.Map as M +import Data.Maybe (fromMaybe) import Data.Yaml (decodeEither) import System.Directory import System.FilePath (joinPath, @@ -34,11 +36,11 @@ import Language.Haskell.Stylish.Step import qualified Language.Haskell.Stylish.Step.Imports as Imports import qualified Language.Haskell.Stylish.Step.LanguagePragmas as LanguagePragmas import qualified Language.Haskell.Stylish.Step.SimpleAlign as SimpleAlign +import qualified Language.Haskell.Stylish.Step.Squash as Squash import qualified Language.Haskell.Stylish.Step.Tabs as Tabs import qualified Language.Haskell.Stylish.Step.TrailingWhitespace as TrailingWhitespace import qualified Language.Haskell.Stylish.Step.UnicodeSyntax as UnicodeSyntax import Language.Haskell.Stylish.Verbose -import Paths_stylish_haskell (getDataFileName) -------------------------------------------------------------------------------- @@ -65,26 +67,22 @@ configFileName = ".stylish-haskell.yaml" -------------------------------------------------------------------------------- -defaultConfigFilePath :: IO FilePath -defaultConfigFilePath = getDataFileName "data/stylish-haskell.yaml" +defaultConfigBytes :: B.ByteString +defaultConfigBytes = $(FileEmbed.embedFile "data/stylish-haskell.yaml") -------------------------------------------------------------------------------- -configFilePath :: Verbose -> Maybe FilePath -> IO FilePath -configFilePath _ (Just userSpecified) = return userSpecified +configFilePath :: Verbose -> Maybe FilePath -> IO (Maybe FilePath) +configFilePath _ (Just userSpecified) = return (Just userSpecified) configFilePath verbose Nothing = do - current <- getCurrentDirectory - home <- getHomeDirectory - def <- defaultConfigFilePath - mbConfig <- search $ + current <- getCurrentDirectory + configPath <- getXdgDirectory XdgConfig "stylish-haskell" + home <- getHomeDirectory + mbConfig <- search $ [d </> configFileName | d <- ancestors current] ++ - [home </> configFileName, def] + [configPath </> "config.yaml", home </> configFileName] - case mbConfig of - Just config -> return config - Nothing -> fail $ - "Language.Haskell.Stylish.Config.configFilePath: " ++ - "could not load default configuration at: " ++ def + return mbConfig where -- All ancestors of a dir (including that dir) ancestors :: FilePath -> [FilePath] @@ -101,11 +99,11 @@ configFilePath verbose Nothing = do -------------------------------------------------------------------------------- loadConfig :: Verbose -> Maybe FilePath -> IO Config -loadConfig verbose mfp = do - fp <- configFilePath verbose mfp - verbose $ "Loading configuration at " ++ fp - bs <- B.readFile fp - case decodeEither bs of +loadConfig verbose userSpecified = do + mbFp <- configFilePath verbose userSpecified + verbose $ "Loading configuration at " ++ fromMaybe "<embedded>" mbFp + bytes <- maybe (return defaultConfigBytes) B.readFile mbFp + case decodeEither bytes of Left err -> error $ "Language.Haskell.Stylish.Config.loadConfig: " ++ err Right config -> return config @@ -140,6 +138,7 @@ catalog = M.fromList [ ("imports", parseImports) , ("language_pragmas", parseLanguagePragmas) , ("simple_align", parseSimpleAlign) + , ("squash", parseSquash) , ("tabs", parseTabs) , ("trailing_whitespace", parseTrailingWhitespace) , ("unicode_syntax", parseUnicodeSyntax) @@ -178,6 +177,11 @@ parseSimpleAlign c o = SimpleAlign.step -------------------------------------------------------------------------------- +parseSquash :: Config -> A.Object -> A.Parser Step +parseSquash _ _ = return Squash.step + + +-------------------------------------------------------------------------------- parseImports :: Config -> A.Object -> A.Parser Step parseImports config o = Imports.step <$> pure (configColumns config) diff --git a/lib/Language/Haskell/Stylish/Parse.hs b/lib/Language/Haskell/Stylish/Parse.hs index 724ebe2..01def63 100644 --- a/lib/Language/Haskell/Stylish/Parse.hs +++ b/lib/Language/Haskell/Stylish/Parse.hs @@ -44,11 +44,11 @@ unCpp = unlines . go False . lines -------------------------------------------------------------------------------- --- | Remove shebang from the first line +-- | Remove shebang lines unShebang :: String -> String -unShebang str - | "#!" `isPrefixOf` str = unlines $ ("" :) $ drop 1 $ lines str - | otherwise = str +unShebang str = + let (shebangs, other) = break (not . ("#!" `isPrefixOf`)) (lines str) in + unlines $ map (const "") shebangs ++ other -------------------------------------------------------------------------------- diff --git a/lib/Language/Haskell/Stylish/Step/Imports.hs b/lib/Language/Haskell/Stylish/Step/Imports.hs index 2284f3d..fc035a2 100644 --- a/lib/Language/Haskell/Stylish/Step/Imports.hs +++ b/lib/Language/Haskell/Stylish/Step/Imports.hs @@ -22,9 +22,9 @@ import Data.Char (toLower) import Data.List (intercalate, sortBy) import qualified Data.Map as M import Data.Maybe (isJust, maybeToList) -import Data.Monoid ((<>)) import Data.Ord (comparing) import qualified Data.Set as S +import Data.Semigroup (Semigroup ((<>))) import qualified Language.Haskell.Exts as H @@ -168,10 +168,13 @@ data ImportPortion l = ImportSome [H.CName l] -- ^ @A(x, y, z)@ | ImportAll -- ^ @A(..)@ +instance Ord l => Semigroup (ImportPortion l) where + ImportSome a <> ImportSome b = ImportSome (setUnion a b) + _ <> _ = ImportAll + instance Ord l => Monoid (ImportPortion l) where mempty = ImportSome [] - mappend (ImportSome a) (ImportSome b) = ImportSome (setUnion a b) - mappend _ _ = ImportAll + mappend = (<>) -- | O(n log n) union. setUnion :: Ord a => [a] -> [a] -> [a] @@ -311,7 +314,11 @@ prettyImport columns Options{..} padQualified padName longest imp ( mapSpecs ( withHead ("( " ++) . withTail (", " ++)) - ++ [")"]) + ++ closer) + where + closer = if null importSpecs + then [] + else [")"] paddedBase = base $ padImport $ compoundImportName imp diff --git a/lib/Language/Haskell/Stylish/Step/SimpleAlign.hs b/lib/Language/Haskell/Stylish/Step/SimpleAlign.hs index c83c482..924d6c5 100644 --- a/lib/Language/Haskell/Stylish/Step/SimpleAlign.hs +++ b/lib/Language/Haskell/Stylish/Step/SimpleAlign.hs @@ -8,6 +8,7 @@ module Language.Haskell.Stylish.Step.SimpleAlign -------------------------------------------------------------------------------- import Data.Data (Data) +import Data.List (foldl') import Data.Maybe (maybeToList) import qualified Language.Haskell.Exts as H @@ -42,14 +43,30 @@ cases modu = [alts | H.Case _ _ alts <- everything modu] -------------------------------------------------------------------------------- -altToAlignable :: H.Alt l -> Maybe (Alignable l) -altToAlignable (H.Alt _ _ _ (Just _)) = Nothing -altToAlignable (H.Alt ann pat rhs Nothing) = Just $ Alignable - { aContainer = ann - , aLeft = H.ann pat - , aRight = H.ann rhs - , aRightLead = length "-> " - } +-- | For this to work well, we require a way to merge annotations. This merge +-- operation should follow the semigroup laws. +altToAlignable :: (l -> l -> l) -> H.Alt l -> Maybe (Alignable l) +altToAlignable _ (H.Alt _ _ _ (Just _)) = Nothing +altToAlignable _ (H.Alt ann pat rhs@(H.UnGuardedRhs _ _) Nothing) = Just $ + Alignable + { aContainer = ann + , aLeft = H.ann pat + , aRight = H.ann rhs + , aRightLead = length "-> " + } +altToAlignable + merge + (H.Alt ann pat (H.GuardedRhss _ [H.GuardedRhs _ guards rhs]) Nothing) = + -- We currently only support the case where an alternative has a single + -- guarded RHS. If there are more, we would need to return multiple + -- `Alignable`s from this function, which would be a significant change. + Just $ Alignable + { aContainer = ann + , aLeft = foldl' merge (H.ann pat) (map H.ann guards) + , aRight = H.ann rhs + , aRightLead = length "-> " + } +altToAlignable _ _ = Nothing -------------------------------------------------------------------------------- @@ -101,9 +118,11 @@ step maxColumns config = makeStep "Cases" $ \ls (module', _) -> , change_ <- align maxColumns aligns ] - configured = concat $ - [changes cases altToAlignable | cCases config] ++ - [changes tlpats matchToAlignable | cTopLevelPatterns config] ++ + configured = concat $ + [ changes cases (altToAlignable H.mergeSrcSpan) + | cCases config + ] ++ + [changes tlpats matchToAlignable | cTopLevelPatterns config] ++ [changes records fieldDeclToAlignable | cRecords config] in applyChanges configured ls diff --git a/lib/Language/Haskell/Stylish/Step/Squash.hs b/lib/Language/Haskell/Stylish/Step/Squash.hs new file mode 100644 index 0000000..0eb4895 --- /dev/null +++ b/lib/Language/Haskell/Stylish/Step/Squash.hs @@ -0,0 +1,62 @@ +-------------------------------------------------------------------------------- +module Language.Haskell.Stylish.Step.Squash + ( step + ) where + + +-------------------------------------------------------------------------------- +import Data.Maybe (mapMaybe) +import qualified Language.Haskell.Exts as H + + +-------------------------------------------------------------------------------- +import Language.Haskell.Stylish.Editor +import Language.Haskell.Stylish.Step +import Language.Haskell.Stylish.Util + + +-------------------------------------------------------------------------------- +squash + :: (H.Annotated l, H.Annotated r) + => l H.SrcSpan -> r H.SrcSpan -> Maybe (Change String) +squash left right + | H.srcSpanEndLine lAnn == H.srcSpanStartLine rAnn = Just $ + changeLine (H.srcSpanEndLine lAnn) $ \str -> + let (pre, post) = splitAt (H.srcSpanEndColumn lAnn) str + in [trimRight pre ++ " " ++ trimLeft post] + | otherwise = Nothing + where + lAnn = H.ann left + rAnn = H.ann right + + +-------------------------------------------------------------------------------- +squashFieldDecl :: H.FieldDecl H.SrcSpan -> Maybe (Change String) +squashFieldDecl (H.FieldDecl _ names type') + | null names = Nothing + | otherwise = squash (last names) type' + + +-------------------------------------------------------------------------------- +squashMatch :: H.Match H.SrcSpan -> Maybe (Change String) +squashMatch (H.InfixMatch _ _ _ _ _ _) = Nothing +squashMatch (H.Match _ name pats rhs _) + | null pats = squash name rhs + | otherwise = squash (last pats) rhs + + +-------------------------------------------------------------------------------- +squashAlt :: H.Alt H.SrcSpan -> Maybe (Change String) +squashAlt (H.Alt _ pat rhs _) = squash pat rhs + + +-------------------------------------------------------------------------------- +step :: Step +step = makeStep "Squash" $ \ls (module', _) -> + let module'' = fmap H.srcInfoSpan module' + changes = concat + [ mapMaybe squashAlt (everything module'') + , mapMaybe squashMatch (everything module'') + , mapMaybe squashFieldDecl (everything module'') + ] + in applyChanges changes ls diff --git a/lib/Language/Haskell/Stylish/Util.hs b/lib/Language/Haskell/Stylish/Util.hs index 54abef5..c634043 100644 --- a/lib/Language/Haskell/Stylish/Util.hs +++ b/lib/Language/Haskell/Stylish/Util.hs @@ -6,6 +6,8 @@ module Language.Haskell.Stylish.Util , padRight , everything , infoPoints + , trimLeft + , trimRight , wrap , wrapRest @@ -18,7 +20,7 @@ module Language.Haskell.Stylish.Util -------------------------------------------------------------------------------- import Control.Arrow ((&&&), (>>>)) -import Data.Char (isAlpha) +import Data.Char (isAlpha, isSpace) import Data.Data (Data) import qualified Data.Generics as G import Data.Maybe (fromMaybe, listToMaybe, @@ -69,6 +71,16 @@ infoPoints = H.srcInfoPoints >>> map (H.srcSpanStart &&& H.srcSpanEnd) -------------------------------------------------------------------------------- +trimLeft :: String -> String +trimLeft = dropWhile isSpace + + +-------------------------------------------------------------------------------- +trimRight :: String -> String +trimRight = reverse . trimLeft . reverse + + +-------------------------------------------------------------------------------- wrap :: Int -- ^ Maximum line width -> String -- ^ Leading string -> Int -- ^ Indentation diff --git a/scripts/latest.sh b/scripts/latest.sh new file mode 100755 index 0000000..dc5c345 --- /dev/null +++ b/scripts/latest.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# Ported from https://raw.githubusercontent.com/ndmitchell/neil/master/misc/travis.sh + +set -e + +PACKAGE=stylish-haskell +echo Downloading and running $PACKAGE... + +RELEASES=$(curl --silent https://github.com/jaspervdj/$PACKAGE/releases) +URL=https://github.com/$(echo $RELEASES | grep -o '\"[^\"]*-linux-x86_64\.tar\.gz\"' | sed s/\"//g | head -n1) +VERSION=$(echo $URL | sed -e 's/.*-\([\.0-9]\+\)-linux-x86_64\.tar\.gz/\1/') +TEMP=$(mktemp --directory .$PACKAGE-XXXXX) + +cleanup(){ + rm -r $TEMP +} +trap cleanup EXIT + +curl --progress-bar --location -o$TEMP/$PACKAGE.tar.gz $URL +tar -xzf $TEMP/$PACKAGE.tar.gz -C$TEMP +$TEMP/$PACKAGE-$VERSION/$PACKAGE $* diff --git a/scripts/stylish-haskell.sh b/scripts/stylish-haskell.sh new file mode 100755 index 0000000..a22712e --- /dev/null +++ b/scripts/stylish-haskell.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# Ported from https://github.com/ndmitchell/hlint/blob/master/misc/travis.sh + +curl -sL https://raw.github.com/jaspervdj/stylish-haskell/master/scripts/latest.sh | sh -s -- stylish-haskell $* diff --git a/src/Main.hs b/src/Main.hs index 8eeb7ab..e71c795 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -6,10 +6,10 @@ module Main -------------------------------------------------------------------------------- import Control.Monad (forM_, unless) +import qualified Data.ByteString.Char8 as BC8 import Data.Monoid ((<>)) import Data.Version (showVersion) import qualified Options.Applicative as OA -import qualified Paths_stylish_haskell import System.Exit (exitFailure) import qualified System.IO as IO import qualified System.IO.Strict as IO.Strict @@ -70,7 +70,7 @@ parseStylishArgs = StylishArgs -------------------------------------------------------------------------------- stylishHaskellVersion :: String -stylishHaskellVersion = "stylish-haskell " <> showVersion Paths_stylish_haskell.version +stylishHaskellVersion = "stylish-haskell " <> showVersion version -------------------------------------------------------------------------------- @@ -94,9 +94,8 @@ stylishHaskell sa = do putStrLn stylishHaskellVersion else if saDefaults sa then do - fileName <- defaultConfigFilePath - verbose' $ "Dumping config from " ++ fileName - readUTF8File fileName >>= putStr + verbose' "Dumping embedded config..." + BC8.putStr defaultConfigBytes else do conf <- loadConfig verbose' (saConfig sa) @@ -1,9 +1,6 @@ flags: {} packages: - '.' +resolver: lts-11.5 extra-deps: -- 'optparse-applicative-0.14.0.0' -resolver: 'nightly-2017-06-19' -install-ghc: true -system-ghc: false -allow-newer: true +- 'aeson-1.3.1.0' diff --git a/stylish-haskell.cabal b/stylish-haskell.cabal index aef50e4..31f9e23 100644 --- a/stylish-haskell.cabal +++ b/stylish-haskell.cabal @@ -1,5 +1,5 @@ Name: stylish-haskell -Version: 0.8.1.0 +Version: 0.9.2.0 Synopsis: Haskell code prettifier Homepage: https://github.com/jaspervdj/stylish-haskell License: BSD3 @@ -18,11 +18,10 @@ Description: <https://github.com/jaspervdj/stylish-haskell/blob/master/README.markdown> -Data-files: - data/stylish-haskell.yaml - Extra-source-files: - CHANGELOG + CHANGELOG, + README.markdown, + data/stylish-haskell.yaml Library Hs-source-dirs: lib @@ -33,6 +32,7 @@ Library Language.Haskell.Stylish.Step.Imports Language.Haskell.Stylish.Step.LanguagePragmas Language.Haskell.Stylish.Step.SimpleAlign + Language.Haskell.Stylish.Step.Squash Language.Haskell.Stylish.Step.Tabs Language.Haskell.Stylish.Step.TrailingWhitespace Language.Haskell.Stylish.Step.UnicodeSyntax @@ -49,16 +49,18 @@ Library Paths_stylish_haskell Build-depends: - aeson >= 0.6 && < 1.3, - base >= 4.8 && < 5, - bytestring >= 0.9 && < 0.11, - containers >= 0.3 && < 0.6, - directory >= 1.1 && < 1.4, - filepath >= 1.1 && < 1.5, - haskell-src-exts >= 1.18 && < 1.20, - mtl >= 2.0 && < 2.3, - syb >= 0.3 && < 0.8, - yaml >= 0.7 && < 0.9 + aeson >= 0.6 && < 1.4, + base >= 4.8 && < 5, + bytestring >= 0.9 && < 0.11, + containers >= 0.3 && < 0.6, + directory >= 1.2.3 && < 1.4, + filepath >= 1.1 && < 1.5, + file-embed >= 0.0.10 && < 0.1, + haskell-src-exts >= 1.18 && < 1.21, + mtl >= 2.0 && < 2.3, + semigroups >= 0.18 && < 0.19, + syb >= 0.3 && < 0.8, + yaml >= 0.7 && < 0.9 Executable stylish-haskell Ghc-options: -Wall @@ -70,16 +72,17 @@ Executable stylish-haskell strict >= 0.3 && < 0.4, optparse-applicative >= 0.12 && < 0.15, -- Copied from regular dependencies... - aeson >= 0.6 && < 1.3, - base >= 4.8 && < 5, - bytestring >= 0.9 && < 0.11, - containers >= 0.3 && < 0.6, - directory >= 1.1 && < 1.4, - filepath >= 1.1 && < 1.5, - haskell-src-exts >= 1.18 && < 1.20, - mtl >= 2.0 && < 2.3, - syb >= 0.3 && < 0.8, - yaml >= 0.7 && < 0.9 + aeson >= 0.6 && < 1.4, + base >= 4.8 && < 5, + bytestring >= 0.9 && < 0.11, + containers >= 0.3 && < 0.6, + directory >= 1.2.3 && < 1.4, + filepath >= 1.1 && < 1.5, + file-embed >= 0.0.10 && < 0.1, + haskell-src-exts >= 1.18 && < 1.21, + mtl >= 2.0 && < 2.3, + syb >= 0.3 && < 0.8, + yaml >= 0.7 && < 0.9 Test-suite stylish-haskell-tests Ghc-options: -Wall @@ -97,6 +100,8 @@ Test-suite stylish-haskell-tests Language.Haskell.Stylish.Step Language.Haskell.Stylish.Step.SimpleAlign Language.Haskell.Stylish.Step.SimpleAlign.Tests + Language.Haskell.Stylish.Step.Squash + Language.Haskell.Stylish.Step.Squash.Tests Language.Haskell.Stylish.Step.Imports Language.Haskell.Stylish.Step.Imports.Tests Language.Haskell.Stylish.Step.LanguagePragmas @@ -116,16 +121,17 @@ Test-suite stylish-haskell-tests test-framework >= 0.4 && < 0.9, test-framework-hunit >= 0.2 && < 0.4, -- Copied from regular dependencies... - aeson >= 0.6 && < 1.3, - base >= 4.8 && < 5, - bytestring >= 0.9 && < 0.11, - containers >= 0.3 && < 0.6, - directory >= 1.1 && < 1.4, - filepath >= 1.1 && < 1.5, - haskell-src-exts >= 1.18 && < 1.20, - mtl >= 2.0 && < 2.3, - syb >= 0.3 && < 0.8, - yaml >= 0.7 && < 0.9 + aeson >= 0.6 && < 1.4, + base >= 4.8 && < 5, + bytestring >= 0.9 && < 0.11, + containers >= 0.3 && < 0.6, + directory >= 1.2.3 && < 1.4, + filepath >= 1.1 && < 1.5, + file-embed >= 0.0.10 && < 0.1, + haskell-src-exts >= 1.18 && < 1.21, + mtl >= 2.0 && < 2.3, + syb >= 0.3 && < 0.8, + yaml >= 0.7 && < 0.9 Source-repository head Type: git diff --git a/tests/Language/Haskell/Stylish/Parse/Tests.hs b/tests/Language/Haskell/Stylish/Parse/Tests.hs index 9806be2..a8ebf39 100644 --- a/tests/Language/Haskell/Stylish/Parse/Tests.hs +++ b/tests/Language/Haskell/Stylish/Parse/Tests.hs @@ -22,6 +22,7 @@ tests = testGroup "Language.Haskell.Stylish.Parse" , testCase "Haskell2010 extension" testHaskell2010 , testCase "Shebang" testShebang , testCase "ShebangExt" testShebangExt + , testCase "ShebangDouble" testShebangDouble , testCase "GADTs extension" testGADTs , testCase "KindSignatures extension" testKindSignatures , testCase "StandalonDeriving extension" testStandaloneDeriving @@ -85,6 +86,16 @@ testShebang = assert $ isRight $ parseModule [] Nothing $ unlines -------------------------------------------------------------------------------- +testShebangDouble :: Assertion +testShebangDouble = assert $ isRight $ parseModule [] Nothing $ unlines + [ "#!nix-shell" + , "#!nix-shell -i runhaskell -p haskellPackages.ghc" + , "module Main where" + , "main = return ()" + ] + +-------------------------------------------------------------------------------- + -- | These tests are for syntactic language extensions that should always be -- enabled for parsing, even when the pragma is absent. diff --git a/tests/Language/Haskell/Stylish/Step/Imports/Tests.hs b/tests/Language/Haskell/Stylish/Step/Imports/Tests.hs index bc6772c..67c7c5a 100644 --- a/tests/Language/Haskell/Stylish/Step/Imports/Tests.hs +++ b/tests/Language/Haskell/Stylish/Step/Imports/Tests.hs @@ -52,6 +52,7 @@ tests = testGroup "Language.Haskell.Stylish.Step.Imports.Tests" , testCase "case 23" case23 , testCase "case 24" case24 , testCase "case 25" case25 + , testCase "case 26 (issue 185)" case26 ] @@ -663,3 +664,17 @@ case25 = expected , "" , "import Data.Foo (Foo (Foo,Bar), Goo(Goo))" ] + + +-------------------------------------------------------------------------------- +case26 :: Assertion +case26 = expected + @=? testStep (step 80 options ) input' + where + options = defaultOptions { listAlign = NewLine, longListAlign = Multiline } + input' = unlines + [ "import Data.List" + ] + expected = unlines + [ "import Data.List" + ] diff --git a/tests/Language/Haskell/Stylish/Step/SimpleAlign/Tests.hs b/tests/Language/Haskell/Stylish/Step/SimpleAlign/Tests.hs index a57e6e9..b8afab4 100644 --- a/tests/Language/Haskell/Stylish/Step/SimpleAlign/Tests.hs +++ b/tests/Language/Haskell/Stylish/Step/SimpleAlign/Tests.hs @@ -25,6 +25,7 @@ tests = testGroup "Language.Haskell.Stylish.Step.SimpleAlign.Tests" , testCase "case 05" case05 , testCase "case 06" case06 , testCase "case 07" case07 + , testCase "case 08" case08 ] @@ -148,3 +149,20 @@ case07 = , " , barqux :: Int" , " }" ] + + +-------------------------------------------------------------------------------- +case08 :: Assertion +case08 = expected @=? testStep (step 80 defaultConfig) input + where + input = unlines + [ "canDrink mbAge = case mbAge of" + , " Just age | age > 18 -> True" + , " _ -> False" + ] + + expected = unlines + [ "canDrink mbAge = case mbAge of" + , " Just age | age > 18 -> True" + , " _ -> False" + ] diff --git a/tests/Language/Haskell/Stylish/Step/Squash/Tests.hs b/tests/Language/Haskell/Stylish/Step/Squash/Tests.hs new file mode 100644 index 0000000..a785d9a --- /dev/null +++ b/tests/Language/Haskell/Stylish/Step/Squash/Tests.hs @@ -0,0 +1,121 @@ +-------------------------------------------------------------------------------- +module Language.Haskell.Stylish.Step.Squash.Tests + ( tests + ) where + + +-------------------------------------------------------------------------------- +import Test.Framework (Test, testGroup) +import Test.Framework.Providers.HUnit (testCase) +import Test.HUnit (Assertion, (@=?)) + + +-------------------------------------------------------------------------------- +import Language.Haskell.Stylish.Step.Squash +import Language.Haskell.Stylish.Tests.Util + + +-------------------------------------------------------------------------------- +tests :: Test +tests = testGroup "Language.Haskell.Stylish.Step.SimpleSquash.Tests" + [ testCase "case 01" case01 + , testCase "case 02" case02 + , testCase "case 03" case03 + , testCase "case 04" case04 + , testCase "case 05" case05 + ] + + +-------------------------------------------------------------------------------- +case01 :: Assertion +case01 = expected @=? testStep step input + where + input = unlines + [ "data Foo = Foo" + , " { foo :: Int" + , " , barqux :: String" + , " } deriving (Show)" + ] + + expected = unlines + [ "data Foo = Foo" + , " { foo :: Int" + , " , barqux :: String" + , " } deriving (Show)" + ] + + +-------------------------------------------------------------------------------- +case02 :: Assertion +case02 = expected @=? testStep step input + where + input = unlines + [ "data Foo = Foo" + , " { fooqux" + , " , bar :: String" + , " } deriving (Show)" + ] + + expected = unlines + [ "data Foo = Foo" + , " { fooqux" + , " , bar :: String" + , " } deriving (Show)" + ] + + +-------------------------------------------------------------------------------- +case03 :: Assertion +case03 = expected @=? testStep step input + where + input = unlines + [ "maybe y0 f mx =" + , " case mx of" + , " Nothing -> y0" + , " Just x -> f x" + ] + + expected = unlines + [ "maybe y0 f mx =" + , " case mx of" + , " Nothing -> y0" + , " Just x -> f x" + ] + + +-------------------------------------------------------------------------------- +case04 :: Assertion +case04 = expected @=? testStep step input + where + input = unlines + [ "maybe y0 f mx =" + , " case mx of" + , " Nothing ->" + , " y0" + , " Just x ->" + , " f x" + ] + + expected = unlines + [ "maybe y0 f mx =" + , " case mx of" + , " Nothing ->" + , " y0" + , " Just x ->" + , " f x" + ] + + +-------------------------------------------------------------------------------- +case05 :: Assertion +case05 = expected @=? testStep step input + where + input = unlines + [ "maybe y0 _ Nothing = y" + , "maybe _ f (Just x) = f x" + ] + + expected = unlines + [ "maybe y0 _ Nothing = y" + , "maybe _ f (Just x) = f x" + ] diff --git a/tests/TestSuite.hs b/tests/TestSuite.hs index 853126d..27963a0 100644 --- a/tests/TestSuite.hs +++ b/tests/TestSuite.hs @@ -13,6 +13,7 @@ import qualified Language.Haskell.Stylish.Parse.Tests import qualified Language.Haskell.Stylish.Step.Imports.Tests import qualified Language.Haskell.Stylish.Step.LanguagePragmas.Tests import qualified Language.Haskell.Stylish.Step.SimpleAlign.Tests +import qualified Language.Haskell.Stylish.Step.Squash.Tests import qualified Language.Haskell.Stylish.Step.Tabs.Tests import qualified Language.Haskell.Stylish.Step.TrailingWhitespace.Tests import qualified Language.Haskell.Stylish.Step.UnicodeSyntax.Tests @@ -25,6 +26,7 @@ main = defaultMain , Language.Haskell.Stylish.Step.Imports.Tests.tests , Language.Haskell.Stylish.Step.LanguagePragmas.Tests.tests , Language.Haskell.Stylish.Step.SimpleAlign.Tests.tests + , Language.Haskell.Stylish.Step.Squash.Tests.tests , Language.Haskell.Stylish.Step.Tabs.Tests.tests , Language.Haskell.Stylish.Step.TrailingWhitespace.Tests.tests , Language.Haskell.Stylish.Step.UnicodeSyntax.Tests.tests |