├── .gitignore ├── Jenkinsfile ├── LICENSE ├── README.md ├── pom.xml └── src ├── .DS_Store ├── main ├── .DS_Store ├── java │ ├── .DS_Store │ └── com │ │ ├── .DS_Store │ │ └── adq │ │ ├── .DS_Store │ │ └── jenkins │ │ └── xmljobtodsl │ │ ├── InitialArgumentsHandler.java │ │ ├── Main.java │ │ ├── dsl │ │ └── strategies │ │ │ ├── AbstractDSLStrategy.java │ │ │ ├── DSLArrayStrategy.java │ │ │ ├── DSLClosureStrategy.java │ │ │ ├── DSLConfigureBlockStrategy.java │ │ │ ├── DSLConstantStrategy.java │ │ │ ├── DSLInnerStrategy.java │ │ │ ├── DSLJobStrategy.java │ │ │ ├── DSLMethodStrategy.java │ │ │ ├── DSLObjectStrategy.java │ │ │ ├── DSLParameterStrategy.java │ │ │ ├── DSLPropertyStrategy.java │ │ │ ├── DSLStrategy.java │ │ │ ├── DSLStrategyFactory.java │ │ │ ├── IValueStrategy.java │ │ │ └── custom │ │ │ ├── DSLBlockOnStrategy.java │ │ │ ├── DSLBuildNameUpdaterStrategy.java │ │ │ ├── DSLChoiceParamStrategy.java │ │ │ ├── DSLChoiceTypeStrategy.java │ │ │ ├── DSLGitHubMethodStrategy.java │ │ │ ├── DSLHiddenTagStrategy.java │ │ │ ├── DSLMandatoryStringStrategy.java │ │ │ ├── DSLMethodIfTrueStrategy.java │ │ │ ├── DSLNonSupportedMethodDSL.java │ │ │ ├── DSLParamStrategy.java │ │ │ ├── DSLPropertyAsMethodParametersStrategy.java │ │ │ ├── DSLReferencedParameterStrategy.java │ │ │ ├── DSLRichTextPublisherStrategy.java │ │ │ ├── DSLStringAsArrayStrategy.java │ │ │ └── DSLStringAsMethodStrategy.java │ │ ├── jenkins │ │ ├── JobCollector.java │ │ └── JobSelectorView.java │ │ ├── parsers │ │ ├── DSLTranslator.java │ │ ├── DSLView.java │ │ ├── IDescriptor.java │ │ ├── JobDescriptor.java │ │ ├── PropertyDescriptor.java │ │ └── XmlParser.java │ │ └── utils │ │ ├── IOUtils.java │ │ └── Pair.java └── resources │ ├── com │ └── adq │ │ └── jenkins │ │ └── xmljobtodsl │ │ └── jenkins │ │ ├── JobSelectorView │ │ ├── config.properties │ │ ├── help-name.html │ │ └── index.jelly │ │ └── Messages.properties │ ├── index.jelly │ ├── syntax.properties │ └── translator.properties └── test ├── java └── com │ └── adq │ └── jenkins │ └── xmljobtodsl │ ├── DSLStrategiesTests.java │ ├── TestsConstants.java │ ├── TestsDSLView.java │ ├── TestsTranslator.java │ └── TestsXmlParser.java └── resources ├── android.groovy ├── android.xml ├── array.groovy ├── array.xml ├── config2.groovy ├── config2.xml ├── configure-block.groovy ├── configure-block.xml ├── description.groovy ├── description.xml ├── example-job.groovy ├── example-job.xml ├── example-multijob.groovy ├── example-multijob.xml ├── example-pipelinejob.groovy ├── example-pipelinejob.xml ├── example2.groovy ├── ios.groovy ├── ios.xml ├── object_parameter.groovy ├── object_parameter.xml ├── scm.groovy ├── scm.xml ├── scm2.groovy ├── scm2.xml └── view.groovy /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | 24 | # maven 25 | target 26 | target/* 27 | 28 | # intellij 29 | .idea 30 | .idea/* 31 | *.iml 32 | 33 | # SO 34 | .DS_Store 35 | 36 | # VSC 37 | .classpath 38 | .project 39 | .settings 40 | .settings/* 41 | 42 | # Jenkins 43 | work 44 | work/* 45 | 46 | # MVN 47 | pom.xml.releaseBackup 48 | release.properties 49 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | buildPlugin() 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XML job to Job DSL plugin 2 | A Jenkins plugin to convert XML jobs in scripts of Job DSL Plugin 3 | 4 | ## Steps 5 | 1. Read the XML file and parse to an internal class set (DONE) 6 | 2. Translate the internal class set to DSL and save it to file, it should be easy to read and easy to mantain (DONE) 7 | 3. Make this program run on command line and test if it works with some XML files (DONE) 8 | 4. Create a view where the user can select which jobs he wants to convert to DSL and generate a file to download (DONE) 9 | 5. Turn it into a Jenkins plugin (DONE) 10 | 6. Increase the number of known tags to translate and improve the plugin 11 | 7. Automatically refactor the generated code to avoid duplicated blocks 12 | 13 | ## Do you want to help? 14 | You can find the list of known tags in the file translator.properties under the path /src/main/resources 15 | 16 | The key (on left) represents the tag in XML, and the value is the tag in Job DSL: 17 | ``` 18 | flow-definition = pipelineJob 19 | ``` 20 | 21 | The key can also have a parent, separated by a dot ".": 22 | ``` 23 | //In this case, "project" is the parent, so this tag "description" will only be parsed if its parent is the tag "project" 24 | project.description = description 25 | 26 | //But in this case, "flow-definition" is the parent, so this tag "description" will only be parsed if its parent is the tag "flow-definition" 27 | flow-definition.description = description 28 | ``` 29 | 30 | The key yet can have a sufix ".type": 31 | ``` 32 | blockingJobs.type = PARAMETER 33 | ``` 34 | 35 | These are the possible types: 36 | * INNER 37 | * OBJECT 38 | * METHOD 39 | * PARAMETER 40 | * PROPERTY 41 | * ARRAY 42 | * CLOSURE 43 | * CONFIGURE 44 | 45 | Or a custom type, just pass a type the whole package of the class to render a custom type: 46 | ``` 47 | url.type = com.adq.jenkins.xmljobtodsl.dsl.strategies.custom.DSLGitHubMethodStrategy 48 | ``` 49 | 50 | Let's describe each type: 51 | 52 | ### INNER 53 | ``` 54 | hudson.tasks.Shell = INNER 55 | ``` 56 | 57 | The type can be the type of the tag, because it don't have a DSL tag, we will just render it children tags 58 | 59 | ### OBJECT 60 | It renders an object in groovy like: 61 | ``` 62 | remote { 63 | name("origin") 64 | github("SymphonyOSF/SANDROID-CLIENT-APP", "ssh") 65 | } 66 | ``` 67 | 68 | ### METHOD 69 | This is the default type, if you don't define a type, METHOD will be used. It render a method in groovy like: 70 | ``` 71 | description() 72 | ``` 73 | 74 | ### PARAMETER 75 | It renders a parameter if its parent is a method, It detects its type (String, integer, boolean, etc) 76 | ``` 77 | name("origin") //origin is the parameter 78 | ``` 79 | 80 | ### PROPERTY 81 | It renders a property like: 82 | ``` 83 | def git = { 84 | remote { 85 | name("origin") 86 | github("alandoni/xml-job-to-dsl-plugin", "ssh") 87 | } 88 | branch("*/\${branch}") 89 | } 90 | 91 | job("test") { 92 | scm git //this is a property 93 | } 94 | ``` 95 | 96 | ### ARRAY 97 | It defines an array of objects: 98 | ``` 99 | choiceParam("METAFILTER", ["all tests", "smoke tests", "sanity tests"], "") 100 | ``` 101 | 102 | ### CLOSURE 103 | It defines a closure: 104 | ``` 105 | trigger("") { // Closure 106 | block { // Object in the closure 107 | buildStepFailure("FAILURE") 108 | unstable("UNSTABLE") 109 | failure("FAILURE") 110 | } 111 | } 112 | ``` 113 | 114 | ### CONFIGURE 115 | Configure is used to represent tags not supported by Job DSL, its syntax is a bit different, and it is always inserted inside an object named "Configure", the job can only have one object configure 116 | 117 | ``` 118 | configure { 119 | it / 'properties' / 'jenkins.model.BuildDiscarderProperty' { // This is the tag of type CONFIGURE 120 | strategy { 121 | 'daysToKeep'('-1') 122 | 'numToKeep'('20') 123 | 'artifactDaysToKeep'('-1') 124 | 'artifactNumToKeep'('-1') 125 | } 126 | } 127 | it / 'properties' / 'com.coravy.hudson.plugins.github.GithubProjectProperty' { // This is the tag of type CONFIGURE 128 | 'projectUrl'('https://github.com/SymphonyOSF/SANDROID-CLIENT-APP/') 129 | 'displayName'() 130 | } 131 | } 132 | ``` 133 | 134 | ### Custom type 135 | To create a custom type, you will need to extend the class ```AbstractDSLStrategy``` 136 | 137 | It demands you to create a constructor: 138 | ``` 139 | /** 140 | * Creates an object of type DSLCustomStrategy 141 | * @param tabs: number of tabs for indentation purposes, it will be increased automatically 142 | * @param propertyDescriptor: the object that represents a class in XML, with its attributes, children, parent and values 143 | * @param name: the name in DSL Groovy 144 | */ 145 | public DSLCustomStrategy(int tabs, PropertyDescriptor propertyDescriptor, String name) { 146 | this(tabs, propertyDescriptor, name, true); // In case you need to change the children tags of this class 147 | // change the last parameter to false 148 | } 149 | ``` 150 | 151 | And override the following method: 152 | ``` 153 | @Override 154 | public String toDSL() { 155 | return ""; //This renders the text in the script 156 | } 157 | ``` 158 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | 7 | 8 | org.jenkins-ci.plugins 9 | plugin 10 | 2.7 11 | 12 | 13 | 14 | com.adq.jenkins 15 | xml-job-to-job-dsl 16 | 0.1.14-SNAPSHOT 17 | 18 | 19 | hpi 20 | 21 | 22 | 2.7.3 23 | 28 | 29 | 30 | 31 | true 32 | 33 | 34 | 35 | XML Job to Job DSL Plugin 36 | XML Job to Job DSL converts the selected job into Groovy Job DSL 37 | https://github.com/jenkinsci/xml-job-to-job-dsl-plugin 38 | 39 | 40 | 41 | MIT License 42 | http://opensource.org/licenses/MIT 43 | 44 | 45 | 46 | 47 | scm:git:http://github.com/jenkinsci/xml-job-to-dsl-plugin.git 48 | scm:git:http://github.com/jenkinsci/xml-job-to-dsl-plugin.git 49 | https://github.com/jenkinsci/xml-job-to-dsl-plugin 50 | xml-job-to-job-dsl-0.1.12 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.codehaus.mojo 58 | findbugs-maven-plugin 59 | 3.0.4 60 | 61 | 62 | org.apache.maven.plugins 63 | maven-compiler-plugin 64 | 3.1 65 | 66 | 1.7 67 | 1.7 68 | 69 | 70 | 71 | 72 | org.apache.maven.plugins 73 | maven-jar-plugin 74 | 3.0.2 75 | 76 | 77 | 78 | true 79 | lib/ 80 | com.adq.jenkins.xmljobtodsl.Main 81 | 82 | 83 | 84 | 85 | 86 | org.apache.maven.plugins 87 | maven-release-plugin 88 | 2.5.2 89 | 90 | 91 | org.apache.maven.scm 92 | maven-scm-provider-gitexe 93 | 1.9.2 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | junit 105 | junit 106 | 4.13.1 107 | test 108 | 109 | 110 | 111 | 112 | com.google.code.gson 113 | gson 114 | 2.8.9 115 | 116 | 117 | 118 | 119 | org.jenkins-ci.plugins 120 | structs 121 | 1.7 122 | 123 | 124 | org.jenkins-ci.plugins.workflow 125 | workflow-step-api 126 | 2.12 127 | test 128 | 129 | 130 | org.jenkins-ci.plugins.workflow 131 | workflow-cps 132 | 2.65 133 | test 134 | 135 | 136 | org.jenkins-ci.plugins.workflow 137 | workflow-job 138 | 2.11.2 139 | test 140 | 141 | 142 | org.jenkins-ci.plugins.workflow 143 | workflow-basic-steps 144 | 2.6 145 | test 146 | 147 | 148 | org.jenkins-ci.plugins.workflow 149 | workflow-durable-task-step 150 | 2.13 151 | test 152 | 153 | 154 | org.jenkins-ci.plugins.workflow 155 | workflow-api 156 | 2.20 157 | test 158 | 159 | 160 | org.jenkins-ci.plugins.workflow 161 | workflow-support 162 | 2.14 163 | test 164 | 165 | 166 | 167 | 168 | 169 | alandoni 170 | Alan Donizete Quintiliano 171 | alan_doni@hotmail.com 172 | 173 | 174 | 175 | 176 | 177 | repo.jenkins-ci.org 178 | https://repo.jenkins-ci.org/public/ 179 | 180 | 181 | 182 | 183 | repo.jenkins-ci.org 184 | https://repo.jenkins-ci.org/public/ 185 | 186 | 187 | -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/xml-job-to-job-dsl-plugin/2a8a96c78bf2ea870cffa2aac62258f7e18df58e/src/.DS_Store -------------------------------------------------------------------------------- /src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/xml-job-to-job-dsl-plugin/2a8a96c78bf2ea870cffa2aac62258f7e18df58e/src/main/.DS_Store -------------------------------------------------------------------------------- /src/main/java/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/xml-job-to-job-dsl-plugin/2a8a96c78bf2ea870cffa2aac62258f7e18df58e/src/main/java/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/xml-job-to-job-dsl-plugin/2a8a96c78bf2ea870cffa2aac62258f7e18df58e/src/main/java/com/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/adq/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkinsci/xml-job-to-job-dsl-plugin/2a8a96c78bf2ea870cffa2aac62258f7e18df58e/src/main/java/com/adq/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/InitialArgumentsHandler.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.DSLTranslator; 4 | import com.adq.jenkins.xmljobtodsl.parsers.JobDescriptor; 5 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 6 | import com.adq.jenkins.xmljobtodsl.parsers.XmlParser; 7 | import com.adq.jenkins.xmljobtodsl.utils.IOUtils; 8 | import org.xml.sax.SAXException; 9 | 10 | import javax.xml.parsers.ParserConfigurationException; 11 | import java.io.File; 12 | import java.io.IOException; 13 | import java.util.ArrayList; 14 | import java.util.HashMap; 15 | import java.util.List; 16 | import java.util.Map; 17 | import java.util.regex.Pattern; 18 | 19 | public class InitialArgumentsHandler { 20 | 21 | private String input; 22 | private String output; 23 | private InputType inputType; 24 | 25 | private String username; 26 | private String password; 27 | 28 | private List unknownTags; 29 | 30 | private enum InputType { 31 | WEB, FILE, DIRECTORY 32 | } 33 | 34 | public InitialArgumentsHandler(String[] args) { 35 | if (args.length == 0) { 36 | throw new RuntimeException("Missing arguments, initialize with at least --file or --url option"); 37 | } 38 | 39 | Map argsMap = new HashMap<>(); 40 | for (int i = 0; i < args.length; i++) { 41 | if (i % 2 == 0) { 42 | argsMap.put(args[i], args[i + 1]); 43 | } 44 | } 45 | 46 | if (argsMap.containsKey("--file") || argsMap.containsKey("-f")) { 47 | input = getValueForKeyOrAbbreviation(argsMap,"--file", "-f"); 48 | inputType = InputType.FILE; 49 | } 50 | if (argsMap.containsKey("--url") || argsMap.containsKey("-u")) { 51 | input = getValueForKeyOrAbbreviation(argsMap, "--url", "-u"); 52 | inputType = InputType.WEB; 53 | } 54 | if (argsMap.containsKey("--directory") || argsMap.containsKey("-d")) { 55 | input = getValueForKeyOrAbbreviation(argsMap, "--directory", "-d"); 56 | inputType = InputType.DIRECTORY; 57 | } 58 | if (argsMap.containsKey("--save-file") || argsMap.containsKey("-s")) { 59 | output = getValueForKeyOrAbbreviation(argsMap, "--save-file", "-s"); 60 | } 61 | if (argsMap.containsKey("--username") || argsMap.containsKey("-us")) { 62 | username = getValueForKeyOrAbbreviation(argsMap, "--username", "-us"); 63 | } 64 | if (argsMap.containsKey("--password") || argsMap.containsKey("-p")) { 65 | password = getValueForKeyOrAbbreviation(argsMap, "--password", "-p"); 66 | } 67 | } 68 | 69 | private String getValueForKeyOrAbbreviation(Map map, String key, String abbreviationKey) { 70 | if (map.containsKey(key)) { 71 | return map.get(key); 72 | } 73 | return map.get(abbreviationKey); 74 | } 75 | 76 | public void process() throws IOException, ParserConfigurationException, SAXException { 77 | String xml = null; 78 | String jobName = null; 79 | IOUtils ioUtils = new IOUtils(); 80 | 81 | JobDescriptor[] descriptors = null; 82 | 83 | if (inputType == InputType.FILE) { 84 | File file = new File(input); 85 | File[] files = new File[1]; 86 | files[0] = file; 87 | descriptors = getJobDescriptors(files); 88 | } 89 | 90 | if (inputType == InputType.WEB) { 91 | String[] segments = input.split("/"); 92 | jobName = segments[segments.length - 2]; 93 | xml = ioUtils.readFromUrl(input, username, password); 94 | JobDescriptor descriptor = new XmlParser(jobName, xml).parse(); 95 | 96 | descriptors = new JobDescriptor[1]; 97 | descriptors[0] = descriptor; 98 | } 99 | if (inputType == InputType.DIRECTORY) { 100 | File[] files = ioUtils.getJobXmlFilesInDirectory(input); 101 | descriptors = getJobDescriptors(files); 102 | } 103 | 104 | DSLTranslator translator = new DSLTranslator(descriptors); 105 | 106 | String dsl = translator.toDSL(); 107 | if (output != null) { 108 | ioUtils.saveToFile(dsl, output); 109 | } else { 110 | System.out.println(dsl); 111 | } 112 | unknownTags = translator.getNotTranslated(); 113 | System.out.println("\n\nWARNING:\nThe following tags couldn't be translated:"); 114 | for (PropertyDescriptor property : unknownTags) { 115 | System.out.println(String.format("* %s", property.getName())); 116 | } 117 | } 118 | 119 | public static String getJobNameBasedOnPath(File file) { 120 | String pattern = File.separator; 121 | String[] segments = file.getAbsolutePath().split(Pattern.quote(pattern)); 122 | return segments[segments.length - 2]; 123 | } 124 | 125 | private JobDescriptor[] getJobDescriptors(File[] files) 126 | throws IOException, ParserConfigurationException, SAXException { 127 | IOUtils ioUtils = new IOUtils(); 128 | 129 | List descriptors = new ArrayList<>(); 130 | 131 | for (File file : files) { 132 | String jobName = getJobNameBasedOnPath(file); 133 | String xml = ioUtils.readFromFile(file); 134 | JobDescriptor descriptor = new XmlParser(jobName, xml).parse(); 135 | descriptors.add(descriptor); 136 | } 137 | return descriptors.toArray(new JobDescriptor[descriptors.size()]); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/Main.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl; 2 | 3 | import org.xml.sax.SAXException; 4 | 5 | import javax.xml.parsers.ParserConfigurationException; 6 | import java.io.IOException; 7 | 8 | /** 9 | * Created by alanquintiliano on 20/12/17. 10 | */ 11 | public class Main { 12 | 13 | public static void main(String args[]) { 14 | try { 15 | new InitialArgumentsHandler(args).process(); 16 | } catch (IOException e) { 17 | System.out.println("Couldn't find file"); 18 | e.printStackTrace(); 19 | } catch (ParserConfigurationException | SAXException e) { 20 | System.out.println("Couldn't parse XML file"); 21 | e.printStackTrace(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/AbstractDSLStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.IDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 5 | import com.adq.jenkins.xmljobtodsl.utils.Pair; 6 | 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.util.*; 10 | import java.util.regex.Matcher; 11 | import java.util.regex.Pattern; 12 | 13 | public abstract class AbstractDSLStrategy implements DSLStrategy { 14 | 15 | public static final String SUFIX_GROOVY_TYPE = ".type"; 16 | 17 | private Properties syntaxProperties; 18 | private Properties translatorProperties; 19 | 20 | private List children = new ArrayList<>(); 21 | 22 | private int tabs = 0; 23 | 24 | private List notTranslatedList = new ArrayList<>(); 25 | private IDescriptor propertyDescriptor; 26 | 27 | public AbstractDSLStrategy(IDescriptor descriptor) { 28 | this(0, descriptor, true); 29 | } 30 | 31 | public AbstractDSLStrategy(int tabs, IDescriptor descriptor) { 32 | this(tabs, descriptor, true); 33 | } 34 | 35 | public AbstractDSLStrategy(int tabs, IDescriptor descriptor, boolean shouldInitChildren) { 36 | this.tabs = tabs; 37 | this.propertyDescriptor = descriptor; 38 | try { 39 | initProperties(); 40 | } catch (IOException e) { 41 | e.printStackTrace(); 42 | } 43 | if (shouldInitChildren) { 44 | initChildren(descriptor); 45 | } 46 | } 47 | 48 | private void initProperties() throws IOException { 49 | InputStream in = getClass().getClassLoader().getResourceAsStream("syntax.properties"); 50 | syntaxProperties = new Properties(); 51 | syntaxProperties.load(in); 52 | 53 | in = getClass().getClassLoader().getResourceAsStream("translator.properties"); 54 | translatorProperties = new Properties(); 55 | translatorProperties.load(in); 56 | } 57 | 58 | public String getType(PropertyDescriptor propertyDescriptor) { 59 | Pair property = getProperty(propertyDescriptor); 60 | 61 | if (property.getValue() == null) { 62 | return null; 63 | } 64 | 65 | if (DSLStrategyFactory.TYPE_INNER.equals(property.getValue())) { 66 | return DSLStrategyFactory.TYPE_INNER; 67 | } 68 | 69 | String type = String.format("%s%s", property.getKey(), SUFIX_GROOVY_TYPE); 70 | String propertyType = translatorProperties.getProperty(type); 71 | 72 | if (propertyType == null) { 73 | propertyType = DSLStrategyFactory.TYPE_METHOD; 74 | } 75 | return propertyType; 76 | } 77 | 78 | protected Pair getProperty(PropertyDescriptor propertyDescriptor) { 79 | if (propertyDescriptor.getParent() != null) { 80 | Pair property = getPropertyByItsParentName(propertyDescriptor.getParent(), propertyDescriptor.getName()); 81 | if (property != null && property.getValue() != null) { 82 | return property; 83 | } 84 | } 85 | 86 | String key = propertyDescriptor.getName(); 87 | String property = translatorProperties.getProperty(key); 88 | return new Pair(key, property); 89 | } 90 | 91 | protected Pair getPropertyByItsParentName(PropertyDescriptor parent, String concatenedParents) { 92 | String key = String.format("%s.%s", parent.getName(), concatenedParents); 93 | Pair pair = null; 94 | if (parent.getParent() != null) { 95 | pair = getPropertyByItsParentName(parent.getParent(), key); 96 | } 97 | if (pair != null && pair.getValue() != null) { 98 | return pair; 99 | } 100 | String property = translatorProperties.getProperty(key); 101 | return new Pair(key, property); 102 | } 103 | 104 | protected String getPropertyByName(String name) { 105 | return translatorProperties.getProperty(name); 106 | } 107 | 108 | public DSLStrategy getStrategyByPropertyDescriptorType(PropertyDescriptor propertyDescriptor) { 109 | String type = getType(propertyDescriptor); 110 | 111 | if (type == null) { 112 | notTranslatedList.add(propertyDescriptor); 113 | return null; 114 | } 115 | 116 | String property = getProperty(propertyDescriptor).getValue(); 117 | return new DSLStrategyFactory().getDSLStrategy(type, propertyDescriptor, property, getTabs() + 1); 118 | } 119 | 120 | protected String getSyntax(String key) { 121 | return syntaxProperties.getProperty(key); 122 | } 123 | 124 | @Override 125 | public List getChildren() { 126 | return children; 127 | } 128 | 129 | @Override 130 | public void addChild(DSLStrategy strategy) { 131 | children.add(strategy); 132 | } 133 | 134 | protected void initChildren(IDescriptor descriptor) { 135 | if (descriptor == null || descriptor.getProperties() == null) { 136 | return; 137 | } 138 | children.clear(); 139 | List properties = descriptor.getProperties(); 140 | Iterator iterator = properties.iterator(); 141 | 142 | while (iterator.hasNext()) { 143 | PropertyDescriptor propertyDescriptor = iterator.next(); 144 | DSLStrategy strategy = getStrategyByPropertyDescriptorType(propertyDescriptor); 145 | if (strategy != null) { 146 | addChild(strategy); 147 | notTranslatedList.addAll(strategy.getNotTranslatedList()); 148 | } 149 | } 150 | } 151 | 152 | protected List getChildrenOfType(PropertyDescriptor parent, String type) { 153 | List selectedPropertyDescription = new ArrayList<>(); 154 | for (PropertyDescriptor propertyDescriptor : parent.getProperties()) { 155 | if (type.equals(getType(propertyDescriptor))) { 156 | selectedPropertyDescription.add(propertyDescriptor); 157 | } 158 | } 159 | return selectedPropertyDescription; 160 | } 161 | 162 | protected String getChildrenDSL() { 163 | StringBuilder dsl = new StringBuilder(); 164 | for (DSLStrategy strategy : getChildren()) { 165 | String strategyDsl = strategy.toDSL(); 166 | dsl.append(strategyDsl); 167 | } 168 | return dsl.toString(); 169 | } 170 | 171 | protected String replaceTabs(String dsl, int tabs) { 172 | return dsl.replaceAll("", getTabsString(tabs)); 173 | } 174 | 175 | public String printValueAccordingOfItsType(String value) { 176 | if (value == null) { 177 | return "\"\""; 178 | } 179 | if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) { 180 | return value; 181 | } 182 | if (value.matches("[0-9.]+") && countChar('.', value) < 2) { 183 | return value; 184 | } 185 | if (value.isEmpty()) { 186 | return "\"\""; 187 | } 188 | 189 | value = value.replaceAll("\\\\", "\\\\\\\\"); 190 | value = value.replaceAll("\\$", Matcher.quoteReplacement("\\$")); 191 | 192 | if (value.contains("\n")) { 193 | value = value.replaceAll(Pattern.quote("\"\"\""), Matcher.quoteReplacement("\\\"\\\"\\\"")); 194 | return "\"\"\"" + value + "\"\"\""; 195 | } else { 196 | value = value.replaceAll(Pattern.quote("\""), Matcher.quoteReplacement("\\\"")); 197 | } 198 | return "\"" + value + "\""; 199 | } 200 | 201 | private int countChar(char lookAt, String str) { 202 | int count = 0; 203 | for (char chr : str.toCharArray()) { 204 | if (chr == lookAt) { 205 | count++; 206 | } 207 | } 208 | return count; 209 | } 210 | 211 | @Override 212 | public int getTabs() { 213 | return tabs; 214 | } 215 | 216 | public void setTabs(int tabs) { 217 | this.tabs = tabs; 218 | } 219 | 220 | public String getTabsString(int tabs) { 221 | StringBuilder builder = new StringBuilder(); 222 | for (int i = 0; i < tabs; i++) { 223 | builder.append(syntaxProperties.getProperty("syntax.tab")); 224 | } 225 | return builder.toString(); 226 | } 227 | 228 | public List getNotTranslatedList() { 229 | return notTranslatedList; 230 | } 231 | 232 | public void setDescriptor(IDescriptor propertyDescriptor) { 233 | this.propertyDescriptor = propertyDescriptor; 234 | } 235 | 236 | public IDescriptor getDescriptor() { 237 | return propertyDescriptor; 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/DSLArrayStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | 5 | public class DSLArrayStrategy extends DSLMethodStrategy implements IValueStrategy { 6 | 7 | public DSLArrayStrategy(PropertyDescriptor descriptor) { 8 | super(descriptor); 9 | } 10 | 11 | @Override 12 | public String toDSL() { 13 | return String.format(getSyntax("syntax.array"), getChildrenDSL()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/DSLClosureStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | 5 | public class DSLClosureStrategy extends AbstractDSLStrategy { 6 | 7 | private String name; 8 | private String parameter; 9 | 10 | public DSLClosureStrategy(int tabs, PropertyDescriptor propertyDescriptor, String name) { 11 | super(tabs, propertyDescriptor, false); 12 | this.name = name; 13 | parameter = propertyDescriptor.getProperties().get(0).getValue(); 14 | propertyDescriptor.getProperties().remove(0); 15 | initChildren(propertyDescriptor); 16 | } 17 | 18 | @Override 19 | public String toDSL() { 20 | return replaceTabs(String.format(getSyntax("syntax.method_call_closure"), 21 | name, printValueAccordingOfItsType(parameter), getChildrenDSL()), getTabs()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/DSLConfigureBlockStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | 5 | public class DSLConfigureBlockStrategy extends AbstractDSLStrategy { 6 | 7 | private final String name; 8 | 9 | public DSLConfigureBlockStrategy(int tabs, PropertyDescriptor descriptor, String name) { 10 | super(tabs, descriptor); 11 | 12 | this.name = name; 13 | } 14 | 15 | @Override 16 | public String toDSL() { 17 | return replaceTabs(String.format(getSyntax("syntax.object_with_name"), name, getChildrenDSL()), getTabs()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/DSLConstantStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | 5 | public class DSLConstantStrategy extends AbstractDSLStrategy { 6 | 7 | private final String name; 8 | 9 | public DSLConstantStrategy(PropertyDescriptor propertyDescriptor, String name) { 10 | super(propertyDescriptor); 11 | this.name = name; 12 | } 13 | 14 | @Override 15 | public String toDSL() { 16 | return String.format(getSyntax("syntax.string_variable"), 17 | name, printValueAccordingOfItsType(((PropertyDescriptor) getDescriptor()).getValue())); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/DSLInnerStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | 5 | public class DSLInnerStrategy extends AbstractDSLStrategy { 6 | 7 | public DSLInnerStrategy(int tabs, PropertyDescriptor propertyDescriptor) { 8 | super(tabs, propertyDescriptor); 9 | } 10 | 11 | @Override 12 | public String toDSL() { 13 | return getChildrenDSL(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/DSLJobStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.JobDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Iterator; 8 | import java.util.List; 9 | 10 | public class DSLJobStrategy extends AbstractDSLStrategy { 11 | 12 | public DSLJobStrategy(JobDescriptor jobDescriptor) { 13 | super(0, jobDescriptor, false); 14 | 15 | checkNeedsBlockAndCreateIt(jobDescriptor, "configure", DSLStrategyFactory.TYPE_CONFIGURE); 16 | initChildren(jobDescriptor); 17 | } 18 | 19 | private void checkNeedsBlockAndCreateIt(JobDescriptor jobDescriptor, String blockName, String blockType) { 20 | List configureBlocks = findConfigureBlockStrategyProperty(jobDescriptor.getProperties(), blockType); 21 | if (configureBlocks.size() > 0) { 22 | PropertyDescriptor configureBlockProperty = new PropertyDescriptor(blockName, null, configureBlocks); 23 | jobDescriptor.getProperties().add(configureBlockProperty); 24 | } 25 | } 26 | 27 | private List findConfigureBlockStrategyProperty(List properties, String blockType) { 28 | List configureBlocksList = new ArrayList<>(); 29 | Iterator iterator = properties.iterator(); 30 | while (iterator.hasNext()) { 31 | PropertyDescriptor descriptor = iterator.next(); 32 | String type = getType(descriptor); 33 | if (blockType.equals(type)) { 34 | configureBlocksList.add(descriptor); 35 | iterator.remove(); 36 | } 37 | if (descriptor.getProperties() != null && descriptor.getProperties().size() > 0) { 38 | configureBlocksList.addAll(findConfigureBlockStrategyProperty(descriptor.getProperties(), blockType)); 39 | } 40 | } 41 | 42 | return configureBlocksList; 43 | } 44 | 45 | @Override 46 | public String toDSL() { 47 | return String.format(getSyntax("syntax.job"), 48 | getProperty(getDescriptor().getProperties().get(0)).getValue(), 49 | getDescriptor().getName(), getChildrenDSL()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/DSLMethodStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class DSLMethodStrategy extends AbstractDSLStrategy { 9 | 10 | private final String methodName; 11 | 12 | public DSLMethodStrategy(int tabs, PropertyDescriptor propertyDescriptor, String methodName, boolean shouldInitChildren) { 13 | super(tabs, propertyDescriptor, shouldInitChildren); 14 | this.methodName = methodName; 15 | this.setTabs(tabs); 16 | } 17 | 18 | public DSLMethodStrategy(int tabs, PropertyDescriptor propertyDescriptor, String methodName) { 19 | this(tabs, propertyDescriptor, methodName, true); 20 | } 21 | 22 | public DSLMethodStrategy(PropertyDescriptor descriptor) { 23 | this(0, descriptor, null, true); 24 | } 25 | 26 | @Override 27 | public String toDSL() { 28 | PropertyDescriptor propertyDescriptor = (PropertyDescriptor) getDescriptor(); 29 | if (propertyDescriptor.getValue() != null) { 30 | 31 | boolean isParentAMethod = propertyDescriptor.getParent() != null && 32 | getType(propertyDescriptor.getParent()).equals(DSLStrategyFactory.TYPE_METHOD); 33 | 34 | if (isParentAMethod) { 35 | return getStrategyForObject(propertyDescriptor).toDSL(); 36 | } 37 | 38 | return replaceTabs(String.format(getSyntax("syntax.method_call"), 39 | methodName, printValueAccordingOfItsType(propertyDescriptor.getValue())), getTabs()); 40 | } 41 | 42 | return replaceTabs(String.format(getSyntax("syntax.method_call"), 43 | methodName, getChildrenDSL()), getTabs()); 44 | } 45 | 46 | private DSLStrategy getStrategyForObject(PropertyDescriptor propertyDescriptor) { 47 | List siblings = getChildrenOfType(propertyDescriptor.getParent(), DSLStrategyFactory.TYPE_METHOD); 48 | 49 | propertyDescriptor.getParent().getProperties().clear(); 50 | 51 | List children = new ArrayList<>(); 52 | for (PropertyDescriptor descriptor : siblings) { 53 | children.add(new PropertyDescriptor(descriptor.getName(), null, 54 | descriptor.getValue(), descriptor.getProperties(), 55 | descriptor.getAttributes())); 56 | } 57 | PropertyDescriptor object = new PropertyDescriptor(null, null, children); 58 | return new DSLObjectStrategy(getTabs(), object, null); 59 | } 60 | 61 | @Override 62 | protected String getChildrenDSL() { 63 | StringBuilder dsl = new StringBuilder(); 64 | 65 | int size = getChildren().size(); 66 | 67 | for (int index = 0; index < size; index++) { 68 | DSLStrategy strategy = getChildren().get(index); 69 | String strategyDsl = strategy.toDSL(); 70 | dsl.append(strategyDsl); 71 | if (index < size - 1 && (strategy instanceof IValueStrategy)) { 72 | dsl.append(", "); 73 | } 74 | } 75 | return dsl.toString(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/DSLObjectStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | 5 | public class DSLObjectStrategy extends AbstractDSLStrategy { 6 | 7 | private final String name; 8 | 9 | public DSLObjectStrategy(int tabs, PropertyDescriptor propertyDescriptor, String name) { 10 | this(tabs, propertyDescriptor, name, true); 11 | } 12 | 13 | public DSLObjectStrategy(int tabs, PropertyDescriptor propertyDescriptor, String name, boolean shouldInitChildren) { 14 | super(tabs, propertyDescriptor, shouldInitChildren); 15 | this.name = name; 16 | } 17 | 18 | @Override 19 | public String toDSL() { 20 | String childrenDSL = getChildrenDSL(); 21 | if (childrenDSL.isEmpty()) { 22 | return ""; 23 | } 24 | 25 | if (name != null) { 26 | return replaceTabs(String.format(getSyntax("syntax.object_with_name"), name, childrenDSL), getTabs()); 27 | } else { 28 | return replaceTabs(String.format(getSyntax("syntax.object"), childrenDSL), getTabs()); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/DSLParameterStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | 5 | public class DSLParameterStrategy extends AbstractDSLStrategy implements IValueStrategy { 6 | 7 | public DSLParameterStrategy(PropertyDescriptor propertyDescriptor) { 8 | super(propertyDescriptor); 9 | } 10 | 11 | @Override 12 | public String toDSL() { 13 | return printValueAccordingOfItsType(((PropertyDescriptor) getDescriptor()).getValue()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/DSLPropertyStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | 5 | public class DSLPropertyStrategy extends AbstractDSLStrategy { 6 | 7 | private String property; 8 | 9 | public DSLPropertyStrategy(int tabs, PropertyDescriptor propertyDescriptor, String property) { 10 | super(tabs, propertyDescriptor); 11 | this.property = property; 12 | } 13 | 14 | @Override 15 | public String toDSL() { 16 | return replaceTabs(String.format(getSyntax("syntax.property"), property, 17 | getChildrenDSL()), getTabs()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/DSLStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.IDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 5 | 6 | import java.util.List; 7 | 8 | public interface DSLStrategy { 9 | 10 | List getChildren(); 11 | 12 | void addChild(DSLStrategy strategy); 13 | 14 | String toDSL(); 15 | 16 | int getTabs(); 17 | 18 | void setTabs(int tabs); 19 | 20 | List getNotTranslatedList(); 21 | 22 | IDescriptor getDescriptor(); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/DSLStrategyFactory.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | 5 | import java.lang.reflect.Constructor; 6 | 7 | public class DSLStrategyFactory { 8 | 9 | public static final String TYPE_CONST = "CONST"; 10 | public static final String TYPE_INNER = "INNER"; 11 | public static final String TYPE_OBJECT = "OBJECT"; 12 | public static final String TYPE_METHOD = "METHOD"; 13 | public static final String TYPE_PARAMETER = "PARAMETER"; 14 | public static final String TYPE_PROPERTY = "PROPERTY"; 15 | public static final String TYPE_ARRAY = "ARRAY"; 16 | public static final String TYPE_CLOSURE = "CLOSURE"; 17 | public static final String TYPE_CONFIGURE = "CONFIGURE"; 18 | 19 | public DSLStrategy getDSLStrategy(String type, PropertyDescriptor propertyDescriptor, String property, int tabs) { 20 | switch (type) { 21 | case TYPE_INNER: 22 | return new DSLInnerStrategy(tabs - 1, propertyDescriptor); 23 | case TYPE_CONST: 24 | return new DSLConstantStrategy(propertyDescriptor, property); 25 | case TYPE_OBJECT: 26 | return new DSLObjectStrategy(tabs, propertyDescriptor, property); 27 | case TYPE_PARAMETER: 28 | return new DSLParameterStrategy(propertyDescriptor); 29 | case TYPE_PROPERTY: 30 | return new DSLPropertyStrategy(tabs, propertyDescriptor, property); 31 | case TYPE_ARRAY: 32 | return new DSLArrayStrategy(propertyDescriptor); 33 | case TYPE_METHOD: 34 | return new DSLMethodStrategy(tabs, propertyDescriptor, property); 35 | case TYPE_CLOSURE: 36 | return new DSLClosureStrategy(tabs, propertyDescriptor, property); 37 | case TYPE_CONFIGURE: 38 | return new DSLConfigureBlockStrategy(tabs, propertyDescriptor, property); 39 | default: 40 | try { 41 | Class clazz = Class.forName(type); 42 | Constructor constructor = clazz.getConstructor(int.class, PropertyDescriptor.class, String.class); 43 | return (DSLStrategy) constructor.newInstance(tabs, propertyDescriptor, property); 44 | } catch (ReflectiveOperationException e) { 45 | e.printStackTrace(); 46 | return null; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/IValueStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies; 2 | 3 | public interface IValueStrategy { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLBlockOnStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLMethodStrategy; 4 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 5 | 6 | public class DSLBlockOnStrategy extends DSLMethodStrategy { 7 | 8 | private final String name; 9 | 10 | public DSLBlockOnStrategy(int tabs, PropertyDescriptor propertyDescriptor, String name) { 11 | super(tabs, propertyDescriptor, name); 12 | this.name = name; 13 | } 14 | 15 | @Override 16 | public String toDSL() { 17 | PropertyDescriptor useBuildBlockerDescriptor = getPropertyByItsName("useBuildBlocker"); 18 | if (!Boolean.parseBoolean(useBuildBlockerDescriptor.getValue())) { 19 | return ""; 20 | } 21 | 22 | PropertyDescriptor blockingJobs = getPropertyByItsName("blockingJobs"); 23 | String parameters = String.format(getSyntax("syntax.method_param"), 24 | printValueAccordingOfItsType(blockingJobs.getValue())); 25 | 26 | PropertyDescriptor blockLevelDescriptor = getPropertyByItsName("blockLevel"); 27 | String innerMethods = String.format(getSyntax("syntax.method_call"), 28 | getProperty(blockLevelDescriptor).getValue(), 29 | printValueAccordingOfItsType(blockLevelDescriptor.getValue())); 30 | 31 | PropertyDescriptor descriptorOfThirdItem = getPropertyByItsName("scanQueueFor"); 32 | innerMethods += String.format(getSyntax("syntax.method_call"), 33 | getProperty(descriptorOfThirdItem).getValue(), 34 | printValueAccordingOfItsType(descriptorOfThirdItem.getValue())); 35 | 36 | innerMethods = replaceTabs(innerMethods, getTabs() + 1); 37 | parameters += String.format(getSyntax("syntax.object"), innerMethods); 38 | return replaceTabs(String.format(getSyntax("syntax.method_call"), name, parameters), getTabs()); 39 | } 40 | 41 | private PropertyDescriptor getPropertyByItsName(String name) { 42 | for (PropertyDescriptor descriptor : getDescriptor().getProperties()){ 43 | String propertyName = getPropertyByName(name); 44 | if (descriptor.getName().equals(propertyName)) { 45 | return descriptor; 46 | } 47 | } 48 | throw new RuntimeException(String.format("Couldn't find any descriptor with name: %s", name)); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLBuildNameUpdaterStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLObjectStrategy; 5 | 6 | public class DSLBuildNameUpdaterStrategy extends DSLObjectStrategy { 7 | 8 | public DSLBuildNameUpdaterStrategy(int tabs, PropertyDescriptor propertyDescriptor, String name) { 9 | super(tabs, propertyDescriptor, name, false); 10 | 11 | PropertyDescriptor buildName = new PropertyDescriptor("buildName", propertyDescriptor); 12 | propertyDescriptor.getProperties().add(0, buildName); 13 | initChildren(propertyDescriptor); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLChoiceParamStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLMethodStrategy; 5 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLStrategy; 6 | 7 | public class DSLChoiceParamStrategy extends DSLMethodStrategy { 8 | 9 | private final String methodName; 10 | 11 | public DSLChoiceParamStrategy(int tabs, PropertyDescriptor propertyDescriptor, String methodName) { 12 | super(tabs, propertyDescriptor, methodName); 13 | this.methodName = methodName; 14 | } 15 | 16 | @Override 17 | public String toDSL() { 18 | return replaceTabs(String.format(getSyntax("syntax.method_call"), 19 | methodName, getOrderedChildrenDSL()), getTabs()); 20 | } 21 | 22 | public String getOrderedChildrenDSL() { 23 | String choices = getChildrenByName("choices").toDSL(); 24 | String name = getChildrenByName("name").toDSL(); 25 | String description = getChildrenByName("description").toDSL(); 26 | return name + ", " + choices + ", " + description; 27 | } 28 | 29 | private DSLStrategy getChildrenByName(String name) { 30 | for (DSLStrategy strategy : getChildren()) { 31 | if (strategy.getDescriptor().getName().equals(name)) { 32 | return strategy; 33 | } 34 | } 35 | throw new RuntimeException(String.format("Child with name: %s not found", name)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLChoiceTypeStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLMethodStrategy; 5 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLStrategy; 6 | 7 | import hudson.model.listeners.ItemListener; 8 | import java.util.logging.Level; 9 | import java.util.logging.Logger; 10 | 11 | public class DSLChoiceTypeStrategy extends DSLMethodStrategy { 12 | 13 | private final String methodName; 14 | 15 | public DSLChoiceTypeStrategy(int tabs, PropertyDescriptor propertyDescriptor, String methodName) { 16 | super(tabs, propertyDescriptor, methodName); 17 | this.methodName = methodName; 18 | } 19 | 20 | @Override 21 | public String toDSL() { 22 | 23 | // convert XML choiceType to jobDSL required choiceType 24 | 25 | PropertyDescriptor propertyDescriptor = (PropertyDescriptor) getDescriptor(); 26 | String choiceType = propertyDescriptor.getValue(); 27 | 28 | String fixedChoiceType = printValueAccordingOfItsType(choiceType.substring(choiceType.indexOf("_") + 1)); 29 | 30 | return replaceTabs(String.format(getSyntax("syntax.method_call"), methodName, fixedChoiceType), getTabs()); 31 | } 32 | 33 | private static final Logger LOGGER = Logger.getLogger(DSLChoiceTypeStrategy.class.getName()); 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLGitHubMethodStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLMethodStrategy; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | public class DSLGitHubMethodStrategy extends DSLMethodStrategy { 12 | 13 | private static final Pattern pattern = Pattern.compile("(?:github\\.com\\/?:?)\\/?([a-zA-Z0-9\\-_]+\\/[a-zA-Z0-9\\-_]+)"); 14 | 15 | public DSLGitHubMethodStrategy(int tabs, PropertyDescriptor propertyDescriptor, String methodName) { 16 | super(tabs, null, methodName, false); 17 | 18 | List list = new ArrayList<>(); 19 | PropertyDescriptor newPropertyDescriptor = new PropertyDescriptor("url", propertyDescriptor.getParent(), list); 20 | 21 | String url = removeSpaces(propertyDescriptor.getValue()); 22 | String method = getMethod(url); 23 | String repository = getRepositoryInformationFromUrl(url); 24 | 25 | PropertyDescriptor urlProperty = new PropertyDescriptor("github.url", newPropertyDescriptor, repository); 26 | list.add(urlProperty); 27 | 28 | PropertyDescriptor methodProperty = new PropertyDescriptor("method", newPropertyDescriptor, method); 29 | list.add(methodProperty); 30 | 31 | setDescriptor(newPropertyDescriptor); 32 | initChildren(newPropertyDescriptor); 33 | } 34 | 35 | public String getRepositoryInformationFromUrl(String url) { 36 | Matcher matcher = pattern.matcher(url); 37 | String repoInfo = url; 38 | if (matcher.find()) { 39 | repoInfo = matcher.group(1); 40 | } 41 | return repoInfo; 42 | } 43 | 44 | private String getMethod(String url) { 45 | if (url.startsWith("https")) { 46 | return "https"; 47 | } 48 | if (url.startsWith("git@") || url.startsWith("ssh")) { 49 | return "ssh"; 50 | } 51 | return ""; 52 | } 53 | 54 | private String removeSpaces(String url) { 55 | return url.replaceAll("\\t", "").replaceAll("\\n", "").trim(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLHiddenTagStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLObjectStrategy; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class DSLHiddenTagStrategy extends DSLObjectStrategy { 10 | 11 | public DSLHiddenTagStrategy(int tabs, PropertyDescriptor propertyDescriptor, String name) { 12 | super(tabs, propertyDescriptor, name, false); 13 | 14 | List children = propertyDescriptor.getProperties(); 15 | 16 | PropertyDescriptor child = new PropertyDescriptor( 17 | getPropertyByName(String.format("%s.hidden_tag", propertyDescriptor.getName())), 18 | propertyDescriptor, children); 19 | List directChildren = new ArrayList<>(); 20 | directChildren.add(child); 21 | 22 | PropertyDescriptor newPropertyDescriptor = new PropertyDescriptor(propertyDescriptor.getName(), propertyDescriptor.getParent(), 23 | directChildren, propertyDescriptor.getAttributes()); 24 | 25 | initChildren(newPropertyDescriptor); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLMandatoryStringStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLMethodStrategy; 5 | 6 | public class DSLMandatoryStringStrategy extends DSLMethodStrategy { 7 | 8 | private final String methodName; 9 | 10 | public DSLMandatoryStringStrategy(int tabs, PropertyDescriptor propertyDescriptor, String methodName) { 11 | super(tabs, propertyDescriptor, methodName); 12 | this.methodName = methodName; 13 | } 14 | 15 | @Override 16 | public String toDSL() { 17 | PropertyDescriptor descriptor = (PropertyDescriptor) getDescriptor(); 18 | String value = descriptor.getValue(); 19 | if (value == null || value.trim().equals("")) { 20 | return replaceTabs(String.format(getSyntax("syntax.method_call"), 21 | methodName, "\"\""), getTabs()); 22 | } 23 | return super.toDSL(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLMethodIfTrueStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.AbstractDSLStrategy; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLObjectStrategy; 5 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLStrategy; 6 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLStrategyFactory; 7 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.IValueStrategy; 8 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class DSLMethodIfTrueStrategy extends AbstractDSLStrategy { 14 | 15 | private final String methodName; 16 | 17 | public DSLMethodIfTrueStrategy(int tabs, PropertyDescriptor propertyDescriptor, String methodName, boolean shouldInitChildren) { 18 | super(tabs, propertyDescriptor, shouldInitChildren); 19 | this.methodName = methodName; 20 | this.setTabs(tabs); 21 | } 22 | 23 | public DSLMethodIfTrueStrategy(int tabs, PropertyDescriptor propertyDescriptor, String methodName) { 24 | this(tabs, propertyDescriptor, methodName, true); 25 | } 26 | 27 | public DSLMethodIfTrueStrategy(PropertyDescriptor descriptor) { 28 | this(0, descriptor, null, true); 29 | } 30 | 31 | @Override 32 | public String toDSL() { 33 | PropertyDescriptor propertyDescriptor = (PropertyDescriptor) getDescriptor(); 34 | 35 | if (propertyDescriptor.getValue().equals("false")) { 36 | return ""; 37 | } 38 | 39 | return replaceTabs(String.format(getSyntax("syntax.method_call"), 40 | methodName, getChildrenDSL()), getTabs()); 41 | } 42 | 43 | private DSLStrategy getStrategyForObject(PropertyDescriptor propertyDescriptor) { 44 | List siblings = getChildrenOfType(propertyDescriptor.getParent(), DSLStrategyFactory.TYPE_METHOD); 45 | 46 | propertyDescriptor.getParent().getProperties().clear(); 47 | 48 | List children = new ArrayList<>(); 49 | for (PropertyDescriptor descriptor : siblings) { 50 | children.add(new PropertyDescriptor(descriptor.getName(), null, 51 | descriptor.getValue(), descriptor.getProperties(), 52 | descriptor.getAttributes())); 53 | } 54 | PropertyDescriptor object = new PropertyDescriptor(null, null, children); 55 | return new DSLObjectStrategy(getTabs(), object, null); 56 | } 57 | 58 | @Override 59 | protected String getChildrenDSL() { 60 | StringBuilder dsl = new StringBuilder(); 61 | 62 | int size = getChildren().size(); 63 | 64 | for (int index = 0; index < size; index++) { 65 | DSLStrategy strategy = getChildren().get(index); 66 | String strategyDsl = strategy.toDSL(); 67 | dsl.append(strategyDsl); 68 | if (index < size - 1 && (strategy instanceof IValueStrategy)) { 69 | dsl.append(", "); 70 | } 71 | } 72 | return dsl.toString(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLNonSupportedMethodDSL.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.AbstractDSLStrategy; 5 | 6 | public class DSLNonSupportedMethodDSL extends AbstractDSLStrategy { 7 | 8 | private final String name; 9 | 10 | public DSLNonSupportedMethodDSL(int tabs, PropertyDescriptor descriptor, String name) { 11 | super(tabs, descriptor); 12 | this.name = name; 13 | } 14 | 15 | @Override 16 | public String toDSL() { 17 | return replaceTabs(String.format(getSyntax("syntax.method_call_non_supported"), name, 18 | ((PropertyDescriptor) getDescriptor()).getValue()), getTabs()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLParamStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLMethodStrategy; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLStrategy; 5 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 6 | 7 | public class DSLParamStrategy extends DSLMethodStrategy { 8 | 9 | private final String methodName; 10 | 11 | public DSLParamStrategy(int tabs, PropertyDescriptor propertyDescriptor, String methodName) { 12 | super(tabs, propertyDescriptor, methodName); 13 | this.methodName = methodName; 14 | } 15 | 16 | @Override 17 | public String toDSL() { 18 | return replaceTabs(String.format(getSyntax("syntax.method_call"), 19 | methodName, getOrderedChildrenDSL()), getTabs()); 20 | } 21 | 22 | public String getOrderedChildrenDSL() { 23 | String defaultValue = getChildrenByName("defaultValue").toDSL(); 24 | String name = getChildrenByName("name").toDSL(); 25 | String description = getChildrenByName("description").toDSL(); 26 | return name + ", " + defaultValue + ", " + description; 27 | } 28 | 29 | private DSLStrategy getChildrenByName(String name) { 30 | for (DSLStrategy strategy : getChildren()) { 31 | if (strategy.getDescriptor().getName().equals(name)) { 32 | return strategy; 33 | } 34 | } 35 | throw new RuntimeException(String.format("Child with name: %s not found", name)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLPropertyAsMethodParametersStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.AbstractDSLStrategy; 5 | 6 | public class DSLPropertyAsMethodParametersStrategy extends AbstractDSLStrategy { 7 | 8 | public DSLPropertyAsMethodParametersStrategy(int tabs, PropertyDescriptor descriptor, String name) { 9 | super(tabs, descriptor); 10 | } 11 | 12 | @Override 13 | public String toDSL() { 14 | String[] variables = ((PropertyDescriptor) getDescriptor()).getValue().split("(\\s+|\t)"); 15 | StringBuilder methods = new StringBuilder(); 16 | 17 | for (String var : variables) { 18 | String[] keyValue = var.split("="); 19 | methods.append(replaceTabs( 20 | String.format(getSyntax("syntax.method_call"), getProperty( 21 | (PropertyDescriptor) getDescriptor()).getValue(), 22 | printValueAccordingOfItsType(keyValue[0]) + ", " + 23 | printValueAccordingOfItsType(keyValue[1])), getTabs())); 24 | } 25 | return methods.toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLReferencedParameterStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLMethodStrategy; 5 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLStrategy; 6 | 7 | import hudson.model.listeners.ItemListener; 8 | import java.util.logging.Level; 9 | import java.util.logging.Logger; 10 | 11 | public class DSLReferencedParameterStrategy extends DSLMethodStrategy { 12 | 13 | private final String methodName; 14 | 15 | public DSLReferencedParameterStrategy(int tabs, PropertyDescriptor propertyDescriptor, String methodName) { 16 | super(tabs, propertyDescriptor, methodName); 17 | this.methodName = methodName; 18 | } 19 | 20 | @Override 21 | public String toDSL() { 22 | 23 | // tokenize referenceParameters into multiple referencedParameter calls 24 | 25 | StringBuilder dsl = new StringBuilder(); 26 | PropertyDescriptor propertyDescriptor = (PropertyDescriptor) getDescriptor(); 27 | 28 | String referencedParams = propertyDescriptor.getValue(); 29 | 30 | if (referencedParams == null) { 31 | return ""; 32 | } 33 | 34 | if (referencedParams.indexOf(',') > -1) { 35 | String[] splitParams = referencedParams.split(","); 36 | 37 | for (String param : splitParams) { 38 | dsl.append(replaceTabs(String.format(getSyntax("syntax.method_call"), 39 | methodName, '"' + param.trim() + '"'), getTabs())); 40 | } 41 | } else { 42 | dsl.append(replaceTabs(String.format(getSyntax("syntax.method_call"), 43 | methodName, '"' + referencedParams.trim() + '"'), getTabs())); 44 | } 45 | 46 | return dsl.toString(); 47 | } 48 | 49 | private static final Logger LOGGER = Logger.getLogger(DSLReferencedParameterStrategy.class.getName()); 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLRichTextPublisherStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLObjectStrategy; 4 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 5 | 6 | import java.util.List; 7 | 8 | public class DSLRichTextPublisherStrategy extends DSLObjectStrategy { 9 | 10 | public DSLRichTextPublisherStrategy(int tabs, PropertyDescriptor propertyDescriptor, String name) { 11 | super(tabs, propertyDescriptor, name, false); 12 | 13 | if (!hasPropertyWithName(propertyDescriptor.getProperties(), "stableText")) { 14 | propertyDescriptor.getProperties().add(new PropertyDescriptor("stableText", propertyDescriptor, "")); 15 | } 16 | if (!hasPropertyWithName(propertyDescriptor.getProperties(), "unstableText")) { 17 | propertyDescriptor.getProperties().add(new PropertyDescriptor("unstableText", propertyDescriptor, "")); 18 | } 19 | if (!hasPropertyWithName(propertyDescriptor.getProperties(), "failedText")) { 20 | propertyDescriptor.getProperties().add(new PropertyDescriptor("failedText", propertyDescriptor, "")); 21 | } 22 | if (!hasPropertyWithName(propertyDescriptor.getProperties(), "abortedText")) { 23 | propertyDescriptor.getProperties().add(new PropertyDescriptor("abortedText", propertyDescriptor, "")); 24 | } 25 | if (!hasPropertyWithName(propertyDescriptor.getProperties(), "abortedAsStable")) { 26 | propertyDescriptor.getProperties().add(new PropertyDescriptor("abortedAsStable", propertyDescriptor, "true")); 27 | } 28 | if (!hasPropertyWithName(propertyDescriptor.getProperties(), "unstableAsStable")) { 29 | propertyDescriptor.getProperties().add(new PropertyDescriptor("unstableAsStable", propertyDescriptor, "true")); 30 | } 31 | if (!hasPropertyWithName(propertyDescriptor.getProperties(), "failedAsStable")) { 32 | propertyDescriptor.getProperties().add(new PropertyDescriptor("failedAsStable", propertyDescriptor, "true")); 33 | } 34 | if (!hasPropertyWithName(propertyDescriptor.getProperties(), "parserName")) { 35 | propertyDescriptor.getProperties().add(new PropertyDescriptor("parserName", propertyDescriptor, "HTML")); 36 | } 37 | if (!hasPropertyWithName(propertyDescriptor.getProperties(), "nullAction")) { 38 | propertyDescriptor.getProperties().add(new PropertyDescriptor("nullAction", propertyDescriptor, "")); 39 | } 40 | 41 | initChildren(propertyDescriptor); 42 | } 43 | 44 | private boolean hasPropertyWithName(List propertyDescriptorList, String name) { 45 | for (PropertyDescriptor propertyDescriptor : propertyDescriptorList) { 46 | if (propertyDescriptor.getName().equals(name)) { 47 | return true; 48 | } 49 | } 50 | return false; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLStringAsArrayStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLArrayStrategy; 5 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.IValueStrategy; 6 | 7 | public class DSLStringAsArrayStrategy extends DSLArrayStrategy implements IValueStrategy { 8 | 9 | public DSLStringAsArrayStrategy(int tabs, PropertyDescriptor descriptor, String name) { 10 | super(descriptor); 11 | } 12 | 13 | @Override 14 | public String toDSL() { 15 | return String.format(getSyntax("syntax.array"), toStringArray(((PropertyDescriptor) getDescriptor()).getValue())); 16 | } 17 | 18 | private String toStringArray(String text) { 19 | String[] lines = text.split("(\r\n)|(\n)"); 20 | StringBuilder builder = new StringBuilder(); 21 | 22 | for (int i = 0; i < lines.length; i++) { 23 | builder.append(lines[i].replace("=", ": \"")); 24 | builder.append("\""); 25 | if (i < lines.length - 1) { 26 | builder.append(String.format(",%n")); 27 | } 28 | } 29 | 30 | return builder.toString(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/dsl/strategies/custom/DSLStringAsMethodStrategy.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.dsl.strategies.custom; 2 | 3 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLObjectStrategy; 4 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 5 | import com.adq.jenkins.xmljobtodsl.utils.Pair; 6 | 7 | import java.util.ArrayList; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | public class DSLStringAsMethodStrategy extends DSLObjectStrategy { 13 | 14 | public DSLStringAsMethodStrategy(int tabs, PropertyDescriptor propertyDescriptor, String name) { 15 | super(tabs - 1, propertyDescriptor, name, false); 16 | 17 | List> pairs = getProps(propertyDescriptor); 18 | 19 | List children = new ArrayList<>(); 20 | 21 | for (Pair pair : pairs) { 22 | List propertyDescriptors = new ArrayList<>(); 23 | propertyDescriptors.add(new PropertyDescriptor("properties.key", propertyDescriptor.getParent(), pair.getKey())); 24 | propertyDescriptors.add(new PropertyDescriptor("properties.value", propertyDescriptor.getParent(), pair.getValue())); 25 | children.add(new PropertyDescriptor(name, propertyDescriptor.getParent(), propertyDescriptors)); 26 | } 27 | 28 | initChildren(new PropertyDescriptor(propertyDescriptor.getName(), propertyDescriptor.getParent(), children)); 29 | } 30 | 31 | private List> getProps(PropertyDescriptor propertyDescriptor) { 32 | String[] values = propertyDescriptor.getValue().split("\\r?\\n"); 33 | List> pairs = new ArrayList<>(); 34 | for (String value : values) { 35 | String[] pair = value.split("="); 36 | pairs.add(new Pair(pair[0], pair[1])); 37 | } 38 | return pairs; 39 | } 40 | 41 | @Override 42 | public String toDSL() { 43 | return getChildrenDSL(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/jenkins/JobCollector.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.jenkins; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.DSLTranslator; 4 | import com.adq.jenkins.xmljobtodsl.parsers.JobDescriptor; 5 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 6 | import com.adq.jenkins.xmljobtodsl.parsers.XmlParser; 7 | import com.adq.jenkins.xmljobtodsl.utils.IOUtils; 8 | import hudson.model.AbstractProject; 9 | import hudson.model.Job; 10 | import jenkins.model.Jenkins; 11 | import org.apache.commons.lang.StringEscapeUtils; 12 | import org.kohsuke.stapler.bind.JavaScriptMethod; 13 | import org.xml.sax.SAXException; 14 | 15 | import javax.xml.parsers.ParserConfigurationException; 16 | import java.io.File; 17 | import java.io.IOException; 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | public class JobCollector { 22 | 23 | public static final String DSL_GROOVY = "dsl.groovy"; 24 | public static final String USER_CONTENT_FOLDER = "userContent"; 25 | private final List allItems; 26 | private final List selectedItems = new ArrayList<>(); 27 | 28 | private String parsedItems = null; 29 | private String nonTranslatedTags = null; 30 | private String dslFilePath = null; 31 | private String error = null; 32 | 33 | public JobCollector() { 34 | allItems = Jenkins.getInstance().getAllItems(Job.class); 35 | } 36 | 37 | public List getJobs() { 38 | return allItems; 39 | } 40 | 41 | public List getSelectedJobs() { 42 | return selectedItems; 43 | } 44 | 45 | @JavaScriptMethod 46 | public int getNumberOfJobs() { 47 | return allItems.size(); 48 | } 49 | 50 | @JavaScriptMethod 51 | public int getNumberOfSelectedJobs() { 52 | return selectedItems.size(); 53 | } 54 | 55 | public void add(Job job) { 56 | selectedItems.add(job); 57 | } 58 | 59 | @JavaScriptMethod 60 | public void add(int jobIndex) { 61 | add(allItems.get(jobIndex)); 62 | } 63 | 64 | public void remove(Job job) { 65 | selectedItems.remove(job); 66 | } 67 | 68 | @JavaScriptMethod 69 | public void remove(int jobIndex) { 70 | remove(allItems.get(jobIndex)); 71 | } 72 | 73 | @JavaScriptMethod 74 | public String getParsedItems() { 75 | return formatString(parsedItems); 76 | } 77 | 78 | @JavaScriptMethod 79 | public String getNonTranslatedTags() { 80 | return nonTranslatedTags; 81 | } 82 | 83 | @JavaScriptMethod 84 | public String getError() { 85 | return error; 86 | } 87 | 88 | @JavaScriptMethod 89 | public String getDslFilePath() { 90 | return dslFilePath; 91 | } 92 | 93 | @JavaScriptMethod 94 | public boolean startOperation(String viewName) { 95 | try { 96 | convertXmlToDSL(viewName); 97 | saveDSLtoFile(); 98 | return true; 99 | } catch (IOException iosException) { 100 | error = "Error getting XML configuration of the job: " + iosException.getLocalizedMessage() + ": " + selectedItems.get(0).getConfigFile().getFile().getParentFile().getParentFile().getParentFile().getAbsolutePath() + File.separator + "userContent" + File.separator + File.separator + DSL_GROOVY; 101 | } catch (SAXException | ParserConfigurationException xmlException) { 102 | error = "Error parsing XML configuration of the job to DSL"; 103 | } 104 | return false; 105 | } 106 | 107 | private void convertXmlToDSL(String viewName) throws IOException, SAXException, ParserConfigurationException { 108 | List jobDescriptorsList = new ArrayList<>(); 109 | for (Job job : selectedItems) { 110 | String xml = job.getConfigFile().asString(); 111 | XmlParser parser = new XmlParser(job.getDisplayName(), xml); 112 | JobDescriptor descriptor = parser.parse(); 113 | jobDescriptorsList.add(descriptor); 114 | } 115 | JobDescriptor[] jobDescriptors = jobDescriptorsList.toArray(new JobDescriptor[jobDescriptorsList.size()]); 116 | DSLTranslator translator = new DSLTranslator(jobDescriptors, viewName); 117 | parsedItems = translator.toDSL(); 118 | nonTranslatedTags = formatNonTranslated(translator.getNotTranslated()); 119 | } 120 | 121 | private void saveDSLtoFile() throws IOException { 122 | File workspacePath = Jenkins.getInstance().getRootDir(); 123 | dslFilePath = ".." + File.separator + USER_CONTENT_FOLDER + File.separator + DSL_GROOVY; 124 | String file = workspacePath.getAbsolutePath() + File.separator + USER_CONTENT_FOLDER + File.separator + DSL_GROOVY; 125 | new IOUtils().saveToFile(parsedItems, file); 126 | } 127 | 128 | public String formatNonTranslated(List nonTranslated) { 129 | StringBuilder builder = new StringBuilder("The following tags couldn't be translated to DSL:"); 130 | builder.append("
    "); 131 | for (PropertyDescriptor descriptor : nonTranslated) { 132 | builder.append("
  • "); 133 | builder.append(formatString(descriptor.getName())); 134 | builder.append("
  • "); 135 | } 136 | builder.append("
