setupCmd :: SetupCmdOpts -> GlobalOpts -> IO ()
setupCmd sco@SetupCmdOpts{..} go@GlobalOpts{..} = do
  lc <- loadConfigWithOpts go
  when (scoUpgradeCabal && nixEnable (configNix (lcConfig lc))) $ do
    throwIO UpgradeCabalUnusable
  withUserFileLock go (configStackRoot $ lcConfig lc) $ \lk -> do
    let getCompilerVersion = loadCompilerVersion go lc
    runStackTGlobal (lcConfig lc) go $
      Docker.reexecWithOptionalContainer
          (lcProjectRoot lc)
          Nothing
          (runStackTGlobal (lcConfig lc) go $
           Nix.reexecWithOptionalShell (lcProjectRoot lc) getCompilerVersion $
           runStackTGlobal () go $ do
              (wantedCompiler, compilerCheck, mstack) <-
                  case scoCompilerVersion of
                      Just v -> return (v, MatchMinor, Nothing)
                      Nothing -> do
                          bc <- lcLoadBuildConfig lc globalCompiler
                          return ( view wantedCompilerVersionL bc
                                 , configCompilerCheck (lcConfig lc)
                                 , Just $ view stackYamlL bc
                                 )
              miniConfig <- loadMiniConfig (lcConfig lc)
              runStackTGlobal miniConfig go $
                  setup sco wantedCompiler compilerCheck mstack
              )
          Nothing
          (Just $ munlockFile lk)
setupCmd :: SetupCmdOpts -> GlobalOpts -> IO ()
setupCmd sco@SetupCmdOpts{..} go@GlobalOpts{..} = do
  lc <- loadConfigWithOpts go
  when (scoUpgradeCabal && nixEnable (configNix (lcConfig lc))) $ do
    throwIO UpgradeCabalUnusable
  withUserFileLock go (configStackRoot $ lcConfig lc) $ \lk -> do
    let getCompilerVersion = loadCompilerVersion go lc
    runStackTGlobal (lcConfig lc) go $
      Docker.reexecWithOptionalContainer
          (lcProjectRoot lc)
          Nothing
          (runStackTGlobal (lcConfig lc) go $
           Nix.reexecWithOptionalShell (lcProjectRoot lc) getCompilerVersion $
           runStackTGlobal () go $ do
              (wantedCompiler, compilerCheck, mstack) <-
                  case scoCompilerVersion of
                      Just v -> return (v, MatchMinor, Nothing)
                      Nothing -> do
                          bc <- lcLoadBuildConfig lc globalCompiler
                          return ( view wantedCompilerVersionL bc
                                 , configCompilerCheck (lcConfig lc)
                                 , Just $ view stackYamlL bc
                                 )
              miniConfig <- loadMiniConfig (lcConfig lc)
              runStackTGlobal miniConfig go $
                  setup sco wantedCompiler compilerCheck mstack
              )
          Nothing
          (Just $ munlockFile lk)
setupCmd sco@SetupCmdOpts{..} go@GlobalOpts{..} = do
  lc <- loadConfigWithOpts go
  when (scoUpgradeCabal && nixEnable (configNix (lcConfig lc))) $ do
    throwIO UpgradeCabalUnusable
  withUserFileLock go (configStackRoot $ lcConfig lc) $ \lk -> do
    let getCompilerVersion = loadCompilerVersion go lc
    runStackTGlobal (lcConfig lc) go $
      Docker.reexecWithOptionalContainer
          (lcProjectRoot lc)
          Nothing
          (runStackTGlobal (lcConfig lc) go $
           Nix.reexecWithOptionalShell (lcProjectRoot lc) getCompilerVersion $
           runStackTGlobal () go $ do
              (wantedCompiler, compilerCheck, mstack) <-
                  case scoCompilerVersion of
                      Just v -> return (v, MatchMinor, Nothing)
                      Nothing -> do
                          bc <- lcLoadBuildConfig lc globalCompiler
                          return ( view wantedCompilerVersionL bc
                                 , configCompilerCheck (lcConfig lc)
                                 , Just $ view stackYamlL bc
                                 )
              miniConfig <- loadMiniConfig (lcConfig lc)
              runStackTGlobal miniConfig go $
                  setup sco wantedCompiler compilerCheck mstack
              )
          Nothing
          (Just $ munlockFile lk)