<commit_before>{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-| Definition of the B9 monad. It encapsulates logging, very basic command
execution profiling, a reader for the "B9.B9Config" and access to the
current build id, the current build directory and the artifact to build.

This module is used by the _effectful_ functions in this library.
-}
module B9.B9Monad ( B9 , run , traceL , dbgL , infoL , errorL , getConfigParser
, getConfig , getBuildId , getBuildDate , getBuildDir , getExecEnvType ,
getSelectedRemoteRepo , getRemoteRepos , getRepoCache , cmd ) where

import           B9.B9Config
import           B9.ConfigUtils
import           B9.Repository
import           Control.Applicative
import           Control.Exception ( bracket )
import           Control.Monad
import           Control.Monad.IO.Class
import           Control.Monad.State

import qualified Data.ByteString.Char8 as B
import           Data.Functor ()
import           Data.Maybe
import           Data.Time.Clock
import           Data.Time.Format
import           Data.Word ( Word32 )
import           System.Directory
import           System.Exit
import           System.FilePath
import           System.Random ( randomIO )
import qualified System.IO as SysIO
import           Text.Printf
import           Control.Concurrent.Async (Concurrently (..))
import           Data.Conduit (($$))
import qualified Data.Conduit.List as CL
import           Data.Conduit.Process

data BuildState = BuildState { bsBuildId :: String
                             , bsBuildDate :: String
                             , bsCfgParser :: ConfigParser
                             , bsCfg :: B9Config
                             , bsBuildDir :: FilePath
                             , bsLogFileHandle :: Maybe SysIO.Handle
                             , bsSelectedRemoteRepo :: Maybe RemoteRepo
                             , bsRemoteRepos :: [RemoteRepo]
                             , bsRepoCache :: RepoCache
                             , bsProf :: [ProfilingEntry]
                             , bsStartTime :: UTCTime
                             , bsInheritStdIn :: Bool
                             }

data ProfilingEntry = IoActionDuration NominalDiffTime
                    | LogEvent LogLevel String
                      deriving (Eq, Show)

run :: ConfigParser -> B9Config -> B9 a -> IO a
run cfgParser cfg action = do
  buildId <- generateBuildId
  now <- getCurrentTime
  withBuildDir buildId (withLogFile . run' buildId now)

  where
    withLogFile f =
      maybe (f Nothing)
            (\logf -> SysIO.withFile logf SysIO.AppendMode (f . Just))
            (logFile cfg)

    withBuildDir buildId = bracket (createBuildDir buildId) removeBuildDir

    run' buildId now buildDir logFileHandle = do
      maybe empty setCurrentDirectory (buildDirRoot cfg)
      -- Check repositories
      repoCache <- initRepoCache (fromMaybe defaultRepositoryCache (repositoryCache cfg))<commit_msg>Fix b9c crash when called w/o --project-dir parameter<commit_after>{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-| Definition of the B9 monad. It encapsulates logging, very basic command
execution profiling, a reader for the "B9.B9Config" and access to the
current build id, the current build directory and the artifact to build.

This module is used by the _effectful_ functions in this library.
-}
module B9.B9Monad ( B9 , run , traceL , dbgL , infoL , errorL , getConfigParser
, getConfig , getBuildId , getBuildDate , getBuildDir , getExecEnvType ,
getSelectedRemoteRepo , getRemoteRepos , getRepoCache , cmd ) where

import           B9.B9Config
import           B9.ConfigUtils
import           B9.Repository
import           Control.Applicative
import           Control.Exception ( bracket )
import           Control.Monad
import           Control.Monad.IO.Class
import           Control.Monad.State

import qualified Data.ByteString.Char8 as B
import           Data.Functor ()
import           Data.Maybe
import           Data.Time.Clock
import           Data.Time.Format
import           Data.Word ( Word32 )
import           System.Directory
import           System.Exit
import           System.FilePath
import           System.Random ( randomIO )
import qualified System.IO as SysIO
import           Text.Printf
import           Control.Concurrent.Async (Concurrently (..))
import           Data.Conduit (($$))
import qualified Data.Conduit.List as CL
import           Data.Conduit.Process

data BuildState = BuildState { bsBuildId :: String
                             , bsBuildDate :: String
                             , bsCfgParser :: ConfigParser
                             , bsCfg :: B9Config
                             , bsBuildDir :: FilePath
                             , bsLogFileHandle :: Maybe SysIO.Handle
                             , bsSelectedRemoteRepo :: Maybe RemoteRepo
                             , bsRemoteRepos :: [RemoteRepo]
                             , bsRepoCache :: RepoCache
                             , bsProf :: [ProfilingEntry]
                             , bsStartTime :: UTCTime
                             , bsInheritStdIn :: Bool
                             }

data ProfilingEntry = IoActionDuration NominalDiffTime
                    | LogEvent LogLevel String
                      deriving (Eq, Show)

run :: ConfigParser -> B9Config -> B9 a -> IO a
run cfgParser cfg action = do
  buildId <- generateBuildId
  now <- getCurrentTime
  withBuildDir buildId (withLogFile . run' buildId now)

  where
    withLogFile f =
      maybe (f Nothing)
            (\logf -> SysIO.withFile logf SysIO.AppendMode (f . Just))
            (logFile cfg)

    withBuildDir buildId = bracket (createBuildDir buildId) removeBuildDir

    run' buildId now buildDir logFileHandle = do
      maybe (print "Keeping PWD as CWD") setCurrentDirectory (buildDirRoot cfg)
      -- Check repositories
      repoCache <- initRepoCache (fromMaybe defaultRepositoryCache (repositoryCache cfg))
{'fraction_non_alphanumeric': 0.06440847655598197, 'fraction_numerical': 0.005506424161521775, 'mean_word_length': 1.8734419942473635, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5485864', 'n_tokens_mistral': 1563, 'n_tokens_neox': 1498, 'n_words': 466}