"); 137 | builder.append("
"); 138 | builder.append("If you need some of them to be translated, please create an issue on our "); 139 | builder.append("GitHub.
"); 140 | return builder.toString(); 141 | } 142 | 143 | public String formatString(String text) { 144 | return StringEscapeUtils.escapeHtml(text); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/jenkins/JobSelectorView.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.jenkins; 2 | 3 | import hudson.Extension; 4 | import hudson.model.UnprotectedRootAction; 5 | 6 | @Extension 7 | public class JobSelectorView implements UnprotectedRootAction { 8 | 9 | @Override 10 | public String getIconFileName() { 11 | return "plugin.png"; 12 | } 13 | 14 | @Override 15 | public String getDisplayName() { 16 | return "XML Job To DSL"; 17 | } 18 | 19 | @Override 20 | public String getUrlName() { 21 | return "xmltodsl"; 22 | } 23 | 24 | public JobCollector getData() { 25 | return new JobCollector(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/parsers/DSLTranslator.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.parsers; 2 | 3 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLJobStrategy; 4 | 5 | import java.io.IOException; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Created by alanquintiliano on 20/12/17. 11 | */ 12 | public class DSLTranslator { 13 | 14 | private JobDescriptor[] jobDescriptors; 15 | private String viewName; 16 | private List notTranslated = new ArrayList<>(); 17 | 18 | public DSLTranslator(JobDescriptor[] jobDescriptors, String viewName) throws IOException { 19 | this.jobDescriptors = jobDescriptors.clone(); 20 | this.viewName = viewName; 21 | } 22 | 23 | public DSLTranslator(JobDescriptor jobDescriptor, String viewName) throws IOException { 24 | this(new JobDescriptor[] { jobDescriptor }, viewName); 25 | } 26 | 27 | public DSLTranslator(JobDescriptor[] jobDescriptors) throws IOException { 28 | this(jobDescriptors, null); 29 | } 30 | 31 | public DSLTranslator(JobDescriptor jobDescriptor) throws IOException { 32 | this(jobDescriptor, null); 33 | } 34 | 35 | public String toDSL() { 36 | StringBuilder builder = new StringBuilder(); 37 | for (JobDescriptor job : jobDescriptors) { 38 | DSLJobStrategy jobStrategy = new DSLJobStrategy(job); 39 | builder.append(jobStrategy.toDSL()); 40 | notTranslated.addAll(jobStrategy.getNotTranslatedList()); 41 | } 42 | if (viewName != null) { 43 | builder.append(new DSLView(viewName, jobDescriptors).generateViewDSL()); 44 | } 45 | return builder.toString().trim(); 46 | } 47 | 48 | public List getNotTranslated() { 49 | return notTranslated; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/parsers/DSLView.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.parsers; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.util.Properties; 6 | 7 | public class DSLView { 8 | 9 | private static final String[] columns = new String[]{ 10 | "status", 11 | "weather", 12 | "name", 13 | "lastSuccess", 14 | "lastFailure", 15 | "lastDuration", 16 | "buildButton" 17 | }; 18 | 19 | private final String[] jobNames; 20 | private final String name; 21 | private Properties syntaxProperties; 22 | 23 | public DSLView(String name, String[] jobNames) { 24 | this.jobNames = jobNames.clone(); 25 | this.name = name; 26 | init(); 27 | } 28 | 29 | public DSLView(String name, JobDescriptor[] jobs) { 30 | String[] names = new String[jobs.length]; 31 | for (int i = 0; i < jobs.length; i++) { 32 | names[i] = jobs[i].getName(); 33 | } 34 | this.jobNames = names; 35 | this.name = name; 36 | init(); 37 | } 38 | 39 | private void init() { 40 | InputStream in = getClass().getClassLoader().getResourceAsStream("syntax.properties"); 41 | syntaxProperties = new Properties(); 42 | try { 43 | syntaxProperties.load(in); 44 | } catch (IOException e) { 45 | e.printStackTrace(); 46 | } 47 | } 48 | 49 | public String generateViewDSL() { 50 | StringBuilder jobsBuilder = new StringBuilder(); 51 | for (String name : jobNames) { 52 | jobsBuilder.append(String.format(syntaxProperties.getProperty("syntax.view.job"), name)); 53 | } 54 | StringBuilder columnsBuilder = new StringBuilder(); 55 | for (String column : columns) { 56 | columnsBuilder.append(String.format(syntaxProperties.getProperty("syntax.view.column"), column)); 57 | } 58 | return String.format(syntaxProperties.getProperty("syntax.view"), name, 59 | jobsBuilder.toString(), columnsBuilder.toString()); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/parsers/IDescriptor.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.parsers; 2 | 3 | import java.util.List; 4 | 5 | public interface IDescriptor { 6 | String getName(); 7 | List getProperties(); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/parsers/JobDescriptor.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.parsers; 2 | 3 | import com.google.gson.ExclusionStrategy; 4 | import com.google.gson.FieldAttributes; 5 | import com.google.gson.GsonBuilder; 6 | 7 | import java.util.List; 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | public class JobDescriptor implements IDescriptor { 12 | 13 | private String name; 14 | private List properties; 15 | 16 | public JobDescriptor(String name, List properties) { 17 | this.name = name; 18 | this.properties = properties; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public List getProperties() { 26 | return properties; 27 | } 28 | 29 | @Override 30 | public boolean equals(Object obj) { 31 | if (!(obj instanceof JobDescriptor)) { 32 | return false; 33 | } 34 | JobDescriptor other = (JobDescriptor) obj; 35 | if (!other.getName().equals(this.getName())) { 36 | return false; 37 | } 38 | return other.getProperties().equals(this.getProperties()); 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | GsonBuilder builder = new GsonBuilder(); 44 | builder.setExclusionStrategies(new ExclusionStrategy() { 45 | 46 | @Override 47 | public boolean shouldSkipField(FieldAttributes fieldAttributes) { 48 | return fieldAttributes.getName().equals("parent"); 49 | } 50 | 51 | @Override 52 | public boolean shouldSkipClass(Class aClass) { 53 | return false; 54 | } 55 | }); 56 | builder.setPrettyPrinting(); 57 | return builder.create().toJson(this).replaceAll(Pattern.quote("\\r"), Matcher.quoteReplacement("")); 58 | } 59 | 60 | @Override 61 | public int hashCode() { 62 | int result = name.hashCode(); 63 | result = 31 * result + (properties != null ? properties.hashCode() : 0); 64 | return result; 65 | } 66 | } -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/parsers/PropertyDescriptor.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.parsers; 2 | 3 | import com.google.gson.ExclusionStrategy; 4 | import com.google.gson.FieldAttributes; 5 | import com.google.gson.GsonBuilder; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.regex.Matcher; 10 | import java.util.regex.Pattern; 11 | 12 | public class PropertyDescriptor implements IDescriptor { 13 | 14 | private String name; 15 | private PropertyDescriptor parent; 16 | private List properties; 17 | private Map attributes; 18 | private String value; 19 | 20 | public PropertyDescriptor(String name, PropertyDescriptor parent) { 21 | this(name, parent, null, null, null); 22 | } 23 | 24 | public PropertyDescriptor(String name, PropertyDescriptor parent , String value) { 25 | this(name, parent, value, null); 26 | } 27 | 28 | public PropertyDescriptor(String name, PropertyDescriptor parent , String value, Map attributes) { 29 | this(name, parent, value, null, attributes); 30 | } 31 | 32 | public PropertyDescriptor(String name, PropertyDescriptor parent , List properties) { 33 | this(name, parent, properties, null); 34 | } 35 | 36 | public PropertyDescriptor(String name, PropertyDescriptor parent , Map attributes) { 37 | this(name, parent, null, null, attributes); 38 | } 39 | 40 | public PropertyDescriptor(String name, PropertyDescriptor parent , List properties, Map attributes) { 41 | this(name, parent, null, properties, attributes); 42 | } 43 | 44 | public PropertyDescriptor(String name, PropertyDescriptor parent , String value, List properties, Map attributes) { 45 | this.name = name; 46 | this.value = value; 47 | this.properties = properties; 48 | this.attributes = attributes; 49 | this.parent = parent; 50 | } 51 | 52 | public String getName() { 53 | return name; 54 | } 55 | 56 | public List getProperties() { 57 | return properties; 58 | } 59 | 60 | public Map getAttributes() { 61 | return attributes; 62 | } 63 | 64 | public String getValue() { 65 | return value; 66 | } 67 | 68 | public PropertyDescriptor getParent() { 69 | return parent; 70 | } 71 | 72 | @Override 73 | public boolean equals(Object obj) { 74 | if (!(obj instanceof PropertyDescriptor)) { 75 | return false; 76 | } 77 | PropertyDescriptor other = (PropertyDescriptor) obj; 78 | if (!other.getName().equals(this.getName())) { 79 | return false; 80 | } 81 | 82 | if (other.getAttributes() != null && this.getAttributes() != null) { 83 | if (!other.getAttributes().equals(this.getAttributes())) { 84 | return false; 85 | } 86 | } 87 | 88 | if (other.getProperties() != null && this.getProperties() != null) { 89 | if (!other.getProperties().equals(this.getProperties())) { 90 | return false; 91 | } 92 | } 93 | 94 | if (other.getValue() != null && this.getValue() != null) { 95 | if (!other.getValue().equals(this.getValue())) { 96 | return false; 97 | } 98 | } 99 | 100 | return true; 101 | } 102 | 103 | @Override 104 | public String toString() { 105 | GsonBuilder builder = new GsonBuilder(); 106 | builder.setExclusionStrategies(new ExclusionStrategy() { 107 | @Override 108 | public boolean shouldSkipField(FieldAttributes fieldAttributes) { 109 | return fieldAttributes.getName().equals("parent"); 110 | } 111 | 112 | @Override 113 | public boolean shouldSkipClass(Class aClass) { 114 | return false; 115 | } 116 | }); 117 | return builder.create().toJson(this).replaceAll(Pattern.quote("\\r"), Matcher.quoteReplacement("")); 118 | } 119 | 120 | @Override 121 | public int hashCode() { 122 | int result = name.hashCode(); 123 | result = 31 * result + (parent != null ? parent.hashCode() : 0); 124 | result = 31 * result + (properties != null ? properties.hashCode() : 0); 125 | result = 31 * result + (attributes != null ? attributes.hashCode() : 0); 126 | result = 31 * result + (value != null ? value.hashCode() : 0); 127 | return result; 128 | } 129 | } -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/parsers/XmlParser.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.parsers; 2 | 3 | import org.w3c.dom.*; 4 | import org.xml.sax.InputSource; 5 | import org.xml.sax.SAXException; 6 | 7 | import javax.xml.parsers.DocumentBuilder; 8 | import javax.xml.parsers.DocumentBuilderFactory; 9 | import javax.xml.parsers.ParserConfigurationException; 10 | import java.io.IOException; 11 | import java.io.StringReader; 12 | import java.util.ArrayList; 13 | import java.util.HashMap; 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | public class XmlParser { 18 | 19 | private String xml; 20 | private String jobName; 21 | 22 | public XmlParser(String jobName, String xml) { 23 | this.jobName = jobName; 24 | this.xml = xml; 25 | prepareXml(); 26 | } 27 | 28 | private String prepareXml() { 29 | return this.xml = this.xml.replaceAll(">%n", "") 30 | .replaceAll("\\s*<", "<") 31 | .replaceAll(" ", String.format("%n")); 32 | } 33 | 34 | public JobDescriptor parse() throws IOException, SAXException, ParserConfigurationException { 35 | DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 36 | InputSource is = new InputSource(new StringReader(xml)); 37 | Document doc = docBuilder.parse(is); 38 | doc.getDocumentElement().normalize(); 39 | 40 | List properties = new ArrayList<>(); 41 | 42 | properties.addAll(getChildNodes(null, doc.getChildNodes())); 43 | 44 | return new JobDescriptor(jobName, properties); 45 | } 46 | 47 | public List getChildNodes(PropertyDescriptor parent, NodeList childNodes) { 48 | List properties = new ArrayList<>(); 49 | for (int i = 0; i < childNodes.getLength(); i++) { 50 | Node node = childNodes.item(i); 51 | if (node.getNodeType() != Node.ELEMENT_NODE) { 52 | continue; 53 | } 54 | String name = node.getNodeName(); 55 | 56 | Map attributes = null; 57 | if (node.hasAttributes()) { 58 | attributes = getAttributes(node.getAttributes()); 59 | } 60 | 61 | if (!node.hasChildNodes()) { 62 | PropertyDescriptor descriptor = new PropertyDescriptor(name, parent, attributes); 63 | properties.add(descriptor); 64 | continue; 65 | } 66 | 67 | Node firstChild = node.getFirstChild(); 68 | 69 | if (firstChild.getNodeType() == Node.TEXT_NODE && !((Text) firstChild).isElementContentWhitespace()) { 70 | String value = node.getFirstChild().getNodeValue(); 71 | value = value.replaceAll("\n", String.format("%n")); 72 | PropertyDescriptor descriptor = new PropertyDescriptor(name, parent, value, attributes); 73 | properties.add(descriptor); 74 | continue; 75 | } 76 | 77 | List childProperties = new ArrayList<>(); 78 | PropertyDescriptor descriptor = new PropertyDescriptor(name, parent, childProperties, attributes); 79 | if (firstChild.getNodeType() == Node.ELEMENT_NODE) { 80 | childProperties.addAll(getChildNodes(descriptor, node.getChildNodes())); 81 | } 82 | properties.add(descriptor); 83 | } 84 | return properties; 85 | } 86 | 87 | public Map getAttributes(NamedNodeMap attributes) { 88 | Map attributesMap = new HashMap<>(); 89 | for (int i = 0; i < attributes.getLength(); i++) { 90 | Node item = attributes.item(i); 91 | attributesMap.put(item.getNodeName(), attributes.item(i).getNodeValue()); 92 | } 93 | return attributesMap; 94 | } 95 | } -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/utils/IOUtils.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.utils; 2 | 3 | import java.io.*; 4 | import java.net.*; 5 | import java.nio.charset.Charset; 6 | import java.nio.charset.StandardCharsets; 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by alanquintiliano on 19/12/17. 13 | */ 14 | public class IOUtils { 15 | 16 | public String readFromFile(String path) throws IOException { 17 | File file = new File(path); 18 | return readFromFile(file); 19 | } 20 | 21 | public String readFromFile(File file) throws IOException { 22 | return readFromStream(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); 23 | } 24 | 25 | private String readFromStream(InputStreamReader stream) throws IOException { 26 | StringBuilder result = new StringBuilder(""); 27 | BufferedReader br = new BufferedReader(stream); 28 | try { 29 | String line = br.readLine(); 30 | 31 | while (line != null) { 32 | result.append(line); 33 | result.append(System.lineSeparator()); 34 | line = br.readLine(); 35 | } 36 | } finally { 37 | br.close(); 38 | stream.close(); 39 | } 40 | 41 | return result.toString(); 42 | } 43 | 44 | public String readFromResource(String path) throws IOException { 45 | ClassLoader classLoader = getClass().getClassLoader(); 46 | String file = URLDecoder.decode(classLoader.getResource(path).getFile(), StandardCharsets.UTF_8.displayName()); 47 | return readFromFile(new File(file)); 48 | } 49 | 50 | public String readFromUrl(String urlString, final String username, final String password) throws IOException { 51 | if (username != null && password != null) { 52 | Authenticator.setDefault(new Authenticator() { 53 | @Override 54 | protected PasswordAuthentication getPasswordAuthentication() { 55 | return new PasswordAuthentication(username, password.toCharArray()); 56 | } 57 | }); 58 | } 59 | URL url = new URL(urlString); 60 | URLConnection uc = url.openConnection(); 61 | return readFromStream(new InputStreamReader(uc.getInputStream(), StandardCharsets.UTF_8)); 62 | } 63 | 64 | public void saveToFile(String text, String path) throws IOException { 65 | File file = new File(path); 66 | if (!file.exists()) { 67 | boolean createdNewFile = file.createNewFile(); 68 | if (!createdNewFile) { 69 | throw new IOException("Couldn't create file at path: " + path); 70 | } 71 | } 72 | PrintWriter out = new PrintWriter(file, StandardCharsets.UTF_8.displayName()); 73 | out.println(text); 74 | out.close(); 75 | } 76 | 77 | public File[] getJobXmlFilesInDirectory(String directory) { 78 | File dir = new File(directory); 79 | if (!dir.isDirectory()) { 80 | throw new RuntimeException(directory + " is not a directory"); 81 | } 82 | File[] directories = dir.listFiles(new FileFilter() { 83 | @Override 84 | public boolean accept(File pathname) { 85 | return pathname.isDirectory(); 86 | } 87 | }); 88 | 89 | if (directories == null) { 90 | return null; 91 | } 92 | 93 | List files = new ArrayList<>(); 94 | for (File innerDirectory : directories) { 95 | File[] innerFiles = innerDirectory.listFiles(new FileFilter() { 96 | @Override 97 | public boolean accept(File pathname) { 98 | return pathname.getPath().endsWith("config.xml"); 99 | } 100 | }); 101 | 102 | if (innerFiles == null) { 103 | continue; 104 | } 105 | 106 | files.addAll(Arrays.asList(innerFiles)); 107 | } 108 | 109 | return files.toArray(new File[files.size()]); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/com/adq/jenkins/xmljobtodsl/utils/Pair.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl.utils; 2 | 3 | public class Pair { 4 | 5 | private final V value; 6 | private final K key; 7 | 8 | public Pair(K key, V value) { 9 | this.key = key; 10 | this.value = value; 11 | } 12 | 13 | public K getKey() { 14 | return key; 15 | } 16 | 17 | public V getValue() { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/com/adq/jenkins/xmljobtodsl/jenkins/JobSelectorView/config.properties: -------------------------------------------------------------------------------- 1 | Name=Name 2 | French=French 3 | FrenchDescr=Check if we should say hello in French -------------------------------------------------------------------------------- /src/main/resources/com/adq/jenkins/xmljobtodsl/jenkins/JobSelectorView/help-name.html: -------------------------------------------------------------------------------- 1 |
2 | View name. 3 |
4 | -------------------------------------------------------------------------------- /src/main/resources/com/adq/jenkins/xmljobtodsl/jenkins/JobSelectorView/index.jelly: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | ${%Number of Jobs}: ${numberOfJobs} | ${%Selected Jobs}: ${data.numberOfSelectedJobs} 15 |
16 |
17 |

