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