22
22
import org .jenkinsci .plugins .workflow .actions .LabelAction ;
23
23
import org .jenkinsci .plugins .workflow .actions .LogAction ;
24
24
import org .jenkinsci .plugins .workflow .actions .QueueItemAction ;
25
- import org .jenkinsci .plugins .workflow .actions .StageAction ;
26
25
import org .jenkinsci .plugins .workflow .actions .TagsAction ;
27
26
import org .jenkinsci .plugins .workflow .actions .ThreadNameAction ;
28
27
import org .jenkinsci .plugins .workflow .cps .nodes .StepAtomNode ;
29
28
import org .jenkinsci .plugins .workflow .cps .nodes .StepStartNode ;
29
+ import org .jenkinsci .plugins .workflow .cps .steps .ParallelStep ;
30
+ import org .jenkinsci .plugins .workflow .graph .AtomNode ;
30
31
import org .jenkinsci .plugins .workflow .graph .FlowNode ;
31
32
import org .jenkinsci .plugins .workflow .steps .FlowInterruptedException ;
32
33
import org .jenkinsci .plugins .workflow .steps .StepDescriptor ;
33
34
import org .jenkinsci .plugins .workflow .support .actions .PauseAction ;
34
35
import org .jenkinsci .plugins .workflow .support .steps .ExecutorStep ;
36
+ import org .jenkinsci .plugins .workflow .support .steps .StageStep ;
35
37
import org .jenkinsci .plugins .workflow .support .steps .input .InputAction ;
36
38
37
39
/** @author Vivek Pandey */
38
40
public class PipelineNodeUtil {
39
41
40
42
private static final String DECLARATIVE_DISPLAY_NAME_PREFIX = "Declarative: " ;
43
+ private static final String PARALLEL_SYNTHETIC_STAGE_NAME = "Parallel" ;
41
44
42
45
public static String getDisplayName (@ NonNull FlowNode node ) {
43
46
ThreadNameAction threadNameAction = node .getAction (ThreadNameAction .class );
@@ -47,11 +50,43 @@ public static String getDisplayName(@NonNull FlowNode node) {
47
50
: name ;
48
51
}
49
52
53
+ public static boolean isStep (FlowNode node ) {
54
+ if (node != null ) {
55
+ if (node instanceof AtomNode ) {
56
+ return true ;
57
+ }
58
+ if (node instanceof StepStartNode ) {
59
+ StepStartNode stepStartNode = (StepStartNode ) node ;
60
+ boolean takesImplicitBlockArgument = false ;
61
+ StepDescriptor sd = stepStartNode .getDescriptor ();
62
+ if (sd != null ) {
63
+ takesImplicitBlockArgument = sd .takesImplicitBlockArgument ();
64
+ }
65
+ return !isStage (node )
66
+ && !isParallelBranch (node )
67
+ && stepStartNode .isBody ()
68
+ && !takesImplicitBlockArgument ;
69
+ }
70
+ }
71
+ return false ;
72
+ }
73
+
50
74
public static boolean isStage (FlowNode node ) {
51
- return node != null
52
- && ((node .getAction (StageAction .class ) != null )
53
- || (node .getAction (LabelAction .class ) != null
54
- && node .getAction (ThreadNameAction .class ) == null ));
75
+ if (node != null ) {
76
+ if (node instanceof StepStartNode ) {
77
+ StepStartNode stepStartNode = (StepStartNode ) node ;
78
+ if (stepStartNode .getDescriptor () != null ) {
79
+ StepDescriptor sd = stepStartNode .getDescriptor ();
80
+ return sd != null && StageStep .DescriptorImpl .class .equals (sd .getClass ()) && stepStartNode .isBody ();
81
+ }
82
+ }
83
+ LabelAction labelAction = node .getAction (LabelAction .class );
84
+ ThreadNameAction threadNameAction = node .getAction (ThreadNameAction .class );
85
+ return labelAction != null
86
+ && PARALLEL_SYNTHETIC_STAGE_NAME .equals (labelAction .getDisplayName ())
87
+ && threadNameAction == null ;
88
+ }
89
+ return false ;
55
90
}
56
91
57
92
public static boolean isSyntheticStage (@ Nullable FlowNode node ) {
@@ -115,9 +150,14 @@ public static boolean isPreSyntheticStage(@Nullable FlowNode node) {
115
150
}
116
151
117
152
public static boolean isParallelBranch (@ Nullable FlowNode node ) {
118
- return node != null
119
- && node .getAction (LabelAction .class ) != null
120
- && node .getAction (ThreadNameAction .class ) != null ;
153
+ if (node != null && node instanceof StepStartNode ) {
154
+ StepStartNode stepStartNode = (StepStartNode ) node ;
155
+ if (stepStartNode .getDescriptor () != null ) {
156
+ StepDescriptor sd = stepStartNode .getDescriptor ();
157
+ return sd != null && ParallelStep .DescriptorImpl .class .equals (sd .getClass ()) && stepStartNode .isBody ();
158
+ }
159
+ }
160
+ return false ;
121
161
}
122
162
123
163
public static boolean isUnhandledException (@ Nullable FlowNode node ) {
@@ -202,17 +242,15 @@ public static boolean isPaused(@NonNull FlowNode step) {
202
242
return (pauseAction != null && pauseAction .isPaused ());
203
243
}
204
244
205
- /* Untested way of determining if we are a parallel block.
206
- * WARNING: Use with caution.
207
- */
208
245
protected static boolean isParallelBlock (@ NonNull FlowNode node ) {
209
- /*
210
- * TODO: Find a better method - list of expected labels.
211
- * Seems to only have (not sure if this is true for other nodes as well though):
212
- * org.jenkinsci.plugins.workflow.support.actions.LogStorageAction
213
- * org.jenkinsci.plugins.workflow.actions.TimingAction
214
- */
215
- return getDisplayName (node ).startsWith ("Execute in parallel" );
246
+ if (node != null && node instanceof StepStartNode ) {
247
+ StepStartNode stepStartNode = (StepStartNode ) node ;
248
+ if (stepStartNode .getDescriptor () != null ) {
249
+ StepDescriptor sd = stepStartNode .getDescriptor ();
250
+ return sd != null && ParallelStep .DescriptorImpl .class .equals (sd .getClass ()) && !stepStartNode .isBody ();
251
+ }
252
+ }
253
+ return false ;
216
254
}
217
255
218
256
/**
0 commit comments