${%Select jobs to parse to DSL}

18 | 19 | 20 | 21 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 40 | 41 | 42 | 43 | 44 | 45 |
22 | ${%Select} 23 | 25 | ${%Job} 26 |
35 | 36 | 38 | ${j.fullName} 39 |
46 | 47 |
48 |
49 | 50 | ${%Create view for all selected jobs: } 51 | 52 | 55 | 56 |
57 |
58 | 59 | 60 |
61 |
62 | 63 | 64 |
65 | 66 |
67 |
68 | 69 | 137 |
138 | -------------------------------------------------------------------------------- /src/main/resources/com/adq/jenkins/xmljobtodsl/jenkins/Messages.properties: -------------------------------------------------------------------------------- 1 | XmlJobToDSLBuilder.DescriptorImpl.errors.missingName=Please set a name 2 | XmlJobToDSLBuilder.DescriptorImpl.warnings.tooShort=Isn't the name too short? 3 | XmlJobToDSLBuilder.DescriptorImpl.warnings.reallyFrench=Are you actually French? 4 | 5 | XmlJobToDSLBuilder.DescriptorImpl.DisplayName=XML Job to DSL -------------------------------------------------------------------------------- /src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 | 2 |
3 | Use this plugin to convert your jobs into DSL Groovy scripts 4 |
5 | -------------------------------------------------------------------------------- /src/main/resources/syntax.properties: -------------------------------------------------------------------------------- 1 | syntax.job = %s("%s") {%n%s}%n%n 2 | syntax.method = def %s(%s) {%nreturn {%n%s}%n}%n%n 3 | syntax.method_param = %s, 4 | syntax.method_call = %s(%s)%n 5 | syntax.method_call_subsequent = << %s(%s) 6 | syntax.method_call_closure = %s(%s) {%n%s}%n 7 | syntax.tab = \t 8 | syntax.object_with_name = %s {%n%s}%n 9 | syntax.object = {%n%s} 10 | syntax.object_def = def %s = {%n%s}%n 11 | syntax.property = %s %s 12 | syntax.string_variable = def String %s = '''%s'''%n 13 | syntax.int_variable = def int %s = '%s' 14 | syntax.check_env_variable = if (binding.variables.%s) {%n%s = binding.variables.%s%n}%n%n 15 | syntax.array = [%s] 16 | syntax.method_call_non_supported = '%s'('%s')%n 17 | syntax.view = listView("%s") {%n\tjobs {%n%s\t}%n\tcolumns {%n%s\t}%n} 18 | syntax.view.job = \t\tname("%s")%n 19 | syntax.view.column = \t\t%s()%n -------------------------------------------------------------------------------- /src/test/java/com/adq/jenkins/xmljobtodsl/DSLStrategiesTests.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl; 2 | 3 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.DSLParameterStrategy; 4 | import com.adq.jenkins.xmljobtodsl.dsl.strategies.custom.DSLGitHubMethodStrategy; 5 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | 9 | public class DSLStrategiesTests { 10 | 11 | @Test 12 | public void testGitHubRepositoryInformation() { 13 | PropertyDescriptor descriptor = new PropertyDescriptor("git", null, "https"); 14 | DSLGitHubMethodStrategy strategy = new DSLGitHubMethodStrategy(0, descriptor, null); 15 | 16 | String repoInfo = strategy.getRepositoryInformationFromUrl("https://www.github.com/alandoni/xml-job-to-dsl.git"); 17 | Assert.assertEquals("alandoni/xml-job-to-dsl", repoInfo); 18 | 19 | repoInfo = strategy.getRepositoryInformationFromUrl("git@github.com:alandoni/xml-job-to-dsl.git"); 20 | Assert.assertEquals("alandoni/xml-job-to-dsl", repoInfo); 21 | 22 | repoInfo = strategy.getRepositoryInformationFromUrl("https://www.github.com/alandoni/xml-job-to-dsl"); 23 | Assert.assertEquals("alandoni/xml-job-to-dsl", repoInfo); 24 | 25 | repoInfo = strategy.getRepositoryInformationFromUrl("git@github.com:alandoni/xml-job-to-dsl"); 26 | Assert.assertEquals("alandoni/xml-job-to-dsl", repoInfo); 27 | 28 | repoInfo = strategy.getRepositoryInformationFromUrl("https://git.ourdomain.com:8444/scm/chef/chef-job-dsl-config.git"); 29 | Assert.assertEquals("https://git.ourdomain.com:8444/scm/chef/chef-job-dsl-config.git", repoInfo); 30 | } 31 | 32 | @Test 33 | public void testPrintValueAccordingOfItsType() { 34 | DSLParameterStrategy strategy = new DSLParameterStrategy(null); 35 | 36 | String actual = strategy.printValueAccordingOfItsType(null); 37 | Assert.assertEquals("\"\"", actual); 38 | 39 | actual = strategy.printValueAccordingOfItsType("true"); 40 | Assert.assertEquals("true", actual); 41 | 42 | actual = strategy.printValueAccordingOfItsType("false"); 43 | Assert.assertEquals("false", actual); 44 | 45 | actual = strategy.printValueAccordingOfItsType("12"); 46 | Assert.assertEquals("12", actual); 47 | 48 | actual = strategy.printValueAccordingOfItsType("1.2"); 49 | Assert.assertEquals("1.2", actual); 50 | 51 | actual = strategy.printValueAccordingOfItsType("10.240.50.36"); 52 | Assert.assertEquals("\"10.240.50.36\"", actual); 53 | 54 | actual = strategy.printValueAccordingOfItsType("1.2.1"); 55 | Assert.assertEquals("\"1.2.1\"", actual); 56 | 57 | actual = strategy.printValueAccordingOfItsType("1,2"); 58 | Assert.assertEquals("\"1,2\"", actual); 59 | 60 | actual = strategy.printValueAccordingOfItsType("1 2"); 61 | Assert.assertEquals("\"1 2\"", actual); 62 | 63 | actual = strategy.printValueAccordingOfItsType("test"); 64 | Assert.assertEquals("\"test\"", actual); 65 | 66 | actual = strategy.printValueAccordingOfItsType("hey \"test\" it"); 67 | Assert.assertEquals("\"hey \\\"test\\\" it\"", actual); 68 | 69 | actual = strategy.printValueAccordingOfItsType("test\ntest"); 70 | Assert.assertEquals("\"\"\"test\ntest\"\"\"", actual); 71 | 72 | actual = strategy.printValueAccordingOfItsType(""); 73 | Assert.assertEquals("\"\"", actual); 74 | 75 | actual = strategy.printValueAccordingOfItsType("test ${test}"); 76 | Assert.assertEquals("\"test \\${test}\"", actual); 77 | 78 | actual = strategy.printValueAccordingOfItsType("test \n ${test}"); 79 | Assert.assertEquals("\"\"\"test \n \\${test}\"\"\"", actual); 80 | 81 | actual = strategy.printValueAccordingOfItsType("$(echo \"test\")"); 82 | Assert.assertEquals("\"\\$(echo \\\"test\\\")\"", actual); 83 | 84 | actual = strategy.printValueAccordingOfItsType("$(echo \"test\")\n$(echo \"test\")"); 85 | Assert.assertEquals("\"\"\"\\$(echo \"test\")\n\\$(echo \"test\")\"\"\"", actual); 86 | 87 | actual = strategy.printValueAccordingOfItsType("origin/master "); 88 | Assert.assertEquals(String.format("\"origin/master \""), actual); 89 | 90 | actual = strategy.printValueAccordingOfItsType("origin/$BRANCH"); 91 | Assert.assertEquals(String.format("\"origin/\\$BRANCH\""), actual); 92 | 93 | actual = strategy.printValueAccordingOfItsType("test \"\"\" test \n test \"\"\" test"); 94 | Assert.assertEquals("\"\"\"test \\\"\\\"\\\" test \n test \\\"\\\"\\\" test\"\"\"", actual); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/test/java/com/adq/jenkins/xmljobtodsl/TestsConstants.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.JobDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 5 | 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public class TestsConstants { 12 | 13 | public static final JobDescriptor getJobDescriptor() { 14 | List propertiesProperties = new ArrayList<>(); 15 | 16 | List buildBlockProperties = new ArrayList<>(); 17 | 18 | List projectProperties = new ArrayList<>(); 19 | PropertyDescriptor projectProperty = new PropertyDescriptor("project", null, projectProperties); 20 | 21 | projectProperties.add(new PropertyDescriptor("properties", projectProperty, propertiesProperties)); 22 | 23 | List buildersProperties = new ArrayList<>(); 24 | 25 | PropertyDescriptor builder = new PropertyDescriptor("builders", projectProperty, buildersProperties); 26 | 27 | Map attributes = new HashMap<>(); 28 | attributes.put("plugin", "build-name-setter@1.6.5"); 29 | 30 | List buildNameUpdaterProperties = new ArrayList<>(); 31 | PropertyDescriptor buildName = new PropertyDescriptor("org.jenkinsci.plugins.buildnameupdater.BuildNameUpdater", builder,null, buildNameUpdaterProperties, attributes); 32 | 33 | buildNameUpdaterProperties.add(new PropertyDescriptor("macroTemplate", buildName,"Test iOS App #${BUILD_NUMBER} | ${APP_VERSION}")); 34 | buildNameUpdaterProperties.add(new PropertyDescriptor("fromFile", buildName,"false")); 35 | buildNameUpdaterProperties.add(new PropertyDescriptor("fromMacro", buildName,"true")); 36 | buildNameUpdaterProperties.add(new PropertyDescriptor("macroFirst", buildName,"true")); 37 | buildersProperties.add(buildName); 38 | 39 | List shellProperties = new ArrayList<>(); 40 | PropertyDescriptor shell = new PropertyDescriptor("hudson.tasks.Shell", builder, shellProperties); 41 | shellProperties.add(new PropertyDescriptor("command", shell, 42 | "export PLATFORM=${platform}" + System.lineSeparator() + 43 | "cd 'iOSTest-AppiumTests/src/scripts/'" + System.lineSeparator() + 44 | "fab -f build.py fetch_git build_app upload_app")); 45 | buildersProperties.add(shell); 46 | 47 | projectProperties.add(builder); 48 | 49 | PropertyDescriptor buildBlocker = new PropertyDescriptor("hudson.plugins.buildblocker.BuildBlockerProperty", builder, buildBlockProperties); 50 | 51 | buildBlockProperties.add(new PropertyDescriptor("blockingJobs", buildBlocker,"Build-iOS-App")); 52 | buildBlockProperties.add(new PropertyDescriptor("useBuildBlocker", buildBlocker, "true")); 53 | buildBlockProperties.add(new PropertyDescriptor("blockLevel", buildBlocker,"GLOBAL")); 54 | buildBlockProperties.add(new PropertyDescriptor("scanQueueFor", buildBlocker,"DISABLED")); 55 | 56 | propertiesProperties.add(buildBlocker); 57 | 58 | List properties = new ArrayList<>(); 59 | properties.add(projectProperty); 60 | 61 | return new JobDescriptor("Test", properties); 62 | } 63 | 64 | public static final String getXml() { 65 | return "" + System.lineSeparator() + 66 | "\t" + System.lineSeparator() + 67 | "\t\t" + System.lineSeparator() + 68 | "\t\t\tBuild-iOS-App" + System.lineSeparator() + 69 | "\t\t\ttrue" + System.lineSeparator() + 70 | "\t\t\tGLOBAL" + System.lineSeparator() + 71 | "\t\t\tDISABLED" + System.lineSeparator() + 72 | "\t\t" + System.lineSeparator() + 73 | "\t" + System.lineSeparator() + 74 | "\t" + System.lineSeparator() + 75 | "\t\t" + System.lineSeparator() + 76 | "\t\t\tTest iOS App #${BUILD_NUMBER} | ${APP_VERSION}" + System.lineSeparator() + 77 | "\t\t\tfalse" + System.lineSeparator() + 78 | "\t\t\ttrue" + System.lineSeparator() + 79 | "\t\t\ttrue" + System.lineSeparator() + 80 | "\t\t" + System.lineSeparator() + 81 | "\t\t" + System.lineSeparator() + 82 | "\t\t\texport PLATFORM=${platform}" + System.lineSeparator() + 83 | "cd 'iOSTest-AppiumTests/src/scripts/'" + System.lineSeparator() + 84 | "fab -f build.py fetch_git build_app upload_app" + System.lineSeparator() + 85 | "\t\t\t" + System.lineSeparator() + 86 | "\t\t" + System.lineSeparator() + 87 | "\t" + System.lineSeparator() + 88 | ""; 89 | } 90 | 91 | public static final String getDSL() { 92 | return "job(\"Test\") {" + System.lineSeparator() + 93 | "\tblockOn(\"Build-iOS-App\", {" + System.lineSeparator() + 94 | "\t\tblockLevel(\"GLOBAL\")" + System.lineSeparator() + 95 | "\t\tscanQueueFor(\"DISABLED\")" + System.lineSeparator() + 96 | "\t})" + System.lineSeparator() + 97 | "\tsteps {" + System.lineSeparator() + 98 | "\t\tbuildNameUpdater {" + System.lineSeparator() + 99 | "\t\t\tbuildName(\"\")" + System.lineSeparator() + 100 | "\t\t\tmacroTemplate(\"Test iOS App #\\${BUILD_NUMBER} | \\${APP_VERSION}\")" + System.lineSeparator() + 101 | "\t\t\tfromFile(false)" + System.lineSeparator() + 102 | "\t\t\tfromMacro(true)" + System.lineSeparator() + 103 | "\t\t\tmacroFirst(true)" + System.lineSeparator() + 104 | "\t\t}" + System.lineSeparator() + 105 | "\t\tshell(\"\"\"export PLATFORM=\\${platform}" + System.lineSeparator() + 106 | "cd 'iOSTest-AppiumTests/src/scripts/'" + System.lineSeparator() + 107 | "fab -f build.py fetch_git build_app upload_app\"\"\")" + System.lineSeparator() + 108 | "\t}" + System.lineSeparator() + 109 | "}"; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/test/java/com/adq/jenkins/xmljobtodsl/TestsDSLView.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.DSLView; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | public class TestsDSLView { 8 | 9 | @Test 10 | public void testViewFile() { 11 | String expected = TestsXmlParser.readFile("view.groovy"); 12 | String actual = new DSLView("test", new String[] { "test1", "test2" }).generateViewDSL(); 13 | Assert.assertEquals(expected, actual); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/adq/jenkins/xmljobtodsl/TestsTranslator.java: -------------------------------------------------------------------------------- 1 | 2 | package com.adq.jenkins.xmljobtodsl; 3 | 4 | import java.io.IOException; 5 | import java.util.List; 6 | import java.util.logging.Level; 7 | import java.util.logging.Logger; 8 | 9 | import com.adq.jenkins.xmljobtodsl.parsers.DSLTranslator; 10 | import com.adq.jenkins.xmljobtodsl.parsers.JobDescriptor; 11 | import com.adq.jenkins.xmljobtodsl.parsers.PropertyDescriptor; 12 | import com.adq.jenkins.xmljobtodsl.parsers.XmlParser; 13 | import org.junit.Test; 14 | import org.xml.sax.SAXException; 15 | 16 | import javax.xml.parsers.ParserConfigurationException; 17 | 18 | import static org.junit.Assert.assertEquals; 19 | 20 | public class TestsTranslator { 21 | 22 | public static String readExampleFile() { 23 | return TestsXmlParser.readFile("example-job.groovy"); 24 | } 25 | 26 | @Test 27 | public void testSimpleDSL() throws IOException { 28 | assertEquals(TestsConstants.getDSL(), 29 | new DSLTranslator(TestsConstants.getJobDescriptor()).toDSL()); 30 | } 31 | 32 | private void readFilesAndTest(String xmlFile, String groovyFile) throws IOException, ParserConfigurationException, SAXException { 33 | String xml = TestsXmlParser.readFile(xmlFile); 34 | JobDescriptor actualJobDescriptor = new XmlParser("test", xml).parse(); 35 | String expectedDSL = TestsXmlParser.readFile(groovyFile); 36 | 37 | DSLTranslator dslTranslator = new DSLTranslator(actualJobDescriptor); 38 | String actualDSL = dslTranslator.toDSL(); 39 | logAllNotKnownTags(dslTranslator.getNotTranslated()); 40 | 41 | assertEquals(expectedDSL, actualDSL); 42 | } 43 | 44 | @Test 45 | public void testDSLWithArrays() throws IOException, ParserConfigurationException, SAXException { 46 | readFilesAndTest("array.xml", "array.groovy"); 47 | } 48 | 49 | @Test 50 | public void testDSLWithObjectAsParameter() throws IOException, ParserConfigurationException, SAXException { 51 | readFilesAndTest("object_parameter.xml", "object_parameter.groovy"); 52 | } 53 | 54 | @Test 55 | public void testDSLScm() throws IOException, ParserConfigurationException, SAXException { 56 | readFilesAndTest("scm.xml", "scm.groovy"); 57 | } 58 | 59 | @Test 60 | public void testDSLScm2() throws IOException, ParserConfigurationException, SAXException { 61 | readFilesAndTest("scm2.xml", "scm2.groovy"); 62 | } 63 | 64 | @Test 65 | public void testDSLDescription() throws IOException, ParserConfigurationException, SAXException { 66 | readFilesAndTest("description.xml", "description.groovy"); 67 | } 68 | 69 | @Test 70 | public void testReadingConfigureBlockFile() throws IOException, ParserConfigurationException, SAXException { 71 | readFilesAndTest("configure-block.xml", "configure-block.groovy"); 72 | } 73 | 74 | @Test 75 | public void testReadingJobFile() throws IOException, ParserConfigurationException, SAXException { 76 | String xml = TestsXmlParser.readFile("example-job.xml"); 77 | JobDescriptor actualJobDescriptor = new XmlParser("test", xml).parse(); 78 | 79 | String expectedDSL = readExampleFile(); 80 | 81 | DSLTranslator dslTranslator = new DSLTranslator(actualJobDescriptor); 82 | String actualDSL = dslTranslator.toDSL(); 83 | logAllNotKnownTags(dslTranslator.getNotTranslated()); 84 | 85 | assertEquals(expectedDSL, actualDSL); 86 | 87 | Logger.getAnonymousLogger().log(Level.INFO, actualDSL); 88 | } 89 | 90 | @Test 91 | public void testReadingPipelineJobFile() throws IOException, ParserConfigurationException, SAXException { 92 | readFilesAndTest("example-pipelinejob.xml", "example-pipelinejob.groovy"); 93 | } 94 | 95 | @Test 96 | public void testRealJobFile() throws IOException, ParserConfigurationException, SAXException { 97 | readFilesAndTest("config2.xml", "config2.groovy"); 98 | } 99 | 100 | @Test 101 | public void testRealJobFile2() throws IOException, ParserConfigurationException, SAXException { 102 | readFilesAndTest("ios.xml", "ios.groovy"); 103 | } 104 | 105 | @Test 106 | public void testRealJobFile3() throws IOException, ParserConfigurationException, SAXException { 107 | readFilesAndTest("android.xml", "android.groovy"); 108 | } 109 | 110 | @Test 111 | public void testMultijobJobFile() throws IOException, ParserConfigurationException, SAXException { 112 | readFilesAndTest("example-multijob.xml", "example-multijob.groovy"); 113 | } 114 | 115 | private void logAllNotKnownTags(List notKnownTags) { 116 | for (PropertyDescriptor property : notKnownTags) { 117 | Logger.getAnonymousLogger().log(Level.WARNING, property.getName()); 118 | } 119 | } 120 | } -------------------------------------------------------------------------------- /src/test/java/com/adq/jenkins/xmljobtodsl/TestsXmlParser.java: -------------------------------------------------------------------------------- 1 | package com.adq.jenkins.xmljobtodsl; 2 | 3 | import com.adq.jenkins.xmljobtodsl.parsers.JobDescriptor; 4 | import com.adq.jenkins.xmljobtodsl.parsers.XmlParser; 5 | import com.adq.jenkins.xmljobtodsl.utils.IOUtils; 6 | import org.junit.Test; 7 | import org.xml.sax.SAXException; 8 | 9 | import javax.xml.parsers.ParserConfigurationException; 10 | import java.io.IOException; 11 | 12 | import static org.junit.Assert.assertEquals; 13 | import static org.junit.Assert.assertNotEquals; 14 | 15 | public class TestsXmlParser { 16 | 17 | private static String readExampleFile() { 18 | return readFile("example-job.xml"); 19 | } 20 | 21 | public static String readFile(String name) { 22 | try { 23 | return new IOUtils().readFromResource(name).trim(); 24 | } catch (IOException e) { 25 | throw new RuntimeException("Cannot read file: " + name); 26 | } 27 | } 28 | 29 | @Test 30 | public void testReadFile() { 31 | assertNotEquals("", readExampleFile()); 32 | } 33 | 34 | @Test 35 | public void testParse() throws ParserConfigurationException, SAXException, IOException { 36 | String expected = TestsConstants.getJobDescriptor().toString(); 37 | expected = expected.replaceAll("(\\\\r)", ""); 38 | String actual = new XmlParser("Test", TestsConstants.getXml()).parse().toString(); 39 | assertEquals(expected, actual); 40 | } 41 | 42 | @Test 43 | public void testParseFile() throws ParserConfigurationException, SAXException, IOException { 44 | String tag = readExampleFile(); 45 | JobDescriptor jobDescriptor = new XmlParser("Test", tag).parse(); 46 | assertEquals("project", jobDescriptor.getProperties().get(0).getName()); 47 | } 48 | } -------------------------------------------------------------------------------- /src/test/resources/android.groovy: -------------------------------------------------------------------------------- 1 | job("test") { 2 | description("Build Android") 3 | keepDependencies(false) 4 | parameters { 5 | stringParam("branch", "master", "") 6 | } 7 | scm { 8 | git { 9 | remote { 10 | name("origin") 11 | github("alandoni/xml-job-to-dsl", "ssh") 12 | } 13 | branch("*/\${branch}") 14 | } 15 | } 16 | disabled(false) 17 | concurrentBuild(false) 18 | steps { 19 | shell("""touch app/fabric.properties 20 | echo "apiSecret=asd 21 | apiKey=asd" > app/fabric.properties 22 | 23 | cp app/fabric.properties messagingapp/fabric.properties 24 | 25 | tools/buildnotes.sh""") 26 | gradle { 27 | description() 28 | switches() 29 | tasks("clean assembleRelease") 30 | fromRootBuildScriptDir() 31 | buildFile() 32 | gradleName("(Default)") 33 | useWrapper(true) 34 | makeExecutable(true) 35 | useWorkspaceAsHome(false) 36 | } 37 | gradle { 38 | description() 39 | switches() 40 | tasks("crashlyticsUploadDistributionRelease") 41 | fromRootBuildScriptDir() 42 | buildFile() 43 | gradleName("(Default)") 44 | useWrapper(true) 45 | makeExecutable(true) 46 | useWorkspaceAsHome(false) 47 | } 48 | } 49 | publishers { 50 | archiveArtifacts { 51 | pattern("job/build/outputs/apk/release/*.apk") 52 | allowEmpty(false) 53 | onlyIfSuccessful(false) 54 | fingerprint(false) 55 | defaultExcludes(true) 56 | } 57 | mailer("alan_doni@hotmail.com", false, false) 58 | } 59 | wrappers { 60 | environmentVariables { 61 | env("ANDROID_HOME", "/Users/Shared/Jenkins/android-sdk-macosx/") 62 | env("KEYSTORE_LOCATION", "/Users/Shared/Jenkins/release.jks") 63 | env("KEYSTORE_PASSWORD", "devsonly") 64 | env("KEY_NAME", "androidDevs") 65 | env("KEY_PASSWORD", "androidDevsOnly") 66 | groovy() 67 | } 68 | } 69 | configure { 70 | it / 'properties' / 'jenkins.model.BuildDiscarderProperty' { 71 | strategy { 72 | 'daysToKeep'('-1') 73 | 'numToKeep'('200') 74 | 'artifactDaysToKeep'('-1') 75 | 'artifactNumToKeep'('-1') 76 | } 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /src/test/resources/android.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Build Android 5 | false 6 | 7 | 8 | 9 | -1 10 | 200 11 | -1 12 | -1 13 | 14 | 15 | 16 | 17 | 18 | branch 19 | 20 | master 21 | 22 | 23 | 24 | 25 | 26 | 2 27 | 28 | 29 | origin 30 | git@github.com:alandoni/xml-job-to-dsl.git 31 | 32 | 33 | 34 | 35 | */${branch} 36 | 37 | 38 | false 39 | 40 | 41 | 42 | true 43 | false 44 | false 45 | false 46 | 47 | false 48 | 49 | 50 | touch app/fabric.properties 51 | echo "apiSecret=asd 52 | apiKey=asd" > app/fabric.properties 53 | 54 | cp app/fabric.properties messagingapp/fabric.properties 55 | 56 | tools/buildnotes.sh 57 | 58 | 59 | 60 | 61 | clean assembleRelease 62 | 63 | 64 | (Default) 65 | true 66 | true 67 | false 68 | 69 | false 70 | 71 | 72 | 73 | 74 | crashlyticsUploadDistributionRelease 75 | 76 | 77 | (Default) 78 | true 79 | true 80 | false 81 | 82 | false 83 | 84 | 85 | 86 | 87 | job/build/outputs/apk/release/*.apk 88 | false 89 | false 90 | false 91 | true 92 | true 93 | 94 | 95 | alan_doni@hotmail.com 96 | false 97 | false 98 | 99 | 100 | 101 | 102 | 103 | ANDROID_HOME=/Users/Shared/Jenkins/android-sdk-macosx/ 104 | 105 | KEYSTORE_LOCATION=/Users/Shared/Jenkins/release.jks 106 | KEYSTORE_PASSWORD=devsonly 107 | KEY_NAME=androidDevs 108 | KEY_PASSWORD=androidDevsOnly 109 | 110 | 111 | false 112 | 113 | false 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /src/test/resources/array.groovy: -------------------------------------------------------------------------------- 1 | job("test") { 2 | choiceParam("POD", ["cip1-qa", "cip2-qa", "cip3-qa", "cip4-qa", "qa4", "qa3", "qa5", "qa6", "qa10", "qa12", "qa20", "qa22", "qa24", "qa26", "qa27", "warpdrive"], "OI") 3 | } -------------------------------------------------------------------------------- /src/test/resources/array.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | cip1-qa 6 | cip2-qa 7 | cip3-qa 8 | cip4-qa 9 | qa4 10 | qa3 11 | qa5 12 | qa6 13 | qa10 14 | qa12 15 | qa20 16 | qa22 17 | qa24 18 | qa26 19 | qa27 20 | warpdrive 21 | 22 | 23 | POD 24 | OI 25 | 26 | -------------------------------------------------------------------------------- /src/test/resources/config2.groovy: -------------------------------------------------------------------------------- 1 | job("test") { 2 | description() 3 | keepDependencies(false) 4 | scm { 5 | git { 6 | remote { 7 | name("origin") 8 | github("alandony/xml-job-to-dsl", "ssh") 9 | } 10 | branch("*/master") 11 | } 12 | } 13 | disabled(true) 14 | triggers { 15 | scm("H/45 * * * *") { 16 | ignorePostCommitHooks(false) 17 | } 18 | } 19 | concurrentBuild(false) 20 | steps { 21 | shell("""touch app/fabric.properties 22 | echo "apiSecret=asdasd 23 | apiKey=asdasd" > app/fabric.properties 24 | 25 | cp app/fabric.properties dsl/fabric.properties 26 | 27 | echo "This build comes from the branch [\${GIT_BRANCH}]" > dsl/notes.txt 28 | 29 | #disable release notes because they're constantly too long 30 | LAST_SUCCESS_REV=\$(curl --silent http://localhost:8080/job/DSL/lastSuccessfulBuild/api/xml?xpath=//lastBuiltRevision/SHA1| sed 's|.*\\(.*\\)|\\1|') 31 | git log --no-merges --format='%s [%cE]' \$LAST_SUCCESS_REV..\${GIT_COMMIT} >> dsl/notes.txt""") 32 | gradle { 33 | switches() 34 | tasks("clean assembleDebug crashlyticsUploadDistributionDebug") 35 | fromRootBuildScriptDir() 36 | buildFile() 37 | gradleName("(Default)") 38 | useWrapper(true) 39 | makeExecutable(true) 40 | useWorkspaceAsHome(false) 41 | } 42 | } 43 | publishers { 44 | archiveArtifacts { 45 | pattern("dsl/build/outputs/apk/*.apk") 46 | allowEmpty(false) 47 | onlyIfSuccessful(false) 48 | fingerprint(false) 49 | defaultExcludes(true) 50 | } 51 | mailer("alan_doni@hotmail.com", true, false) 52 | } 53 | wrappers { 54 | environmentVariables { 55 | env("ANDROID_HOME", "/Users/jenkins/android-sdk/") 56 | env("JAVA_HOME", "/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home") 57 | } 58 | } 59 | configure { 60 | it / 'properties' / 'jenkins.model.BuildDiscarderProperty' { 61 | strategy { 62 | 'daysToKeep'('-1') 63 | 'numToKeep'('200') 64 | 'artifactDaysToKeep'('-1') 65 | 'artifactNumToKeep'('-1') 66 | } 67 | } 68 | it / 'properties' / 'com.sonyericsson.rebuild.RebuildSettings' { 69 | 'autoRebuild'('false') 70 | 'rebuildDisabled'('false') 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /src/test/resources/config2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | false 9 | GLOBAL 10 | DISABLED 11 | 12 | 13 | 14 | 15 | -1 16 | 200 17 | -1 18 | -1 19 | 20 | 21 | 22 | false 23 | false 24 | 25 | 26 | 27 | 2 28 | 29 | 30 | origin 31 | git@github.com:alandony/xml-job-to-dsl.git 32 | 33 | 34 | 35 | 36 | */master 37 | 38 | 39 | false 40 | 41 | 42 | 43 | true 44 | true 45 | false 46 | false 47 | 48 | 49 | H/45 * * * * 50 | false 51 | 52 | 53 | false 54 | 55 | 56 | touch app/fabric.properties 57 | echo "apiSecret=asdasd 58 | apiKey=asdasd" > app/fabric.properties 59 | 60 | cp app/fabric.properties dsl/fabric.properties 61 | 62 | echo "This build comes from the branch [${GIT_BRANCH}]" > dsl/notes.txt 63 | 64 | #disable release notes because they're constantly too long 65 | LAST_SUCCESS_REV=$(curl --silent http://localhost:8080/job/DSL/lastSuccessfulBuild/api/xml?xpath=//lastBuiltRevision/SHA1| sed 's|.*<SHA1>\(.*\)</SHA1>|\1|') 66 | git log --no-merges --format='%s [%cE]' $LAST_SUCCESS_REV..${GIT_COMMIT} >> dsl/notes.txt 67 | 68 | 69 | 70 | clean assembleDebug crashlyticsUploadDistributionDebug 71 | 72 | 73 | (Default) 74 | true 75 | true 76 | false 77 | 78 | false 79 | false 80 | 81 | 82 | 83 | 84 | dsl/build/outputs/apk/*.apk 85 | false 86 | false 87 | false 88 | true 89 | true 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | AND 98 | 99 | 100 | false 101 | true 102 | 105 | 106 | 107 | 108 | 109 | alan_doni@hotmail.com 110 | true 111 | false 112 | 113 | 114 | 115 | 116 | 117 | ANDROID_HOME=/Users/jenkins/android-sdk/ 118 | JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home 119 | false 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /src/test/resources/configure-block.groovy: -------------------------------------------------------------------------------- 1 | job("test") { 2 | configure { 3 | it / 'properties' / 'jenkins.model.BuildDiscarderProperty' { 4 | strategy { 5 | 'daysToKeep'('50') 6 | 'numToKeep'('-1') 7 | 'artifactDaysToKeep'('-1') 8 | 'artifactNumToKeep'('-1') 9 | } 10 | } 11 | it / 'builders' / 'au.com.rayh.XCodeBuilder' { 12 | cleanBeforeBuild(true) 13 | cleanTestReports(false) 14 | configuration("Release") 15 | target() 16 | sdk() 17 | symRoot() 18 | buildDir() 19 | xcodeProjectPath("/Users/jenkins/jobs/job-name/workspace/Framework/FrameworkDemo") 20 | xcodeProjectFile() 21 | xcodebuildArguments() 22 | xcodeSchema("ios") 23 | xcodeWorkspaceFile("ios") 24 | cfBundleVersionValue("\${BUILD_NUMBER}") 25 | cfBundleShortVersionStringValue() 26 | buildIpa(false) 27 | ipaExportMethod("ad-hoc") 28 | generateArchive(true) 29 | unlockKeychain(true) 30 | keychainName("none (specify one below)") 31 | keychainPath("/Users/Shared/Jenkins/Library/Keychains/login.keychain") 32 | keychainPwd("App-Name") 33 | developmentTeamName("none (specify one below)") 34 | developmentTeamID("ASD1321ASD") 35 | allowFailingBuildResults(false) 36 | ipaName("\${MARKETING_VERSION}-\${VERSION}") 37 | ipaOutputDirectory() 38 | provideApplicationVersion(true) 39 | changeBundleID(false) 40 | bundleID() 41 | bundleIDInfoPlistPath() 42 | interpretTargetAsRegEx(false) 43 | ipaManifestPlistUrl() 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/test/resources/configure-block.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 50 6 | -1 7 | -1 8 | -1 9 | 10 | 11 | 12 | 13 | 14 | true 15 | false 16 | Release 17 | 18 | 19 | 20 | 21 | /Users/jenkins/jobs/job-name/workspace/Framework/FrameworkDemo 22 | 23 | 24 | ios 25 | ios 26 | ${BUILD_NUMBER} 27 | 28 | false 29 | ad-hoc 30 | true 31 | true 32 | none (specify one below) 33 | /Users/Shared/Jenkins/Library/Keychains/login.keychain 34 | App-Name 35 | none (specify one below) 36 | ASD1321ASD 37 | false 38 | ${MARKETING_VERSION}-${VERSION} 39 | 40 | true 41 | false 42 | 43 | 44 | false 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/test/resources/description.groovy: -------------------------------------------------------------------------------- 1 | job("test") { 2 | description("""Builds a Crashlytics app from origin/master 3 | """) 4 | keepDependencies(false) 5 | } -------------------------------------------------------------------------------- /src/test/resources/description.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Builds a Crashlytics app from origin/master 4 | 5 | false 6 | -------------------------------------------------------------------------------- /src/test/resources/example-job.groovy: -------------------------------------------------------------------------------- 1 | job("test") { 2 | description("This builds app from pull requests") 3 | keepDependencies(false) 4 | blockOn("""Build-iOS-App 5 | Build-Android-App 6 | Run-iOS-Tests 7 | Run-Android-Tests""", { 8 | blockLevel("GLOBAL") 9 | scanQueueFor("DISABLED") 10 | }) 11 | parameters { 12 | stringParam("GIT_BRANCH", "dev", "Name of the branch that will be checked out from Repo") 13 | stringParam("SELECTED_BINARY", "none", "Local path of binary to run the tests against") 14 | booleanParam("REAL_DEVICE", false, """Check this if you want to run on a plugged in device instead of the simulator 15 | Make sure only one device is plugged. 16 | UDID will be automatically fetched""") 17 | choiceParam("PLATFORM", ["Android", "iOS"], "Select the platform to test") 18 | } 19 | environmentVariables { 20 | env("PLATFORM", "iOS") 21 | env("VARIABLE", "value") 22 | loadFilesFromMaster(false) 23 | groovy() 24 | keepSystemVariables(true) 25 | keepBuildVariables(true) 26 | overrideBuildParameters(false) 27 | } 28 | disabled(true) 29 | quietPeriod(5) 30 | displayName("Pipeline") 31 | concurrentBuild(false) 32 | steps { 33 | dsl { 34 | text("def String gitUrl = 'alandoni/xml-job-to-dsl'") 35 | ignoreExisting(false) 36 | removeAction("DELETE") 37 | removeViewAction("IGNORE") 38 | lookupStrategy("JENKINS_ROOT") 39 | } 40 | buildNameUpdater { 41 | buildName("") 42 | macroTemplate("Build App") 43 | fromFile(false) 44 | fromMacro(true) 45 | macroFirst(true) 46 | } 47 | shell("""export PLATFORM=iOS 48 | cd 'xml-job-to-dsl/src/scripts/' 49 | ./run.sh""") 50 | downstreamParameterized { 51 | trigger("Pipeline") { 52 | block { 53 | buildStepFailure("FAILURE") 54 | failure("FAILURE") 55 | unstable("UNSTABLE") 56 | } 57 | parameters { 58 | booleanParam("DEPLOY_TO_CRASHLYTICS", false) 59 | booleanParam("REAL_DEVICE", false) 60 | predefinedProps([EMAILS: "alan_doni@hotmail.com", 61 | REMOTE_USER: "jenkins", 62 | LOG_LEVEL: "warn", 63 | GIT_BRANCH: "dev", 64 | SELECTED_BINARY: "none"]) 65 | } 66 | } 67 | } 68 | gradle { 69 | switches() 70 | tasks("clean :apps:blackberry:assembleRelease :apps:blackberry:crashlyticsUploadDistributionRelease") 71 | fromRootBuildScriptDir() 72 | buildFile() 73 | gradleName("(Default)") 74 | useWrapper(true) 75 | makeExecutable(true) 76 | useWorkspaceAsHome(false) 77 | } 78 | } 79 | publishers { 80 | archiveArtifacts { 81 | pattern("build/**/*") 82 | allowEmpty(false) 83 | defaultExcludes(true) 84 | fingerprint(false) 85 | onlyIfSuccessful(false) 86 | } 87 | richTextPublisher { 88 | stableText("\${FILE:xml-job-to-dsl/tests_report.html} \${FILE:build_variables.html}") 89 | unstableText("") 90 | failedText("") 91 | abortedText("") 92 | nullAction("") 93 | unstableAsStable(true) 94 | failedAsStable(true) 95 | abortedAsStable(true) 96 | parserName("HTML") 97 | } 98 | extendedEmail { 99 | recipientList("alan_doni@hotmail.com") 100 | triggers { 101 | always { 102 | subject("\$PROJECT_DEFAULT_SUBJECT") 103 | content("\$PROJECT_DEFAULT_CONTENT") 104 | attachmentPatterns() 105 | attachBuildLog(false) 106 | compressBuildLog(false) 107 | replyToList("\$PROJECT_DEFAULT_REPLYTO") 108 | contentType("project") 109 | } 110 | } 111 | contentType("default") 112 | defaultSubject("\$DEFAULT_SUBJECT") 113 | defaultContent("\$DEFAULT_CONTENT") 114 | attachmentPatterns() 115 | preSendScript("\$DEFAULT_PRESEND_SCRIPT") 116 | attachBuildLog(true) 117 | compressBuildLog(false) 118 | replyToList("\$DEFAULT_REPLYTO") 119 | saveToWorkspace(false) 120 | disabled(false) 121 | } 122 | postBuildScripts { 123 | steps { 124 | steps { 125 | shell("""git tag "beta-\$BUILD_NUMBER" 126 | git push origin --tags 127 | git remote prune origin""") 128 | } 129 | } 130 | markBuildUnstable(false) 131 | onlyIfBuildSucceeds(true) 132 | onlyIfBuildFails(false) 133 | markBuildUnstable(false) 134 | } 135 | mailer("alan_doni@hotmail.com.com", false, false) 136 | downstream("Other-Project-Name", "SUCCESS") 137 | archiveJunit("*.xml") { 138 | healthScaleFactor(1.0) 139 | allowEmptyResults(false) 140 | } 141 | githubCommitNotifier() 142 | } 143 | wrappers { 144 | credentialsBinding { 145 | string("PASSWORD", "\${PASS_WORD}") 146 | usernamePassword("GITHUB_CREDENTIALS", "jenkins") 147 | } 148 | environmentVariables { 149 | env("ANDROID_HOME", "/Users/jenkins/android-sdk-macosx/") 150 | env("JAVA_HOME", "/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/home") 151 | env("KEYSTORE_LOCATION", "/Users/jenkins/release.jks") 152 | env("KEYSTORE_PASSWORD", "asd") 153 | env("KEY_NAME", "name") 154 | env("KEY_PASSWORD", "pass") 155 | } 156 | timeout { 157 | absolute(30) 158 | } 159 | timestamps() 160 | preBuildCleanup { 161 | deleteDirectories(false) 162 | cleanupParameter() 163 | } 164 | sshAgent("0bdbb6ac-187e-473b-a2c2-12e4c6e87568") 165 | } 166 | logRotator(50) 167 | scm { 168 | git { 169 | remote { 170 | name("origin") 171 | github("alandoni/xml-job-to-dsl", "https") 172 | credentials("jenkins") 173 | } 174 | branch("*/\${GIT_BRANCH}") 175 | extensions { 176 | wipeOutWorkspace() 177 | } 178 | } 179 | } 180 | triggers { 181 | githubPullRequest { 182 | cron("H/5 * * * *") 183 | triggerPhrase("\\QJenkins, build this please\\E") 184 | permitAll(true) 185 | } 186 | githubPush() 187 | scm("H/2 * * * *") { 188 | ignorePostCommitHooks(false) 189 | } 190 | } 191 | configure { 192 | it / 'properties' / 'com.coravy.hudson.plugins.github.GithubProjectProperty' { 193 | 'projectUrl'('https://github.com/alandoni/xml-job-to-dsl/') 194 | } 195 | it / 'properties' / 'com.sonyericsson.rebuild.RebuildSettings' { 196 | 'autoRebuild'('false') 197 | 'rebuildDisabled'('false') 198 | } 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /src/test/resources/example-multijob.groovy: -------------------------------------------------------------------------------- 1 | multiJob("test") { 2 | description() 3 | keepDependencies(false) 4 | parameters { 5 | textParam("POD_NAME", "mobile-aut2", "") 6 | } 7 | disabled(false) 8 | concurrentBuild(false) 9 | steps { 10 | phase("create-pod") { 11 | phaseJob("create-pod-mobile-automation") { 12 | currentJobParameters(true) 13 | exposedScm(false) 14 | disableJob(false) 15 | abortAllJobs(false) 16 | killPhaseCondition("NEVER") 17 | } 18 | continuationCondition("ALWAYS") 19 | executionType("PARALLEL") 20 | } 21 | shell("sleep 1200s") 22 | phase("run smoke tests") { 23 | phaseJob("ios-smoke-tests") { 24 | currentJobParameters(true) 25 | exposedScm(false) 26 | disableJob(false) 27 | abortAllJobs(false) 28 | parameters { 29 | predefinedProp("POD", "warpdrive:\${POD_NAME}-pod1") 30 | predefinedProp("XPOD", "warpdrive-xpod:\${POD_NAME}-pod2") 31 | predefinedProp("METAFILTER", "smoke") 32 | } 33 | killPhaseCondition("NEVER") 34 | } 35 | continuationCondition("ALWAYS") 36 | executionType("PARALLEL") 37 | } 38 | } 39 | pollSubjobs(false) 40 | } -------------------------------------------------------------------------------- /src/test/resources/example-multijob.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | false 9 | GLOBAL 10 | DISABLED 11 | 12 | 13 | 14 | 15 | 16 | POD_NAME 17 | 18 | mobile-aut2 19 | 20 | 21 | 22 | 23 | 24 | true 25 | false 26 | false 27 | false 28 | 29 | false 30 | 31 | 32 | create-pod 33 | 34 | 35 | create-pod-mobile-automation 36 | true 37 | false 38 | false 39 | 40 | 0 41 | false 42 | false 43 | false 44 | 45 | 46 | NEVER 47 | false 48 | false 49 | 50 | 51 | ALWAYS 52 | PARALLEL 53 | 54 | 55 | sleep 1200s 56 | 57 | 58 | run smoke tests 59 | 60 | 61 | ios-smoke-tests 62 | true 63 | false 64 | false 65 | 66 | 0 67 | false 68 | false 69 | false 70 | 71 | 72 | 73 | POD=warpdrive:${POD_NAME}-pod1 74 | XPOD=warpdrive-xpod:${POD_NAME}-pod2 75 | METAFILTER=smoke 76 | 77 | 78 | NEVER 79 | false 80 | false 81 | 82 | 83 | ALWAYS 84 | PARALLEL 85 | 86 | 87 | 88 | 89 | false 90 | -------------------------------------------------------------------------------- /src/test/resources/example-pipelinejob.groovy: -------------------------------------------------------------------------------- 1 | pipelineJob("test") { 2 | description("This builds app from pull requests") 3 | keepDependencies(false) 4 | blockOn("""Build-iOS-App 5 | Build-Android-App 6 | Run-iOS-Tests 7 | Run-Android-Tests""", { 8 | blockLevel("GLOBAL") 9 | scanQueueFor("DISABLED") 10 | }) 11 | parameters { 12 | credentialsParam("PASS_WORD") { 13 | description("Credential of type \"Secret Text\" with the password used to log in slave machines") 14 | defaultValue("JenkinsMachinePassword") 15 | type("org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl") 16 | required(false) 17 | } 18 | stringParam("GIT_BRANCH", "dev", "Name of the branch that will be checked out from Repo") 19 | stringParam("SELECTED_BINARY", "none", "Local path of binary to run the tests against") 20 | booleanParam("REAL_DEVICE", false, """Check this if you want to run on a plugged in device instead of the simulator 21 | Make sure only one device is plugged. 22 | UDID will be automatically fetched""") 23 | choiceParam("PLATFORM", ["Android", "iOS"], "Select the platform to test") 24 | } 25 | environmentVariables { 26 | env("PLATFORM", "iOS") 27 | env("VARIABLE", "value") 28 | loadFilesFromMaster(false) 29 | groovy() 30 | keepSystemVariables(true) 31 | keepBuildVariables(true) 32 | overrideBuildParameters(false) 33 | } 34 | disabled(true) 35 | quietPeriod(5) 36 | displayName("Pipeline") 37 | concurrentBuild(false) 38 | steps { 39 | dsl { 40 | text("def String gitUrl = 'alandoni/xml-job-to-dsl'") 41 | ignoreExisting(false) 42 | removeAction("DELETE") 43 | removeViewAction("IGNORE") 44 | lookupStrategy("JENKINS_ROOT") 45 | } 46 | buildNameUpdater { 47 | buildName("") 48 | macroTemplate("Build App") 49 | fromFile(false) 50 | fromMacro(true) 51 | macroFirst(true) 52 | } 53 | shell("""export PLATFORM=iOS 54 | cd 'xml-job-to-dsl/src/scripts/' 55 | ./run.sh""") 56 | downstreamParameterized { 57 | trigger("Pipeline") { 58 | block { 59 | buildStepFailure("FAILURE") 60 | failure("FAILURE") 61 | unstable("UNSTABLE") 62 | } 63 | parameters { 64 | booleanParam("DEPLOY_TO_CRASHLYTICS", false) 65 | booleanParam("REAL_DEVICE", false) 66 | predefinedProps([EMAILS: "alan_doni@hotmail.com", 67 | REMOTE_USER: "jenkins", 68 | LOG_LEVEL: "warn", 69 | GIT_BRANCH: "dev", 70 | SELECTED_BINARY: "none"]) 71 | } 72 | } 73 | } 74 | gradle { 75 | switches() 76 | tasks("clean :apps:blackberry:assembleRelease :apps:blackberry:crashlyticsUploadDistributionRelease") 77 | fromRootBuildScriptDir() 78 | buildFile() 79 | gradleName("(Default)") 80 | useWrapper(true) 81 | makeExecutable(true) 82 | useWorkspaceAsHome(false) 83 | } 84 | } 85 | publishers { 86 | archiveArtifacts { 87 | pattern("build/**/*") 88 | allowEmpty(false) 89 | defaultExcludes(true) 90 | fingerprint(false) 91 | onlyIfSuccessful(false) 92 | } 93 | richTextPublisher { 94 | stableText("""\${FILE:xml-job-to-dsl/tests_report.html} 95 | \${FILE:build_variables.html}""") 96 | unstableText("") 97 | unstableAsStable(true) 98 | failedAsStable(true) 99 | abortedAsStable(true) 100 | parserName("HTML") 101 | failedText("") 102 | abortedText("") 103 | nullAction("") 104 | } 105 | extendedEmail { 106 | recipientList("alan_doni@hotmail.com") 107 | triggers { 108 | always { 109 | subject("\$PROJECT_DEFAULT_SUBJECT") 110 | content("\$PROJECT_DEFAULT_CONTENT") 111 | attachmentPatterns() 112 | attachBuildLog(false) 113 | compressBuildLog(false) 114 | replyToList("\$PROJECT_DEFAULT_REPLYTO") 115 | contentType("project") 116 | } 117 | } 118 | contentType("default") 119 | defaultSubject("\$DEFAULT_SUBJECT") 120 | defaultContent("\$DEFAULT_CONTENT") 121 | attachmentPatterns() 122 | preSendScript("\$DEFAULT_PRESEND_SCRIPT") 123 | attachBuildLog(true) 124 | compressBuildLog(false) 125 | replyToList("\$DEFAULT_REPLYTO") 126 | saveToWorkspace(false) 127 | disabled(false) 128 | } 129 | postBuildScripts { 130 | steps { 131 | steps { 132 | shell("""git tag "beta-\$BUILD_NUMBER" 133 | git push origin --tags 134 | git remote prune origin""") 135 | } 136 | } 137 | markBuildUnstable(false) 138 | onlyIfBuildSucceeds(true) 139 | onlyIfBuildFails(false) 140 | markBuildUnstable(false) 141 | } 142 | mailer("alan_doni@hotmail.com.com", false, false) 143 | downstream("Other-Project-Name", "SUCCESS") 144 | archiveJunit("*.xml") { 145 | healthScaleFactor(1.0) 146 | allowEmptyResults(false) 147 | } 148 | githubCommitNotifier() 149 | } 150 | wrappers { 151 | credentialsBinding { 152 | string("PASSWORD", "\${BUILD_PASS_WORD}") 153 | usernamePassword("GITHUB_CREDENTIALS", "jenkins-mobile") 154 | } 155 | credentialsBinding { 156 | string("PASSWORD", "\${PASS_WORD}") 157 | } 158 | environmentVariables { 159 | env("ANDROID_HOME", "/Users/jenkins/android-sdk-macosx/") 160 | env("JAVA_HOME", "/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/home") 161 | env("KEYSTORE_LOCATION", "/Users/jenkins/release.jks") 162 | env("KEYSTORE_PASSWORD", "asd") 163 | env("KEY_NAME", "name") 164 | env("KEY_PASSWORD", "pass") 165 | } 166 | timeout { 167 | absolute(30) 168 | } 169 | timestamps() 170 | preBuildCleanup { 171 | deleteDirectories(false) 172 | cleanupParameter() 173 | } 174 | sshAgent("asd") 175 | } 176 | logRotator(50) 177 | scm { 178 | git { 179 | remote { 180 | name("origin") 181 | github("alandoni/xml-job-to-dsl", "https") 182 | credentials("jenkins") 183 | } 184 | branch("*/\${GIT_BRANCH}") 185 | extensions { 186 | wipeOutWorkspace() 187 | } 188 | } 189 | } 190 | definition { 191 | cpsScm { 192 | scm { 193 | git { 194 | remote { 195 | github("alandoni/xml-job-to-dsl", "https") 196 | credentials("jenkins") 197 | } 198 | branch("*/\${GIT_BRANCH}") 199 | extensions { 200 | wipeOutWorkspace() 201 | } 202 | } 203 | } 204 | scriptPath("xml-job-to-dsl/src/scripts/pipeline.groovy") 205 | } 206 | } 207 | triggers { 208 | githubPullRequest { 209 | cron("H/5 * * * *") 210 | triggerPhrase("\\QJenkins, build this please\\E") 211 | permitAll(true) 212 | } 213 | githubPush() 214 | scm("H/2 * * * *") { 215 | ignorePostCommitHooks(false) 216 | } 217 | } 218 | configure { 219 | it / 'properties' / 'jenkins.model.BuildDiscarderProperty' { 220 | strategy { 221 | 'daysToKeep'('50') 222 | 'numToKeep'('-1') 223 | 'artifactDaysToKeep'('-1') 224 | 'artifactNumToKeep'('-1') 225 | } 226 | } 227 | it / 'properties' / 'com.coravy.hudson.plugins.github.GithubProjectProperty' { 228 | 'projectUrl'('https://github.com/alandoni/xml-job-to-dsl/') 229 | } 230 | it / 'properties' / 'com.sonyericsson.rebuild.RebuildSettings' { 231 | 'autoRebuild'('false') 232 | 'rebuildDisabled'('false') 233 | } 234 | it / 'builders' / 'au.com.rayh.XCodeBuilder' { 235 | cleanBeforeBuild(true) 236 | cleanTestReports(false) 237 | configuration("Release") 238 | target() 239 | sdk() 240 | symRoot() 241 | buildDir() 242 | xcodeProjectPath("/Users/jenkins/jobs/job-name/workspace/Framework/FrameworkDemo") 243 | xcodeProjectFile() 244 | xcodebuildArguments() 245 | xcodeSchema("ios") 246 | xcodeWorkspaceFile("ios") 247 | cfBundleVersionValue("\${BUILD_NUMBER}") 248 | cfBundleShortVersionStringValue() 249 | buildIpa(false) 250 | ipaExportMethod("ad-hoc") 251 | generateArchive(true) 252 | unlockKeychain(true) 253 | keychainName("none (specify one below)") 254 | keychainPath("/Users/Shared/Jenkins/Library/Keychains/login.keychain") 255 | keychainPwd("App-Name") 256 | developmentTeamName("none (specify one below)") 257 | developmentTeamID("asd") 258 | allowFailingBuildResults(false) 259 | ipaName("\${MARKETING_VERSION}-\${VERSION}") 260 | ipaOutputDirectory() 261 | provideApplicationVersion(true) 262 | changeBundleID(false) 263 | bundleID() 264 | bundleIDInfoPlistPath() 265 | interpretTargetAsRegEx(false) 266 | ipaManifestPlistUrl() 267 | } 268 | } 269 | } 270 | -------------------------------------------------------------------------------- /src/test/resources/example-pipelinejob.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | This builds app from pull requests 5 | false 6 | 7 | 8 | true 9 | Build-iOS-App 10 | Build-Android-App 11 | Run-iOS-Tests 12 | Run-Android-Tests 13 | 14 | GLOBAL 15 | DISABLED 16 | 17 | 18 | 19 | 50 20 | -1 21 | -1 22 | -1 23 | 24 | 25 | 26 | 27 | 28 | PASS_WORD 29 | Credential of type "Secret Text" with the password used to log in slave machines 30 | JenkinsMachinePassword 31 | org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl 32 | false 33 | 34 | 35 | GIT_BRANCH 36 | dev 37 | Name of the branch that will be checked out from Repo 38 | 39 | 40 | SELECTED_BINARY 41 | none 42 | Local path of binary to run the tests against 43 | 44 | 45 | REAL_DEVICE 46 | false 47 | Check this if you want to run on a plugged in device instead of the simulator 48 | Make sure only one device is plugged. 49 | UDID will be automatically fetched 50 | 51 | choiceParam('PLATFORM', ['Android', 'iOS'], 'Select the platform to test') 52 | 53 | 54 | 55 | Android 56 | iOS 57 | 58 | 59 | PLATFORM 60 | Select the platform to test 61 | 62 | 63 | 64 | 65 | https://github.com/alandoni/xml-job-to-dsl/ 66 | 67 | 68 | 69 | PLATFORM=iOS 70 | VARIABLE=value 71 | false 72 | 73 | 74 | false 75 | 76 | 77 | true 78 | true 79 | true 80 | false 81 | 82 | 83 | 84 | false 85 | false 86 | 87 | 88 | true 89 | true 90 | false 91 | false 92 | 5 93 | Pipeline 94 | false 95 | 96 | 97 | def String gitUrl = 'alandoni/xml-job-to-dsl' 98 | 99 | true 100 | false 101 | false 102 | false 103 | false 104 | false 105 | DELETE 106 | IGNORE 107 | IGNORE 108 | JENKINS_ROOT 109 | 110 | 111 | Build App 112 | false 113 | true 114 | true 115 | 116 | 117 | export PLATFORM=iOS 118 | cd 'xml-job-to-dsl/src/scripts/' 119 | ./run.sh 120 | 121 | 122 | 123 | 124 | 125 | Pipeline 126 | ALWAYS 127 | false 128 | 129 | 130 | FAILURE 131 | 2 132 | RED 133 | true 134 | 135 | 136 | FAILURE 137 | 2 138 | RED 139 | true 140 | 141 | 142 | UNSTABLE 143 | 1 144 | YELLOW 145 | true 146 | 147 | 148 | 149 | 150 | 151 | 152 | DEPLOY_TO_CRASHLYTICS 153 | false 154 | 155 | 156 | REAL_DEVICE 157 | false 158 | 159 | 160 | 161 | 162 | EMAILS=alan_doni@hotmail.com 163 | REMOTE_USER=jenkins 164 | LOG_LEVEL=warn 165 | GIT_BRANCH=dev 166 | SELECTED_BINARY=none 167 | 168 | 169 | 170 | false 171 | 172 | 173 | 174 | 175 | 176 | clean :apps:blackberry:assembleRelease :apps:blackberry:crashlyticsUploadDistributionRelease 177 | 178 | 179 | (Default) 180 | true 181 | true 182 | false 183 | 184 | false 185 | false 186 | 187 | 188 | 189 | ${WORKSPACE}/env_vars 190 | Stuff like MARKETING_VERSION & build date/time 191 | 192 | 193 | 194 | true 195 | false 196 | Release 197 | 198 | 199 | 200 | 201 | /Users/jenkins/jobs/job-name/workspace/Framework/FrameworkDemo 202 | 203 | 204 | ios 205 | ios 206 | ${BUILD_NUMBER} 207 | 208 | false 209 | ad-hoc 210 | true 211 | true 212 | none (specify one below) 213 | /Users/Shared/Jenkins/Library/Keychains/login.keychain 214 | App-Name 215 | none (specify one below) 216 | asd 217 | false 218 | ${MARKETING_VERSION}-${VERSION} 219 | 220 | true 221 | false 222 | 223 | 224 | false 225 | 226 | 227 | 228 | 229 | 230 | build/**/* 231 | false 232 | true 233 | false 234 | false 235 | 236 | 237 | ${FILE:xml-job-to-dsl/tests_report.html} 238 | ${FILE:build_variables.html} 239 | 240 | true 241 | true 242 | true 243 | HTML 244 | 245 | 246 | alan_doni@hotmail.com 247 | 248 | 249 | 250 | $PROJECT_DEFAULT_SUBJECT 251 | $PROJECT_DEFAULT_CONTENT 252 | 253 | 254 | 255 | 256 | false 257 | false 258 | $PROJECT_DEFAULT_REPLYTO 259 | project 260 | 261 | 262 | 263 | default 264 | $DEFAULT_SUBJECT 265 | $DEFAULT_CONTENT 266 | 267 | $DEFAULT_PRESEND_SCRIPT 268 | $DEFAULT_POSTSEND_SCRIPT 269 | true 270 | false 271 | $DEFAULT_REPLYTO 272 | false 273 | false 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | AND 282 | 283 | 284 | false 285 | true 286 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | SUCCESS 299 | 300 | BOTH 301 | 302 | 303 | git tag "beta-$BUILD_NUMBER" 304 | git push origin --tags 305 | git remote prune origin 306 | 307 | 308 | 309 | 310 | false 311 | 312 | 313 | 314 | 315 | true 316 | false 317 | false 318 | 319 | 320 | alan_doni@hotmail.com.com 321 | false 322 | false 323 | 324 | 325 | Other-Project-Name 326 | 327 | SUCCESS 328 | 0 329 | BLUE 330 | true 331 | 332 | 333 | 334 | *.xml 335 | false 336 | 1.0 337 | false 338 | 339 | 340 | 341 | 342 | 343 | FAILURE 344 | 345 | 346 | 347 | 348 | 349 | 350 | PASSWORD 351 | ${BUILD_PASS_WORD} 352 | 353 | 354 | GITHUB_CREDENTIALS 355 | jenkins-mobile 356 | 357 | 358 | 359 | 360 | 361 | 362 | PASSWORD 363 | ${PASS_WORD} 364 | 365 | 366 | 367 | 368 | 369 | ANDROID_HOME=/Users/jenkins/android-sdk-macosx/ 370 | JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/home 371 | 372 | KEYSTORE_LOCATION=/Users/jenkins/release.jks 373 | KEYSTORE_PASSWORD=asd 374 | KEY_NAME=name 375 | KEY_PASSWORD=pass 376 | false 377 | 378 | 379 | 380 | 381 | 30 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | false 390 | 391 | 392 | 393 | 394 | 395 | asd 396 | 397 | false 398 | 399 | 400 | 401 | 50 402 | -1 403 | -1 404 | -1 405 | 406 | 407 | 408 | 409 | origin 410 | https://github.com/alandoni/xml-job-to-dsl.git 411 | jenkins 412 | 413 | 414 | 415 | 416 | */${GIT_BRANCH} 417 | 418 | 419 | 2 420 | false 421 | Default 422 | 423 | 424 | 425 | 426 | true 427 | false 428 | 429 | 30 430 | 0 431 | false 432 | 433 | 434 | false 435 | true 436 | true 437 | 438 | false 439 | 440 | 441 | 442 | https://github.com/alandoni/xml-job-to-dsl 443 | 444 | 445 | 446 | 447 | 448 | 449 | https://github.com/alandoni/xml-job-to-dsl.git 450 | jenkins 451 | 452 | 453 | 454 | 455 | */${GIT_BRANCH} 456 | 457 | 458 | 2 459 | false 460 | Default 461 | 462 | 463 | 464 | 465 | https://github.com/alandoni/xml-job-to-dsl/ 466 | 467 | 468 | xml-job-to-dsl/src/scripts/pipeline.groovy 469 | false 470 | 471 | 472 | 473 | H H(2-4) * * 3,5,6 474 | 475 | 476 | H/5 * * * * 477 | 3 478 | 3 479 | 480 | false 481 | 482 | H/5 * * * * 483 | false 484 | false 485 | 486 | false 487 | false 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | eipoc 496 | 497 | 498 | \QJenkins, build this please\E 499 | true 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | false 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | H/2 * * * * 517 | false 518 | 519 | 520 | 521 | Other-Project-Name 522 | 523 | SUCCESS 524 | 0 525 | BLUE 526 | true 527 | 528 | 529 | 530 | 531 | -------------------------------------------------------------------------------- /src/test/resources/example2.groovy: -------------------------------------------------------------------------------- 1 | def String job_name_prefix = '' 2 | if (binding.variables.JOB_NAME_PREFIX) { 3 | job_name_prefix = binding.variables.JOB_NAME_PREFIX 4 | } 5 | 6 | def String gitUrl = 'SymphonyOSF/iOSTest' 7 | def String androidGitUrl = 'SymphonyOSF/SANDROID-CLIENT-APP' 8 | def String iOSGitUrl = 'SymphonyOSF/SIOS-CLIENT-APP' 9 | def String androidDefaultUrls = '10.240.50.18:4724,10.240.50.36:4724,10.240.50.37:4724' 10 | def String iosDefaultUrls = '10.240.50.18:4723,10.240.50.36:4723,10.240.50.37:4723' 11 | 12 | def String testsBlockingJobs = """${job_name_prefix}Build-iOS-App 13 | ${job_name_prefix}Build-Android-App 14 | ${job_name_prefix}Run-iOS-Tests 15 | ${job_name_prefix}Run-Android-Tests 16 | """ 17 | def String prBuilderBlockingJobs = """${job_name_prefix}DSL-iOS-PR-Builder 18 | ${job_name_prefix}DSL-Android-PR-Builder 19 | ${job_name_prefix}DSL-Mobile-Tests-PR-Builder 20 | """ 21 | 22 | def Closure buildNameStep(String macro) { 23 | return { 24 | buildName(null) 25 | fromFile(false) 26 | macroFirst(true) 27 | fromMacro(true) 28 | macroTemplate(macro) 29 | } 30 | } 31 | 32 | def Closure buildParams() { 33 | return { 34 | stringParam('BUILD_HOST', '10.240.50.18', '''The URL of the machine where the app will be built''') 35 | stringParam('BUILD_REMOTE_USER', 'jenkins', '''User of the slave machines to log in''') 36 | credentialsParam('BUILD_PASS_WORD') { 37 | defaultValue('JenkinsMachinePassword') 38 | type('org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl') 39 | description('Credential of type "Secret Text" with the password used to log in slave machines') 40 | } 41 | } 42 | } 43 | 44 | def Closure testParams(defaultUrls) { 45 | return { 46 | stringParam('REMOTE_USER', 'jenkins', '''User of the slave machines to log in''') 47 | credentialsParam('PASS_WORD') { 48 | defaultValue('JenkinsMachinePassword') 49 | type('org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl') 50 | description('Credential of type "Secret Text" with the password used to log in slave machines') 51 | } 52 | choiceParam('POD', ['cip1-qa', 'cip2-qa', 'cip3-qa', 'cip4-qa', 'qa4', 'qa3', 'qa5', 'qa6', 'qa10', 'qa12', 'qa20', 'qa22', 'qa24', 'qa26', 'qa27', 'warpdrive'], '') 53 | choiceParam('XPOD', ['cip3-qa', 'cip2-qa', 'cip1-qa', 'cip4-qa', 'qa4', 'qa3', 'qa5', 'qa6', 'qa10', 'qa12', 'qa20', 'qa22', 'qa24', 'qa26', 'qa27', 'warpdrive'], '') 54 | stringParam('STORIES', 'all', '') 55 | stringParam('TESTRAIL_RUN_ID', 'None', '''Use this to have the tests post their status into an existing Testrail run instead of creating a new one. 56 | Enter the ID of the run into this field or leave it as "None" to have the tests create a new one. 57 | E.g.: 692, 677, 123''') 58 | choiceParam('LOG_LEVEL', ['warn', 'debug', 'info'], 'This is the Appium log level') 59 | stringParam('URLS', defaultUrls, '''List of URL:PORT for all Appium\'s servers 60 | Use ODD Ports for iOS Parallel Tests. 61 | Use EVEN Ports for Android Parallel Tests. 62 | 127.0.0.1 for localhost. 63 | Comma separated''') 64 | choiceParam('METAFILTER', ['none', 'smoke', 'sanity'], '') 65 | booleanParam('DONT_RESET_APP', false, 'Check this if you want to avoid resetting app between stories') 66 | } 67 | } 68 | 69 | def Closure commonParams() { 70 | return { 71 | stringParam('GIT_BRANCH', 'dev', 'Name of the branch that will be checked out from SymphonyOSF/iOSTest Repo') 72 | stringParam('SELECTED_BINARY', 'none', 'Local path of binary to run the tests against') 73 | booleanParam('REAL_DEVICE', false, 'Check this if you want to run on a plugged in device instead of the simulator\n' + 74 | 'Make sure only one device is plugged.\n' + 75 | 'UDID will be automatically fetched') 76 | stringParam('APP_VERSION', 'latest-dev', '''The version of the app used to run the tests against 77 | * The default value "latest-qa" gets the latest github tag starting with "qa-" for the android app repo 78 | * "latest-dev" gets the latest github tag starting with "dev-" from the app repo 79 | 80 | Examples: 81 | latest-qa 82 | latest-dev 83 | qa-123 84 | dev-321 85 | 86 | A list of available versions can be found here: 87 | https://github.com/SymphonyOSF/SANDROID-CLIENT-APP/tags''') 88 | } 89 | } 90 | 91 | def Closure deployParams() { 92 | return { 93 | booleanParam('DEPLOY_TO_CRASHLYTICS', false, '''If everything runs fine, publish the current build to crashlytics''') 94 | stringParam('EMAILS', 'aquintiliano@symphony.com', '''The e-mail of users''') 95 | stringParam('LAST_SUCCESS_COMMIT', '', '''Commit hash of the last success build''') 96 | } 97 | } 98 | 99 | def Closure platformParam() { 100 | return { 101 | choiceParam('PLATFORM', ['Android', 'iOS'], 'Select the platform to test') 102 | } 103 | } 104 | 105 | def githubSettings = { 106 | git { 107 | remote { 108 | github(gitUrl, 'https') 109 | credentials('jenkins-mobile') 110 | } 111 | branch('*/${GIT_BRANCH}') 112 | extensions { 113 | wipeOutWorkspace() 114 | } 115 | } 116 | } 117 | 118 | def Closure prBuilderGithubSettings(githubUrl) { 119 | return { 120 | git { 121 | remote { 122 | github(githubUrl, 'https') 123 | credentials('jenkins-mobile') 124 | } 125 | branch('${ghprbActualCommit}') 126 | extensions { 127 | wipeOutWorkspace() 128 | } 129 | } 130 | } 131 | } 132 | 133 | def Closure buildSteps(buildName, platform) { 134 | return { 135 | buildNameUpdater buildNameStep(buildName) 136 | shell("""export PLATFORM=${platform} 137 | cd 'iOSTest-AppiumTests/src/scripts/' 138 | fab -f build.py fetch_git build_app upload_app 139 | """) 140 | } 141 | } 142 | 143 | def Closure testSteps(buildName, platform) { 144 | return { 145 | buildNameUpdater buildNameStep(buildName) 146 | shell("""export PLATFORM=${platform} 147 | cd 'iOSTest-AppiumTests/src/scripts/' 148 | fab -f test.py initialize_env run_appium run_tests kill_appium 149 | """) 150 | } 151 | } 152 | 153 | def Closure deploySteps(buildName, platform) { 154 | return { 155 | buildNameUpdater buildNameStep(buildName) 156 | shell("""export PLATFORM=${platform} 157 | cd 'iOSTest-AppiumTests/src/scripts/' 158 | fab -f deploy.py deploy 159 | """) 160 | } 161 | } 162 | 163 | def Closure archiveArtifactories(path) { 164 | return { 165 | archiveArtifacts { 166 | pattern(path) 167 | } 168 | } 169 | } 170 | 171 | def Closure publishBuild(path) { 172 | return { 173 | archiveArtifacts { 174 | pattern(path) 175 | } 176 | richTextPublisher { 177 | stableText('''${FILE:iOSTest-AppiumTests/testrail_report.html} 178 | ${FILE:build_variables.html}''') 179 | unstableText('') 180 | failedText('') 181 | abortedText('') 182 | nullAction('') 183 | abortedAsStable(true) 184 | unstableAsStable(true) 185 | failedAsStable(true) 186 | parserName('HTML') 187 | } 188 | } 189 | } 190 | 191 | def blockJobs = { 192 | blockLevel('GLOBAL') 193 | scanQueueFor('DISABLED') 194 | } 195 | 196 | def Closure credentials() { 197 | return { 198 | credentialsBinding { 199 | string('PASSWORD', '${PASS_WORD}') 200 | } 201 | } 202 | } 203 | 204 | def Closure buildCredentials() { 205 | return { 206 | credentialsBinding { 207 | string('PASSWORD', '${BUILD_PASS_WORD}') 208 | usernamePassword('GITHUB_CREDENTIALS', 'jenkins-mobile') 209 | } 210 | } 211 | } 212 | 213 | def Closure envVars(platform) { 214 | return { 215 | env('PLATFORM', platform) 216 | keepBuildVariables(true) 217 | } 218 | } 219 | 220 | def Closure pipelineDefinition(githubSettings) { 221 | return { 222 | cpsScm { 223 | scm githubSettings 224 | scriptPath("iOSTest-AppiumTests/src/scripts/pipeline.groovy") 225 | } 226 | } 227 | } 228 | 229 | def Closure githubTrigger() { 230 | return { 231 | githubPullRequest { 232 | cron('H/5 * * * *') 233 | triggerPhrase('\\QJenkins, build this please\\E') 234 | permitAll() 235 | } 236 | } 237 | } 238 | 239 | def Closure parameterizedTrigger(pipelineName, defaultUrls, branch) { 240 | return { 241 | downstreamParameterized { 242 | trigger(pipelineName) { 243 | block { 244 | buildStepFailure('FAILURE') 245 | failure('FAILURE') 246 | unstable('UNSTABLE') 247 | } 248 | parameters { 249 | booleanParam('DEPLOY_TO_CRASHLYTICS', false) 250 | booleanParam('REAL_DEVICE', false) 251 | predefinedProps([EMAILS: 'giulliano.carnielli@symphony.com', 252 | REMOTE_USER: 'jenkins', 253 | POD: 'cip2-qa', 254 | XPOD: 'cip4-qa', 255 | STORIES: 'all', 256 | TESTRAIL_RUN_ID: 'None', 257 | LOG_LEVEL: 'warn', 258 | URLS: defaultUrls, 259 | METAFILTER: 'sanity', 260 | BUILD_HOST: '10.240.50.18', 261 | BUILD_REMOTE_USER: 'jenkins', 262 | GIT_BRANCH: 'dev', 263 | SELECTED_BINARY: 'none', 264 | APP_VERSION: branch]) 265 | } 266 | } 267 | } 268 | } 269 | } 270 | 271 | def Closure epodStep() { 272 | return { 273 | shell('''if [ "${USE_WARPDRIVE}" == true ]; then 274 | curl -X POST 'https://warpdrive-lab.dev.symphony.com/jenkins/job/AUT-SFE-EPH/buildWithParameters?ENABLE_SELENIUM_TESTS=false&DEPLOYMENT_TIME_TO_LIVE=14400&token=build_ephemeral_pods\' 275 | sleep 3 276 | curl -X GET 'https://warpdrive-lab.dev.symphony.com/jenkins/job/AUT-SFE-EPH/lastBuild/buildNumber' > build-number.txt 277 | else 278 | echo 'Do not use Epod, skipping\' 279 | fi''') 280 | } 281 | } 282 | 283 | job("${job_name_prefix}Build-iOS-App") { 284 | logRotator(50) 285 | parameters commonParams() << buildParams() 286 | scm githubSettings 287 | steps buildSteps('Build iOS App #${BUILD_NUMBER} | ${APP_VERSION}', 'iOS') 288 | publishers publishBuild('build/**/*') 289 | wrappers buildCredentials() 290 | } 291 | 292 | job("${job_name_prefix}Build-Android-App") { 293 | logRotator(50) 294 | parameters commonParams() << buildParams() 295 | scm githubSettings 296 | steps buildSteps('Build Android App #${BUILD_NUMBER} | ${APP_VERSION}', 'Android') 297 | publishers publishBuild('build/**/*') 298 | wrappers buildCredentials() 299 | } 300 | 301 | job("${job_name_prefix}Run-iOS-Tests") { 302 | blockOn(testsBlockingJobs, blockJobs) 303 | logRotator(50) 304 | parameters commonParams() << testParams(iosDefaultUrls) 305 | scm githubSettings 306 | steps testSteps('Test iOS App #${BUILD_NUMBER} | ${APP_VERSION}', 'iOS') 307 | publishers publishBuild('iOSTest-AppiumTests/target/test-output/**/*') 308 | wrappers credentials() 309 | } 310 | 311 | job("${job_name_prefix}Run-Android-Tests") { 312 | blockOn(testsBlockingJobs, blockJobs) 313 | logRotator(50) 314 | parameters commonParams() << testParams(androidDefaultUrls) 315 | scm githubSettings 316 | steps testSteps('Test Android App #${BUILD_NUMBER} | ${APP_VERSION}', 'Android') 317 | publishers publishBuild('iOSTest-AppiumTests/target/test-output/**/*') 318 | wrappers credentials() 319 | } 320 | 321 | job("${job_name_prefix}Deploy-iOS-App") { 322 | blockOn(testsBlockingJobs, blockJobs) 323 | logRotator(50) 324 | parameters commonParams() << deployParams() << buildParams() 325 | scm githubSettings 326 | steps deploySteps('Deploy iOS App #${BUILD_NUMBER}', 'iOS') 327 | publishers publishBuild('artifactory/**/*') 328 | wrappers buildCredentials() 329 | } 330 | 331 | job("${job_name_prefix}Deploy-Android-App") { 332 | blockOn(testsBlockingJobs, blockJobs) 333 | logRotator(50) 334 | parameters commonParams() << deployParams() << buildParams() 335 | scm githubSettings 336 | steps deploySteps('Deploy Android App #${BUILD_NUMBER}', 'Android') 337 | publishers publishBuild('artifactory/**/*') 338 | wrappers buildCredentials() 339 | } 340 | 341 | pipelineJob("${job_name_prefix}Android-Pipeline") { 342 | displayName("${job_name_prefix}Android-Pipeline") 343 | parameters commonParams() << buildParams() << testParams(androidDefaultUrls) << deployParams() 344 | environmentVariables envVars('Android') 345 | definition pipelineDefinition(githubSettings) 346 | wrappers credentials() << buildCredentials() 347 | publishers publishBuild('artifactory/**/*') 348 | } 349 | 350 | pipelineJob("${job_name_prefix}iOS-Pipeline") { 351 | displayName("${job_name_prefix}iOS-Pipeline") 352 | parameters commonParams() << buildParams() << testParams(iosDefaultUrls) << deployParams() 353 | environmentVariables envVars('iOS') 354 | definition pipelineDefinition(githubSettings) 355 | wrappers credentials() << buildCredentials() 356 | } 357 | 358 | job("${job_name_prefix}DSL-Android-PR-Builder") { 359 | disabled() 360 | blockOn(testsBlockingJobs + prBuilderBlockingJobs, blockJobs) 361 | logRotator(50) 362 | scm prBuilderGithubSettings(androidGitUrl) 363 | triggers githubTrigger() 364 | steps parameterizedTrigger("${job_name_prefix}Android-Pipeline", androidDefaultUrls, '${ghprbActualCommit}') 365 | } 366 | 367 | job("${job_name_prefix}DSL-iOS-PR-Builder") { 368 | disabled() 369 | blockOn(testsBlockingJobs + prBuilderBlockingJobs, blockJobs) 370 | logRotator(50) 371 | scm prBuilderGithubSettings(iOSGitUrl) 372 | triggers githubTrigger() 373 | steps parameterizedTrigger("${job_name_prefix}iOS-Pipeline", iosDefaultUrls, '${ghprbActualCommit}') 374 | } 375 | 376 | job("${job_name_prefix}DSL-Mobile-Tests-PR-Builder") { 377 | disabled() 378 | blockOn(testsBlockingJobs + prBuilderBlockingJobs, blockJobs) 379 | logRotator(50) 380 | scm prBuilderGithubSettings(gitUrl) 381 | triggers githubTrigger() 382 | steps parameterizedTrigger('iOS-Pipeline, Android-Pipeline', iosDefaultUrls, 'latest-dev') 383 | } 384 | 385 | job("${job_name_prefix}Trigger-Epod-Run-On-Warpdrive") { 386 | parameters { 387 | booleanParam('USE_WARPDRIVE', false, 'Define if the job should trigger Epod warpdrive build') 388 | } 389 | logRotator(50) 390 | steps epodStep() 391 | publishers archiveArtifactories('build-number.txt') 392 | } 393 | 394 | listView("${job_name_prefix}MobileTest") { 395 | jobs { 396 | name("${job_name_prefix}Build-iOS-App") 397 | name("${job_name_prefix}Build-Android-App") 398 | name("${job_name_prefix}Run-iOS-Tests") 399 | name("${job_name_prefix}Run-Android-Tests") 400 | name("${job_name_prefix}Deploy-Android-App") 401 | name("${job_name_prefix}Deploy-iOS-App") 402 | name("${job_name_prefix}iOS-Pipeline") 403 | name("${job_name_prefix}Android-Pipeline") 404 | name("${job_name_prefix}DSL-Android-PR-Builder") 405 | name("${job_name_prefix}DSL-iOS-PR-Builder") 406 | name("${job_name_prefix}DSL-Mobile-Tests-PR-Builder") 407 | } 408 | columns { 409 | status() 410 | weather() 411 | name() 412 | lastSuccess() 413 | lastFailure() 414 | lastDuration() 415 | buildButton() 416 | } 417 | } 418 | -------------------------------------------------------------------------------- /src/test/resources/ios.groovy: -------------------------------------------------------------------------------- 1 | job("test") { 2 | description("""Builds a Crashlytics app from origin/master 3 | """) 4 | keepDependencies(false) 5 | scm { 6 | git { 7 | remote { 8 | name("origin") 9 | github("alandoni/xml-job-to-dsl", "https") 10 | credentials("abc123") 11 | } 12 | branch("refs/heads/master") 13 | extensions { 14 | wipeOutWorkspace() 15 | } 16 | } 17 | } 18 | quietPeriod(5) 19 | disabled(false) 20 | triggers { 21 | scm("H/30 * * * *") { 22 | ignorePostCommitHooks(false) 23 | } 24 | } 25 | concurrentBuild(false) 26 | steps { 27 | shell("""#!/bin/bash -ex 28 | 29 | env 30 | 31 | YEAR=`date -j -f "%a %b %d %T %Z %Y" "\\`date\\`" "+%Y"` 32 | MONTH=`date -j -f "%a %b %d %T %Z %Y" "\\`date\\`" "+%m"` 33 | DAY=`date -j -f "%a %b %d %T %Z %Y" "\\`date\\`" "+%d"` 34 | version=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "\${WORKSPACE}"/ios/ios-Info.plist` 35 | bundleVersion=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "\${WORKSPACE}"/ios/ios-Info.plist` 36 | MARKETING_VERSION=\$version.\$bundleVersion 37 | 38 | LAST_SUCCESS_REV=\$(curl --fail --silent http://localhost:8080/job/iOS-master/lastSuccessfulBuild/api/xml?xpath=//lastBuiltRevision/SHA1| sed 's|.*\\(.*\\)|\\1|') 39 | 40 | # Store some environment variables in this file 41 | # A later build step ingests these env variables 42 | echo"">\${WORKSPACE}/env_vars 43 | echo "MARKETING_VERSION"=\$MARKETING_VERSION>>\${WORKSPACE}/env_vars 44 | # Capture the MM DD YY at the beginning of the build in case the date changes during the build. (a midnight build) 45 | echo "YEAR"=\$YEAR>>\${WORKSPACE}/env_vars 46 | echo "MONTH"=\$MONTH>>\${WORKSPACE}/env_vars 47 | echo "DAY"=\$DAY>>\${WORKSPACE}/env_vars 48 | 49 | 50 | echo "This build comes from the branch [\${GIT_BRANCH}]" > notes.txt 51 | echo "------------------" >> notes.txt 52 | echo "Marketing Version:" >> notes.txt 53 | echo \$MARKETING_VERSION >> notes.txt 54 | echo "------------------" >> notes.txt 55 | echo "Commits:" >> notes.txt 56 | 57 | # For what those %s & %cE mean, see https://git-scm.com/docs/git-log 58 | # %s means subject (first line of commit) 59 | # %cE means committer's email address 60 | #git log --no-merges --format='%s [%cE]' \$LAST_SUCCESS_REV..\${GIT_COMMIT} >> notes.txt 61 | 62 | # Below changes by Iwan: 63 | # Change to %cN to show committer's name 64 | # Get only the first 20 commits (avoid Crashlytics' 16KB hard limit on changelog when building a different branch from last succesful build) 65 | git log --no-merges --format='%s [%cN]' --max-count=20 \$LAST_SUCCESS_REV..\${GIT_COMMIT} >> notes.txt 66 | 67 | #echo "Server: " >> notes.txt 68 | #echo URL="\$(cat "\${WORKSPACE}"/ios/Constants.h | grep '^\\#define defaultUrlPrefix ' | cut -c 26- )" >> notes.txt 69 | 70 | 71 | #Manually cleaning out the DerivedData directory 72 | echo "Manually cleaning out the DerivedData directory" 73 | echo "rm -rf /Users/jenkins/Library/Developer/Xcode/DerivedData" 74 | rm -rf /Users/jenkins/Library/Developer/Xcode/DerivedData || true""") 75 | shell("""#!/bin/bash -ex 76 | 77 | /usr/local/bin/pod install""") 78 | shell("ditto -c -k --keepParent -rsrc \${WORKSPACE}/Build/Intermediates/ArchiveIntermediates/ios/BuildProductsPath/Release-iphoneos/ios.app.dSYM \${WORKSPACE}/Build/Release-iphoneos/ios-master-\${MARKETING_VERSION}-\${BUILD_NUMBER}-dSYM.zip") 79 | shell("""echo "\${WORKSPACE}/iOS/Vendor/Crashlytics.framework/submit abc123 abc123 -ipaPath \${WORKSPACE}/Build/Release-iphoneos/*ipa -emails alan_doni@hotmail.com -notesPath \${WORKSPACE}/notes.txt -groupAliases Master -notifications YES" 80 | \${WORKSPACE}/iOS/Vendor/Crashlytics.framework/submit abc123 abc123 -ipaPath \${WORKSPACE}/Build/Release-iphoneos/*ipa -emails alan_doni@hotmail.com -notesPath \${WORKSPACE}/notes.txt -groupAliases Master -notifications YES 81 | 82 | 83 | # abc123 84 | echo find \${WORKSPACE}/Build/Intermediates/ArchiveIntermediates/ios/BuildProductsPath/Release-iphoneos -name "*.dSYM" -execdir \${WORKSPACE}/iOS/Vendor/upload-symbols -p ios -a abc123 {} \\; 85 | find \${WORKSPACE}/Build/Intermediates/ArchiveIntermediates/ios/BuildProductsPath/Release-iphoneos -name "*.dSYM" -execdir \${WORKSPACE}/iOS/Vendor/upload-symbols -p ios -a abc123 {} \\;""") 86 | shell("""#cp -v \${WORKSPACE}/Build/*.ipa \$DROPBOX_DIR 87 | #cp -v \${WORKSPACE}/Build/*.zip \$DROPBOX_DIR 88 | 89 | #cp -v \${WORKSPACE}/Build/*.ipa \$DROPBOX_DIR""") 90 | } 91 | publishers { 92 | archiveArtifacts { 93 | pattern("Build/Release-iphoneos/*zip,Build/Release-iphoneos/*ipa") 94 | allowEmpty(false) 95 | onlyIfSuccessful(false) 96 | fingerprint(false) 97 | defaultExcludes(true) 98 | } 99 | githubCommitNotifier() 100 | postBuildScripts { 101 | steps { 102 | steps { 103 | shell("""git tag "ios-master-\$MARKETING_VERSION-\$BUILD_NUMBER" 104 | git push origin --tags""") 105 | } 106 | } 107 | markBuildUnstable(false) 108 | onlyIfBuildSucceeds(true) 109 | onlyIfBuildFails(false) 110 | markBuildUnstable(false) 111 | } 112 | mailer("alan_doni@hotmail.com", false, true) 113 | } 114 | wrappers { 115 | timeout { 116 | absolute(30) 117 | } 118 | timestamps() 119 | } 120 | configure { 121 | it / 'properties' / 'jenkins.model.BuildDiscarderProperty' { 122 | strategy { 123 | 'daysToKeep'('-1') 124 | 'numToKeep'('200') 125 | 'artifactDaysToKeep'('-1') 126 | 'artifactNumToKeep'('-1') 127 | } 128 | } 129 | it / 'properties' / 'com.coravy.hudson.plugins.github.GithubProjectProperty' { 130 | 'projectUrl'('https://github.com/alandoni/xml-job-to-dsl/') 131 | displayName() 132 | } 133 | it / 'properties' / 'com.sonyericsson.rebuild.RebuildSettings' { 134 | 'autoRebuild'('false') 135 | 'rebuildDisabled'('false') 136 | } 137 | it / 'builders' / 'au.com.rayh.XCodeBuilder' { 138 | cleanBeforeBuild(true) 139 | cleanTestReports(false) 140 | configuration("Release") 141 | target() 142 | sdk() 143 | symRoot() 144 | buildDir() 145 | xcodeProjectPath() 146 | xcodeProjectFile() 147 | xcodebuildArguments() 148 | xcodeSchema("ios") 149 | xcodeWorkspaceFile("ios") 150 | cfBundleVersionValue("\${BUILD_NUMBER}") 151 | cfBundleShortVersionStringValue() 152 | buildIpa(true) 153 | ipaExportMethod("ad-hoc") 154 | generateArchive(true) 155 | unlockKeychain(true) 156 | keychainName("none (specify one below)") 157 | keychainPath("/Users/jenkins/Library/Keychains/login.keychain") 158 | keychainPwd("abc123") 159 | developmentTeamName("none (specify one below)") 160 | developmentTeamID("abc123") 161 | allowFailingBuildResults(false) 162 | ipaName("ios-master-\${MARKETING_VERSION}-\${BUILD_NUMBER}") 163 | ipaOutputDirectory() 164 | provideApplicationVersion(true) 165 | changeBundleID(false) 166 | bundleID() 167 | bundleIDInfoPlistPath() 168 | interpretTargetAsRegEx(false) 169 | ipaManifestPlistUrl() 170 | } 171 | } 172 | } -------------------------------------------------------------------------------- /src/test/resources/ios.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Builds a Crashlytics app from origin/master 5 | 6 | false 7 | 8 | 9 | false 10 | GLOBAL 11 | DISABLED 12 | 13 | 14 | 15 | 16 | -1 17 | 200 18 | -1 19 | -1 20 | 21 | 22 | 23 | https://github.com/alandoni/xml-job-to-dsl/ 24 | 25 | 26 | 27 | false 28 | false 29 | 30 | 31 | 32 | 2 33 | 34 | 35 | origin 36 | https://github.com/alandoni/xml-job-to-dsl.git 37 | abc123 38 | 39 | 40 | 41 | 42 | refs/heads/master 43 | 44 | 45 | false 46 | 47 | 48 | 49 | 50 | true 51 | false 52 | 53 | 30 54 | 0 55 | false 56 | 57 | 58 | 59 | 5 60 | true 61 | false 62 | false 63 | false 64 | 65 | 66 | H/30 * * * * 67 | false 68 | 69 | 70 | false 71 | 72 | 73 | #!/bin/bash -ex 74 | 75 | env 76 | 77 | YEAR=`date -j -f "%a %b %d %T %Z %Y" "\`date\`" "+%Y"` 78 | MONTH=`date -j -f "%a %b %d %T %Z %Y" "\`date\`" "+%m"` 79 | DAY=`date -j -f "%a %b %d %T %Z %Y" "\`date\`" "+%d"` 80 | version=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${WORKSPACE}"/ios/ios-Info.plist` 81 | bundleVersion=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${WORKSPACE}"/ios/ios-Info.plist` 82 | MARKETING_VERSION=$version.$bundleVersion 83 | 84 | LAST_SUCCESS_REV=$(curl --fail --silent http://localhost:8080/job/iOS-master/lastSuccessfulBuild/api/xml?xpath=//lastBuiltRevision/SHA1| sed 's|.*<SHA1>\(.*\)</SHA1>|\1|') 85 | 86 | # Store some environment variables in this file 87 | # A later build step ingests these env variables 88 | echo"">${WORKSPACE}/env_vars 89 | echo "MARKETING_VERSION"=$MARKETING_VERSION>>${WORKSPACE}/env_vars 90 | # Capture the MM DD YY at the beginning of the build in case the date changes during the build. (a midnight build) 91 | echo "YEAR"=$YEAR>>${WORKSPACE}/env_vars 92 | echo "MONTH"=$MONTH>>${WORKSPACE}/env_vars 93 | echo "DAY"=$DAY>>${WORKSPACE}/env_vars 94 | 95 | 96 | echo "This build comes from the branch [${GIT_BRANCH}]" > notes.txt 97 | echo "------------------" >> notes.txt 98 | echo "Marketing Version:" >> notes.txt 99 | echo $MARKETING_VERSION >> notes.txt 100 | echo "------------------" >> notes.txt 101 | echo "Commits:" >> notes.txt 102 | 103 | # For what those %s & %cE mean, see https://git-scm.com/docs/git-log 104 | # %s means subject (first line of commit) 105 | # %cE means committer's email address 106 | #git log --no-merges --format='%s [%cE]' $LAST_SUCCESS_REV..${GIT_COMMIT} >> notes.txt 107 | 108 | # Below changes by Iwan: 109 | # Change to %cN to show committer's name 110 | # Get only the first 20 commits (avoid Crashlytics' 16KB hard limit on changelog when building a different branch from last succesful build) 111 | git log --no-merges --format='%s [%cN]' --max-count=20 $LAST_SUCCESS_REV..${GIT_COMMIT} >> notes.txt 112 | 113 | #echo "Server: " >> notes.txt 114 | #echo URL="$(cat "${WORKSPACE}"/ios/Constants.h | grep '^\#define defaultUrlPrefix ' | cut -c 26- )" >> notes.txt 115 | 116 | 117 | #Manually cleaning out the DerivedData directory 118 | echo "Manually cleaning out the DerivedData directory" 119 | echo "rm -rf /Users/jenkins/Library/Developer/Xcode/DerivedData" 120 | rm -rf /Users/jenkins/Library/Developer/Xcode/DerivedData || true 121 | 122 | 123 | 124 | 125 | 126 | ${WORKSPACE}/env_vars 127 | Stuff like MARKETING_VERSION & build date/time 128 | 129 | 130 | 131 | #!/bin/bash -ex 132 | 133 | /usr/local/bin/pod install 134 | 135 | 136 | true 137 | false 138 | Release 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | ios 147 | ios 148 | ${BUILD_NUMBER} 149 | 150 | true 151 | ad-hoc 152 | true 153 | true 154 | none (specify one below) 155 | /Users/jenkins/Library/Keychains/login.keychain 156 | abc123 157 | none (specify one below) 158 | abc123 159 | false 160 | ios-master-${MARKETING_VERSION}-${BUILD_NUMBER} 161 | 162 | true 163 | false 164 | 165 | 166 | false 167 | 168 | 169 | 170 | ditto -c -k --keepParent -rsrc ${WORKSPACE}/Build/Intermediates/ArchiveIntermediates/ios/BuildProductsPath/Release-iphoneos/ios.app.dSYM ${WORKSPACE}/Build/Release-iphoneos/ios-master-${MARKETING_VERSION}-${BUILD_NUMBER}-dSYM.zip 171 | 172 | 173 | echo "${WORKSPACE}/iOS/Vendor/Crashlytics.framework/submit abc123 abc123 -ipaPath ${WORKSPACE}/Build/Release-iphoneos/*ipa -emails alan_doni@hotmail.com -notesPath ${WORKSPACE}/notes.txt -groupAliases Master -notifications YES" 174 | ${WORKSPACE}/iOS/Vendor/Crashlytics.framework/submit abc123 abc123 -ipaPath ${WORKSPACE}/Build/Release-iphoneos/*ipa -emails alan_doni@hotmail.com -notesPath ${WORKSPACE}/notes.txt -groupAliases Master -notifications YES 175 | 176 | 177 | # abc123 178 | echo find ${WORKSPACE}/Build/Intermediates/ArchiveIntermediates/ios/BuildProductsPath/Release-iphoneos -name "*.dSYM" -execdir ${WORKSPACE}/iOS/Vendor/upload-symbols -p ios -a abc123 {} \; 179 | find ${WORKSPACE}/Build/Intermediates/ArchiveIntermediates/ios/BuildProductsPath/Release-iphoneos -name "*.dSYM" -execdir ${WORKSPACE}/iOS/Vendor/upload-symbols -p ios -a abc123 {} \; 180 | 181 | 182 | #cp -v ${WORKSPACE}/Build/*.ipa $DROPBOX_DIR 183 | #cp -v ${WORKSPACE}/Build/*.zip $DROPBOX_DIR 184 | 185 | #cp -v ${WORKSPACE}/Build/*.ipa $DROPBOX_DIR 186 | 187 | 188 | 189 | 190 | 191 | Build/Release-iphoneos/*zip,Build/Release-iphoneos/*ipa 192 | false 193 | false 194 | false 195 | true 196 | false 197 | 198 | 199 | 200 | 201 | 202 | FAILURE 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | SUCCESS 212 | 213 | BOTH 214 | 215 | 216 | git tag "ios-master-$MARKETING_VERSION-$BUILD_NUMBER" 217 | git push origin --tags 218 | 219 | 220 | 221 | 222 | false 223 | 224 | 225 | 226 | 227 | true 228 | false 229 | false 230 | 231 | 232 | alan_doni@hotmail.com 233 | false 234 | true 235 | 236 | 237 | 238 | 239 | 240 | 30 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /src/test/resources/object_parameter.groovy: -------------------------------------------------------------------------------- 1 | job("test") { 2 | blockOn("""Build-iOS-App 3 | Build-Android-App 4 | Run-iOS-Tests 5 | Run-Android-Tests""", { 6 | blockLevel("GLOBAL") 7 | scanQueueFor("DISABLED") 8 | }) 9 | configure { 10 | it / 'properties' / 'com.coravy.hudson.plugins.github.GithubProjectProperty' { 11 | 'projectUrl'('https://github.com/SymphonyOSF/iOSTest/') 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/test/resources/object_parameter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | Build-iOS-App 6 | Build-Android-App 7 | Run-iOS-Tests 8 | Run-Android-Tests 9 | 10 | GLOBAL 11 | DISABLED 12 | 13 | 14 | https://github.com/SymphonyOSF/iOSTest/ 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/test/resources/scm.groovy: -------------------------------------------------------------------------------- 1 | job("test") { 2 | scm { 3 | git { 4 | remote { 5 | github("alandoni/xml-job-to-dsl", "https") 6 | credentials("jenkins") 7 | } 8 | branch("*/\${GIT_BRANCH}") 9 | extensions { 10 | wipeOutWorkspace() 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/test/resources/scm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | https://github.com/alandoni/xml-job-to-dsl 6 | jenkins 7 | 8 | 9 | 10 | 11 | */${GIT_BRANCH} 12 | 13 | 14 | 2 15 | false 16 | Default 17 | 18 | 19 | 20 | 21 | https://github.com/alandoni/xml-job-to-dsl 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/test/resources/scm2.groovy: -------------------------------------------------------------------------------- 1 | job("test") { 2 | scm { 3 | git { 4 | remote { 5 | github("https://git.ourdomain.com:8444/scm/chef/chef-job-dsl-config.git", "https") 6 | credentials("gituser") 7 | } 8 | branch("branches/INFRA-2353") 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/resources/scm2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2 4 | 5 | 6 | 7 | https://git.ourdomain.com:8444/scm/chef/chef-job-dsl-config.git 8 | 9 | gituser 10 | 11 | 12 | 13 | 14 | branches/INFRA-2353 15 | 16 | 17 | false 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/test/resources/view.groovy: -------------------------------------------------------------------------------- 1 | listView("test") { 2 | jobs { 3 | name("test1") 4 | name("test2") 5 | } 6 | columns { 7 | status() 8 | weather() 9 | name() 10 | lastSuccess() 11 | lastFailure() 12 | lastDuration() 13 | buildButton() 14 | } 15 | } --------------------------------------------------------------------------------