github.com/jaylevin/jenkins-library@v1.230.4/documentation/bin/resolveTransitiveCalls.groovy (about)

     1  import groovy.json.JsonSlurper
     2  
     3  def cli = new CliBuilder(
     4      usage: 'groovy createDocu [<options>]',
     5      header: 'Options:',
     6      footer: 'Copyright: SAP SE')
     7  
     8  cli.with {
     9      i longOpt: 'in', args: 1, argName: 'file', 'The file containing the mapping as created by the unit tests..'
    10      o longOpt: 'out', args: 1, argName: 'file', 'The file containing the condenced mappings.'
    11      h longOpt: 'help', 'Prints this help.'
    12  }
    13  
    14  def options = cli.parse(args)
    15  
    16  if(options.h) {
    17      System.err << "Printing help.\n"
    18      cli.usage()
    19      return
    20  }
    21  
    22  if(! options.i) {
    23      System.err << "No input file"
    24      cli.usage()
    25      return
    26  }
    27  if(! options.o) {
    28      System.err << "No output file"
    29      cli.usage()
    30      return
    31  }
    32  
    33  def steps = new JsonSlurper().parseText(new File(options.i).text)
    34  
    35  def piperSteps = steps.piperSteps
    36  def calls = steps.calls
    37  
    38  // only temporary in order to avoid manipulating the map during
    39  // iterating over it.
    40  def tmpCalls = [:]
    41  
    42  // Adjust naming
    43  calls.each { c ->
    44      tmpCalls.put(retrieveStepName(c.key), c.value as Set)
    45  }
    46  
    47  calls = tmpCalls
    48  tmpCalls = null
    49  
    50  // Remove selfs
    51  calls.each { c ->
    52      c.value.remove(c.key)
    53  }
    54  
    55  int counter=0
    56  
    57  def alreadyHandled = []
    58  
    59  //
    60  // in case we exceed the value we assume some cyclic call
    61  // between plugin steps.
    62  int MAX_LOOP = 1600
    63  
    64  boolean done = false
    65  
    66  while(counter < MAX_LOOP) {
    67  
    68      def hereWeNeedToReplace = null
    69      def toBeReplaced = null
    70  
    71      if(alreadyHandled.size() == calls.size()) {
    72          done = true
    73          break
    74      }
    75  
    76      for (def call in calls.entrySet()) {
    77  
    78          stepName = call.key
    79          calledSteps = call.value
    80  
    81          if(alreadyHandled.contains(stepName)) {
    82              continue
    83          }
    84  
    85          for (def calledStep in calledSteps) {
    86  
    87              if(! ( calledStep in Map)) {
    88  
    89                  // in case the calledStep is a map the map
    90                  // was introduced in an earlier loop.
    91                  // This means this entry is already handled.
    92  
    93                  if(calledStep in piperSteps) {
    94                      toBeReplaced = calledStep
    95                      hereWeNeedToReplace = calledSteps
    96                      break
    97                  }
    98              }
    99          }
   100          if(toBeReplaced) {
   101              def replacement = [:]
   102              replacement[toBeReplaced] = calls[toBeReplaced] as Set
   103              def removed = hereWeNeedToReplace.remove(toBeReplaced)
   104              hereWeNeedToReplace.add(replacement)
   105              counter++
   106          } else {
   107              alreadyHandled << stepName
   108          }
   109          break
   110      }
   111  }
   112  
   113  if(! done) {
   114      throw new Exception('Unable to resolve transitive plugin calls.')
   115  }
   116  
   117  piperStepCallMappings = [:]
   118  
   119  for(def entry : calls.entrySet()) {
   120      def performedCalls = flatten(entry, (Set)[])
   121      piperStepCallMappings.put(entry.key, performedCalls)
   122  }
   123  
   124  //
   125  // special handling since since changeManagement util class
   126  // is separated from the steps itself
   127  //
   128  // should be improved in the future in order not to have
   129  // that bells and whistles here.
   130  
   131  def cm = piperStepCallMappings.get('changeManagement')
   132  
   133  for (cmStepName in [
   134      'checkChangeInDevelopment',
   135      'transportRequestCreate',
   136      'transportRequestUploadFile',
   137      'transportRequestRelease',
   138  ]) {
   139      piperStepCallMappings.get(cmStepName).addAll(cm)
   140  }
   141  
   142  // end of special handling
   143  //
   144  
   145  File performedCalls = new File(options.o)
   146  if (performedCalls.exists()) performedCalls.delete()
   147  performedCalls << groovy.json.JsonOutput.toJson(piperStepCallMappings)
   148  
   149  def flatten(def entry, Set result) {
   150  
   151      for(def e : entry.value) {
   152          if(e in Map) { // the map here is expected to hold one entry always
   153              for(def steps : e.entrySet().value) {
   154                  for(def step : steps) {
   155                      if (step in Map) {
   156                          flatten(step, result)
   157                      } else {
   158                          result << step
   159                      }
   160                  }
   161              }
   162          } else {
   163              result << e.value.toString()
   164          }
   165      }
   166      result
   167  }
   168  
   169  static retrieveStepName(String s) {
   170      firstCharToLowerCase(removeTrailing(s, 'Test'))
   171  }
   172  
   173  static removeTrailing(String s, String trail) {
   174      return s.replaceAll(trail + '$', '')
   175  }
   176  
   177  static firstCharToLowerCase(CharSequence cs) {
   178      char[] c = cs.getChars()
   179      c[0] = Character.toLowerCase(c[0])
   180      new String(c)
   181  }