packages feed

stackctl 1.5.0.1 → 1.6.0.0

raw patch · 19 files changed

+185/−258 lines, 19 filesdep +amazonka-mtldep ~Globdep ~QuickCheckdep ~aeson

Dependencies added: amazonka-mtl

Dependency ranges changed: Glob, QuickCheck, aeson, aeson-casing, aeson-pretty, bytestring, conduit, containers, envparse, errors, exceptions, extra, filepath, hspec, lens, lens-aeson, monad-logger, mtl, optparse-applicative, resourcet, rio, semigroups, text, text-metrics, time, transformers, typed-process, unordered-containers, uuid, yaml

Files

CHANGELOG.md view
@@ -1,4 +1,10 @@-## [_Unreleased_](https://github.com/freckle/stackctl/compare/v1.5.0.1...main)+## [_Unreleased_](https://github.com/freckle/stackctl/compare/v1.6.0.0...main)++## [v1.6.0.0](https://github.com/freckle/stackctl/compare/v1.5.0.1...v1.6.0.0)++- Re-implement `Stackctl.AWS` with `amazonka-mtl`.++_No CLI or behavior changes._  ## [v1.5.0.1](https://github.com/freckle/stackctl/compare/v1.5.0.0...v1.5.0.1) 
src/Stackctl/AWS/CloudFormation.hs view
@@ -86,6 +86,7 @@   , _MatchServiceError   , _ServiceError   )+import qualified Amazonka.Env as Amazonka import Amazonka.Waiter (Accept (..)) import Conduit import Control.Lens ((?~))@@ -97,7 +98,7 @@ import Data.Time (UTCTime, defaultTimeLocale, formatTime, getCurrentTime) import qualified Data.UUID as UUID import qualified Data.UUID.V4 as UUID-import Stackctl.AWS.Core+import Stackctl.AWS.Core as AWS import Stackctl.Sort import Stackctl.StackDescription import System.FilePath.Glob@@ -172,16 +173,16 @@   pure $ ChangeSetName $ T.intercalate "-" $ map pack parts  awsCloudFormationDescribeStack-  :: (MonadResource m, MonadReader env m, HasAwsEnv env) => StackName -> m Stack+  :: (MonadIO m, MonadAWS m) => StackName -> m Stack awsCloudFormationDescribeStack stackName = do   let req = newDescribeStacks & describeStacks_stackName ?~ unStackName stackName -  awsSimple req $ \resp -> do+  AWS.simple req $ \resp -> do     stacks <- resp ^. describeStacksResponse_stacks     listToMaybe stacks  awsCloudFormationDescribeStackMaybe-  :: (MonadUnliftIO m, MonadResource m, MonadReader env m, HasAwsEnv env)+  :: (MonadUnliftIO m, MonadAWS m)   => StackName   -> m (Maybe Stack) awsCloudFormationDescribeStackMaybe stackName =@@ -193,7 +194,7 @@     <$> awsCloudFormationDescribeStack stackName  awsCloudFormationDescribeStackOutputs-  :: (MonadResource m, MonadReader env m, HasAwsEnv env)+  :: (MonadIO m, MonadAWS m)   => StackName   -> m [Output] awsCloudFormationDescribeStackOutputs stackName = do@@ -201,7 +202,7 @@   pure $ fromMaybe [] $ outputs stack  awsCloudFormationDescribeStackEvents-  :: (MonadResource m, MonadReader env m, HasAwsEnv env)+  :: (MonadIO m, MonadAWS m)   => StackName   -> Maybe Text   -- ^ Last-seen Id@@ -213,21 +214,21 @@           ?~ unStackName stackName    runConduit-    $ awsPaginate req+    $ AWS.paginate req     .| mapC (fromMaybe [] . (^. describeStackEventsResponse_stackEvents))     .| concatC     .| takeWhileC (\e -> Just (e ^. stackEvent_eventId) /= mLastId)     .| sinkList  awsCloudFormationGetStackNamesMatching-  :: (MonadResource m, MonadReader env m, HasAwsEnv env)+  :: (MonadIO m, MonadAWS m)   => Pattern   -> m [StackName] awsCloudFormationGetStackNamesMatching p = do   let req = newListStacks & listStacks_stackStatusFilter ?~ runningStatuses    runConduit-    $ awsPaginate req+    $ AWS.paginate req     .| concatMapC (^. listStacksResponse_stackSummaries)     .| concatC     .| mapC (^. stackSummary_stackName)@@ -236,7 +237,7 @@     .| sinkList  awsCloudFormationGetMostRecentStackEventId-  :: (MonadResource m, MonadReader env m, HasAwsEnv env)+  :: (MonadIO m, MonadAWS m)   => StackName   -> m (Maybe Text) awsCloudFormationGetMostRecentStackEventId stackName = do@@ -252,14 +253,14 @@       [] -> Nothing       (e : _) -> Just $ e ^. stackEvent_eventId -  awsSimple req+  AWS.simple req     $ pure     . getFirstEventId     . fromMaybe []     . (^. describeStackEventsResponse_stackEvents)  awsCloudFormationDeleteStack-  :: (MonadResource m, MonadLogger m, MonadReader env m, HasAwsEnv env)+  :: (MonadIO m, MonadLogger m, MonadAWS m)   => StackName   -> m StackDeleteResult awsCloudFormationDeleteStack stackName = do@@ -268,25 +269,25 @@     describeReq =       newDescribeStacks & describeStacks_stackName ?~ unStackName stackName -  awsSimple deleteReq $ const $ pure ()+  AWS.simple deleteReq $ const $ pure ()    logDebug "Awaiting DeleteStack"-  stackDeleteResult <$> awsAwait newStackDeleteComplete describeReq+  stackDeleteResult <$> AWS.await newStackDeleteComplete describeReq  awsCloudFormationWait-  :: (MonadUnliftIO m, MonadResource m, MonadReader env m, HasAwsEnv env)+  :: (MonadUnliftIO m, MonadAWS m)   => StackName   -> m StackDeployResult awsCloudFormationWait stackName = do   either stackCreateResult stackUpdateResult     <$> race-      (awsAwait newStackCreateComplete req)-      (awsAwait newStackUpdateComplete req)+      (AWS.await newStackCreateComplete req)+      (AWS.await newStackUpdateComplete req)  where   req = newDescribeStacks & describeStacks_stackName ?~ unStackName stackName  awsCloudFormationGetTemplate-  :: (MonadResource m, MonadReader env m, HasAwsEnv env) => StackName -> m Value+  :: (MonadIO m, MonadAWS m) => StackName -> m Value awsCloudFormationGetTemplate stackName = do   let     req =@@ -298,7 +299,7 @@     decodeTemplateBody body =       fromMaybe (toJSON body) $ decodeStrict $ encodeUtf8 body -  awsSimple req $ \resp -> do+  AWS.simple req $ \resp -> do     body <- resp ^. getTemplateResponse_templateBody     pure $ decodeTemplateBody body @@ -366,10 +367,8 @@  awsCloudFormationCreateChangeSet   :: ( MonadUnliftIO m-     , MonadResource m      , MonadLogger m-     , MonadReader env m-     , HasAwsEnv env+     , MonadAWS m      )   => StackName   -> Maybe StackDescription@@ -410,22 +409,22 @@       logInfo         $ "Creating changeset..."         :# ["name" .= name, "type" .= changeSetType]-      csId <- awsSimple req (^. createChangeSetResponse_id)+      csId <- AWS.simple req (^. createChangeSetResponse_id)        logDebug "Awaiting CREATE_COMPLETE"-      void $ awsAwait newChangeSetCreateComplete $ newDescribeChangeSet csId+      void $ AWS.await newChangeSetCreateComplete $ newDescribeChangeSet csId        logInfo "Retrieving changeset..."       cs <- awsCloudFormationDescribeChangeSet $ ChangeSetId csId       pure $ cs <$ guard (not $ changeSetFailed cs)  awsCloudFormationDescribeChangeSet-  :: (MonadResource m, MonadReader env m, HasAwsEnv env)+  :: (MonadIO m, MonadAWS m)   => ChangeSetId   -> m ChangeSet awsCloudFormationDescribeChangeSet changeSetId = do   let req = newDescribeChangeSet $ unChangeSetId changeSetId-  awsSimple req changeSetFromResponse+  AWS.simple req changeSetFromResponse  sortChanges :: [Change] -> [Change] sortChanges = sortByDependencies changeName changeCausedBy@@ -445,18 +444,16 @@   T.takeWhile (/= '.') <$> causingEntity  awsCloudFormationExecuteChangeSet-  :: (MonadResource m, MonadReader env m, HasAwsEnv env) => ChangeSetId -> m ()+  :: (MonadIO m, MonadAWS m) => ChangeSetId -> m () awsCloudFormationExecuteChangeSet changeSetId = do-  void $ awsSend $ newExecuteChangeSet $ unChangeSetId changeSetId+  void $ AWS.send $ newExecuteChangeSet $ unChangeSetId changeSetId  awsCloudFormationDeleteAllChangeSets-  :: (MonadResource m, MonadLogger m, MonadReader env m, HasAwsEnv env)-  => StackName-  -> m ()+  :: (MonadIO m, MonadLogger m, MonadAWS m) => StackName -> m () awsCloudFormationDeleteAllChangeSets stackName = do   logInfo "Deleting all changesets"   runConduit-    $ awsPaginate (newListChangeSets $ unStackName stackName)+    $ AWS.paginate (newListChangeSets $ unStackName stackName)     .| concatMapC       ( \resp -> fromMaybe [] $ do           ss <- resp ^. listChangeSetsResponse_summaries@@ -465,7 +462,7 @@     .| mapM_C       ( \csId -> do           logInfo $ "Enqueing delete" :# ["changeSetId" .= csId]-          void $ awsSend $ newDeleteChangeSet csId+          void $ AWS.send $ newDeleteChangeSet csId       )  -- | Did we abandoned this Stack's first ever ChangeSet?@@ -509,3 +506,8 @@ _ValidationError :: AsError a => Getting (First ServiceError) a ServiceError _ValidationError =   _MatchServiceError defaultService "ValidationError" . hasStatus 400++awsSilently :: MonadAWS m => m a -> m a+awsSilently = AWS.localEnv $ Amazonka.env_logger .~ noop+ where+  noop _level _msg = pure ()
src/Stackctl/AWS/Core.hs view
@@ -1,95 +1,76 @@ module Stackctl.AWS.Core-  ( AwsEnv-  , HasAwsEnv (..)-  , awsEnvDiscover-  , awsWithAuth-  , awsSimple-  , awsSend-  , awsPaginate-  , awsAwait-  , awsAssumeRole--    -- * Modifiers on 'AwsEnv'-  , awsWithin-  , awsTimeout-  , awsSilently+  ( MonadAWS+  , send+  , paginate+  , await+  , withAuth+  , localEnv -    -- * 'Amazonka' extensions-  , AccountId (..)+    -- * "Control.Monad.AWS" extensions+  , simple+  , discover+  , assumeRole      -- * Error-handling   , handlingServiceError   , formatServiceError -    -- * 'Amazonka'/'ResourceT' re-exports+    -- * "Amazonka" extensions+  , AccountId (..)++    -- * "Amazonka" re-exports   , Region (..)   , FromText (..)   , ToText (..)-  , MonadResource   ) where -import Stackctl.Prelude hiding (timeout)+import Stackctl.Prelude -import Amazonka hiding (LogLevel (..))-import qualified Amazonka as AWS+import Amazonka+  ( AWSRequest+  , AWSResponse+  , Region+  , ServiceError+  , serviceError_code+  , serviceError_message+  , serviceError_requestId+  , _Sensitive+  , _ServiceError+  )+import qualified Amazonka import Amazonka.Auth.Keys (fromSession) import Amazonka.Data.Text (FromText (..), ToText (..))-import Amazonka.Env (env_auth, env_logger, env_region)+import qualified Amazonka.Env as Amazonka import Amazonka.STS.AssumeRole-import Conduit (ConduitM)+import Control.Monad.AWS import Control.Monad.Logger (defaultLoc, toLogStr)-import Control.Monad.Trans.Resource (MonadResource) import Data.Typeable (typeRep) import Stackctl.AWS.Orphans () import UnliftIO.Exception.Lens (handling) -newtype AwsEnv = AwsEnv-  { unAwsEnv :: Env-  }--unL :: Lens' AwsEnv Env-unL = lens unAwsEnv $ \x y -> x {unAwsEnv = y}--awsEnvDiscover :: MonadLoggerIO m => m AwsEnv-awsEnvDiscover = do-  env <- liftIO $ newEnv discover-  AwsEnv <$> configureLogging env--configureLogging :: MonadLoggerIO m => Env -> m Env-configureLogging env = do+discover :: MonadLoggerIO m => m Amazonka.Env+discover = do+  env <- liftIO $ Amazonka.newEnv Amazonka.discover   loggerIO <- askLoggerIO    let logger level = do         loggerIO-          defaultLoc -- TODO: there may be a way to get a CallStack/Loc+          defaultLoc           "Amazonka"           ( case level of-              AWS.Info -> LevelInfo-              AWS.Error -> LevelError-              AWS.Debug -> LevelDebug-              AWS.Trace -> LevelOther "trace"+              Amazonka.Info -> LevelInfo+              Amazonka.Error -> LevelError+              Amazonka.Debug -> LevelDebug+              Amazonka.Trace -> LevelOther "trace"           )           . toLogStr-  pure $ env & env_logger .~ logger--class HasAwsEnv env where-  awsEnvL :: Lens' env AwsEnv--instance HasAwsEnv AwsEnv where-  awsEnvL = id--awsWithAuth-  :: (MonadIO m, MonadReader env m, HasAwsEnv env) => (AuthEnv -> m a) -> m a-awsWithAuth f = do-  auth <- view $ awsEnvL . unL . env_auth . to runIdentity-  withAuth auth f+  pure $ env & Amazonka.env_logger .~ logger -awsSimple-  :: forall a env m b+simple+  :: forall a m b    . ( HasCallStack-     , MonadResource m-     , MonadReader env m-     , HasAwsEnv env+     , MonadIO m+     , MonadAWS m      , AWSRequest a      , Typeable a      , Typeable (AWSResponse a)@@ -97,8 +78,8 @@   => a   -> (AWSResponse a -> Maybe b)   -> m b-awsSimple req post = do-  resp <- awsSend req+simple req post = do+  resp <- send req    let     name = show $ typeRep $ Proxy @a@@ -106,53 +87,8 @@    maybe (throwString err) pure $ post resp -awsSend-  :: ( MonadResource m-     , MonadReader env m-     , HasAwsEnv env-     , AWSRequest a-     , Typeable a-     , Typeable (AWSResponse a)-     )-  => a-  -> m (AWSResponse a)-awsSend req = do-  AwsEnv env <- view awsEnvL-  send env req--awsPaginate-  :: ( MonadResource m-     , MonadReader env m-     , HasAwsEnv env-     , AWSPager a-     , Typeable a-     , Typeable (AWSResponse a)-     )-  => a-  -> ConduitM () (AWSResponse a) m ()-awsPaginate req = do-  AwsEnv env <- view awsEnvL-  paginateEither env req >>= hoistEither--hoistEither :: MonadIO m => Either Error a -> m a-hoistEither = either (liftIO . throwIO) pure--awsAwait-  :: ( MonadResource m-     , MonadReader env m-     , HasAwsEnv env-     , AWSRequest a-     , Typeable a-     )-  => Wait a-  -> a-  -> m Accept-awsAwait w req = do-  AwsEnv env <- view awsEnvL-  await env w req--awsAssumeRole-  :: (MonadResource m, MonadReader env m, HasAwsEnv env)+assumeRole+  :: (MonadIO m, MonadAWS m)   => Text   -- ^ Role ARN   -> Text@@ -160,31 +96,21 @@   -> m a   -- ^ Action to run as the assumed role   -> m a-awsAssumeRole role sessionName f = do+assumeRole role sessionName f = do   let req = newAssumeRole role sessionName -  assumeEnv <- awsSimple req $ \resp -> do+  assumeEnv <- simple req $ \resp -> do     let creds = resp ^. assumeRoleResponse_credentials-    token <- creds ^. authEnv_sessionToken+    token <- creds ^. Amazonka.authEnv_sessionToken      let-      accessKeyId = creds ^. authEnv_accessKeyId-      secretAccessKey = creds ^. authEnv_secretAccessKey . _Sensitive--    pure $ fromSession accessKeyId secretAccessKey $ token ^. _Sensitive--  local (awsEnvL . unL %~ assumeEnv) f--awsWithin :: (MonadReader env m, HasAwsEnv env) => Region -> m a -> m a-awsWithin r = local $ awsEnvL . unL . env_region .~ r+      accessKeyId = creds ^. Amazonka.authEnv_accessKeyId+      secretAccessKey = creds ^. Amazonka.authEnv_secretAccessKey . _Sensitive+      sessionToken = token ^. _Sensitive -awsTimeout :: (MonadReader env m, HasAwsEnv env) => Seconds -> m a -> m a-awsTimeout t = local $ awsEnvL . unL %~ globalTimeout t+    pure $ fromSession accessKeyId secretAccessKey sessionToken -awsSilently :: (MonadReader env m, HasAwsEnv env) => m a -> m a-awsSilently = local $ awsEnvL . unL . env_logger .~ noop- where-  noop _level _msg = pure ()+  localEnv assumeEnv f  newtype AccountId = AccountId   { unAccountId :: Text
src/Stackctl/AWS/EC2.hs view
@@ -6,13 +6,13 @@  import Amazonka.EC2.DescribeAvailabilityZones import Amazonka.EC2.Types (AvailabilityZone (..))-import Stackctl.AWS.Core+import Stackctl.AWS.Core as AWS  awsEc2DescribeFirstAvailabilityZoneRegionName-  :: (MonadResource m, MonadReader env m, HasAwsEnv env) => m Region+  :: (MonadIO m, MonadAWS m) => m Region awsEc2DescribeFirstAvailabilityZoneRegionName = do   let req = newDescribeAvailabilityZones-  awsSimple req $ \resp -> do+  AWS.simple req $ \resp -> do     azs <- resp ^. describeAvailabilityZonesResponse_availabilityZones     az <- listToMaybe azs     rn <- regionName az
src/Stackctl/AWS/Lambda.hs view
@@ -10,10 +10,11 @@  import Stackctl.Prelude hiding (trace) +import Amazonka (globalTimeout) import Amazonka.Lambda.Invoke import Data.Aeson import qualified Data.ByteString.Lazy as BSL-import Stackctl.AWS.Core+import Stackctl.AWS.Core as AWS  data LambdaInvokeResult   = LambdaInvokeSuccess ByteString@@ -63,10 +64,9 @@   deriving anyclass (FromJSON, ToJSON)  awsLambdaInvoke-  :: ( MonadResource m+  :: ( MonadIO m      , MonadLogger m-     , MonadReader env m-     , HasAwsEnv env+     , MonadAWS m      , ToJSON a      )   => Text@@ -78,8 +78,8 @@    -- Match Lambda's own limit (15 minutes) and add some buffer   resp <--    awsTimeout 905-      $ awsSend+    AWS.localEnv (globalTimeout 905)+      $ AWS.send       $ newInvoke name       $ BSL.toStrict       $ encode
src/Stackctl/AWS/STS.hs view
@@ -5,10 +5,9 @@ import Stackctl.Prelude  import Amazonka.STS.GetCallerIdentity-import Stackctl.AWS.Core+import Stackctl.AWS.Core as AWS -awsGetCallerIdentityAccount-  :: (MonadResource m, MonadReader env m, HasAwsEnv env) => m AccountId+awsGetCallerIdentityAccount :: (MonadIO m, MonadAWS m) => m AccountId awsGetCallerIdentityAccount = do-  awsSimple newGetCallerIdentity $ \resp -> do+  AWS.simple newGetCallerIdentity $ \resp -> do     AccountId <$> resp ^. getCallerIdentityResponse_account
src/Stackctl/AWS/Scope.hs view
@@ -64,8 +64,7 @@ instance HasAwsScope AwsScope where   awsScopeL = id -fetchAwsScope-  :: (MonadResource m, MonadReader env m, HasAwsEnv env) => m AwsScope+fetchAwsScope :: (MonadIO m, MonadAWS m) => m AwsScope fetchAwsScope =   AwsScope     <$> awsGetCallerIdentityAccount
src/Stackctl/Action.hs view
@@ -92,11 +92,11 @@   deriving anyclass (Exception)  runActions-  :: ( MonadResource m+  :: ( MonadIO m      , MonadLogger m+     , MonadAWS m      , MonadReader env m      , HasLogger env-     , HasAwsEnv env      )   => StackName   -> ActionOn@@ -109,11 +109,11 @@ shouldRunOn Action {on} on' = on == on'  runAction-  :: ( MonadResource m+  :: ( MonadIO m      , MonadLogger m+     , MonadAWS m      , MonadReader env m      , HasLogger env-     , HasAwsEnv env      )   => StackName   -> Action
src/Stackctl/AutoSSO.hs view
@@ -13,7 +13,7 @@ import Data.Semigroup (Last (..)) import qualified Env import Options.Applicative-import Stackctl.AWS.Core (formatServiceError)+import Stackctl.AWS.Core as AWS (formatServiceError) import Stackctl.Prompt import System.Process.Typed import UnliftIO.Exception.Lens (catching)
src/Stackctl/CLI.hs view
@@ -8,9 +8,11 @@ import Stackctl.Prelude  import qualified Blammo.Logging.LogSettings.Env as LoggingEnv+import Control.Monad.AWS as AWS+import Control.Monad.AWS.ViaReader as AWS import Control.Monad.Catch (MonadCatch)-import Control.Monad.Trans.Resource (ResourceT, runResourceT)-import Stackctl.AWS+import Control.Monad.Trans.Resource (MonadResource, ResourceT, runResourceT)+import qualified Stackctl.AWS.Core as AWS import Stackctl.AWS.Scope import Stackctl.AutoSSO import Stackctl.ColorOption@@ -24,7 +26,7 @@   , appConfig :: Config   , appOptions :: options   , appAwsScope :: AwsScope-  , appAwsEnv :: AwsEnv+  , appAwsEnv :: AWS.Env   }  optionsL :: Lens' (App options) options@@ -39,8 +41,8 @@ instance HasAwsScope (App options) where   awsScopeL = lens appAwsScope $ \x y -> x {appAwsScope = y} -instance HasAwsEnv (App options) where-  awsEnvL = lens appAwsEnv $ \x y -> x {appAwsEnv = y}+instance AWS.HasEnv (App options) where+  envL = lens appAwsEnv $ \x y -> x {appAwsEnv = y}  instance HasDirectoryOption options => HasDirectoryOption (App options) where   directoryOptionL = optionsL . directoryOptionL@@ -73,6 +75,7 @@     , MonadCatch     , MonadMask     )+  deriving (MonadAWS) via (ReaderAWS (AppT app m))  runAppT   :: ( MonadMask m@@ -99,12 +102,12 @@         envLogSettings    app <- runResourceT $ runLoggerLoggingT logger $ do-    aws <- runReaderT (handleAutoSSO options awsEnvDiscover) logger+    aws <- runReaderT (handleAutoSSO options AWS.discover) logger      App logger       <$> loadConfigOrExit       <*> pure options-      <*> runReaderT fetchAwsScope aws+      <*> AWS.runEnvT fetchAwsScope aws       <*> pure aws    let
src/Stackctl/RemovedStack.hs view
@@ -7,16 +7,15 @@ import Control.Error.Util (hoistMaybe) import Control.Monad.Trans.Maybe (MaybeT (..), runMaybeT) import Stackctl.AWS.CloudFormation-import Stackctl.AWS.Core+import Stackctl.AWS.Core as AWS import Stackctl.AWS.Scope import Stackctl.FilterOption import UnliftIO.Directory (doesFileExist)  inferRemovedStacks   :: ( MonadUnliftIO m-     , MonadResource m+     , MonadAWS m      , MonadReader env m-     , HasAwsEnv env      , HasAwsScope env      , HasFilterOption env      )@@ -27,7 +26,7 @@   catMaybes <$> traverse (findRemovedStack scope) paths  findRemovedStack-  :: (MonadUnliftIO m, MonadResource m, MonadReader env m, HasAwsEnv env)+  :: (MonadUnliftIO m, MonadAWS m)   => AwsScope   -> FilePath   -> m (Maybe Stack)
src/Stackctl/Spec/Capture.hs view
@@ -77,11 +77,10 @@ runCapture   :: ( MonadMask m      , MonadUnliftIO m-     , MonadResource m+     , MonadAWS m      , MonadLogger m      , MonadReader env m      , HasAwsScope env-     , HasAwsEnv env      , HasConfig env      , HasDirectoryOption env      )
src/Stackctl/Spec/Cat.hs view
@@ -54,8 +54,8 @@       )  runCat-  :: ( MonadMask m-     , MonadResource m+  :: ( MonadIO m+     , MonadMask m      , MonadLogger m      , MonadReader env m      , HasLogger env
src/Stackctl/Spec/Changes.hs view
@@ -52,12 +52,11 @@ runChanges   :: ( MonadMask m      , MonadUnliftIO m-     , MonadResource m+     , MonadAWS m      , MonadLogger m      , MonadReader env m      , HasLogger env      , HasAwsScope env-     , HasAwsEnv env      , HasConfig env      , HasDirectoryOption env      , HasFilterOption env
src/Stackctl/Spec/Deploy.hs view
@@ -71,12 +71,11 @@ runDeploy   :: ( MonadMask m      , MonadUnliftIO m-     , MonadResource m+     , MonadAWS m      , MonadLogger m      , MonadReader env m      , HasLogger env      , HasAwsScope env-     , HasAwsEnv env      , HasConfig env      , HasDirectoryOption env      , HasFilterOption env@@ -114,12 +113,12 @@           when sdoClean $ awsCloudFormationDeleteAllChangeSets stackName  deleteRemovedStack-  :: ( MonadMask m-     , MonadResource m+  :: ( MonadIO m+     , MonadMask m+     , MonadAWS m      , MonadLogger m      , MonadReader env m      , HasLogger env-     , HasAwsEnv env      )   => DeployConfirmation   -> Stack@@ -146,11 +145,10 @@  checkIfStackRequiresDeletion   :: ( MonadUnliftIO m-     , MonadResource m+     , MonadAWS m      , MonadLogger m      , MonadReader env m      , HasLogger env-     , HasAwsEnv env      )   => DeployConfirmation   -> StackName@@ -174,7 +172,7 @@     deleteStack stackName  deleteStack-  :: (MonadResource m, MonadLogger m, MonadReader env m, HasAwsEnv env)+  :: (MonadIO m, MonadAWS m, MonadLogger m)   => StackName   -> m () deleteStack stackName = do@@ -186,11 +184,10 @@  deployChangeSet   :: ( MonadUnliftIO m-     , MonadResource m+     , MonadAWS m      , MonadLogger m      , MonadReader env m      , HasLogger env-     , HasAwsEnv env      )   => DeployConfirmation   -> ChangeSet@@ -232,11 +229,11 @@   changeSetId = csChangeSetId changeSet  tailStackEventsSince-  :: ( MonadResource m+  :: ( MonadIO m+     , MonadAWS m      , MonadLogger m      , MonadReader env m      , HasLogger env-     , HasAwsEnv env      )   => StackName   -> Maybe Text
src/Stackctl/Spec/Discover.hs view
@@ -21,8 +21,8 @@ import System.FilePath.Glob  forEachSpec_-  :: ( MonadMask m-     , MonadResource m+  :: ( MonadIO m+     , MonadMask m      , MonadLogger m      , MonadReader env m      , HasAwsScope env@@ -35,8 +35,8 @@ forEachSpec_ f = traverse_ f =<< discoverSpecs  discoverSpecs-  :: ( MonadMask m-     , MonadResource m+  :: ( MonadIO m+     , MonadMask m      , MonadLogger m      , MonadReader env m      , HasAwsScope env
src/Stackctl/Spec/List.hs view
@@ -37,11 +37,10 @@ runList   :: ( MonadUnliftIO m      , MonadMask m-     , MonadResource m+     , MonadAWS m      , MonadLogger m      , MonadReader env m      , HasAwsScope env-     , HasAwsEnv env      , HasLogger env      , HasConfig env      , HasDirectoryOption env
src/Stackctl/StackSpec.hs view
@@ -185,10 +185,8 @@ -- | Create a Change Set between a Stack Specification and deployed state createChangeSet   :: ( MonadUnliftIO m-     , MonadResource m      , MonadLogger m-     , MonadReader env m-     , HasAwsEnv env+     , MonadAWS m      )   => StackSpec   -> [Parameter]
stackctl.cabal view
@@ -1,6 +1,6 @@ cabal-version:   1.18 name:            stackctl-version:         1.5.0.1+version:         1.6.0.0 license:         MIT license-file:    LICENSE copyright:       2022 Renaissance Learning Inc@@ -84,45 +84,46 @@      build-depends:         Blammo >=1.1.2.1,-        Glob,-        QuickCheck,-        aeson,-        aeson-casing,-        aeson-pretty,+        Glob >=0.10.2,+        QuickCheck >=2.14.2,+        aeson >=2.0.3.0,+        aeson-casing >=0.2.0.0,+        aeson-pretty >=0.8.9,         amazonka >=2.0,         amazonka-cloudformation >=2.0,         amazonka-core >=2.0,         amazonka-ec2 >=2.0,         amazonka-lambda >=2.0,+        amazonka-mtl >=0.1.1.0,         amazonka-sso >=2.0,         amazonka-sts >=2.0,         base >=4 && <5,-        bytestring,+        bytestring >=0.11.3.1,         cfn-flip >=0.1.0.3,-        conduit,-        containers,-        envparse,-        errors,-        exceptions,-        extra,-        filepath,-        lens,-        lens-aeson,-        monad-logger,-        mtl,-        optparse-applicative,-        resourcet,-        rio,-        semigroups,-        text,-        text-metrics,-        time,-        transformers,-        typed-process,+        conduit >=1.3.4.3,+        containers >=0.6.5.1,+        envparse >=0.5.0,+        errors >=2.3.0,+        exceptions >=0.10.4,+        extra >=1.7.12,+        filepath >=1.4.2.2,+        lens >=5.1.1,+        lens-aeson >=1.2.2,+        monad-logger >=0.3.37,+        mtl >=2.2.2,+        optparse-applicative >=0.17.0.0,+        resourcet >=1.2.6,+        rio >=0.1.22.0,+        semigroups >=0.20,+        text >=1.2.5.0,+        text-metrics >=0.3.2,+        time >=1.11.1.1,+        transformers >=0.5.6.2,+        typed-process >=0.2.10.1,         unliftio >=0.2.25.0,-        unordered-containers,-        uuid,-        yaml+        unordered-containers >=0.2.19.1,+        uuid >=1.3.15,+        yaml >=0.11.8.0  executable stackctl     main-is:            Main.hs@@ -187,14 +188,14 @@         -optP-Wno-nonportable-include-path      build-depends:-        Glob,-        QuickCheck,-        aeson,+        Glob >=0.10.2,+        QuickCheck >=2.14.2,+        aeson >=2.0.3.0,         base >=4 && <5,-        bytestring,-        filepath,-        hspec,+        bytestring >=0.11.3.1,+        filepath >=1.4.2.2,+        hspec >=2.9.7,         hspec-golden >=0.2.1.0,-        mtl,+        mtl >=2.2.2,         stackctl,-        yaml+        yaml >=0.11.8.0