jenkins_pipeline_builder 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +4 -0
  5. data/Rakefile +68 -0
  6. data/bin/generate +28 -0
  7. data/config/login.yml +24 -0
  8. data/jenkins_pipeline_builder.gemspec +42 -0
  9. data/lib/jenksin_pipeline_builder.rb +39 -0
  10. data/lib/jenksin_pipeline_builder/builders.rb +72 -0
  11. data/lib/jenksin_pipeline_builder/cli/base.rb +69 -0
  12. data/lib/jenksin_pipeline_builder/cli/helper.rb +68 -0
  13. data/lib/jenksin_pipeline_builder/cli/pipeline.rb +40 -0
  14. data/lib/jenksin_pipeline_builder/cli/view.rb +40 -0
  15. data/lib/jenksin_pipeline_builder/compiler.rb +81 -0
  16. data/lib/jenksin_pipeline_builder/generator.rb +346 -0
  17. data/lib/jenksin_pipeline_builder/job_builder.rb +82 -0
  18. data/lib/jenksin_pipeline_builder/module_registry.rb +82 -0
  19. data/lib/jenksin_pipeline_builder/publishers.rb +113 -0
  20. data/lib/jenksin_pipeline_builder/triggers.rb +38 -0
  21. data/lib/jenksin_pipeline_builder/utils.rb +46 -0
  22. data/lib/jenksin_pipeline_builder/version.rb +25 -0
  23. data/lib/jenksin_pipeline_builder/view.rb +259 -0
  24. data/lib/jenksin_pipeline_builder/wrappers.rb +91 -0
  25. data/lib/jenksin_pipeline_builder/xml_helper.rb +40 -0
  26. data/spec/func_tests/spec_helper.rb +18 -0
  27. data/spec/func_tests/view_spec.rb +93 -0
  28. data/spec/unit_tests/compiler_spec.rb +19 -0
  29. data/spec/unit_tests/fixtures/files/Job-Build-Flow.xml +57 -0
  30. data/spec/unit_tests/fixtures/files/Job-Build-Flow.yaml +22 -0
  31. data/spec/unit_tests/fixtures/files/Job-Build-Maven.xml +90 -0
  32. data/spec/unit_tests/fixtures/files/Job-Build-Maven.yaml +26 -0
  33. data/spec/unit_tests/fixtures/files/Job-DSL.yaml +14 -0
  34. data/spec/unit_tests/fixtures/files/Job-DSL1.xml +27 -0
  35. data/spec/unit_tests/fixtures/files/Job-DSL2.xml +25 -0
  36. data/spec/unit_tests/fixtures/files/Job-Gem-Build.xml +142 -0
  37. data/spec/unit_tests/fixtures/files/Job-Gem-Build.yaml +41 -0
  38. data/spec/unit_tests/fixtures/files/Job-Generate-From-Template.xml +32 -0
  39. data/spec/unit_tests/fixtures/files/Job-Generate-From-Template.yaml +8 -0
  40. data/spec/unit_tests/fixtures/files/Job-Multi-Project.xml +117 -0
  41. data/spec/unit_tests/fixtures/files/Job-Multi-Project.yaml +36 -0
  42. data/spec/unit_tests/fixtures/files/project.yaml +15 -0
  43. data/spec/unit_tests/generator_spec.rb +67 -0
  44. data/spec/unit_tests/module_registry_spec.rb +19 -0
  45. data/spec/unit_tests/resolve_dependencies_spec.rb +230 -0
  46. data/spec/unit_tests/spec_helper.rb +29 -0
  47. metadata +75 -6
