<commit_before>/*
   Copyright 2014-2017 <NAME> - https://github.com/samrocketman/jervis

   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 net.gleske.jervis.lang

import net.gleske.jervis.exceptions.PipelineGeneratorException
import static net.gleske.jervis.lang.lifecycleGenerator.getObjectValue

/**
  This class offers helper forunctions for using Jervis in the context of a
  Jenkins <a href="https://jenkins.io/doc/book/pipeline/shared-libraries/" target=_blank>pipeline global shared library</a>.

  <h2>Sample usage</h2>
  <p>To run this example, clone Jervis and execute <tt>./gradlew console</tt>
  to bring up a <a href="http://groovy-lang.org/groovyconsole.html" target="_blank">Groovy Console</a>
  with the classpath set up.</p>

<pre><tt>import net.gleske.jervis.lang.lifecycleGenerator
import net.gleske.jervis.lang.pipelineGenerator

def generator = new lifecycleGenerator()
generator.loadLifecyclesString(new File('resources/lifecycles-ubuntu1604-stable.json').text)
generator.loadToolchainsString(new File('resources/toolchains-ubuntu1604-stable.json').text)

generator.loadYamlString('''
language: groovy
env: ["GROOVY_VERSION=1.8.9", "GROOVY_VERSION=2.4.12"]
jdk:
  - openjdk8
  - openjdk9
jenkins:
  stash:
    - name: artifacts
      allow_empty: true
      includes: build/lib/*.jar
      matrix_axis:
        env: GROOVY_VERSION=2.4.12
        jdk: openjdk8
  collect:
    artifacts: build/lib/*.jar
'''.trim())
def pipeline_generator = new pipelineGenerator(generator)
pipeline_generator.supported_collections = ['artifacts']
pipeline_generator.getBuildableMatrixAxes().each { axis ->
    if(pipeline_generator.getStashMap(axis)) {
        println "stash ${axis}  --->  ${pipeline_generator.getStashMap(axis)}"
    }
}
println "Buildable matrices: " + pipeline_generator.getBuildableMatrixAxes().size()</tt></pre>
 */
class pipelineGenerator implements Serializable {

    /**
      A lifecycle generator which has already been instantiated and processed
      lifecycle, toolchains, and platforms JSON as well as Jervis YAML.
     */
    private def generator

    /**
      A set of collections which a global pipeline library might support.
      Examples of collections include: cobertura reports, artifacts, or junit
      tests.
     */
    Set<String> supported_collections

    /**
      A list of items to collect from the build.
     */
    private Map collect_items

    /**
      A list of stash maps collected from the Jervis YAML.
     */
    private List<Map> stashes

    /**
      Instantiates this class with a <tt>{@link lifecycleGenerator}</tt> which
      is used for helper functions when creating a pipeline job designed to
      support Jervis.
     */
    def pipelineGenerator(lifecycleGenerator generator) {
        this.generator = generator
        processCollectItems()
        def stashes = (getObjectValue(generator.jervis_yaml, 'jenkins.stash', []))?: getObjectValue(generator.jervis_yaml, 'jenkins.stash', [:])
        this.stashes = (stashes instanceof List)? stashes : [stashes]
        if(!generator.isMatrixBuild()) {
            //append the items to collect to the end of the list of stashes (overrides prior entries)
            this.stashes += this.collect_items.collect { k, v ->
                [name: k, includes: v]
            }
        }
    }

    /**
      Process each value from a Jenkins collect items map so that it supports multiple types.
     */
    private String processCollectValue(def v) {
		if(v in List) {
			v.join(',')
		}
		else if(v in Map) {
			processCollectValue((v['path'])?: '')
		}
		else {
			v
		}
    }

    /**
      Processes jenkins.collect items from Jervis YAML.
     */
    void processCollectItems() {
        this.collect_items = getObjectValue(generator.jervis_yaml, 'jenkins.collect', [:]).collect { k, v ->
            try {
                [(k): processCollectValue(v)]
            }
            catch(StackOverflowError e) {
                throw new PipelineGeneratorException("Infinite loop error in YAML key: jenkins.collect.${k}\n\nAre you using YAML anchors and aliases and accidentally circled a loop?")
            }
        }.sum()
    }

