side_boom 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 80ded80fc1fad3ad923d90ea39e238d698593c5c
4
+ data.tar.gz: c3a1351dc07f9aecba775116d11356a402c62650
5
+ SHA512:
6
+ metadata.gz: 452b7b2bdb715808e55a8ac33a372998e44c114087762697c3eabd2eeae9fcebe6348834e751e34dc4e4c59f8f45247548421ef2793b787dcfe9b7ff813e8ee1
7
+ data.tar.gz: b20dcb5a05a304845ffea26c2b2e585c8ae155dea1989aba38a7fe9060838ec3ed76891d29cdb787ebf10a2cd138e8f4fb1f9a3b88bbe09480b43a2a4b397ed4
@@ -0,0 +1,2 @@
1
+ *.sideboom linguist-language=Ruby
2
+ .sideboom gitlab-language=Ruby
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.gem
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
@@ -0,0 +1,33 @@
1
+ # Generated by SideBoom
2
+ ---
3
+ stages:
4
+ - test
5
+ rspec ruby 2.3:
6
+ before_script:
7
+ - bundle install -j 4
8
+ script:
9
+ - bundle exec rspec
10
+ image: ruby:2.3
11
+ stage: test
12
+ rspec ruby 2.4:
13
+ before_script:
14
+ - bundle install -j 4
15
+ script:
16
+ - bundle exec rspec
17
+ image: ruby:2.4
18
+ stage: test
19
+ rspec ruby 2.5:
20
+ before_script:
21
+ - bundle install -j 4
22
+ script:
23
+ - bundle exec rspec
24
+ image: ruby:2.5
25
+ stage: test
26
+ rspec ruby rc:
27
+ before_script:
28
+ - bundle install -j 4
29
+ script:
30
+ - bundle exec rspec
31
+ image: ruby:rc
32
+ allow_failure: true
33
+ stage: test
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,17 @@
1
+ # vim: autoindent tabstop=2 shiftwidth=2 expandtab softtabstop=2 filetype=ruby
2
+ SideBoom::Pipeline.define('.gitlab-ci.yml') do
3
+ RUBY_VERSIONS = %w[2.3 2.4 2.5 rc]
4
+
5
+ before_script 'bundle install -j 4'
6
+ script 'bundle exec rspec'
7
+
8
+ stage 'test' do
9
+ RUBY_VERSIONS.each do |version|
10
+ job "rspec ruby #{version}" do
11
+ image "ruby:#{version}"
12
+
13
+ allow_failure! if version == 'rc'
14
+ end
15
+ end
16
+ end
17
+ end
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in side_boom.gemspec
4
+ gemspec
@@ -0,0 +1,37 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ side_boom (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ byebug (10.0.2)
10
+ diff-lcs (1.3)
11
+ rake (10.5.0)
12
+ rspec (3.8.0)
13
+ rspec-core (~> 3.8.0)
14
+ rspec-expectations (~> 3.8.0)
15
+ rspec-mocks (~> 3.8.0)
16
+ rspec-core (3.8.0)
17
+ rspec-support (~> 3.8.0)
18
+ rspec-expectations (3.8.2)
19
+ diff-lcs (>= 1.2.0, < 2.0)
20
+ rspec-support (~> 3.8.0)
21
+ rspec-mocks (3.8.0)
22
+ diff-lcs (>= 1.2.0, < 2.0)
23
+ rspec-support (~> 3.8.0)
24
+ rspec-support (3.8.0)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ bundler (~> 1.16)
31
+ byebug (~> 10.0)
32
+ rake (~> 10.0)
33
+ rspec (~> 3.0)
34
+ side_boom!
35
+
36
+ BUNDLED WITH
37
+ 1.16.6
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Zeger-Jan van de Weg
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,70 @@
1
+ # SideBoom
2
+
3
+ Creating and maintaining your projects CI/CD specifications with a programming
4
+ language instead of a markup language.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'side_boom'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ ```shell
17
+ $ bundle exec sideboom
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ Examples are found in the [Examples directory](./examples), and as new features
23
+ become available these will be expanded. But just to show:
24
+
25
+ ```ruby
26
+ # Save this to .sideboom
27
+ # Generate output with `sideboom`
28
+ SideBoom::Pipeline.define('.gitlab-ci.yml') do
29
+ RUBY_VERSIONS = %w[2.3 2.4 2.5 rc]
30
+
31
+ before_script ['bundle -j 4']
32
+ script ['bundle exec rspec']
33
+
34
+ stage 'test' do
35
+ RUBY_VERSIONS.each do |version|
36
+ job "rspec ruby #{version}" do
37
+ image "ruby:#{version}"
38
+
39
+ allow_failure! if version == 'rc'
40
+ end
41
+ end
42
+ end
43
+ end
44
+ ```
45
+
46
+ ```yaml
47
+ # Generated by SideBoom
48
+ ---
49
+ stages:
50
+ - test
51
+ rspec ruby 2.3:
52
+ image: ruby:2.3
53
+ stage: test
54
+ rspec ruby 2.4:
55
+ image: ruby:2.4
56
+ stage: test
57
+ rspec ruby 2.5:
58
+ image: ruby:2.5
59
+ stage: test
60
+ rspec ruby rc:
61
+ image: ruby:rc
62
+ allow_failure: true
63
+ stage: test
64
+ ```
65
+
66
+ ### TODO
67
+ - [ ] Better documentation, now is just an example
68
+ - [ ] Support for caching
69
+ - [ ] Support for artifacts
70
+ - [ ] Support advanced features, like services and dependencies
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ begin
6
+ require 'side_boom'
7
+ rescue LoadError
8
+ require_relative '../lib/side_boom'
9
+ end
10
+
11
+ options = {}
12
+ OptionParser.new do |opts|
13
+ opts.banner = 'Usage: sideboom [options]'
14
+
15
+ opts.on('-fNAME', '--file NAME', 'File to interpret') do |path|
16
+ options[:file] = path
17
+ end
18
+ end.parse!
19
+
20
+ options[:file] ||= '.sideboom'
21
+
22
+ eval File.read(options[:file])
@@ -0,0 +1,37 @@
1
+ # Generated by SideBoom
2
+ ---
3
+ stages:
4
+ - test
5
+ Ruby 2.3:
6
+ before_script:
7
+ - bundle install -j 4
8
+ script:
9
+ - rspec
10
+ - rubocop
11
+ image: ruby:2.3
12
+ stage: test
13
+ Ruby 2.4:
14
+ before_script:
15
+ - bundle install -j 4
16
+ script:
17
+ - rspec
18
+ - rubocop
19
+ image: ruby:2.4
20
+ stage: test
21
+ Ruby 2.5:
22
+ before_script:
23
+ - bundle install -j 4
24
+ script:
25
+ - rspec
26
+ - rubocop
27
+ image: ruby:2.5
28
+ stage: test
29
+ Ruby rc:
30
+ before_script:
31
+ - bundle install -j 4
32
+ script:
33
+ - rspec
34
+ - rubocop
35
+ image: ruby:rc
36
+ allow_failure: true
37
+ stage: test
@@ -0,0 +1,38 @@
1
+ # vim: autoindent tabstop=2 shiftwidth=2 expandtab softtabstop=2 filetype=ruby
2
+
3
+ # Pipeline.define takes an optional argument, the sink. If this is a string,
4
+ # the output YAML will be written to that path. If no sink is passed, the output
5
+ # will be written to STDOUT
6
+ SideBoom::Pipeline.define do
7
+ VERSIONS = %w[2.3 2.4 2.5 rc]
8
+
9
+ # This before_script is a single line, thus a string can be passed.
10
+ # If multiple commands should be in the before script, an Array should be passed
11
+ # where each member responds to #to_s
12
+ # This before_script will be used by all jobs, unless their stage, or they
13
+ # themselfs define another before_script.
14
+ before_script 'bundle install -j 4'
15
+
16
+ # This defines the first stage of the pipeline, and thus the stage that will
17
+ # be executed first. 'test' is the name for this stage.
18
+ stage 'test' do
19
+ # Like the before_script explain earlier, but now passing an Array of Strings.
20
+ script ["rspec", "rubocop"]
21
+
22
+ # This just leverages Ruby, this is not SideBoom specific
23
+ VERSIONS.each do |v|
24
+ # In a loop, generate jobs in the current stage.
25
+ # Each of these jobs inherrits the before_script from the pipeline and the
26
+ # script from the stage as the job itself doesn't define any.
27
+ job "Ruby #{v}" do
28
+ # This is the main difference between each job, the image attribute
29
+ # If the stage, or the pipeline defined an image, these would not be used.
30
+ image "ruby:#{v}"
31
+
32
+ # Again, leveraging Ruby to either set this job as an allowed failure,
33
+ # or in most cases, don't let it fail.
34
+ allow_failure! if v == 'rc'
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+ require 'yaml'
3
+
4
+ Dir[File.join(__dir__, 'side_boom', '*.rb')].sort.each { |file| require file }
5
+
6
+ module SideBoom
7
+ VERSION = '0.1.0'.freeze
8
+ end
@@ -0,0 +1,50 @@
1
+ module SideBoom
2
+ ## Attributes define the methods that can be set on both Pipeline, Stage, and
3
+ # Job level. Attributes set at pipeline level can be overriden at either stage-
4
+ # or job-level. Stage level attributes can be overriden by any of its jobs.
5
+ module Attributes
6
+ class << self
7
+ def boolean_attribute(*attrs)
8
+ attrs.each do |attr|
9
+ define_method("#{attr}!") do
10
+ @attributes[attr.to_s] = true
11
+ end
12
+
13
+ define_method("dis#{attr}!") do
14
+ @attributes[attr.to_s] = false
15
+ end
16
+
17
+ define_method(attr) do |arg|
18
+ @attributes[attr.to_s] = !!arg
19
+ end
20
+ end
21
+ end
22
+
23
+ def string_attribute(*attrs)
24
+ attrs.each do |attr|
25
+ define_method(attr) do |arg|
26
+ attributes[attr.to_s] = arg.to_s
27
+ end
28
+ end
29
+ end
30
+
31
+ def array_attribute(*attrs)
32
+ attrs.each do |attr|
33
+ define_method(attr) do |args|
34
+ args = [args] if args.is_a?(String)
35
+
36
+ attributes[attr.to_s] = args.map(&:to_s)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ boolean_attribute :allow_failure
43
+ string_attribute :coverage, :image
44
+ array_attribute :script, :before_script, :after_script
45
+
46
+ def attributes
47
+ @attributes ||= {}
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,41 @@
1
+ module SideBoom
2
+ # To keep the context during defining the pipeline, allowing for RSpec like
3
+ # definitions, without explicitly linking a job to a stage. Example:
4
+ #
5
+ # SideBoom::Pipeline.define '.gitlab-ci.yml' do
6
+ # stage 'compile' do
7
+ # job 'golang 1.9' do
8
+ # # specifications here
9
+ # end
10
+ # end
11
+ # end
12
+ class Context
13
+ @stack = []
14
+
15
+ class << self
16
+ def push(context)
17
+ @stack.push(context)
18
+ end
19
+
20
+ def pop
21
+ @stack.pop
22
+ end
23
+
24
+ def peek
25
+ @stack.last
26
+ end
27
+
28
+ def clear
29
+ @stack = []
30
+ end
31
+
32
+ def in(context)
33
+ push(context)
34
+ val = yield peek
35
+ pop
36
+
37
+ val
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SideBoom
4
+ class Job
5
+ include SideBoom::Attributes
6
+
7
+ attr_reader :name, :stage
8
+
9
+ def initialize(name)
10
+ @name = name
11
+ @stage = SideBoom::Context.peek
12
+ end
13
+
14
+ def to_hash
15
+ attrs = stage.merged_attributes.merge(attributes)
16
+ attrs['stage'] = stage.name
17
+
18
+ duplicated_values(attrs)
19
+ end
20
+
21
+ private
22
+
23
+ # Avoid YAML to use inherritence, so output remains readable
24
+ def duplicated_values(dup_hash)
25
+ dup_hash.each_with_object({}) do |(key, value), hash|
26
+ hash[key] = begin
27
+ value.dup
28
+ rescue TypeError # The unduppables
29
+ value
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SideBoom
4
+ class Pipeline
5
+ include SideBoom::Attributes
6
+
7
+ class << self
8
+ def define(sink = $stdout, &block)
9
+ sink = File.open(sink, 'w+') if sink.is_a?(String)
10
+
11
+ SideBoom::Context.in(self) do
12
+ pipeline = new(sink)
13
+ pipeline.instance_eval(&block)
14
+ pipeline.write!
15
+ end
16
+ end
17
+ end
18
+
19
+ attr_reader :stages, :sink
20
+
21
+ def initialize(sink)
22
+ @sink = sink
23
+ @stages = []
24
+ end
25
+
26
+ def stage(name, &block)
27
+ SideBoom::Context.in(self) do
28
+ new_stage = SideBoom::Stage.new(name)
29
+ new_stage.instance_eval(&block) if block_given?
30
+ @stages << new_stage
31
+ end
32
+ end
33
+
34
+ def write!
35
+ content = "# Generated by SideBoom\n" + to_yaml
36
+ @sink.write(content)
37
+ @sink.close if @sink.is_a?(File)
38
+ end
39
+
40
+ private
41
+
42
+ def to_hash
43
+ hsh = {}
44
+ hsh['stages'] = @stages.map(&:name)
45
+
46
+ @stages.each { |stage| hsh.merge!(stage.to_hash) }
47
+ hsh
48
+ end
49
+
50
+ def to_yaml
51
+ to_hash.to_yaml
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SideBoom
4
+ class Stage
5
+ include SideBoom::Attributes
6
+
7
+ attr_reader :name, :jobs, :pipeline
8
+
9
+ def initialize(name)
10
+ @name = name
11
+ @pipeline = SideBoom::Context.peek
12
+ @jobs = []
13
+ end
14
+
15
+ def job(name, &block)
16
+ SideBoom::Context.in(self) do
17
+ new_job = SideBoom::Job.new(name)
18
+ new_job.instance_eval(&block) if block_given?
19
+
20
+ @jobs << new_job
21
+ end
22
+ end
23
+
24
+ def merged_attributes
25
+ pipeline.attributes.merge(attributes)
26
+ end
27
+
28
+ def to_hash
29
+ @jobs.each_with_object({}) do |job, hash|
30
+ hash[job.name] = job.to_hash
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,33 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'side_boom'
4
+
5
+ description = <<-DESC
6
+ The .gitlab-ci.yml is hard to maintain if your project grows, and its hard to
7
+ determine what is defined where, and why. This Ruby DSL allows you to not be
8
+ limited by YAMLs limitations, but have all Ruby's features at your disposal.
9
+ DESC
10
+
11
+ Gem::Specification.new do |spec|
12
+ spec.name = 'side_boom'
13
+ spec.version = SideBoom::VERSION
14
+ spec.authors = ['Zeger-Jan van de Weg']
15
+ spec.email = ['git@zjvandeweg.nl']
16
+
17
+ spec.summary = 'Construct and maintain your GitLab CI/CD pipeline'
18
+ spec.description = description
19
+ spec.homepage = 'https://gitlab.com/zj/side_boom'
20
+ spec.license = 'MIT'
21
+
22
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
23
+ f.match(%r{^(test|spec|features)/})
24
+ end
25
+ spec.bindir = 'bin'
26
+ spec.executables = ['sideboom']
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_development_dependency 'bundler', '~> 1.16'
30
+ spec.add_development_dependency 'byebug', '~> 10.0'
31
+ spec.add_development_dependency 'rake', '~> 10.0'
32
+ spec.add_development_dependency 'rspec', '~> 3.0'
33
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: side_boom
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Zeger-Jan van de Weg
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-10-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: byebug
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description: |2
70
+ The .gitlab-ci.yml is hard to maintain if your project grows, and its hard to
71
+ determine what is defined where, and why. This Ruby DSL allows you to not be
72
+ limited by YAMLs limitations, but have all Ruby's features at your disposal.
73
+ email:
74
+ - git@zjvandeweg.nl
75
+ executables:
76
+ - sideboom
77
+ extensions: []
78
+ extra_rdoc_files: []
79
+ files:
80
+ - ".gitattributes"
81
+ - ".gitignore"
82
+ - ".gitlab-ci.yml"
83
+ - ".rspec"
84
+ - ".sideboom"
85
+ - Gemfile
86
+ - Gemfile.lock
87
+ - LICENSE.md
88
+ - README.md
89
+ - bin/sideboom
90
+ - examples/simple.out
91
+ - examples/simple.sideboom
92
+ - lib/side_boom.rb
93
+ - lib/side_boom/attributes.rb
94
+ - lib/side_boom/context.rb
95
+ - lib/side_boom/job.rb
96
+ - lib/side_boom/pipeline.rb
97
+ - lib/side_boom/stage.rb
98
+ - side_boom.gemspec
99
+ homepage: https://gitlab.com/zj/side_boom
100
+ licenses:
101
+ - MIT
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.5.2.3
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: Construct and maintain your GitLab CI/CD pipeline
123
+ test_files: []