jujube 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +9 -0
- data/.yardopts +4 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +180 -0
- data/Rakefile +15 -0
- data/acceptance/fixtures/endToEnd/endToEnd.job +43 -0
- data/acceptance/fixtures/endToEnd/expected.yml +80 -0
- data/acceptance/fixtures/multipleFiles/job1.job +1 -0
- data/acceptance/fixtures/multipleFiles/job2.job +1 -0
- data/acceptance/fixtures/multipleJobs/test.job +2 -0
- data/acceptance/fixtures/nestedDirectories/job1.job +1 -0
- data/acceptance/fixtures/nestedDirectories/nested/job2.job +1 -0
- data/acceptance/fixtures/singleJob/test.job +3 -0
- data/acceptance/jujube/acceptance_test.rb +47 -0
- data/acceptance/jujube/end_to_end_test.rb +13 -0
- data/acceptance/jujube/usage_test.rb +90 -0
- data/bin/jujube +5 -0
- data/jujube.gemspec +29 -0
- data/lib/jujube.rb +6 -0
- data/lib/jujube/components.rb +23 -0
- data/lib/jujube/components/builders.rb +19 -0
- data/lib/jujube/components/helpers.rb +40 -0
- data/lib/jujube/components/macros.rb +31 -0
- data/lib/jujube/components/notifications.rb +11 -0
- data/lib/jujube/components/parameters.rb +50 -0
- data/lib/jujube/components/publishers.rb +97 -0
- data/lib/jujube/components/scm.rb +19 -0
- data/lib/jujube/components/triggers.rb +105 -0
- data/lib/jujube/components/wrappers.rb +28 -0
- data/lib/jujube/driver.rb +78 -0
- data/lib/jujube/dsl.rb +43 -0
- data/lib/jujube/job.rb +226 -0
- data/lib/jujube/job_file_generator.rb +17 -0
- data/lib/jujube/job_loader.rb +51 -0
- data/lib/jujube/macros.rb +35 -0
- data/lib/jujube/utils.rb +27 -0
- data/lib/jujube/version.rb +5 -0
- data/test/components/builders_test.rb +10 -0
- data/test/components/parameters_test.rb +15 -0
- data/test/components/publishers_test.rb +51 -0
- data/test/components/scm_test.rb +11 -0
- data/test/components/triggers_test.rb +81 -0
- data/test/components/wrappers_test.rb +19 -0
- data/test/driver_test.rb +47 -0
- data/test/job_test.rb +79 -0
- data/test/test_helper.rb +4 -0
- metadata +186 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative "acceptance_test.rb"
|
2
|
+
require "minitest/autorun"
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
class EndToEndTest < AcceptanceTest
|
6
|
+
def test_end_to_end
|
7
|
+
with_fixture("endToEnd") do
|
8
|
+
run_jujube("endToEnd.job")
|
9
|
+
assert_exits_cleanly
|
10
|
+
assert_equal(YAML.load_file("expected.yml"), YAML.load_file("jobs.yml"))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require_relative "acceptance_test.rb"
|
2
|
+
require "minitest/autorun"
|
3
|
+
|
4
|
+
class UsageTest < AcceptanceTest
|
5
|
+
|
6
|
+
def test_generates_single_job
|
7
|
+
with_fixture("singleJob") do
|
8
|
+
run_jujube("test.job")
|
9
|
+
assert_exits_cleanly
|
10
|
+
assert_file_exists("jobs.yml")
|
11
|
+
assert_job_created("example")
|
12
|
+
assert_match(/^\s*description: DESCRIPTION\s*$/m, File.read("jobs.yml"))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_generates_multiple_jobs_from_single_file
|
17
|
+
with_fixture("multipleJobs") do
|
18
|
+
run_jujube("test.job")
|
19
|
+
assert_exits_cleanly
|
20
|
+
assert_file_exists("jobs.yml")
|
21
|
+
assert_job_created("job1")
|
22
|
+
assert_job_created("job2")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_generates_jobs_from_multiple_files
|
27
|
+
with_fixture("multipleFiles") do
|
28
|
+
run_jujube("job1.job", "job2.job")
|
29
|
+
assert_exits_cleanly
|
30
|
+
assert_file_exists("jobs.yml")
|
31
|
+
assert_job_created("job1")
|
32
|
+
assert_job_created("job2")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_generates_jobs_from_all_files_in_current_directory_by_default
|
37
|
+
with_fixture("multipleFiles") do
|
38
|
+
run_jujube
|
39
|
+
assert_exits_cleanly
|
40
|
+
assert_file_exists("jobs.yml")
|
41
|
+
assert_job_created("job1")
|
42
|
+
assert_job_created("job2")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_generates_jobs_from_all_files_in_directory
|
47
|
+
with_fixture("multipleFiles") do
|
48
|
+
run_jujube(".")
|
49
|
+
assert_exits_cleanly
|
50
|
+
assert_file_exists("jobs.yml")
|
51
|
+
assert_job_created("job1")
|
52
|
+
assert_job_created("job2")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_generates_jobs_from_all_recursive_files_in_directory
|
57
|
+
with_fixture("multipleFiles") do
|
58
|
+
run_jujube(".")
|
59
|
+
assert_exits_cleanly
|
60
|
+
assert_file_exists("jobs.yml")
|
61
|
+
assert_job_created("job1")
|
62
|
+
assert_job_created("job2")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_places_output_in_current_directory_by_default
|
67
|
+
with_fixture("multipleFiles") do
|
68
|
+
run_jujube(".")
|
69
|
+
assert_exits_cleanly
|
70
|
+
assert_file_exists("jobs.yml")
|
71
|
+
assert_job_created("job1")
|
72
|
+
assert_job_created("job2")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_places_output_in_specified_output_file
|
77
|
+
with_fixture("singleJob") do
|
78
|
+
run_jujube("test.job", "-o", "output/my_jobs.yml")
|
79
|
+
assert_exits_cleanly
|
80
|
+
assert_directory_exists("output")
|
81
|
+
assert_file_exists("output/my_jobs.yml")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def assert_job_created(job, output_file = "jobs.yml")
|
88
|
+
assert_match(/^- job:\s*\n name: #{job}$/m, File.read(output_file))
|
89
|
+
end
|
90
|
+
end
|
data/bin/jujube
ADDED
data/jujube.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'jujube/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "jujube"
|
8
|
+
spec.version = Jujube::VERSION
|
9
|
+
spec.authors = ["Randy Coulman"]
|
10
|
+
spec.email = ["rcoulman@gmail.com"]
|
11
|
+
spec.description = <<EOF
|
12
|
+
Jujube provides a Ruby front-end for specifying Jenkins jobs. It generates YAML files that
|
13
|
+
are then used as input for jenkins-job-builder.
|
14
|
+
EOF
|
15
|
+
spec.summary = %q{Ruby front-end for jenkins-job-builder}
|
16
|
+
spec.homepage = "https://github.com/randycoulman/jujube"
|
17
|
+
spec.license = "MIT"
|
18
|
+
|
19
|
+
spec.files = `git ls-files`.split($/)
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features|acceptance)/})
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.1"
|
26
|
+
spec.add_development_dependency "minitest", "~> 5.3"
|
27
|
+
spec.add_development_dependency "flexmock", "~> 1.3"
|
28
|
+
spec.add_development_dependency "yard", "~>0.8.7"
|
29
|
+
end
|
data/lib/jujube.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative "components/macros"
|
2
|
+
require_relative "components/helpers"
|
3
|
+
require_relative "components/parameters"
|
4
|
+
require_relative "components/scm"
|
5
|
+
require_relative "components/triggers"
|
6
|
+
require_relative "components/wrappers"
|
7
|
+
require_relative "components/builders"
|
8
|
+
require_relative "components/publishers"
|
9
|
+
require_relative "components/notifications"
|
10
|
+
|
11
|
+
module Jujube
|
12
|
+
# Helper methods for creating jenkins-job-builder components.
|
13
|
+
module Components
|
14
|
+
include Helpers
|
15
|
+
include Parameters
|
16
|
+
include Scm
|
17
|
+
include Triggers
|
18
|
+
include Wrappers
|
19
|
+
include Builders
|
20
|
+
include Publishers
|
21
|
+
include Notifications
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Jujube
|
2
|
+
module Components
|
3
|
+
|
4
|
+
# Helper methods for creating builder components.
|
5
|
+
module Builders
|
6
|
+
|
7
|
+
# Specify a `shell` builder for a job.
|
8
|
+
#
|
9
|
+
# See {http://ci.openstack.org/jenkins-job-builder/builders.html#builders.shell}.
|
10
|
+
#
|
11
|
+
# @param command [String] The shell command to execute.
|
12
|
+
# @return [Hash] The specification for the component.
|
13
|
+
def shell(command)
|
14
|
+
{'shell' => command}
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Jujube
|
2
|
+
module Components
|
3
|
+
|
4
|
+
# Helper methods for working with options hashes.
|
5
|
+
module Helpers
|
6
|
+
include Jujube::Utils
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# Build a named array of nested configuration options by yielding to a client-supplied
|
11
|
+
# block.
|
12
|
+
#
|
13
|
+
# @param name [Symbol] The name of the nested configuration options.
|
14
|
+
# @param options [Hash] Additional top-level configuration options.
|
15
|
+
# @return [Hash] A named configuration that includes the top-level options and all
|
16
|
+
# nested options provided by the client's block.
|
17
|
+
# @yieldparam nested [Array] The array of nested options to be built up by the
|
18
|
+
# client-provided block.
|
19
|
+
def nested_options(name, options = {})
|
20
|
+
nested = []
|
21
|
+
yield(nested) if block_given?
|
22
|
+
options.merge!(name => nested) unless nested.empty?
|
23
|
+
options
|
24
|
+
end
|
25
|
+
|
26
|
+
# Convert a name and a set of named options into the canonical `Hash` format
|
27
|
+
# required by jenkins-job-builder.
|
28
|
+
#
|
29
|
+
# @param key [Symbol] The name for the options.
|
30
|
+
# @param options [Hash] The named options.
|
31
|
+
# @return [Hash, String] The resulting canonical `Hash`. If no options are
|
32
|
+
# provided, then just the `canonicalize`d name will be returned.
|
33
|
+
def to_config(key, options)
|
34
|
+
return key if options.empty?
|
35
|
+
|
36
|
+
{key => canonicalize_options(options)}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Jujube
|
2
|
+
module Components
|
3
|
+
|
4
|
+
# Macros for defining components and their nested configuration elements
|
5
|
+
module Macros
|
6
|
+
include Jujube::Utils
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# A macro that defines a standard component. A standard
|
11
|
+
# component has a name and a `Hash` of named options. The name and all option
|
12
|
+
# keys are {#canonicalize}d.
|
13
|
+
#
|
14
|
+
# @param name [Symbol] The name of the component to generate.
|
15
|
+
def standard_component(name)
|
16
|
+
named_config(name)
|
17
|
+
end
|
18
|
+
|
19
|
+
# A macro that defines methods that generate a standard named
|
20
|
+
# configuration. A standard named configuration has a name and a `Hash`
|
21
|
+
# of named options. The names and all option keys are {#canonicalize}d.
|
22
|
+
#
|
23
|
+
# @param name [Symbol] The name of the method to generate.
|
24
|
+
def named_config(name)
|
25
|
+
define_method(name) do |options = {}|
|
26
|
+
to_config(canonicalize(name), options)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Jujube
|
2
|
+
module Components
|
3
|
+
|
4
|
+
# Helper methods for creating job parameter components.
|
5
|
+
module Parameters
|
6
|
+
|
7
|
+
# @!group Matrix Axes
|
8
|
+
|
9
|
+
# Specify a `label-expression` axis for a matrix job.
|
10
|
+
#
|
11
|
+
# See {http://ci.openstack.org/jenkins-job-builder/project_matrix.html}.
|
12
|
+
#
|
13
|
+
# @param name [Symbol, String] The name of the axis.
|
14
|
+
# @param values [Array<String>] The values of the axis.
|
15
|
+
# @return [Hash] The specification for the axis.
|
16
|
+
def label_expression(name, values)
|
17
|
+
axis(name, values, :label_expression)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Specify a `slave` axis for a matrix job.
|
21
|
+
#
|
22
|
+
# See {http://ci.openstack.org/jenkins-job-builder/project_matrix.html}.
|
23
|
+
#
|
24
|
+
# @param name [Symbol, String] The name of the axis.
|
25
|
+
# @param values [Array<String>] The values of the axis.
|
26
|
+
# @return [Hash] The specification for the axis.
|
27
|
+
def slave(name, values)
|
28
|
+
axis(name, values, :slave)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Specify an axis for a matrix job.
|
34
|
+
#
|
35
|
+
# See {http://ci.openstack.org/jenkins-job-builder/project_matrix.html}.
|
36
|
+
#
|
37
|
+
# @param name [Symbol, String] The name of the axis.
|
38
|
+
# @param values [Array<String>] The values of the axis.
|
39
|
+
# @param type [Symbol, String] The axis type.
|
40
|
+
# @return [Hash] The specification for the axis.
|
41
|
+
def axis(name, values, type)
|
42
|
+
options = {type: canonicalize(type), name: canonicalize(name), values: values}
|
43
|
+
to_config("axis", options)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @!endgroup
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Jujube
|
2
|
+
module Components
|
3
|
+
|
4
|
+
# Helper methods for creating publisher components.
|
5
|
+
module Publishers
|
6
|
+
extend Macros
|
7
|
+
|
8
|
+
# @!method archive(options = {})
|
9
|
+
# Specify an `archive` component for a job.
|
10
|
+
#
|
11
|
+
# See {http://ci.openstack.org/jenkins-job-builder/publishers.html#publishers.archive}.
|
12
|
+
#
|
13
|
+
# @param options [Hash] The configuration options for the component.
|
14
|
+
# @return [Hash] The specification for the component.
|
15
|
+
standard_component :archive
|
16
|
+
|
17
|
+
# @!method cppcheck(options = {})
|
18
|
+
# Specify a `cppcheck` component for a job.
|
19
|
+
#
|
20
|
+
# See {http://ci.openstack.org/jenkins-job-builder/publishers.html#publishers.cppcheck}.
|
21
|
+
#
|
22
|
+
# @param options [Hash] The configuration options for the component.
|
23
|
+
# @return [Hash] The specification for the component.
|
24
|
+
standard_component :cppcheck
|
25
|
+
|
26
|
+
# @!method email_ext(options = {})
|
27
|
+
# Specify an `email-ext` component for a job.
|
28
|
+
#
|
29
|
+
# See {http://ci.openstack.org/jenkins-job-builder/publishers.html#publishers.email-ext}.
|
30
|
+
#
|
31
|
+
# @param options [Hash] The configuration options for the component.
|
32
|
+
# @return [Hash] The specification for the component.
|
33
|
+
standard_component :email_ext
|
34
|
+
|
35
|
+
# @!method ircbot(options = {})
|
36
|
+
# Specify an `ircbot` component for a job.
|
37
|
+
#
|
38
|
+
# See {http://ci.openstack.org/jenkins-job-builder/publishers.html#publishers.ircbot}.
|
39
|
+
#
|
40
|
+
# @param options [Hash] The configuration options for the component.
|
41
|
+
# @return [Hash] The specification for the component.
|
42
|
+
standard_component :ircbot
|
43
|
+
|
44
|
+
# @!method junit(options = {})
|
45
|
+
# Specify a `junit` component for a job.
|
46
|
+
#
|
47
|
+
# See {http://ci.openstack.org/jenkins-job-builder/publishers.html#publishers.junit}.
|
48
|
+
#
|
49
|
+
# @param options [Hash] The configuration options for the component.
|
50
|
+
# @return [Hash] The specification for the component.
|
51
|
+
standard_component :junit
|
52
|
+
|
53
|
+
# @!method trigger(options = {})
|
54
|
+
# Specify a `trigger` component for a job.
|
55
|
+
#
|
56
|
+
# See {http://ci.openstack.org/jenkins-job-builder/publishers.html#publishers.trigger}.
|
57
|
+
#
|
58
|
+
# @param options [Hash] The configuration options for the component.
|
59
|
+
# @return [Hash] The specification for the component.
|
60
|
+
standard_component :trigger
|
61
|
+
|
62
|
+
# Specify an `xunit` component for a job.
|
63
|
+
#
|
64
|
+
# See {http://ci.openstack.org/jenkins-job-builder/publishers.html#publishers.xunit}.
|
65
|
+
#
|
66
|
+
# `xunit` can publish multiple sets of test results. The specification for each set
|
67
|
+
# of test results is added in a nested configuration block using the {#unittest} method.
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# job "xunit-example" do |j|
|
71
|
+
# j.publishers << xunit do |types|
|
72
|
+
# types << unittest(pattern: "PATTERN", deleteoutput: false)
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
# @param options [Hash] Top-level options for configuring the component.
|
77
|
+
# @yieldparam types [Array] An array to which nested test type specifications should be
|
78
|
+
# added by the block.
|
79
|
+
# @return [Hash] The specification for the component.
|
80
|
+
def xunit(options = {}, &block)
|
81
|
+
to_config("xunit", nested_options(:types, options, &block))
|
82
|
+
end
|
83
|
+
|
84
|
+
# @!group xunit Test Types
|
85
|
+
|
86
|
+
# @!method unittest(options = {})
|
87
|
+
# Configure a `unittest` test type for an {#xunit} component.
|
88
|
+
#
|
89
|
+
# See {http://ci.openstack.org/jenkins-job-builder/publishers.html#publishers.xunit}.
|
90
|
+
#
|
91
|
+
# @param options [Hash] The configuration options for the test type.
|
92
|
+
# @return [Hash] The specification for the test type.
|
93
|
+
named_config :unittest
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Jujube
|
2
|
+
module Components
|
3
|
+
|
4
|
+
# Helper methods for creating SCM components.
|
5
|
+
module Scm
|
6
|
+
extend Macros
|
7
|
+
|
8
|
+
# @!method git(options = {})
|
9
|
+
# Specify a `git` component for a job.
|
10
|
+
#
|
11
|
+
# See {http://ci.openstack.org/jenkins-job-builder/publishers.html#scm.git}.
|
12
|
+
#
|
13
|
+
# @param options [Hash] The configuration options for the component.
|
14
|
+
# @return [Hash] The specification for the component.
|
15
|
+
standard_component :git
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|