From ec442e92638fd7855cb4e0d3ee7cf7ce05245dd6 Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Thu, 12 Sep 2024 16:43:12 -0600 Subject: [PATCH 01/15] caching the same repository avoid reload multiple time on the same build --- .../injectors/LibraryStepInjector.groovy | 2 ++ .../jte/job/TemplateFlowDefinition.groovy | 4 +++- .../jte/util/FileSystemWrapperFactory.groovy | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy b/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy index 885e69808..b36f487c0 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy @@ -90,6 +90,8 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob // load all the libraries // this will copy their contents to ${jteDir} for the run LinkedHashMap aggregatedConfig = config.getConfig() + + aggregatedConfig[KEY].each{ libName, libConfig -> LibraryProvider provider = providers.find{ provider -> provider.hasLibrary(flowOwner, libName) diff --git a/src/main/groovy/org/boozallen/plugins/jte/job/TemplateFlowDefinition.groovy b/src/main/groovy/org/boozallen/plugins/jte/job/TemplateFlowDefinition.groovy index d869c26cb..b1b9b77d1 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/job/TemplateFlowDefinition.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/job/TemplateFlowDefinition.groovy @@ -15,6 +15,8 @@ */ package org.boozallen.plugins.jte.job +import org.boozallen.plugins.jte.util.FileSystemWrapperFactory + import static org.jenkinsci.plugins.workflow.cps.persistence.PersistenceContext.JOB import org.boozallen.plugins.jte.init.primitives.TemplatePrimitiveCollector @@ -83,7 +85,7 @@ abstract class TemplateFlowDefinition extends FlowDefinition { CpsFlowExecution exec = new CpsFlowExecution(template, true, owner, hint) // Step 3: Invoke TemplatePrimitiveInjectors TemplatePrimitiveInjector.orchestrate(exec, config) - + FileSystemWrapperFactory.clear_cache(owner) return exec } diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy index 01c703253..edc8dd7a5 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy @@ -36,6 +36,8 @@ import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject */ class FileSystemWrapperFactory { +|| private static Map cache = [:] + /** * Creates a FileSystemWrapper. Can either be provided an SCM directly * or try to infer the SCM from the current job @@ -50,6 +52,13 @@ class FileSystemWrapperFactory { throw new IllegalStateException("Job cannot be null when creating FileSystemWrapper") } + final String cacheKey = job.getFullName() + + if (cache.containsKey(cacheKey)) { + return cache.get(cacheKey) + } + + FileSystemWrapper fsw ItemGroup parent = job.getParent() FlowDefinition definition = job.getDefinition() @@ -66,6 +75,8 @@ class FileSystemWrapperFactory { if(fsw.fs == null){ TemplateLogger logger = new TemplateLogger(owner.getListener()) logger.printWarning("FileSystemWrapperFactory: Unable to create SCMFileSystem: job: ${job.getFullName()}, scm: ${scm}") + } else { + cache.put(cacheKey, fsw) } return fsw } @@ -121,4 +132,11 @@ class FileSystemWrapperFactory { return fsw } + static void clear_cache(FlowExecutionOwner owner) { + WorkflowRun run = owner.run() + WorkflowJob job = run.getParent() + final String cacheKey = job.getFullName() + cache.remove(cacheKey) + } + } From a83227d0b60933926af3a5d73f03f7880f49a655 Mon Sep 17 00:00:00 2001 From: arechavarria Date: Thu, 12 Sep 2024 18:39:29 -0600 Subject: [PATCH 02/15] Actualizar CI.yml --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 8c9f406d4..084807bbb 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -26,7 +26,7 @@ jobs: - uses: eskatos/gradle-command-action@v1 with: arguments: --no-daemon codenarc - - uses: actions/upload-artifact@v1 + - uses: actions/upload-artifact@v4 if: failure() with: name: codenarc-results From dc190dacc0aa1b7a496116bcf77300e2254a6c8d Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Thu, 12 Sep 2024 18:47:14 -0600 Subject: [PATCH 03/15] upgrade to action upload-actifact version 4 / fix code break --- .github/workflows/CI.yml | 4 ++-- .../plugins/jte/util/FileSystemWrapperFactory.groovy | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 084807bbb..ee85acc2b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -62,7 +62,7 @@ jobs: - uses: eskatos/gradle-command-action@v1 with: arguments: --no-daemon test jacocoTestReport - - uses: actions/upload-artifact@v1 + - uses: actions/upload-artifact@v4 if: failure() with: name: test-results @@ -78,7 +78,7 @@ jobs: - uses: eskatos/gradle-command-action@v1 with: arguments: --no-daemon jpi - - uses: actions/upload-artifact@v1 + - uses: actions/upload-artifact@v4 with: name: jpi path: build/libs/templating-engine.hpi diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy index edc8dd7a5..653c03215 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy @@ -36,7 +36,7 @@ import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject */ class FileSystemWrapperFactory { -|| private static Map cache = [:] + private static Map cache = [:] /** * Creates a FileSystemWrapper. Can either be provided an SCM directly From 97424487c3b870d525519be998e033767e5f30fe Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Sun, 15 Sep 2024 22:24:52 -0600 Subject: [PATCH 04/15] create cache key class --- .../TemplatePrimitiveInjector.groovy | 21 +++--- .../jte/job/TemplateFlowDefinition.groovy | 1 - .../jte/util/FileSystemCacheKey.groovy | 40 ++++++++++++ .../jte/util/FileSystemWrapperFactory.groovy | 64 +++++++++++-------- 4 files changed, 92 insertions(+), 34 deletions(-) create mode 100644 src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy diff --git a/src/main/groovy/org/boozallen/plugins/jte/init/primitives/TemplatePrimitiveInjector.groovy b/src/main/groovy/org/boozallen/plugins/jte/init/primitives/TemplatePrimitiveInjector.groovy index cd7a0d4da..099926305 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/init/primitives/TemplatePrimitiveInjector.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/init/primitives/TemplatePrimitiveInjector.groovy @@ -20,6 +20,7 @@ import hudson.ExtensionPoint import jenkins.model.Jenkins import org.boozallen.plugins.jte.init.governance.config.dsl.PipelineConfigurationObject import org.boozallen.plugins.jte.util.AggregateException +import org.boozallen.plugins.jte.util.FileSystemWrapperFactory import org.boozallen.plugins.jte.util.JTEException import org.codehaus.groovy.reflection.CachedMethod import org.jenkinsci.plugins.workflow.cps.CpsFlowExecution @@ -84,14 +85,18 @@ abstract class TemplatePrimitiveInjector implements ExtensionPoint{ * @param config the aggregated pipeline configuration */ static void orchestrate(CpsFlowExecution exec, PipelineConfigurationObject config){ - invoke("validateConfiguration", exec, config) - FlowExecutionOwner flowOwner = exec.getOwner() - WorkflowRun run = flowOwner.run() - TemplatePrimitiveCollector collector = new TemplatePrimitiveCollector() - run.addOrReplaceAction(collector) // may be used by one of the injectors - invoke(run, collector, "injectPrimitives", exec, config) - invoke("validatePrimitives", exec, config, collector) - run.addOrReplaceAction(collector) + try { + invoke("validateConfiguration", exec, config) + FlowExecutionOwner flowOwner = exec.getOwner() + WorkflowRun run = flowOwner.run() + TemplatePrimitiveCollector collector = new TemplatePrimitiveCollector() + run.addOrReplaceAction(collector) // may be used by one of the injectors + invoke(run, collector, "injectPrimitives", exec, config) + invoke("validatePrimitives", exec, config, collector) + run.addOrReplaceAction(collector) + } finally { + FileSystemWrapperFactory.clearCache(exec.getOwner()) + } } /** diff --git a/src/main/groovy/org/boozallen/plugins/jte/job/TemplateFlowDefinition.groovy b/src/main/groovy/org/boozallen/plugins/jte/job/TemplateFlowDefinition.groovy index b1b9b77d1..1cc9115c8 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/job/TemplateFlowDefinition.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/job/TemplateFlowDefinition.groovy @@ -85,7 +85,6 @@ abstract class TemplateFlowDefinition extends FlowDefinition { CpsFlowExecution exec = new CpsFlowExecution(template, true, owner, hint) // Step 3: Invoke TemplatePrimitiveInjectors TemplatePrimitiveInjector.orchestrate(exec, config) - FileSystemWrapperFactory.clear_cache(owner) return exec } diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy new file mode 100644 index 000000000..9fd40128a --- /dev/null +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy @@ -0,0 +1,40 @@ +package org.boozallen.plugins.jte.util + +import hudson.scm.SCM +import jenkins.scm.api.SCMHead +import jenkins.scm.api.SCMRevision +import jenkins.scm.api.SCMSource +import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner + +class FileSystemCacheKey { + FlowExecutionOwner owner + SCM scm + SCMSource scmSource + SCMHead scmHead + SCMRevision scmRevision + + boolean equals(o) { + if (this.is(o)) return true + if (!(o instanceof FileSystemCacheKey)) return false + + FileSystemCacheKey that = (FileSystemCacheKey) o + + if (owner != that.owner) return false + if (scm != that.scm) return false + if (scmHead != that.scmHead) return false + if (scmRevision != that.scmRevision) return false + if (scmSource != that.scmSource) return false + + return true + } + + int hashCode() { + int result + result = (owner != null ? owner.hashCode() : 0) + result = 31 * result + (scm != null ? scm.hashCode() : 0) + result = 31 * result + (scmSource != null ? scmSource.hashCode() : 0) + result = 31 * result + (scmHead != null ? scmHead.hashCode() : 0) + result = 31 * result + (scmRevision != null ? scmRevision.hashCode() : 0) + return result + } +} diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy index 653c03215..d347c8046 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy @@ -36,7 +36,7 @@ import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject */ class FileSystemWrapperFactory { - private static Map cache = [:] + private static Map cache = [:] /** * Creates a FileSystemWrapper. Can either be provided an SCM directly @@ -52,13 +52,6 @@ class FileSystemWrapperFactory { throw new IllegalStateException("Job cannot be null when creating FileSystemWrapper") } - final String cacheKey = job.getFullName() - - if (cache.containsKey(cacheKey)) { - return cache.get(cacheKey) - } - - FileSystemWrapper fsw ItemGroup parent = job.getParent() FlowDefinition definition = job.getDefinition() @@ -75,8 +68,6 @@ class FileSystemWrapperFactory { if(fsw.fs == null){ TemplateLogger logger = new TemplateLogger(owner.getListener()) logger.printWarning("FileSystemWrapperFactory: Unable to create SCMFileSystem: job: ${job.getFullName()}, scm: ${scm}") - } else { - cache.put(cacheKey, fsw) } return fsw } @@ -84,11 +75,17 @@ class FileSystemWrapperFactory { throw new IllegalStateException("Unable to build a FileSystemWrapper") } - private static FileSystemWrapper fromSCM(FlowExecutionOwner owner, WorkflowJob job, SCM scm){ - SCMFileSystem fs - fs = SCMFileSystem.of(job, scm) - FileSystemWrapper fsw = new FileSystemWrapper(fs: fs, scmKey: scm.getKey(), owner: owner) - return fsw + private static FileSystemWrapper fromSCM(FlowExecutionOwner owner, WorkflowJob job, SCM scm) { + FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scm: scm) + if (cache.containsKey(cacheKey)) { + return cache.get(cacheKey) + } else { + SCMFileSystem fs + fs = SCMFileSystem.of(job, scm) + FileSystemWrapper fsw = new FileSystemWrapper(fs: fs, scmKey: scm.getKey(), owner: owner) + cache.put(cacheKey, fsw) + return fsw + } } private static FileSystemWrapper fromMultiBranchProject(FlowExecutionOwner owner, WorkflowJob job, TaskListener listener){ @@ -100,6 +97,7 @@ class FileSystemWrapperFactory { } Branch branch = property.getBranch() + SCMSource scmSource = parent.getSCMSource(branch.getSourceId()) if (!scmSource) { throw new IllegalStateException("${branch.getSourceId()} not found") @@ -113,11 +111,23 @@ class FileSystemWrapperFactory { if (tip) { scmKey = branch.getScm().getKey() SCMRevision rev = scmSource.getTrustedRevision(tip, listener) - fs = SCMFileSystem.of(scmSource, head, rev) + FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scmSource: scmSource, scmHead: head, scmRevision: rev) + if (cache.containsKey(cacheKey)) { + fs = cache.get(cacheKey) + } else { + fs = SCMFileSystem.of(scmSource, head, rev) + cache.put(cacheKey, fs) + } } else { SCM jobSCM = branch.getScm() - fs = SCMFileSystem.of(job, jobSCM) scmKey = jobSCM.getKey() + FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scm: jobSCM) + if (cache.containsKey(cacheKey)) { + fs = cache.get(cacheKey) + } else { + fs = SCMFileSystem.of(job, jobSCM) + cache.put(cacheKey, fs) + } } FileSystemWrapper fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) return fsw @@ -127,16 +137,20 @@ class FileSystemWrapperFactory { FlowDefinition definition = job.getDefinition() SCM jobSCM = definition.getScm() String scmKey = jobSCM.getKey() - SCMFileSystem fs = SCMFileSystem.of(job, jobSCM) - FileSystemWrapper fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) - return fsw + FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scm: jobSCM) + if (cache.containsKey(cacheKey)) { + return cache.get(cacheKey) + } else { + SCMFileSystem fs = SCMFileSystem.of(job, jobSCM) + jobSCM.g + FileSystemWrapper fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) + cache.put(cacheKey, fs) + return fsw + } } - static void clear_cache(FlowExecutionOwner owner) { - WorkflowRun run = owner.run() - WorkflowJob job = run.getParent() - final String cacheKey = job.getFullName() - cache.remove(cacheKey) + static void clearCache(FlowExecutionOwner owner) { + cache.entrySet().removeIf { entry -> entry.getKey().getOwner() == owner } } } From be932be50c1aa8a15a30b063d84cdd3a40a22844 Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Sun, 15 Sep 2024 22:30:36 -0600 Subject: [PATCH 05/15] create cache key class --- .../plugins/jte/util/FileSystemCacheKey.groovy | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy index 9fd40128a..77133b0f6 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy @@ -1,3 +1,18 @@ +/* + Copyright 2018 Booz Allen Hamilton + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ package org.boozallen.plugins.jte.util import hudson.scm.SCM From 5bdded46bff3bc7dfa20ec623d7a2e4870360ed0 Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Sun, 15 Sep 2024 22:48:30 -0600 Subject: [PATCH 06/15] create javadoc --- .../jte/util/FileSystemCacheKey.groovy | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy index 77133b0f6..e5411b412 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ + package org.boozallen.plugins.jte.util import hudson.scm.SCM @@ -21,13 +22,63 @@ import jenkins.scm.api.SCMRevision import jenkins.scm.api.SCMSource import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner +/** + * The FileSystemCacheKey class is a utility for creating cache keys based on various + * SCM (Source Code Management) related objects within the Jenkins Pipeline ecosystem. + * This key is intended to uniquely identify a cache entry based on SCM configurations + * and the owner of the pipeline execution. + * + *