    /**
      Returns a list of maps which are buildable matrices in a matrix build.  This
      method takes into account that there are matrix exclusions and white lists in
      the YAML configuration.
     */
    List getBuildableMatrixAxes() {
        List matrix_axis_maps = generator.yaml_matrix_axes.collect { axis ->
            //the following map hack is so the key is not an instance of GStringImpl
            generator.matrixGetAxisValue(axis).split().collect {
                [(axis): it]
            }
        }
        if(generator.yaml_matrix_axes.size() < 2) {
            matrix_axis_maps = matrix_axis_maps[0]
        }
        else {
            //creates a list of lists which contain maps to be summed into one list of maps with every possible matrix combination
            //create a groovy cartesian product of the maps and then sum each list of maps together<commit_msg>Process non-matrix stashes in processCollectItems<commit_after>/*
   Copyright 2014-2017 <NAME> - https://github.com/samrocketman/jervis

   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 net.gleske.jervis.lang

import net.gleske.jervis.exceptions.PipelineGeneratorException
import static net.gleske.jervis.lang.lifecycleGenerator.getObjectValue

/**
  This class offers helper forunctions for using Jervis in the context of a
  Jenkins <a href="https://jenkins.io/doc/book/pipeline/shared-libraries/" target=_blank>pipeline global shared library</a>.

  <h2>Sample usage</h2>
  <p>To run this example, clone Jervis and execute <tt>./gradlew console</tt>
  to bring up a <a href="http://groovy-lang.org/groovyconsole.html" target="_blank">Groovy Console</a>
  with the classpath set up.</p>

<pre><tt>import net.gleske.jervis.lang.lifecycleGenerator
import net.gleske.jervis.lang.pipelineGenerator

def generator = new lifecycleGenerator()
generator.loadLifecyclesString(new File('resources/lifecycles-ubuntu1604-stable.json').text)
generator.loadToolchainsString(new File('resources/toolchains-ubuntu1604-stable.json').text)

generator.loadYamlString('''
language: groovy
env: ["GROOVY_VERSION=1.8.9", "GROOVY_VERSION=2.4.12"]
jdk:
  - openjdk8
  - openjdk9
jenkins:
  stash:
    - name: artifacts
      allow_empty: true
      includes: build/lib/*.jar
      matrix_axis:
        env: GROOVY_VERSION=2.4.12
        jdk: openjdk8
  collect:
    artifacts: build/lib/*.jar
'''.trim())
def pipeline_generator = new pipelineGenerator(generator)
pipeline_generator.supported_collections = ['artifacts']
pipeline_generator.getBuildableMatrixAxes().each { axis ->
    if(pipeline_generator.getStashMap(axis)) {
        println "stash ${axis}  --->  ${pipeline_generator.getStashMap(axis)}"
    }
}
println "Buildable matrices: " + pipeline_generator.getBuildableMatrixAxes().size()</tt></pre>
 */
class pipelineGenerator implements Serializable {

    /**
      A lifecycle generator which has already been instantiated and processed
      lifecycle, toolchains, and platforms JSON as well as Jervis YAML.
     */
    private def generator

    /**
      A set of collections which a global pipeline library might support.
      Examples of collections include: cobertura reports, artifacts, or junit
      tests.
     */
    Set<String> supported_collections

    /**
      A list of items to collect from the build.
     */
    private Map collect_items

    /**
      A list of stash maps collected from the Jervis YAML.
     */
    private List<Map> stashes

    /**
      Instantiates this class with a <tt>{@link lifecycleGenerator}</tt> which
      is used for helper functions when creating a pipeline job designed to
      support Jervis.
     */
    def pipelineGenerator(lifecycleGenerator generator) {
        this.generator = generator
        def stashes = (getObjectValue(generator.jervis_yaml, 'jenkins.stash', []))?: getObjectValue(generator.jervis_yaml, 'jenkins.stash', [:])
        this.stashes = (stashes instanceof List)? stashes : [stashes]
        processCollectItems()
    }

    /**
      Process each value from a Jenkins collect items map so that it supports multiple types.
     */
    private String processCollectValue(def v) {
		if(v in List) {
			v.join(',')
		}
		else if(v in Map) {
			processCollectValue((v['path'])?: '')
		}
		else {
			v
		}
    }

    /**
      Processes jenkins.collect items from Jervis YAML.
     */
    void processCollectItems() {
        this.collect_items = getObjectValue(generator.jervis_yaml, 'jenkins.collect', [:]).collect { k, v ->
            try {
                [(k): processCollectValue(v)]
            }
            catch(StackOverflowError e) {
                throw new PipelineGeneratorException("Infinite loop error in YAML key: jenkins.collect.${k}\n\nAre you using YAML anchors and aliases and accidentally circled a loop?")
            }
        }.sum()

        if(!generator.isMatrixBuild()) {
            //append the items to collect to the end of the list of stashes (overrides prior entries)
            this.stashes += this.collect_items.collect { k, v ->
                [name: k, includes: v]
            }
        }
    }

    /**
      Returns a list of maps which are buildable matrices in a matrix build.  This
      method takes into account that there are matrix exclusions and white lists in
      the YAML configuration.
     */
    List getBuildableMatrixAxes() {
        List matrix_axis_maps = generator.yaml_matrix_axes.collect { axis ->
            //the following map hack is so the key is not an instance of GStringImpl
            generator.matrixGetAxisValue(axis).split().collect {
                [(axis): it]
            }
        }
        if(generator.yaml_matrix_axes.size() < 2) {
            matrix_axis_maps = matrix_axis_maps[0]
        }
        else {
            //creates a list of lists which contain maps to be summed into one list of maps with every possible matrix combination
            //create a groovy cartesian product of the maps and then sum each list of maps together
{'fraction_non_alphanumeric': 0.09411028688890875, 'fraction_numerical': 0.006792385378496738, 'mean_word_length': 2.889468196037539, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 51, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5759815', 'n_tokens_mistral': 3289, 'n_tokens_neox': 3161, 'n_words': 993}