side_boom 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []