Skip to content

Commit fb70a9a

Browse files
authored
Integrate Folder Properties in P4Plugin. (#242)
Resolve the folder properties used in P4Plugin for FreeStyle, Pipeline and MultiBranch project configuration.
1 parent 1bd8b7b commit fb70a9a

File tree

12 files changed

+122
-8
lines changed

12 files changed

+122
-8
lines changed

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@
7575
<version>2024.2.2695691</version>
7676
</dependency>
7777

78+
<dependency>
79+
<groupId>com.mig82</groupId>
80+
<artifactId>folder-properties</artifactId>
81+
<version>57.vde5161ec7a_b_a_</version>
82+
</dependency>
83+
7884
<dependency>
7985
<groupId>commons-io</groupId>
8086
<artifactId>commons-io</artifactId>

src/main/java/org/jenkinsci/plugins/p4/PerforceScm.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.jenkinsci.plugins.p4;
22

33
import com.cloudbees.plugins.credentials.CredentialsProvider;
4+
import com.mig82.folders.properties.PropertiesLoader;
45
import com.perforce.p4java.exception.P4JavaException;
56
import hudson.AbortException;
67
import hudson.EnvVars;
@@ -432,6 +433,10 @@ private PollingResult pollWorkspace(EnvVars envVars, TaskListener listener, File
432433
ws.setRootPath(null);
433434
ws.setExpand(envVars);
434435

436+
EnvVars folderPropertiesVars = PropertiesLoader.loadFolderProperties(lastRun.getParent());
437+
if (!folderPropertiesVars.isEmpty()) {
438+
folderPropertiesVars.forEach(ws::addEnv);
439+
}
435440
// Set EXPANDED client
436441
String client = ws.getFullName();
437442
listener.getLogger().println("P4: Polling on: " + nodeName + " with:" + client);
@@ -519,7 +524,7 @@ private List<P4Ref> lookForChanges(FilePath buildWorkspace, Workspace ws, Run<?,
519524
}
520525
}
521526
}
522-
527+
523528
// no previous build, return null.
524529
listener.getLogger().println("P4: Polling: No changes in previous build(s).");
525530
return null;
@@ -589,6 +594,10 @@ public void checkout(Run<?, ?> run, Launcher launcher, FilePath buildWorkspace,
589594

590595
// Get workspace used for the Task
591596
Workspace ws = task.setEnvironment(run, workspace, buildWorkspace);
597+
EnvVars folderPropertiesVars = PropertiesLoader.loadFolderProperties(run.getParent());
598+
if (!folderPropertiesVars.isEmpty()) {
599+
folderPropertiesVars.forEach(ws::addEnv);
600+
}
592601

593602
// Add review to environment, if defined
594603
if (review != null) {
@@ -727,7 +736,7 @@ private void setStreamEnvVariables(Run<?, ?> run, Workspace ws) {
727736
streamName = ((StreamWorkspaceImpl) ws).getStreamName();
728737
}
729738
if (StringUtils.isNotBlank(streamName) || StringUtils.isNotBlank(streamAtChange)) {
730-
run.addAction(new P4StreamEnvironmentContributionAction(streamName,streamAtChange));
739+
run.addAction(new P4StreamEnvironmentContributionAction(streamName, streamAtChange));
731740
}
732741
}
733742

src/main/java/org/jenkinsci/plugins/p4/browsers/SwarmBrowser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public String getDisplayName() {
6565
return "Swarm browser";
6666
}
6767

68-
public FormValidation doCheck(@QueryParameter final String value) throws IOException, ServletException {
68+
public FormValidation doCheckUrl(@QueryParameter final String value) throws IOException, ServletException {
6969

7070
String url = Util.fixEmpty(value);
7171
if (url == null) {

src/main/java/org/jenkinsci/plugins/p4/build/P4EnvironmentContributor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.jenkinsci.plugins.p4.build;
22

3+
import com.mig82.folders.properties.PropertiesLoader;
34
import hudson.EnvVars;
45
import hudson.Extension;
56
import hudson.model.Descriptor;
@@ -34,6 +35,10 @@ public void buildEnvironmentFor(Run run, EnvVars env, TaskListener listener) thr
3435
TagAction tagAction = TagAction.getLastAction(run);
3536
buildEnvironment(tagAction, env);
3637
injectSwarmEnvVars(run, env);
38+
EnvVars folderPropertiesVars = PropertiesLoader.loadFolderProperties(run.getParent());
39+
if (!folderPropertiesVars.isEmpty()) {
40+
env.putAll(folderPropertiesVars);
41+
}
3742
}
3843

3944
public static void buildEnvironment(TagAction tagAction, Map<String, String> map) {
@@ -135,7 +140,7 @@ private static void injectSwarmEnvVars(Run run, EnvVars env) {
135140
}
136141
Map<String, String> swarmParameters = ((P4SCMHead) head).getSwarmParams();
137142

138-
if(swarmParameters == null || swarmParameters.isEmpty()) {
143+
if (swarmParameters == null || swarmParameters.isEmpty()) {
139144
continue;
140145
}
141146
String swarmBranch = swarmParameters.get(ReviewProp.SWARM_BRANCH.toString());

src/main/java/org/jenkinsci/plugins/p4/scm/AbstractP4ScmSource.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.jenkinsci.plugins.p4.populate.Populate;
3737
import org.jenkinsci.plugins.p4.review.ReviewProp;
3838
import org.jenkinsci.plugins.p4.scm.events.P4BranchScanner;
39+
import org.jenkinsci.plugins.p4.utils.FolderPropertiesUtil;
3940
import org.jenkinsci.plugins.p4.workspace.Workspace;
4041
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
4142
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
@@ -182,6 +183,18 @@ protected void retrieve(@CheckForNull SCMSourceCriteria criteria, @NonNull SCMHe
182183
}
183184
}
184185

186+
public boolean pathContainsFolderPropertyVar(List<String> paths) {
187+
if (paths == null || paths.isEmpty()) {
188+
return false;
189+
}
190+
for (String path : paths) {
191+
if (path.contains(FolderPropertiesUtil.PROP_EXPANSION_PATTERN)) {
192+
return true;
193+
}
194+
}
195+
return false;
196+
}
197+
185198
private List<P4SCMHead> getP4SCMHeads(SCMHeadObserver observer, TaskListener listener) throws Exception {
186199
List<P4SCMHead> heads = new ArrayList<>();
187200
Set<SCMHead> includedHead = observer.getIncludes();

src/main/java/org/jenkinsci/plugins/p4/scm/BranchesScmSource.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.jenkinsci.plugins.p4.browsers.P4Browser;
1010
import org.jenkinsci.plugins.p4.client.ConnectionHelper;
1111
import org.jenkinsci.plugins.p4.client.ViewMapHelper;
12+
import org.jenkinsci.plugins.p4.utils.FolderPropertiesUtil;
1213
import org.jenkinsci.plugins.p4.workspace.ManualWorkspaceImpl;
1314
import org.jenkinsci.plugins.p4.workspace.Workspace;
1415
import org.jenkinsci.plugins.p4.workspace.WorkspaceSpec;
@@ -88,6 +89,10 @@ public List<P4SCMHead> getHeads(@NonNull TaskListener listener) throws Exception
8889

8990
Pattern excludesPattern = Pattern.compile(getExcludes());
9091
List<String> paths = getIncludePaths();
92+
if (pathContainsFolderPropertyVar(paths)) {
93+
paths = FolderPropertiesUtil.processFolderPropertiesIn(paths, getOwner());
94+
}
95+
9196
List<P4SCMHead> list = new ArrayList<>();
9297

9398
try (ConnectionHelper p4 = new ConnectionHelper(getOwner(), getCredential(), listener)) {

src/main/java/org/jenkinsci/plugins/p4/scm/StreamsScmSource.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.jenkinsci.Symbol;
88
import org.jenkinsci.plugins.p4.browsers.P4Browser;
99
import org.jenkinsci.plugins.p4.client.ConnectionHelper;
10+
import org.jenkinsci.plugins.p4.utils.FolderPropertiesUtil;
1011
import org.jenkinsci.plugins.p4.workspace.StreamWorkspaceImpl;
1112
import org.jenkinsci.plugins.p4.workspace.Workspace;
1213
import org.kohsuke.stapler.DataBoundConstructor;
@@ -47,8 +48,11 @@ public List<P4SCMHead> getTags(@NonNull TaskListener listener) throws Exception
4748
@Override
4849
public List<P4SCMHead> getHeads(@NonNull TaskListener listener) throws Exception {
4950
List<String> paths = getIncludePaths();
50-
HashSet<P4SCMHead> list = new HashSet<P4SCMHead>();
5151

52+
if (pathContainsFolderPropertyVar(paths)) {
53+
paths = FolderPropertiesUtil.processFolderPropertiesIn(paths, getOwner());
54+
}
55+
HashSet<P4SCMHead> list = new HashSet<>();
5256
try (ConnectionHelper p4 = new ConnectionHelper(getOwner(), credential, listener)) {
5357

5458
Pattern excludesPattern = Pattern.compile(getExcludes());

src/main/java/org/jenkinsci/plugins/p4/tasks/AbstractTask.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ public static Workspace setup(Run<?, ?> run, Workspace wsType, FilePath buildWor
9999
envVars.put("NODE_NAME", envVars.get("NODE_NAME", nodeName));
100100
String executor = ExecutorHelper.getExecutorID(buildWorkspace, listener);
101101
envVars.put("EXECUTOR_NUMBER", envVars.get("EXECUTOR_NUMBER", executor));
102-
103102
ws.setExpand(envVars);
104103

105104
// Set workspace root (check for parallel execution)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.jenkinsci.plugins.p4.utils;
2+
3+
import com.cloudbees.hudson.plugins.folder.AbstractFolder;
4+
import com.cloudbees.hudson.plugins.folder.AbstractFolderProperty;
5+
import com.cloudbees.hudson.plugins.folder.AbstractFolderPropertyDescriptor;
6+
import com.mig82.folders.properties.FolderProperties;
7+
import hudson.model.ItemGroup;
8+
import hudson.util.DescribableList;
9+
import jenkins.scm.api.SCMSourceOwner;
10+
import org.jenkinsci.plugins.p4.workspace.Expand;
11+
12+
import java.util.ArrayList;
13+
import java.util.Arrays;
14+
import java.util.HashMap;
15+
import java.util.List;
16+
import java.util.Map;
17+
import java.util.Objects;
18+
import java.util.stream.Collectors;
19+
20+
public final class FolderPropertiesUtil {
21+
public static final String PROP_EXPANSION_PATTERN = "${";
22+
23+
private FolderPropertiesUtil() {
24+
}
25+
26+
public static List<String> processFolderPropertiesIn(List<String> paths, SCMSourceOwner owner) {
27+
if (paths == null || paths.isEmpty()) {
28+
return new ArrayList<>();
29+
}
30+
Map<String, String> folderProperties = getFolderPropertiesFrom(owner);
31+
if (folderProperties.isEmpty()) {
32+
return paths;
33+
}
34+
Expand expand = new Expand(folderProperties);
35+
return paths.stream()
36+
.map(path -> expand.format(path, false))
37+
.collect(Collectors.toList());
38+
39+
}
40+
41+
private static Map<String, String> getFolderPropertiesFrom(SCMSourceOwner owner) {
42+
if (owner == null) {
43+
return new HashMap<>();
44+
}
45+
ItemGroup<?> parent = owner.getParent();
46+
Map<String, String> propertyMap = new HashMap<>();
47+
while (parent instanceof AbstractFolder) {
48+
AbstractFolder<?> folder = (AbstractFolder<?>) parent;
49+
DescribableList<AbstractFolderProperty<?>, AbstractFolderPropertyDescriptor> properties = folder.getProperties();
50+
addFolderPropertiesToMap(properties, propertyMap);
51+
parent = folder.getParent();
52+
}
53+
return propertyMap;
54+
}
55+
56+
private static void addFolderPropertiesToMap(DescribableList<AbstractFolderProperty<?>, AbstractFolderPropertyDescriptor> properties, Map<String, String> propertyMap) {
57+
if (properties == null) {
58+
return;
59+
}
60+
FolderProperties folderProperties = properties.get(FolderProperties.class);
61+
62+
if (folderProperties == null) {
63+
return;
64+
}
65+
Arrays.stream(folderProperties.getProperties())
66+
.filter(Objects::nonNull)
67+
.forEach(prop -> propertyMap.put(prop.getKey(), prop.getValue()));
68+
}
69+
}

src/main/resources/org/jenkinsci/plugins/p4/scm/BranchesScmSource/config-detail.jelly

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
</f:entry>
4242

4343
<f:entry field="useNewDirectoryStructure">
44-
<f:checkbox title="Use new directory structure" default="false"/>
44+
<f:checkbox title="Enable variable branch position in “Include branches”." default="false"/>
4545
</f:entry>
4646

4747
<t:listScmBrowsers name="p4.browser"/>

0 commit comments

Comments
 (0)