github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/web/elm/src/Build/StepTree/Models.elm (about)

     1  module Build.StepTree.Models exposing
     2      ( BuildEvent(..)
     3      , BuildEventEnvelope
     4      , HookedStep
     5      , MetadataField
     6      , Origin
     7      , Step
     8      , StepFocus
     9      , StepName
    10      , StepState(..)
    11      , StepTree(..)
    12      , StepTreeModel
    13      , TabFocus(..)
    14      , Version
    15      , focusTabbed
    16      , isActive
    17      , lastActive
    18      , mostSevereStepState
    19      , showStepState
    20      , toggleSubHeaderExpanded
    21      , treeIsActive
    22      , updateAt
    23      )
    24  
    25  import Ansi.Log
    26  import Array exposing (Array)
    27  import Concourse
    28  import Concourse.BuildStatus exposing (BuildStatus)
    29  import Dict exposing (Dict)
    30  import List.Extra
    31  import Maybe.Extra
    32  import Ordering exposing (Ordering)
    33  import Routes exposing (Highlight, StepID)
    34  import Time
    35  
    36  
    37  type alias StepTreeModel =
    38      { tree : StepTree
    39      , steps : Dict StepID Step
    40      , highlight : Highlight
    41      , resources : Concourse.BuildResources
    42      }
    43  
    44  
    45  type StepTree
    46      = Task StepID
    47      | Check StepID
    48      | Get StepID
    49      | Put StepID
    50      | SetPipeline StepID
    51      | LoadVar StepID
    52      | ArtifactInput StepID
    53      | ArtifactOutput StepID
    54      | Aggregate (Array StepTree)
    55      | InParallel (Array StepTree)
    56      | Across StepID (List String) (List (List Concourse.JsonValue)) (Array StepTree)
    57      | Retry StepID (Array StepTree)
    58      | Do (Array StepTree)
    59      | OnSuccess HookedStep
    60      | OnFailure HookedStep
    61      | OnAbort HookedStep
    62      | OnError HookedStep
    63      | Ensure HookedStep
    64      | Try StepTree
    65      | Timeout StepTree
    66  
    67  
    68  type alias HookedStep =
    69      { step : StepTree
    70      , hook : StepTree
    71      }
    72  
    73  
    74  type alias StepFocus =
    75      (StepTree -> StepTree) -> StepTree -> StepTree
    76  
    77  
    78  type alias Step =
    79      { id : StepID
    80      , name : StepName
    81      , state : StepState
    82      , log : Ansi.Log.Model
    83      , error : Maybe String
    84      , expanded : Bool
    85      , version : Maybe Version
    86      , metadata : List MetadataField
    87      , changed : Bool
    88      , timestamps : Dict Int Time.Posix
    89      , initialize : Maybe Time.Posix
    90      , start : Maybe Time.Posix
    91      , finish : Maybe Time.Posix
    92      , tabFocus : TabFocus
    93      , expandedHeaders : Dict Int Bool
    94      , initializationExpanded : Bool
    95      , imageCheck : Maybe StepTree
    96      , imageGet : Maybe StepTree
    97      }
    98  
    99  
   100  type alias StepName =
   101      String
   102  
   103  
   104  type StepState
   105      = StepStatePending
   106      | StepStateRunning
   107      | StepStateInterrupted
   108      | StepStateCancelled
   109      | StepStateSucceeded
   110      | StepStateFailed
   111      | StepStateErrored
   112  
   113  
   114  showStepState : StepState -> String
   115  showStepState state =
   116      case state of
   117          StepStatePending ->
   118              "pending"
   119  
   120          StepStateRunning ->
   121              "running"
   122  
   123          StepStateInterrupted ->
   124              "interrupted"
   125  
   126          StepStateCancelled ->
   127              "cancelled"
   128  
   129          StepStateSucceeded ->
   130              "succeeded"
   131  
   132          StepStateFailed ->
   133              "failed"
   134  
   135          StepStateErrored ->
   136              "errored"
   137  
   138  
   139  stepStateOrdering : Ordering StepState
   140  stepStateOrdering =
   141      Ordering.explicit
   142          [ StepStateFailed
   143          , StepStateErrored
   144          , StepStateInterrupted
   145          , StepStateCancelled
   146          , StepStateRunning
   147          , StepStatePending
   148          , StepStateSucceeded
   149          ]
   150  
   151  
   152  mostSevereStepState : StepTreeModel -> StepTree -> StepState
   153  mostSevereStepState model stepTree =
   154      activeTreeSteps model stepTree
   155          |> List.foldl
   156              (\step state ->
   157                  case stepStateOrdering step.state state of
   158                      LT ->
   159                          step.state
   160  
   161                      _ ->
   162                          state
   163              )
   164              StepStateSucceeded
   165  
   166  
   167  type alias Version =
   168      Dict String String
   169  
   170  
   171  type alias MetadataField =
   172      { name : String
   173      , value : String
   174      }
   175  
   176  
   177  type TabFocus
   178      = Auto
   179      | Manual Int
   180  
   181  
   182  type alias BuildEventEnvelope =
   183      { data : BuildEvent
   184      , url : String
   185      }
   186  
   187  
   188  type BuildEvent
   189      = BuildStatus BuildStatus Time.Posix
   190      | InitializeTask Origin Time.Posix
   191      | StartTask Origin Time.Posix
   192      | FinishTask Origin Int Time.Posix
   193      | Initialize Origin Time.Posix
   194      | Start Origin Time.Posix
   195      | Finish Origin Time.Posix Bool
   196      | InitializeGet Origin Time.Posix
   197      | StartGet Origin Time.Posix
   198      | FinishGet Origin Int Concourse.Version Concourse.Metadata (Maybe Time.Posix)
   199      | InitializePut Origin Time.Posix
   200      | StartPut Origin Time.Posix
   201      | FinishPut Origin Int Concourse.Version Concourse.Metadata (Maybe Time.Posix)
   202      | SetPipelineChanged Origin Bool
   203      | Log Origin String (Maybe Time.Posix)
   204      | SelectedWorker Origin String (Maybe Time.Posix)
   205      | Error Origin String Time.Posix
   206      | ImageCheck Origin Concourse.BuildPlan
   207      | ImageGet Origin Concourse.BuildPlan
   208      | End
   209      | Opened
   210      | NetworkError
   211  
   212  
   213  type alias Origin =
   214      { source : String
   215      , id : String
   216      }
   217  
   218  
   219  
   220  -- model manipulation functions
   221  
   222  
   223  focusTabbed : Int -> Step -> Step
   224  focusTabbed tab step =
   225      { step | tabFocus = Manual tab }
   226  
   227  
   228  toggleSubHeaderExpanded : Int -> Step -> Step
   229  toggleSubHeaderExpanded idx step =
   230      { step | expandedHeaders = Dict.update idx (Just << not << Maybe.withDefault False) step.expandedHeaders }
   231  
   232  
   233  updateAt : StepID -> (Step -> Step) -> StepTreeModel -> StepTreeModel
   234  updateAt id update model =
   235      { model | steps = Dict.update id (Maybe.map update) model.steps }
   236  
   237  
   238  activeStepIds : StepTreeModel -> StepTree -> List StepID
   239  activeStepIds model tree =
   240      let
   241          hooked step hook state =
   242              activeStepIds model step
   243                  ++ (if mostSevereStepState model step == state then
   244                          activeStepIds model hook
   245  
   246                      else
   247                          []
   248                     )
   249      in
   250      case tree of
   251          Task stepId ->
   252              [ stepId ]
   253  
   254          Check stepId ->
   255              [ stepId ]
   256  
   257          Get stepId ->
   258              [ stepId ]
   259  
   260          Put stepId ->
   261              [ stepId ]
   262  
   263          ArtifactInput stepId ->
   264              [ stepId ]
   265  
   266          ArtifactOutput stepId ->
   267              [ stepId ]
   268  
   269          SetPipeline stepId ->
   270              [ stepId ]
   271  
   272          LoadVar stepId ->
   273              [ stepId ]
   274  
   275          Aggregate trees ->
   276              List.concatMap (activeStepIds model) (Array.toList trees)
   277  
   278          InParallel trees ->
   279              List.concatMap (activeStepIds model) (Array.toList trees)
   280  
   281          Do trees ->
   282              List.concatMap (activeStepIds model) (Array.toList trees)
   283  
   284          Across _ _ _ trees ->
   285              List.concatMap (activeStepIds model) (Array.toList trees)
   286  
   287          OnSuccess { step, hook } ->
   288              hooked step hook StepStateSucceeded
   289  
   290          OnFailure { step, hook } ->
   291              hooked step hook StepStateFailed
   292  
   293          OnAbort { step, hook } ->
   294              hooked step hook StepStateInterrupted
   295  
   296          OnError { step, hook } ->
   297              hooked step hook StepStateErrored
   298  
   299          Ensure { step, hook } ->
   300              activeStepIds model step ++ activeStepIds model hook
   301  
   302          Try subTree ->
   303              activeStepIds model subTree
   304  
   305          Timeout subTree ->
   306              activeStepIds model subTree
   307  
   308          Retry _ trees ->
   309              trees
   310                  |> Array.toList
   311                  |> List.Extra.takeWhile (mostSevereStepState model >> (/=) StepStateSucceeded)
   312                  |> List.concatMap (activeStepIds model)
   313  
   314  
   315  activeTreeSteps : StepTreeModel -> StepTree -> List Step
   316  activeTreeSteps model stepTree =
   317      activeStepIds model stepTree
   318          |> List.map (\id -> Dict.get id model.steps)
   319          |> Maybe.Extra.values
   320  
   321  
   322  treeIsActive : StepTreeModel -> StepTree -> Bool
   323  treeIsActive model stepTree =
   324      activeTreeSteps model stepTree
   325          |> List.any (.state >> isActive)
   326  
   327  
   328  lastActive : StepTreeModel -> Array StepTree -> Maybe Int
   329  lastActive model trees =
   330      Array.toIndexedList trees
   331          |> List.reverse
   332          |> List.filter (Tuple.second >> treeIsActive model)
   333          |> List.head
   334          |> Maybe.map Tuple.first
   335  
   336  
   337  isActive : StepState -> Bool
   338  isActive state =
   339      state /= StepStatePending && state /= StepStateCancelled