It overrides the {@link #equals(Object)} and {@link #hashCode()} methods to ensure + * that cache keys are properly compared and can be used effectively in hash-based collections.

+ * + *

This class is used in caching scenarios to avoid re-fetching or recalculating information + * that has already been retrieved from the SCM system during a Jenkins pipeline execution.

+ * + *

Fields:

+ *
    + *
  • {@code owner} - The {@link FlowExecutionOwner} that represents the owner of the flow execution.
  • + *
  • {@code scm} - The {@link SCM} instance that represents the source code management system in use.
  • + *
  • {@code scmSource} - The {@link SCMSource} which defines the SCM source for the project.
  • + *
  • {@code scmHead} - The {@link SCMHead} that identifies the branch, tag, or other head in the SCM repository.
  • + *
  • {@code scmRevision} - The {@link SCMRevision} that represents the revision of the SCM head.
  • + *
+ * + *

Methods:

+ *
    + *
  • {@link #equals(Object)} - Compares this cache key with another object for equality, based on the owner, SCM, and related fields.
  • + *
  • {@link #hashCode()} - Generates a hash code based on the owner, SCM, and related fields for use in hash-based collections.
  • + *
+ * + *

Copyright: 2018 Booz Allen Hamilton

+ * + *

License: This class is licensed under the Apache License, Version 2.0. See the LICENSE file or + * visit http://www.apache.org/licenses/LICENSE-2.0 for details.

+ * + * @see FlowExecutionOwner + * @see SCM + * @see SCMSource + * @see SCMHead + * @see SCMRevision + */ class FileSystemCacheKey { + FlowExecutionOwner owner SCM scm SCMSource scmSource SCMHead scmHead SCMRevision scmRevision + /** + * Compares this FileSystemCacheKey instance with another object to determine if they are equal. + * The comparison is based on the equality of the following fields: {@code owner}, {@code scm}, + * {@code scmSource}, {@code scmHead}, and {@code scmRevision}. + * + *

If the provided object is not an instance of {@code FileSystemCacheKey}, this method returns {@code false}.

+ * + * @param o the object to be compared with this instance. + * @return {@code true} if the provided object is equal to this instance, {@code false} otherwise. + */ + @Override boolean equals(o) { if (this.is(o)) return true if (!(o instanceof FileSystemCacheKey)) return false @@ -43,6 +94,17 @@ class FileSystemCacheKey { return true } + /** + * Generates a hash code for this FileSystemCacheKey instance. + * The hash code is computed based on the {@code owner}, {@code scm}, {@code scmSource}, + * {@code scmHead}, and {@code scmRevision} fields. + * + *

This method is used to efficiently store and retrieve instances of {@code FileSystemCacheKey} + * in hash-based collections such as {@link java.util.HashMap} or {@link java.util.HashSet}.

+ * + * @return the hash code value for this instance. + */ + @Override int hashCode() { int result result = (owner != null ? owner.hashCode() : 0) From 3e1dac951d220a6b7bf6287a59d8b0782944bf3d Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Sun, 15 Sep 2024 22:52:37 -0600 Subject: [PATCH 07/15] create javadoc --- .../jte/util/FileSystemWrapperFactory.groovy | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy index d347c8046..8a3abcab3 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy @@ -36,6 +36,24 @@ import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject */ class FileSystemWrapperFactory { + /** + * A static cache that maps {@link FileSystemCacheKey} instances to their corresponding + * {@link FileSystemWrapper} objects. + * + *

This cache is used to avoid redundant filesystem operations by reusing {@code FileSystemWrapper} + * instances that have already been created for a given {@link FileSystemCacheKey}. It helps + * improve performance by preventing repeated lookups or calculations for the same SCM data + * during Jenkins pipeline executions.

+ * + *

The cache is implemented as a {@code Map}, where:

+ *
    + *
  • The key is an instance of {@link FileSystemCacheKey}, which uniquely identifies the SCM context.
  • + *
  • The value is an instance of {@link FileSystemWrapper}, which encapsulates file system operations for that context.
  • + *
+ * + *

This cache is a static attribute of the class, shared across all instances of {@code FileSystemCacheKey}, + * and is initialized as an empty map, represented by {@code [:]}. It can grow dynamically as new entries are added during runtime.

+ */ private static Map cache = [:] /** From ef34828b51936551fc856e21a8f550882b0c37f6 Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Sun, 15 Sep 2024 22:56:17 -0600 Subject: [PATCH 08/15] create javadoc --- .../org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy index e5411b412..0b9ff4862 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy @@ -13,7 +13,6 @@ See the License for the specific language governing permissions and limitations under the License. */ - package org.boozallen.plugins.jte.util import hudson.scm.SCM From 16e54b68fb04c52bd36917c8be510ba1a7b78155 Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Mon, 16 Sep 2024 10:17:50 -0600 Subject: [PATCH 09/15] fix codenarc issues --- .../injectors/LibraryStepInjector.groovy | 1 - .../jte/job/TemplateFlowDefinition.groovy | 2 - .../jte/util/FileSystemCacheKey.groovy | 47 +++++++++++------ .../jte/util/FileSystemWrapperFactory.groovy | 52 ++++++++++--------- 4 files changed, 59 insertions(+), 43 deletions(-) diff --git a/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy b/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy index b36f487c0..fe2061287 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/init/primitives/injectors/LibraryStepInjector.groovy @@ -91,7 +91,6 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob // this will copy their contents to ${jteDir} for the run LinkedHashMap aggregatedConfig = config.getConfig() - aggregatedConfig[KEY].each{ libName, libConfig -> LibraryProvider provider = providers.find{ provider -> provider.hasLibrary(flowOwner, libName) diff --git a/src/main/groovy/org/boozallen/plugins/jte/job/TemplateFlowDefinition.groovy b/src/main/groovy/org/boozallen/plugins/jte/job/TemplateFlowDefinition.groovy index 1cc9115c8..98294d509 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/job/TemplateFlowDefinition.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/job/TemplateFlowDefinition.groovy @@ -15,8 +15,6 @@ */ package org.boozallen.plugins.jte.job -import org.boozallen.plugins.jte.util.FileSystemWrapperFactory - import static org.jenkinsci.plugins.workflow.cps.persistence.PersistenceContext.JOB import org.boozallen.plugins.jte.init.primitives.TemplatePrimitiveCollector diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy index 0b9ff4862..3c001ca26 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy @@ -61,6 +61,8 @@ import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner */ class FileSystemCacheKey { + private static final int MULTIPLIER = 31 + FlowExecutionOwner owner SCM scm SCMSource scmSource @@ -77,23 +79,37 @@ class FileSystemCacheKey { * @param o the object to be compared with this instance. * @return {@code true} if the provided object is equal to this instance, {@code false} otherwise. */ - @Override boolean equals(o) { - if (this.is(o)) return true - if (!(o instanceof FileSystemCacheKey)) return false + if (this.is(o)) { + return true + } + if (!(o instanceof FileSystemCacheKey)) { + return false + } FileSystemCacheKey that = (FileSystemCacheKey) o - if (owner != that.owner) return false - if (scm != that.scm) return false - if (scmHead != that.scmHead) return false - if (scmRevision != that.scmRevision) return false - if (scmSource != that.scmSource) return false + boolean result = true - return true - } + if (owner != that.owner) { + result = false + } + if (scm != that.scm) { + result = false + } + if (scmHead != that.scmHead) { + result = false + } + if (scmRevision != that.scmRevision) { + result = false + } + if (scmSource != that.scmSource) { + result = false + } - /** + return result + } +/** * Generates a hash code for this FileSystemCacheKey instance. * The hash code is computed based on the {@code owner}, {@code scm}, {@code scmSource}, * {@code scmHead}, and {@code scmRevision} fields. @@ -107,10 +123,11 @@ class FileSystemCacheKey { int hashCode() { int result result = (owner != null ? owner.hashCode() : 0) - result = 31 * result + (scm != null ? scm.hashCode() : 0) - result = 31 * result + (scmSource != null ? scmSource.hashCode() : 0) - result = 31 * result + (scmHead != null ? scmHead.hashCode() : 0) - result = 31 * result + (scmRevision != null ? scmRevision.hashCode() : 0) + result = MULTIPLIER * result + (scm != null ? scm.hashCode() : 0) + result = MULTIPLIER * result + (scmSource != null ? scmSource.hashCode() : 0) + result = MULTIPLIER * result + (scmHead != null ? scmHead.hashCode() : 0) + result = MULTIPLIER * result + (scmRevision != null ? scmRevision.hashCode() : 0) return result } + } diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy index 8a3abcab3..ad20a3dfb 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy @@ -54,7 +54,11 @@ class FileSystemWrapperFactory { *

This cache is a static attribute of the class, shared across all instances of {@code FileSystemCacheKey}, * and is initialized as an empty map, represented by {@code [:]}. It can grow dynamically as new entries are added during runtime.

*/ - private static Map cache = [:] + private final static Map CACHE = [:] + + static void clearCache(FlowExecutionOwner owner) { + CACHE.entrySet().removeIf { entry -> entry.getKey().getOwner() == owner } + } /** * Creates a FileSystemWrapper. Can either be provided an SCM directly @@ -94,16 +98,18 @@ class FileSystemWrapperFactory { } private static FileSystemWrapper fromSCM(FlowExecutionOwner owner, WorkflowJob job, SCM scm) { + FileSystemWrapper fsw FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scm: scm) - if (cache.containsKey(cacheKey)) { - return cache.get(cacheKey) + if (CACHE.containsKey(cacheKey)) { + fsw = CACHE.get(cacheKey) } else { SCMFileSystem fs fs = SCMFileSystem.of(job, scm) - FileSystemWrapper fsw = new FileSystemWrapper(fs: fs, scmKey: scm.getKey(), owner: owner) - cache.put(cacheKey, fsw) - return fsw + fsw = new FileSystemWrapper(fs: fs, scmKey: scm.getKey(), owner: owner) + CACHE.put(cacheKey, fsw) } + + return fsw } private static FileSystemWrapper fromMultiBranchProject(FlowExecutionOwner owner, WorkflowJob job, TaskListener listener){ @@ -115,7 +121,6 @@ class FileSystemWrapperFactory { } Branch branch = property.getBranch() - SCMSource scmSource = parent.getSCMSource(branch.getSourceId()) if (!scmSource) { throw new IllegalStateException("${branch.getSourceId()} not found") @@ -123,31 +128,32 @@ class FileSystemWrapperFactory { SCMHead head = branch.getHead() SCMRevision tip = scmSource.fetch(head, listener) - + FileSystemWrapper fsw SCMFileSystem fs String scmKey if (tip) { scmKey = branch.getScm().getKey() SCMRevision rev = scmSource.getTrustedRevision(tip, listener) FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scmSource: scmSource, scmHead: head, scmRevision: rev) - if (cache.containsKey(cacheKey)) { - fs = cache.get(cacheKey) + if (CACHE.containsKey(cacheKey)) { + fsw = CACHE.get(cacheKey) } else { fs = SCMFileSystem.of(scmSource, head, rev) - cache.put(cacheKey, fs) + fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) + CACHE.put(cacheKey, fsw) } } else { SCM jobSCM = branch.getScm() scmKey = jobSCM.getKey() FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scm: jobSCM) - if (cache.containsKey(cacheKey)) { - fs = cache.get(cacheKey) + if (CACHE.containsKey(cacheKey)) { + fsw = CACHE.get(cacheKey) } else { fs = SCMFileSystem.of(job, jobSCM) - cache.put(cacheKey, fs) + fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) + CACHE.put(cacheKey, fsw) } } - FileSystemWrapper fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) return fsw } @@ -156,19 +162,15 @@ class FileSystemWrapperFactory { SCM jobSCM = definition.getScm() String scmKey = jobSCM.getKey() FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scm: jobSCM) - if (cache.containsKey(cacheKey)) { - return cache.get(cacheKey) + FileSystemWrapper fsw + if (CACHE.containsKey(cacheKey)) { + fsw = CACHE.get(cacheKey) } else { SCMFileSystem fs = SCMFileSystem.of(job, jobSCM) - jobSCM.g - FileSystemWrapper fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) - cache.put(cacheKey, fs) - return fsw + fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) + CACHE.put(cacheKey, fsw) } - } - - static void clearCache(FlowExecutionOwner owner) { - cache.entrySet().removeIf { entry -> entry.getKey().getOwner() == owner } + return fsw } } From 05254577d390ab7c6ab07bb97be10d24b3c9e7d1 Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Mon, 16 Sep 2024 10:26:17 -0600 Subject: [PATCH 10/15] fix codenarc issues --- .../org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy index 3c001ca26..320d0e396 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemCacheKey.groovy @@ -79,7 +79,8 @@ class FileSystemCacheKey { * @param o the object to be compared with this instance. * @return {@code true} if the provided object is equal to this instance, {@code false} otherwise. */ - boolean equals(o) { + @Override + boolean equals(Object o) { if (this.is(o)) { return true } From 9c8663e5c89500dc4ae9195bfca01fced943463d Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Mon, 16 Sep 2024 12:08:32 -0600 Subject: [PATCH 11/15] log message when scm comes from cache --- .../plugins/jte/util/FileSystemWrapperFactory.groovy | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy index ad20a3dfb..be3783359 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy @@ -99,9 +99,11 @@ class FileSystemWrapperFactory { private static FileSystemWrapper fromSCM(FlowExecutionOwner owner, WorkflowJob job, SCM scm) { FileSystemWrapper fsw + TemplateLogger logger = new TemplateLogger(owner.getListener()) FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scm: scm) if (CACHE.containsKey(cacheKey)) { fsw = CACHE.get(cacheKey) + logger.print("Loading scm: ${scm.getKey()} from cache") } else { SCMFileSystem fs fs = SCMFileSystem.of(job, scm) @@ -114,7 +116,7 @@ class FileSystemWrapperFactory { private static FileSystemWrapper fromMultiBranchProject(FlowExecutionOwner owner, WorkflowJob job, TaskListener listener){ ItemGroup parent = job.getParent() - + TemplateLogger logger = new TemplateLogger(owner.getListener()) BranchJobProperty property = job.getProperty(BranchJobProperty) if (!property) { throw new JTEException("BranchJobProperty is somehow missing") @@ -137,6 +139,7 @@ class FileSystemWrapperFactory { FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scmSource: scmSource, scmHead: head, scmRevision: rev) if (CACHE.containsKey(cacheKey)) { fsw = CACHE.get(cacheKey) + logger.print("Loading scm: ${scmKey} from cache") } else { fs = SCMFileSystem.of(scmSource, head, rev) fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) @@ -148,6 +151,7 @@ class FileSystemWrapperFactory { FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scm: jobSCM) if (CACHE.containsKey(cacheKey)) { fsw = CACHE.get(cacheKey) + logger.print("Loading scm: ${scmKey} from cache") } else { fs = SCMFileSystem.of(job, jobSCM) fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) @@ -158,6 +162,7 @@ class FileSystemWrapperFactory { } private static FileSystemWrapper fromPipelineJob(FlowExecutionOwner owner, WorkflowJob job){ + TemplateLogger logger = new TemplateLogger(owner.getListener()) FlowDefinition definition = job.getDefinition() SCM jobSCM = definition.getScm() String scmKey = jobSCM.getKey() @@ -165,6 +170,7 @@ class FileSystemWrapperFactory { FileSystemWrapper fsw if (CACHE.containsKey(cacheKey)) { fsw = CACHE.get(cacheKey) + logger.print("Loading scm: ${scmKey} from cache") } else { SCMFileSystem fs = SCMFileSystem.of(job, jobSCM) fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) From f9895c785874e446de4980a4d49394531b436a2a Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Thu, 19 Sep 2024 11:32:10 -0600 Subject: [PATCH 12/15] fix vale stage --- .github/workflows/CI.yml | 2 +- docs/styles/Vocab/JTE/accept.txt | 2 ++ .../plugins/jte/util/FileSystemWrapperFactory.groovy | 12 +++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index ee85acc2b..3493a9de1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -45,7 +45,7 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'jenkinsci/templating-engine-plugin' container: - image: jdkato/vale:v2.18.0 + image: jdkato/vale:v2.21.3 options: --user root steps: - uses: actions/checkout@v2 diff --git a/docs/styles/Vocab/JTE/accept.txt b/docs/styles/Vocab/JTE/accept.txt index 897d1e364..c8687e434 100644 --- a/docs/styles/Vocab/JTE/accept.txt +++ b/docs/styles/Vocab/JTE/accept.txt @@ -33,3 +33,5 @@ Splunk [Tt]emplat(e|es|ed|ing)\b truthy [Ww]alkthroughs? +JTE's +stageContext \ No newline at end of file diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy index be3783359..5c728ed59 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy @@ -57,7 +57,17 @@ class FileSystemWrapperFactory { private final static Map CACHE = [:] static void clearCache(FlowExecutionOwner owner) { - CACHE.entrySet().removeIf { entry -> entry.getKey().getOwner() == owner } + if (!CACHE.isEmpty()) { + TemplateLogger logger = new TemplateLogger(owner.getListener()) + ArrayList msg = [ + "Values were found in the cache, so this helped reduce pipeline initiation time.", + ] + CACHE.entrySet().find { it.getKey().getOwner() == owner}.each { + msg.add("-- scm ${it.value.getScmKey()}") + } + logger.print(msg) + CACHE.entrySet().removeIf { entry -> entry.getKey().getOwner() == owner } + } } /** From cb675c81b2078169d9a8c4aaef180fd864b81deb Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Thu, 19 Sep 2024 11:43:06 -0600 Subject: [PATCH 13/15] fix codenarc issues --- .../plugins/jte/util/FileSystemWrapperFactory.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy index 5c728ed59..adf35186d 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy @@ -62,8 +62,8 @@ class FileSystemWrapperFactory { ArrayList msg = [ "Values were found in the cache, so this helped reduce pipeline initiation time.", ] - CACHE.entrySet().find { it.getKey().getOwner() == owner}.each { - msg.add("-- scm ${it.value.getScmKey()}") + CACHE.entrySet().find { entry -> entry.getKey().getOwner() == owner }.each { entry -> + msg.add("-- scm ${entry.getValue().getScmKey()}") } logger.print(msg) CACHE.entrySet().removeIf { entry -> entry.getKey().getOwner() == owner } From ba00ee182fe893040164b89b42225d65bf372906 Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Thu, 10 Oct 2024 17:22:25 -0600 Subject: [PATCH 14/15] remove println to avoid spam --- .../plugins/jte/util/FileSystemWrapperFactory.groovy | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy index adf35186d..c668e4edc 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy @@ -109,15 +109,12 @@ class FileSystemWrapperFactory { private static FileSystemWrapper fromSCM(FlowExecutionOwner owner, WorkflowJob job, SCM scm) { FileSystemWrapper fsw - TemplateLogger logger = new TemplateLogger(owner.getListener()) FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scm: scm) if (CACHE.containsKey(cacheKey)) { fsw = CACHE.get(cacheKey) - logger.print("Loading scm: ${scm.getKey()} from cache") } else { SCMFileSystem fs fs = SCMFileSystem.of(job, scm) - fsw = new FileSystemWrapper(fs: fs, scmKey: scm.getKey(), owner: owner) CACHE.put(cacheKey, fsw) } @@ -126,7 +123,6 @@ class FileSystemWrapperFactory { private static FileSystemWrapper fromMultiBranchProject(FlowExecutionOwner owner, WorkflowJob job, TaskListener listener){ ItemGroup parent = job.getParent() - TemplateLogger logger = new TemplateLogger(owner.getListener()) BranchJobProperty property = job.getProperty(BranchJobProperty) if (!property) { throw new JTEException("BranchJobProperty is somehow missing") @@ -149,7 +145,6 @@ class FileSystemWrapperFactory { FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scmSource: scmSource, scmHead: head, scmRevision: rev) if (CACHE.containsKey(cacheKey)) { fsw = CACHE.get(cacheKey) - logger.print("Loading scm: ${scmKey} from cache") } else { fs = SCMFileSystem.of(scmSource, head, rev) fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) @@ -161,7 +156,6 @@ class FileSystemWrapperFactory { FileSystemCacheKey cacheKey = new FileSystemCacheKey(owner: owner, scm: jobSCM) if (CACHE.containsKey(cacheKey)) { fsw = CACHE.get(cacheKey) - logger.print("Loading scm: ${scmKey} from cache") } else { fs = SCMFileSystem.of(job, jobSCM) fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) @@ -172,7 +166,6 @@ class FileSystemWrapperFactory { } private static FileSystemWrapper fromPipelineJob(FlowExecutionOwner owner, WorkflowJob job){ - TemplateLogger logger = new TemplateLogger(owner.getListener()) FlowDefinition definition = job.getDefinition() SCM jobSCM = definition.getScm() String scmKey = jobSCM.getKey() @@ -180,7 +173,6 @@ class FileSystemWrapperFactory { FileSystemWrapper fsw if (CACHE.containsKey(cacheKey)) { fsw = CACHE.get(cacheKey) - logger.print("Loading scm: ${scmKey} from cache") } else { SCMFileSystem fs = SCMFileSystem.of(job, jobSCM) fsw = new FileSystemWrapper(fs: fs, scmKey: scmKey, owner: owner) From 083a3942c75ba3f39e352b217276c7ace8ef8a11 Mon Sep 17 00:00:00 2001 From: Aaron Echavarria Date: Thu, 10 Oct 2024 17:31:16 -0600 Subject: [PATCH 15/15] remove println to avoid spam --- .../boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy index c668e4edc..69d1e2353 100644 --- a/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy +++ b/src/main/groovy/org/boozallen/plugins/jte/util/FileSystemWrapperFactory.groovy @@ -115,6 +115,7 @@ class FileSystemWrapperFactory { } else { SCMFileSystem fs fs = SCMFileSystem.of(job, scm) + fsw = new FileSystemWrapper(fs: fs, scmKey: scm.getKey(), owner: owner) CACHE.put(cacheKey, fsw) }