@@ -0,0 +1,82 @@
1
+ #
2
+ # Copyright (c) 2014 Igor Moochnick
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ module JenkinsPipelineBuilder
24
+ class JobBuilder
25
+ def self.change_description(description, n_xml)
26
+ desc = n_xml.xpath("//description").first
27
+ desc.content = "#{description}"
28
+ end
29
+
30
+ def self.apply_scm_params(params, n_xml)
31
+ XmlHelper.update_node_text(n_xml, '//scm/localBranch', params[:local_branch]) if params[:local_branch]
32
+ XmlHelper.update_node_text(n_xml, '//scm/recursiveSubmodules', params[:recursive_update]) if params[:recursive_update]
33
+ XmlHelper.update_node_text(n_xml, '//scm/wipeOutWorkspace', params[:wipe_workspace]) if params[:wipe_workspace]
34
+ XmlHelper.update_node_text(n_xml, '//scm/excludedUsers', params[:excuded_users]) if params[:excuded_users]
35
+ end
36
+
37
+ def self.hipchat_notifier(params, n_xml)
38
+ raise "No HipChat room specified" unless params[:room]
39
+
40
+ properties = n_xml.xpath("//properties").first
41
+ Nokogiri::XML::Builder.with(properties) do |xml|
42
+ xml.send('jenkins.plugins.hipchat.HipChatNotifier_-HipChatJobProperty') {
43
+ xml.room params[:room]
44
+ xml.startNotification params[:'start-notify'] || false
45
+ }
46
+ end
47
+ end
48
+
49
+ def self.build_parameters(params, n_xml)
50
+ n_builders = n_xml.xpath('//properties').first
51
+ Nokogiri::XML::Builder.with(n_builders) do |xml|
52
+ xml.send('hudson.model.ParametersDefinitionProperty') {
53
+ xml.parameterDefinitions {
54
+ param_proc = lambda do |xml, name, type, default, description|
55
+ xml.send(type) {
56
+ xml.name name
57
+ xml.description description
58
+ xml.defaultValue default
59
+ }
60
+ end
61
+ params.each do |param|
62
+ case param[:type]
63
+ when 'string'
64
+ paramType = 'hudson.model.StringParameterDefinition'
65
+ when 'bool'
66
+ paramType = 'hudson.model.BooleanParameterDefinition'
67
+ when 'text'
68
+ paramType = 'hudson.model.TextParameterDefinition'
69
+ when 'password'
70
+ paramType = 'hudson.model.PasswordParameterDefinition'
71
+ else
72
+ paramType = 'hudson.model.StringParameterDefinition'
73
+ end
74
+
75
+ param_proc.call xml, param[:name], paramType, param[:default], param[:description]
76
+ end
77
+ }
78
+ }
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,82 @@
1
+ #
2
+ # Copyright (c) 2014 Igor Moochnick
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ module JenkinsPipelineBuilder
24
+ class ModuleRegistry
25
+ attr_accessor :registry
26
+
27
+ def initialize(registry)
28
+ @registry = registry
29
+ end
30
+
31
+ def get(path)
32
+ parts = path.split('/')
33
+ self.get_by_path_collection(parts, @registry)
34
+ end
35
+
36
+ def get_by_path_collection(path, registry)
37
+ item = registry[path.shift.to_sym]
38
+ if path.count == 0
39
+ return item
40
+ end
41
+
42
+ get_by_path_collection(path, item)
43
+ end
44
+
45
+ def traverse_registry_path(path, params, n_xml)
46
+ registry = get(path)
47
+ traverse_registry(registry, params, n_xml)
48
+ end
49
+
50
+ def traverse_registry(registry, params, n_xml)
51
+ params.each do |key, value|
52
+ execute_registry_item(registry, key, value, n_xml)
53
+ end
54
+ end
55
+
56
+ def traverse_registry_param_array(registry, params, n_xml)
57
+ params.each do |item|
58
+ key = item.keys.first
59
+ next if key.nil?
60
+ execute_registry_item(registry, key, item[key], n_xml)
61
+ end
62
+ end
63
+
64
+ def execute_registry_item(registry, key, value, n_xml)
65
+ registry_item = registry[key]
66
+ if registry_item.kind_of?(Hash)
67
+ sub_registry = registry_item[:registry]
68
+ method = registry_item[:method]
69
+ method.call(sub_registry, value, n_xml)
70
+ elsif registry_item.kind_of?(Method)
71
+ registry_item.call(value, n_xml) unless registry_item.nil?
72
+ end
73
+ end
74
+
75
+ def run_registry_on_path(path, registry, params, n_xml)
76
+ n_builders = n_xml.xpath(path).first
77
+ Nokogiri::XML::Builder.with(n_builders) do |xml|
78
+ traverse_registry_param_array(registry, params, xml)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,113 @@
1
+ #
2
+ # Copyright (c) 2014 Igor Moochnick
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ module JenkinsPipelineBuilder
24
+ class Publishers
25
+ def self.description_setter(params, xml)
26
+ xml.send('hudson.plugins.descriptionsetter.DescriptionSetterPublisher') {
27
+ xml.regexp params[:regexp]
28
+ xml.regexpForFailed params[:regexp]
29
+ xml.description params[:description]
30
+ xml.descriptionForFailed params[:description]
31
+ xml.setForMatrix false
32
+ }
33
+ end
34
+
35
+ def self.push_to_projects(params, xml)
36
+ xml.send('hudson.plugins.parameterizedtrigger.BuildTrigger') {
37
+ xml.configs {
38
+ xml.send('hudson.plugins.parameterizedtrigger.BuildTriggerConfig') {
39
+ xml.configs {
40
+ params[:data] = [ { params: "" } ] unless params[:data]
41
+ params[:data].each do |config|
42
+ if config[:params]
43
+ xml.send('hudson.plugins.parameterizedtrigger.PredefinedBuildParameters') {
44
+ xml.properties config[:params]
45
+ }
46
+ end
47
+ if config[:file]
48
+ xml.send('hudson.plugins.parameterizedtrigger.FileBuildParameters') {
49
+ xml.propertiesFile config[:file]
50
+ xml.failTriggerOnMissing false
51
+ }
52
+ end
53
+ end
54
+ }
55
+ xml.projects params[:project]
56
+ xml.condition 'SUCCESS'
57
+ xml.triggerWithNoParameters false
58
+ }
59
+ }
60
+ }
61
+ end
62
+
63
+ def self.push_to_hipchat(params, xml)
64
+ params = {} if params == true
65
+ xml.send('jenkins.plugins.hipchat.HipChatNotifier') {
66
+ xml.jenkinsUrl params[:jenkinsUrl] || ''
67
+ xml.authToken params[:authToken] || ''
68
+ xml.room params[:room] || ''
69
+ }
70
+ end
71
+
72
+ def self.push_to_git(params, xml)
73
+ xml.send('hudson.plugins.git.GitPublisher') {
74
+ xml.configVersion params[:configVersion] || 2
75
+ xml.pushMerge params[:'push-merge'] || false
76
+ xml.pushOnlyIfSuccess params[:'push-only-if-success'] || false
77
+ xml.branchesToPush {
78
+ xml.send('hudson.plugins.git.GitPublisher_-BranchToPush') {
79
+ xml.targetRepoName params[:targetRepoName] || 'origin'
80
+ xml.branchName params[:branchName] || 'master'
81
+ }
82
+ }
83
+ }
84
+ end
85
+
86
+ def self.publish_junit(params, xml)
87
+ xml.send('hudson.tasks.junit.JUnitResultArchiver') {
88
+ xml.testResults params[:test_results] || ''
89
+ xml.keepLongStdio false
90
+ xml.testDataPublishers
91
+ }
92
+ end
93
+
94
+ def self.coverage_metric(name, params, xml)
95
+ xml.send('hudson.plugins.rubyMetrics.rcov.model.MetricTarget') {
96
+ xml.metric name
97
+ xml.healthy params[:healthy]
98
+ xml.unhealthy params[:unhealthy]
99
+ xml.unstable params[:unstable]
100
+ }
101
+ end
102
+
103
+ def self.publish_rcov(params, xml)
104
+ xml.send('hudson.plugins.rubyMetrics.rcov.RcovPublisher') {
105
+ xml.reportDir params[:report_dir]
106
+ xml.targets {
107
+ coverage_metric('TOTAL_COVERAGE', params[:total], xml)
108
+ coverage_metric('CODE_COVERAGE', params[:code], xml)
109
+ }
110
+ }
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,38 @@
1
+ #
2
+ # Copyright (c) 2014 Igor Moochnick
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ module JenkinsPipelineBuilder
24
+ class Triggers
25
+ def self.enable_git_push(git_push, xml)
26
+ xml.send('com.cloudbees.jenkins.GitHubPushTrigger') {
27
+ xml.spec
28
+ }
29
+ end
30
+
31
+ def self.enable_scm_polling(scm_polling, xml)
32
+ xml.send('hudson.triggers.SCMTrigger') {
33
+ xml.spec scm_polling
34
+ xml.ignorePostCommitHooks false
35
+ }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,46 @@
1
+ #
2
+ # Copyright (c) 2014 Igor Moochnick
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ module JenkinsPipelineBuilder
24
+ class ::Hash
25
+ def deep_merge(second)
26
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
27
+ self.merge(second, &merger)
28
+ end
29
+ end
30
+
31
+ class Utils
32
+ # Code was duplicated from jeknins_api_client
33
+ def self.symbolize_keys_deep!(h)
34
+ return unless h.kind_of?(Hash)
35
+ h.keys.each do |k|
36
+ ks = k.respond_to?(:to_sym) ? k.to_sym : k
37
+ h[ks] = h.delete k # Preserve order even when k == ks
38
+ symbolize_keys_deep! h[ks] if h[ks].kind_of? Hash
39
+ if h[ks].kind_of? Array
40
+ #puts "Array #{h[ks]}"
41
+ h[ks].each { |item| symbolize_keys_deep!(item) }
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ #
2
+ # Copyright (c) 2014 Igor Moochnick
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ module JenkinsPipelineBuilder
24
+ VERSION = "0.1.3"
25
+ end
@@ -0,0 +1,259 @@
1
+ #
2
+ # Copyright (c) 2014 Igor Moochnick
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+
23
+ module JenkinsPipelineBuilder
24
+ class View
25
+ # Initializes a new View object.
26
+ #
27
+ # @param generator [Generator] the client object
28
+ #
29
+ # @return [View] the view object
30
+ #
31
+ def initialize(generator)
32
+ @generator = generator
33
+ @client = generator.client
34
+ @logger = @client.logger
35
+ end
36
+
37
+ def generate(path)
38
+ yaml = YAML.load_file(path)
39
+
40
+ yaml.each do |item|
41
+ Utils.symbolize_keys_deep!(item)
42
+ create(item[:view]) if item[:view]
43
+ end
44
+ end
45
+
46
+ def get_mode(type)
47
+ case type
48
+ when 'listview'
49
+ 'hudson.model.ListView'
50
+ when 'myview'
51
+ 'hudson.model.MyView'
52
+ when 'nestedView'
53
+ 'hudson.plugins.nested_view.NestedView'
54
+ when 'categorizedView'
55
+ 'org.jenkinsci.plugins.categorizedview.CategorizedJobsView'
56
+ when 'dashboardView'
57
+ 'hudson.plugins.view.dashboard.Dashboard'
58
+ when 'multijobView'
59
+ 'com.tikal.jenkins.plugins.multijob.views.MultiJobView'
60
+ else
61
+ raise "Type #{type} is not supported by Jenkins."
62
+ end
63
+ end
64
+
65
+ # Creates a new empty view of the given type
66
+ #
67
+ # @param [String] view_name Name of the view to be created
68
+ # @param [String] type Type of view to be created. Valid options:
69
+ # listview, myview. Default: listview
70
+ #
71
+ def create_base_view(view_name, type = 'listview', parent_view_name = nil)
72
+ @logger.info "Creating a view '#{view_name}' of type '#{type}'"
73
+ mode = get_mode(type)
74
+ initial_post_params = {
75
+ 'name' => view_name,
76
+ 'mode' => mode,
77
+ 'json' => {
78
+ 'name' => view_name,
79
+ 'mode' => mode
80
+ }.to_json
81
+ }
82
+
83
+ if @generator.debug
84
+ pp initial_post_params
85
+ return
86
+ end
87
+
88
+ view_path = parent_view_name.nil? ? '' : "/view/#{path_encode parent_view_name}"
89
+ view_path += '/createView'
90
+
91
+ @client.api_post_request(view_path, initial_post_params)
92
+ end
93
+
94
+ # Creates a listview by accepting the given parameters hash
95
+ #
96
+ # @param [Hash] params options to create the new view
97
+ # @option params [String] :name Name of the view
98
+ # @option params [String] :type Description of the view
99
+ # @option params [String] :description Description of the view
100
+ # @option params [String] :status_filter Filter jobs based on the status.
101
+ # Valid options: all_selected_jobs, enabled_jobs_only,
102
+ # disabled_jobs_only. Default: all_selected_jobs
103
+ # @option params [Boolean] :filter_queue true or false
104
+ # @option params [Boolean] :filter_executors true or false
105
+ # @option params [String] :regex Regular expression to filter jobs that
106
+ # are to be added to the view
107
+ #
108
+ # @raise [ArgumentError] if the required parameter +:name+ is not
109
+ # specified
110
+ #
111
+ def create(params)
112
+ # Name is a required parameter. Raise an error if not specified
113
+ raise ArgumentError, "Name is required for creating view" \
114
+ unless params.is_a?(Hash) && params[:name]
115
+ unless @generator.debug
116
+ if @client.view.exists?(params[:name])
117
+ @client.view.delete(params[:name])
118
+ end
119
+ end
120
+ params[:type] = 'listview' unless params[:type]
121
+ create_base_view(params[:name], params[:type], params[:parent_view])
122
+ @logger.debug "Creating a #{params[:type]} view with params: #{params.inspect}"
123
+ status_filter = case params[:status_filter]
124
+ when "all_selected_jobs"
125
+ ""
126
+ when "enabled_jobs_only"
127
+ "1"
128
+ when "disabled_jobs_only"
129
+ "2"
130
+ else
131
+ ""
132
+ end
133
+
134
+ json = {
135
+ "name" => params[:name],
136
+ "description" => params[:description],
137
+ "mode" => get_mode(params[:type]),
138
+ "statusFilter" => "",
139
+ "columns" => get_columns(params[:type])
140
+ }
141
+ json.merge!("groupingRules" => params[:groupingRules]) if params[:groupingRules]
142
+ post_params = {
143
+ "name" => params[:name],
144
+ "mode" => get_mode(params[:type]),
145
+ "description" => params[:description],
146
+ "statusFilter" => status_filter,
147
+ "json" => json.to_json
148
+ }
149
+ post_params.merge!("filterQueue" => "on") if params[:filter_queue]
150
+ post_params.merge!("filterExecutors" => "on") if params[:filter_executors]
151
+ post_params.merge!("useincluderegex" => "on",
152
+ "includeRegex" => params[:regex]) if params[:regex]
153
+
154
+ if @generator.debug
155
+ pp post_params
156
+ return
157
+ end
158
+
159
+ view_path = params[:parent_view].nil? ? '' : "/view/#{path_encode params[:parent_view]}"
160
+ view_path += "/view/#{path_encode params[:name]}/configSubmit"
161
+
162
+ @client.api_post_request(view_path, post_params)
163
+ end
164
+
165
+ def get_columns(type)
166
+ columns_repository = {
167
+ 'Status' =>
168
+ {
169
+ 'stapler-class' => 'hudson.views.StatusColumn',
170
+ 'kind' => 'hudson.views.StatusColumn'
171
+ },
172
+ 'Weather' =>
173
+ {
174
+ "stapler-class" => "hudson.views.WeatherColumn",
175
+ "kind" => "hudson.views.WeatherColumn"
176
+ },
177
+ 'Name' =>
178
+ {
179
+ "stapler-class" => "hudson.views.JobColumn",
180
+ "kind" => "hudson.views.JobColumn"
181
+ },
182
+ 'Last Success' =>
183
+ {
184
+ "stapler-class" => "hudson.views.LastSuccessColumn",
185
+ "kind" => "hudson.views.LastSuccessColumn"
186
+ },
187
+ 'Last Failure' =>
188
+ {
189
+ "stapler-class" => "hudson.views.LastFailureColumn",
190
+ "kind" => "hudson.views.LastFailureColumn"
191
+ },
192
+ 'Last Duration' =>
193
+ {
194
+ "stapler-class" => "hudson.views.LastDurationColumn",
195
+ "kind" => "hudson.views.LastDurationColumn"
196
+ },
197
+ 'Build Button' =>
198
+ {
199
+ 'stapler-class' => 'hudson.views.BuildButtonColumn',
200
+ 'kind' => 'hudson.views.BuildButtonColumn'
201
+ },
202
+ 'Categorized - Job' =>
203
+ {
204
+ 'stapler-class' => 'org.jenkinsci.plugins.categorizedview.IndentedJobColumn',
205
+ 'kind' => 'org.jenkinsci.plugins.categorizedview.IndentedJobColumn'
206
+ }
207
+ }
208
+
209
+ column_names = case type
210
+ when 'categorizedView'
211
+ ['Status', 'Weather', 'Categorized - Job', 'Last Success', 'Last Failure', 'Last Duration', 'Build Button']
212
+ else
213
+ ['Status', 'Weather', 'Name', 'Last Success', 'Last Failure', 'Last Duration', 'Build Button']
214
+ end
215
+
216
+ result = []
217
+ column_names.each do |name|
218
+ result << columns_repository[name]
219
+ end
220
+ return result
221
+ end
222
+
223
+ def path_encode(path)
224
+ URI.escape(path.encode(Encoding::UTF_8))
225
+ end
226
+
227
+ # This method lists all views
228
+ #
229
+ # @param [String] parent_view a name of the parent view
230
+ # @param [String] filter a regex to filter view names
231
+ # @param [Bool] ignorecase whether to be case sensitive or not
232
+ #
233
+ def list_children(parent_view = nil, filter = "", ignorecase = true)
234
+ @logger.info "Obtaining children views of parent #{parent_view} based on filter '#{filter}'"
235
+ view_names = []
236
+ path = parent_view.nil? ? '' : "/view/#{path_encode parent_view}"
237
+ response_json = @client.api_get_request(path)
238
+ response_json["views"].each { |view|
239
+ if ignorecase
240
+ view_names << view["name"] if view["name"] =~ /#{filter}/i
241
+ else
242
+ view_names << view["name"] if view["name"] =~ /#{filter}/
243
+ end
244
+ }
245
+ view_names
246
+ end
247
+
248
+ # Delete a view
249
+ #
250
+ # @param [String] view_name
251
+ #
252
+ def delete(view_name, parent_view = nil)
253
+ @logger.info "Deleting view '#{view_name}'"
254
+ path = parent_view.nil? ? '' : "/view/#{path_encode parent_view}"
255
+ path += "/view/#{path_encode view_name}/doDelete"
256
+ @client.api_post_request(path)
257
+ end
258
+ end
259
+ end