diff --git a/.gitignore b/.gitignore index 420d122..77c5857 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ cabal.project.local ptl-pthread *.tix +*.cabal diff --git a/.stylish-haskell.yaml b/.stylish-haskell.yaml new file mode 100644 index 0000000..319672c --- /dev/null +++ b/.stylish-haskell.yaml @@ -0,0 +1,23 @@ +# stylish-haskell configuration file +# ================================== + +# The stylish-haskell tool is mainly configured by specifying steps. These steps +# are a list, so they have an order, and one specific step may appear more than +# once (if needed). Each file is processed by these steps in the given order. +steps: + - imports: + align: file + list_align: after_alias + long_list_align: inline + list_padding: 4 + separate_lists: true + - language_pragmas: + style: vertical + align: true + remove_redundant: true + - tabs: + spaces: 4 + - trailing_whitespace: {} +columns: 80 +language_extensions: + - OverloadedStrings diff --git a/HLint.hs b/HLint.hs new file mode 100644 index 0000000..c044d91 --- /dev/null +++ b/HLint.hs @@ -0,0 +1,6 @@ +-- HLint configuration file + +module HLint.HLint where + +import "hint" HLint.Hlint +import "hint" HLint.Generalise diff --git a/Makefile b/Makefile index 2e2d1b4..89b92be 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +.PHONY: hlint_install, hlint, hlint_apply_refact, hlint_refactor +.PHONY: stylish_haskell_install, stylish_haskell_check build: clean @stack install @@ -14,3 +16,24 @@ package-bin: static-build clean: @stack clean + +# The following tasks cribbed from: https://lwm.github.io/haskell-static/ +hlint_install: + @stack install hlint + +hlint: hlint_install + @hlint test/ src/ app/ + +hlint_apply_refact: hlint_install + @stack install apply-refact + +HLINT=hlint --refactor --refactor-options -i {} \; +hlint_refactor: hlint_apply_refact + @find src/ test/ app/ -name "*.hs" -exec $(HLINT) + +stylish_haskell_install: + @stack install stylish-haskell + +STYLISH=stylish-haskell -i {} \; +stylish_haskell_check: stylish_haskell_install + @find test/ app/ src/ -name "*.hs" -exec $(STYLISH) && git diff --exit-code diff --git a/README.md b/README.md index bc5e380..c93145d 100644 --- a/README.md +++ b/README.md @@ -147,13 +147,15 @@ You can get a list of available options with the `-h` flag: ``` $ bartlett -h -bartlett - the Jenkins command-line tool to serve your needs. +bartlett 1.6.0 - the Jenkins command-line tool to serve your needs. -Usage: bartlett [-u|--username USERNAME] [-j|--jenkins JENKINS_INSTANCE] - [-p|--profile PROFILE_NAME] [--refresh-credentials] COMMAND +Usage: bartlett [--version] [-u|--username USERNAME] + [-j|--jenkins JENKINS_INSTANCE] [-p|--profile PROFILE_NAME] + [--refresh-credentials] COMMAND Available options: -h,--help Show this help text + --version Print the current version and exit. -u,--username USERNAME The user to authenticate with -j,--jenkins JENKINS_INSTANCE The Jenkins instance to interact with diff --git a/app/Main.hs b/app/Main.hs index 10b424c..3168968 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -1,24 +1,25 @@ module Main where -import Prelude hiding (putStr) - +import qualified Bartlett.Actions.Artifact as AA +import qualified Bartlett.Actions.Build as AB +import qualified Bartlett.Actions.Config as AC +import qualified Bartlett.Actions.Info as AI +import qualified Bartlett.Actions.Log as AL +import qualified Bartlett.Configuration as C +import Bartlett.Parsers (parseOptions, withInfo) import Bartlett.Types -import Bartlett.Parsers (parseOptions, withInfo) -import qualified Bartlett.Configuration as C -import qualified Bartlett.Actions.Info as AI -import qualified Bartlett.Actions.Build as AB -import qualified Bartlett.Actions.Config as AC -import qualified Bartlett.Actions.Artifact as AA -import qualified Bartlett.Actions.Log as AL -import Control.Exception (bracket_) -import Control.Monad.Reader (local, liftIO, ask, asks, runReaderT) -import Data.ByteString.Lazy.Char8 (ByteString, pack, unpack, hPutStr) -import Data.Maybe (fromMaybe) -import Options.Applicative -import System.Exit (die) -import System.IO (hFlush, stdout, stdin, stderr, hSetEcho, hGetEcho, hPutChar) -import qualified System.Keyring as SK +import Control.Exception (bracket_) +import Control.Monad.Reader (ask, asks, liftIO, local, + runReaderT) +import Data.ByteString.Lazy.Char8 (ByteString, hPutStr, pack, unpack) +import Data.Maybe (fromMaybe) +import Options.Applicative +import Prelude hiding (putStr) +import System.Exit (die) +import System.IO (hFlush, hGetEcho, hPutChar, + hSetEcho, stderr, stdin, stdout) +import qualified System.Keyring as SK -- | Wrapper determining if the given action should be echoed to stdout. withEcho :: Bool -> IO a -> IO a diff --git a/bartlett.cabal b/bartlett.cabal deleted file mode 100644 index 35c632e..0000000 --- a/bartlett.cabal +++ /dev/null @@ -1,94 +0,0 @@ -name: bartlett -version: 1.5.1 -synopsis: The Jenkins command-line tool to serve your needs. -description: Please see README.md -homepage: https://github.com/Nike-inc/bartlett -license: BSD3 -license-file: LICENSE -author: Fernando Freire -maintainer: fernando.freire@nike.com -copyright: 2016 Nike, Inc. -category: CLI -build-type: Simple -cabal-version: >=1.10 - -library - hs-source-dirs: src - exposed-modules: Bartlett.Types, - Bartlett.Util, - Bartlett.Parsers, - Bartlett.Network, - Bartlett.Configuration, - Bartlett.Actions.Info, - Bartlett.Actions.Build, - Bartlett.Actions.Config, - Bartlett.Actions.Artifact, - Bartlett.Actions.Log - ghc-options: - -fwarn-tabs - -fwarn-unused-imports - -fwarn-missing-signatures - -fwarn-name-shadowing - -fwarn-incomplete-patterns - default-extensions: OverloadedStrings - default-language: Haskell2010 - build-depends: base >= 4.7 && < 5, - wreq, - configurator, - filepath, - bytestring, - lens, - optparse-applicative, - aeson, - aeson-pretty, - lens-aeson, - text, - http-types, - http-client, - uri-bytestring, - case-insensitive, - mtl, - transformers - -executable bartlett - main-is: app/Main.hs - default-language: Haskell2010 - default-extensions: OverloadedStrings - ld-options: - -optl-static - -optl-pthread - ghc-options: - -threaded - -rtsopts - -with-rtsopts=-N - build-depends: base >= 4.7 && < 5, - bartlett, - bytestring, - optparse-applicative, - keyring, - mtl - -test-suite bartlett-test - type: exitcode-stdio-1.0 - hs-source-dirs: test - other-modules: Bartlett.TypesSpec, - Bartlett.UtilSpec, - Bartlett.Actions.InfoSpec - main-is: Spec.hs - ghc-options: - -threaded - -rtsopts - -with-rtsopts=-N - default-language: Haskell2010 - default-extensions: OverloadedStrings - build-depends: base >= 4.7 && < 5, - hscolour, - bartlett, - hspec, - bytestring, - aeson, - wreq, - http-types, - lens, - uri-bytestring, - either-unwrap diff --git a/package.yaml b/package.yaml new file mode 100644 index 0000000..ff50d08 --- /dev/null +++ b/package.yaml @@ -0,0 +1,88 @@ +name: bartlett +version: '1.6.0' +synopsis: The Jenkins command-line tool to serve your needs. +description: Please see README.md +category: CLI +author: Fernando Freire +maintainer: fernando.freire@nike.com +copyright: 2016-Present Nike, Inc. +license: BSD3 +github: Nike-inc/bartlett +default-extensions: + - OverloadedStrings +dependencies: + - base >=4.7 && <5 + - bytestring +library: + source-dirs: src + ghc-options: + - -Wall + - -fwarn-tabs + - -fwarn-unused-imports + - -fwarn-missing-signatures + - -fwarn-name-shadowing + - -fwarn-incomplete-patterns + exposed-modules: + - Bartlett.Types + - Bartlett.Util + - Bartlett.Parsers + - Bartlett.Network + - Bartlett.Configuration + - Bartlett.Actions.Info + - Bartlett.Actions.Build + - Bartlett.Actions.Config + - Bartlett.Actions.Artifact + - Bartlett.Actions.Log + dependencies: + - aeson + - aeson-pretty + - case-insensitive + - configurator + - filepath + - http-client + - http-types + - lens + - lens-aeson + - mtl + - optparse-applicative + - text + - transformers + - uri-bytestring + - wreq +executables: + bartlett: + main: app/Main.hs + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + ld-options: + - -optl-static + - -optl-pthread + dependencies: + - bartlett + - keyring + - mtl + - optparse-applicative +tests: + bartlett-test: + main: Tasty.hs + source-dirs: test + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + dependencies: + - aeson + - bartlett + - either-unwrap + - hspec + - http-types + - lens + - smallcheck + - tasty + - tasty-discover + - tasty-hspec + - tasty-smallcheck + - uri-bytestring + - wreq diff --git a/src/Bartlett/Actions/Artifact.hs b/src/Bartlett/Actions/Artifact.hs index 6ea9eaa..949bcc2 100644 --- a/src/Bartlett/Actions/Artifact.hs +++ b/src/Bartlett/Actions/Artifact.hs @@ -12,16 +12,16 @@ module Bartlett.Actions.Artifact ( getArtifact ) where -import Bartlett.Network (execRequest) -import Bartlett.Types -import Bartlett.Util (mkUrl) +import Bartlett.Network (execRequest) +import Bartlett.Types +import Bartlett.Util (mkUrl) -import Control.Lens (set, (^.), (&)) -import Control.Monad.Reader (asks, liftIO) -import Data.Maybe (fromJust) -import Data.Monoid ((<>)) +import Control.Lens (set, (&), (^.)) +import Control.Monad.Reader (asks, liftIO) import qualified Data.ByteString.Lazy.Char8 as BL -import Network.Wreq (responseBody, defaults, auth) +import Data.Maybe (fromJust) +import Data.Monoid ((<>)) +import Network.Wreq (auth, defaults, responseBody) -- | Download an artifact from the provided job. getArtifact :: diff --git a/src/Bartlett/Actions/Build.hs b/src/Bartlett/Actions/Build.hs index 80bf774..51af7cf 100644 --- a/src/Bartlett/Actions/Build.hs +++ b/src/Bartlett/Actions/Build.hs @@ -12,16 +12,16 @@ module Bartlett.Actions.Build ( postBuild ) where -import Bartlett.Network (execRequest) -import Bartlett.Types -import qualified Bartlett.Util as BU +import Bartlett.Network (execRequest) +import Bartlett.Types +import qualified Bartlett.Util as BU -import Control.Lens (set, (^.), (&)) -import Control.Monad.Reader (asks, liftIO) -import Data.Maybe (fromJust) -import Data.Aeson.Encode.Pretty (encodePretty) +import Control.Lens (set, (&), (^.)) +import Control.Monad.Reader (asks, liftIO) +import Data.Aeson.Encode.Pretty (encodePretty) import qualified Data.ByteString.Lazy.Char8 as BL -import Network.Wreq (Options, responseStatus, auth) +import Data.Maybe (fromJust) +import Network.Wreq (Options, auth, responseStatus) -- | Parses and determines type of job to trigger based on supplied parameters. diff --git a/src/Bartlett/Actions/Config.hs b/src/Bartlett/Actions/Config.hs index 8e4de6d..4d06de5 100644 --- a/src/Bartlett/Actions/Config.hs +++ b/src/Bartlett/Actions/Config.hs @@ -10,16 +10,17 @@ Methods for executing config requests against Jenkins. -} module Bartlett.Actions.Config where -import Bartlett.Network (execRequest) -import Bartlett.Types -import Bartlett.Util (toResponseStatus, mkUrl) +import Bartlett.Network (execRequest) +import Bartlett.Types +import Bartlett.Util (mkUrl, toResponseStatus) -import Control.Lens (set, (^.), (&)) -import Data.Maybe (Maybe, fromJust) -import Data.Aeson.Encode.Pretty (encodePretty) +import Control.Lens (set, (&), (^.)) +import Control.Monad.Reader (asks, liftIO) +import Data.Aeson.Encode.Pretty (encodePretty) import qualified Data.ByteString.Lazy.Char8 as BL -import Network.Wreq (responseStatus, responseBody, defaults, auth) -import Control.Monad.Reader (liftIO, asks) +import Data.Maybe (Maybe, fromJust) +import Network.Wreq (auth, defaults, responseBody, + responseStatus) -- | Construct a URL to interact with Job configurations. configUri :: JenkinsInstance -> JobPath -> JenkinsInstance diff --git a/src/Bartlett/Actions/Info.hs b/src/Bartlett/Actions/Info.hs index 2a61974..9f3bca2 100644 --- a/src/Bartlett/Actions/Info.hs +++ b/src/Bartlett/Actions/Info.hs @@ -12,15 +12,15 @@ module Bartlett.Actions.Info ( getInfo ) where -import Bartlett.Network (execRequest) -import Bartlett.Types -import Bartlett.Util (toPrettyJson, mkUrl) +import Bartlett.Network (execRequest) +import Bartlett.Types +import Bartlett.Util (mkUrl, toPrettyJson) -import Control.Lens (set, (^.), (&)) -import Control.Monad.Reader (asks, liftIO) -import Data.Maybe (fromJust) +import Control.Lens (set, (&), (^.)) +import Control.Monad.Reader (asks, liftIO) import qualified Data.ByteString.Lazy.Char8 as BL -import Network.Wreq (responseBody, defaults, auth) +import Data.Maybe (fromJust) +import Network.Wreq (auth, defaults, responseBody) -- | Retrieve information for the given job from the given jenkins instance. diff --git a/src/Bartlett/Actions/Log.hs b/src/Bartlett/Actions/Log.hs index f024488..b81ea69 100644 --- a/src/Bartlett/Actions/Log.hs +++ b/src/Bartlett/Actions/Log.hs @@ -12,19 +12,20 @@ module Bartlett.Actions.Log ( getLogs ) where -import Bartlett.Network (execRequest) -import Bartlett.Types -import Bartlett.Util (mkUrl, toText) +import Bartlett.Network (execRequest) +import Bartlett.Types +import Bartlett.Util (mkUrl, toText) -import Control.Concurrent (threadDelay) -import Control.Lens (set, (^.), (&), (^?)) -import Control.Monad.Reader (asks, liftIO) -import Control.Monad (when, unless) -import Data.Maybe (fromJust, isJust) -import Data.Monoid ((<>)) +import Control.Concurrent (threadDelay) +import Control.Lens (set, (&), (^.), (^?)) +import Control.Monad (unless, when) +import Control.Monad.Reader (asks, liftIO) import qualified Data.ByteString.Lazy.Char8 as BL -import qualified Data.Text as T -import Network.Wreq (responseBody, responseHeader, defaults, auth, param) +import Data.Maybe (fromJust, isJust) +import Data.Monoid ((<>)) +import qualified Data.Text as T +import Network.Wreq (auth, defaults, param, + responseBody, responseHeader) -- | Internal helper to recursively get logs from the given Jenkins instance. requestLogs :: diff --git a/src/Bartlett/Configuration.hs b/src/Bartlett/Configuration.hs index 091a00b..6453385 100644 --- a/src/Bartlett/Configuration.hs +++ b/src/Bartlett/Configuration.hs @@ -18,14 +18,14 @@ module Bartlett.Configuration ( getStorePassword ) where -import Bartlett.Util (toText) -import Bartlett.Types +import Bartlett.Types +import Bartlett.Util (toText) -import qualified Data.Configurator as C -import Data.ByteString.Lazy.Char8 (toStrict) -import Data.Configurator.Types -import System.FilePath (()) -import URI.ByteString (parseURI, strictURIParserOptions) +import Data.ByteString.Lazy.Char8 (toStrict) +import qualified Data.Configurator as C +import Data.Configurator.Types +import System.FilePath (()) +import URI.ByteString (parseURI, strictURIParserOptions) -- | Default config file location defaultConfigLoc :: FilePath @@ -52,7 +52,7 @@ getJenkinsInstance cfg = do return Nothing Just inst -> case parseURI strictURIParserOptions (toStrict inst) of - Left err -> + Left _ -> return Nothing Right i -> return $ Just i diff --git a/src/Bartlett/Network.hs b/src/Bartlett/Network.hs index bb35795..f069e1b 100644 --- a/src/Bartlett/Network.hs +++ b/src/Bartlett/Network.hs @@ -19,20 +19,21 @@ module Bartlett.Network ( recoverableErrorHandler )where -import qualified Bartlett.Util as BU -import Bartlett.Types (RequestType(..), JenkinsInstance) +import Bartlett.Types (JenkinsInstance, RequestType (..)) +import qualified Bartlett.Util as BU -import qualified Control.Exception as E -import Control.Lens ((.~), (^?), (&)) -import Data.Aeson.Encode.Pretty (encodePretty) -import Data.Aeson.Lens (key, _String) -import qualified Data.CaseInsensitive as CI -import Data.ByteString.Lazy.Char8 (ByteString, unpack, toStrict, empty) -import Data.Maybe (fromMaybe) -import qualified Network.HTTP.Client as NHC -import System.Exit (die) -import Network.Wreq (Options, Response, param, responseBody, header) -import qualified Network.Wreq.Session as S +import qualified Control.Exception as E +import Control.Lens ((&), (.~), (^?)) +import Data.Aeson.Encode.Pretty (encodePretty) +import Data.Aeson.Lens (key, _String) +import Data.ByteString.Lazy.Char8 (ByteString, toStrict, unpack) +import qualified Data.CaseInsensitive as CI +import Data.Maybe (fromMaybe) +import qualified Network.HTTP.Client as NHC +import Network.Wreq (Options, Response, header, param, + responseBody) +import qualified Network.Wreq.Session as S +import System.Exit (die) -- | Attempt to request a CSRF token from the Jenkins server. @@ -55,9 +56,9 @@ requestCSRFToken sess opts jenkins = do reqOpts = opts & param "xpath" .~ [BU.toText "concat(//crumbRequestField,\":\",//crumb)"] -- | Construct a valid header from a potential CSRF response. -consCSRFHeader :: IO (Maybe ByteString, Maybe ByteString) -> IO (Options -> Options) -consCSRFHeader ioCrumb = ioCrumb >>= \ (field, crumb) -> - return $ header (CI.mk . toStrict . fromMaybe empty $ field) .~ [(toStrict . fromMaybe empty) crumb] +consCSRFHeader :: (ByteString, ByteString) -> (Options -> Options) +consCSRFHeader (field, crumb) = + header (CI.mk . toStrict $ field) .~ [toStrict crumb] -- | General request handler that provides basic error handling. @@ -71,12 +72,19 @@ execRequest requestType reqOpts reqUrl postBody = S.withAPISession $ \session -> case requestType of Post -> do - csrfCrumb <- consCSRFHeader $ requestCSRFToken session reqOpts reqUrl - postSession reqUrl (reqOpts & csrfCrumb) + opts <- getOpts + postSession reqUrl opts `E.catch` - recoverableErrorHandler (postSession (BU.withForcedSSL reqUrl) (reqOpts & csrfCrumb)) - where fileToUpload = fromMaybe "" postBody :: ByteString - postSession url opts = S.postWith opts session (BU.uriToString url) fileToUpload + recoverableErrorHandler (postSession (BU.withForcedSSL reqUrl) opts) + where fileToUpload = fromMaybe "" postBody :: ByteString + postSession url opts = S.postWith opts session (BU.uriToString url) fileToUpload + getOpts = do + csrfCrumb <- requestCSRFToken session reqOpts reqUrl + case csrfCrumb of + (Just field, Just crumb) -> + return $ reqOpts & consCSRFHeader (field, crumb) + _ -> + return reqOpts Get -> getSession reqUrl `E.catch` diff --git a/src/Bartlett/Parsers.hs b/src/Bartlett/Parsers.hs index d6ad5c8..b0cc74e 100644 --- a/src/Bartlett/Parsers.hs +++ b/src/Bartlett/Parsers.hs @@ -10,13 +10,20 @@ Parsers used to extract command line options at invocation. -} module Bartlett.Parsers where -import Bartlett.Types +import Bartlett.Types -import Data.ByteString.Lazy.Char8 (ByteString, pack, unpack, toStrict) -import Data.Monoid ((<>)) -import URI.ByteString (URIRef, Absolute, parseURI, strictURIParserOptions) -import Options.Applicative -import Options.Applicative.Types (readerAsk) +import Data.ByteString.Lazy.Char8 (ByteString, pack, toStrict, unpack) +import Data.Monoid ((<>)) +import Data.Version (showVersion) +import Options.Applicative +import Options.Applicative.Types (readerAsk) +import qualified Paths_bartlett +import URI.ByteString (Absolute, URIRef, parseURI, + strictURIParserOptions) + +-- | The current bartlett version +bartlettVersion :: String +bartlettVersion = "bartlett " <> showVersion Paths_bartlett.version -- | Parse a command line option as a "ByteString". readerByteString :: ReadM ByteString @@ -36,12 +43,18 @@ readerUriRef = do -- | Wrap parsers with doc strings and metadata. withInfo :: Parser a -> ByteString -> ParserInfo a -withInfo opts desc = info (helper <*> opts) +withInfo opts desc = info (helper <*> parseVersion <*> opts) (fullDesc <> progDesc (unpack desc) - <> header "bartlett - the Jenkins command-line tool to serve your needs." + <> header (bartlettVersion <> " - the Jenkins command-line tool to serve your needs.") <> footer "Copyright (c) Nike, Inc. 2016-present") +-- | Parse a version flag. +parseVersion :: Parser (a -> a) +parseVersion = infoOption bartlettVersion $ + long "version" + <> help "Print the current version and exit." + -- | Parse a credentials flag. parseRefreshCredentials :: Parser Bool parseRefreshCredentials = switch $ diff --git a/src/Bartlett/Types.hs b/src/Bartlett/Types.hs index a589f65..6af3d76 100644 --- a/src/Bartlett/Types.hs +++ b/src/Bartlett/Types.hs @@ -1,4 +1,5 @@ -{-# LANGUAGE DeriveGeneric, GeneralizedNewtypeDeriving #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-| Module : Types @@ -36,13 +37,13 @@ module Bartlett.Types ( Bartlett(..) ) where -import Data.Aeson (ToJSON, FromJSON) +import Control.Monad.IO.Class (MonadIO) +import Control.Monad.Reader (MonadReader, ReaderT) +import Data.Aeson (FromJSON, ToJSON) import Data.ByteString.Lazy.Char8 (ByteString, toStrict) -import GHC.Generics (Generic) -import Network.Wreq (Auth, basicAuth) -import URI.ByteString (URIRef, Absolute) -import Control.Monad.IO.Class (MonadIO) -import Control.Monad.Reader (MonadReader, ReaderT) +import GHC.Generics (Generic) +import Network.Wreq (Auth, basicAuth) +import URI.ByteString (Absolute, URIRef) -- TODO use newtypes!! doesn't require boxing diff --git a/src/Bartlett/Util.hs b/src/Bartlett/Util.hs index 0ff2489..23c9464 100644 --- a/src/Bartlett/Util.hs +++ b/src/Bartlett/Util.hs @@ -30,21 +30,22 @@ module Bartlett.Util ( optionsBuilder )where -import Prelude hiding (null, dropWhile) - -import Bartlett.Types - -import Control.Lens (set, (^.)) -import Data.Aeson (decode, Object) -import Data.Aeson.Encode.Pretty (encodePretty) -import Data.Monoid ((<>)) -import Data.ByteString.Lazy.Char8 -import Data.ByteString.Builder (toLazyByteString) -import qualified Data.Text as T -import qualified Data.Text.Encoding as TE -import qualified Network.Wreq as W -import Network.HTTP.Types.Status -import URI.ByteString (pathL, uriSchemeL, schemeBSL, serializeURIRef) +import Prelude hiding (dropWhile, null) + +import Bartlett.Types + +import Control.Lens (set, (^.)) +import Data.Aeson (Object, decode) +import Data.Aeson.Encode.Pretty (encodePretty) +import Data.ByteString.Builder (toLazyByteString) +import Data.ByteString.Lazy.Char8 +import Data.Monoid ((<>)) +import qualified Data.Text as T +import qualified Data.Text.Encoding as TE +import Network.HTTP.Types.Status +import qualified Network.Wreq as W +import URI.ByteString (pathL, schemeBSL, serializeURIRef, + uriSchemeL) setPath :: JenkinsInstance -> ByteString -> JenkinsInstance setPath jenkins path = diff --git a/stack.yaml b/stack.yaml index 1e4a8cc..399cd21 100644 --- a/stack.yaml +++ b/stack.yaml @@ -15,7 +15,7 @@ # resolver: # name: custom-snapshot # location: "./custom-snapshot.yaml" -resolver: lts-8.2 +resolver: lts-9.0 # User packages to be built. # Various formats can be used as shown in the example below. diff --git a/test/Bartlett/Actions/InfoSpec.hs b/test/Bartlett/Actions/InfoSpec.hs index 2793819..b6add8b 100644 --- a/test/Bartlett/Actions/InfoSpec.hs +++ b/test/Bartlett/Actions/InfoSpec.hs @@ -8,9 +8,7 @@ import Test.Hspec -- TODO figure out how to mock some HTTP request action -- this might be a good resource: https://github.com/bos/wreq/blob/master/tests/UnitTests.hs -spec :: Spec -spec = describe "Info tests" $ - +spec_info = describe "Info tests" $ describe "getInfo" $ it "should make a request to jenkins" $ 1 `shouldBe` 1 diff --git a/test/Bartlett/TypesSpec.hs b/test/Bartlett/TypesSpec.hs index ea5f95b..2c18a23 100644 --- a/test/Bartlett/TypesSpec.hs +++ b/test/Bartlett/TypesSpec.hs @@ -4,11 +4,10 @@ module Bartlett.TypesSpec where import Bartlett.Types -import Network.Wreq hiding (statusCode, statusMessage) +import Network.Wreq hiding (statusCode, statusMessage) import Test.Hspec -spec :: Spec -spec = +spec_types = describe "Type tests" $ do describe "getBasicAuth for BasicAuthUser" $ diff --git a/test/Bartlett/UtilSpec.hs b/test/Bartlett/UtilSpec.hs index c85b750..3aa8883 100644 --- a/test/Bartlett/UtilSpec.hs +++ b/test/Bartlett/UtilSpec.hs @@ -1,19 +1,19 @@ module Bartlett.UtilSpec where -import Bartlett.Types -import Bartlett.Util +import Bartlett.Types +import Bartlett.Util -import Control.Exception (evaluate) -import Control.Lens -import Data.Aeson -import Data.ByteString.Lazy.Char8 -import GHC.Exts -import qualified Network.Wreq as W -import Network.HTTP.Types.Status hiding (statusCode, statusMessage) -import Test.Hspec +import Control.Exception (evaluate) +import Control.Lens +import Data.Aeson +import Data.ByteString.Lazy.Char8 +import GHC.Exts +import Network.HTTP.Types.Status hiding (statusCode, statusMessage) +import qualified Network.Wreq as W +import Test.Hspec -import URI.ByteString -import Data.Either.Unwrap +import Data.Either.Unwrap +import URI.ByteString -- | Helper to create instances of 'JenkinsInstance'. jenkins :: Bool -> JenkinsInstance @@ -23,8 +23,7 @@ jenkins withSSL = then "https://example.com" else "http://example.com" -spec :: Spec -spec = +spec_util = describe "Util tests" $ do describe "mkUrl" $ do diff --git a/test/ReplSugar.hs b/test/ReplSugar.hs index a5103fa..ba23e9c 100644 --- a/test/ReplSugar.hs +++ b/test/ReplSugar.hs @@ -1,15 +1,15 @@ {-# LANGUAGE OverloadedStrings #-} module ReplSugar where -import Control.Lens -import Bartlett.Types -import Bartlett.Util -import Bartlett.Configuration -import Bartlett.Network -import Data.Maybe -import Data.ByteString.Lazy.Char8 -import qualified Network.Wreq as W -import qualified Network.Wreq.Session as S +import Bartlett.Configuration +import Bartlett.Network +import Bartlett.Types +import Bartlett.Util +import Control.Lens +import Data.ByteString.Lazy.Char8 +import Data.Maybe +import qualified Network.Wreq as W +import qualified Network.Wreq.Session as S -- | Docker Jenkins user. usr :: User diff --git a/test/Spec.hs b/test/Spec.hs deleted file mode 100644 index 344bdf9..0000000 --- a/test/Spec.hs +++ /dev/null @@ -1,2 +0,0 @@ -{-# OPTIONS_GHC -F -pgmF hspec-discover #-} --- Allows HSpec to discover tests diff --git a/test/Tasty.hs b/test/Tasty.hs new file mode 100644 index 0000000..9bca844 --- /dev/null +++ b/test/Tasty.hs @@ -0,0 +1,5 @@ +{-# + OPTIONS_GHC -F + -pgmF tasty-discover + -optF --tree-display +#-}