rumrunner 0.2.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c2323b66b28f0897ada2d3f99a3caabb2ba3fe48347d2c482b9267f68044c327
4
+ data.tar.gz: b00540b6c558f1b1db377fc649acfeb20bbf4dfb6a4603fa376a9b6d86facc67
5
+ SHA512:
6
+ metadata.gz: 8527ea31f1d909e0a4d335d3ec880594cd7b40d1ca04ad70284fa65bdca34cab3abe36c7fe16dd254275fd0fb49d6c43b6e3d487fa8cd6d98a51e84fb3761282
7
+ data.tar.gz: 8f0dafd92f2c32a86b7a1cfc24077652cbc578d38bbfd127556b96710c2a6c1742b8a8f9f0e79a538ea7ddc058a2c26de428430d2e325c0651c2c384e84b4bc6
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Alexander Mancevice
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,164 @@
1
+ <img alt="rumrunner" src="./docs/icon.png"/>
2
+
3
+ [![Build Status](https://travis-ci.com/amancevice/rumrunner.svg?branch=master)](https://travis-ci.com/amancevice/rumrunner)
4
+ [![codecov](https://codecov.io/gh/amancevice/rumrunner/branch/master/graph/badge.svg)](https://codecov.io/gh/amancevice/rumrunner)
5
+
6
+ Rumrunner is a Rake-based utility for building projects using multi-stage Dockerfiles.
7
+
8
+ Rumrunner allows users to minimally annotate builds using a Rake-like DSL
9
+ and execute them with a rake-like CLI.
10
+
11
+ Carfofile has the following features:
12
+ * Rumfiles are completely defined in standard Ruby syntax, like Rakefiles.
13
+ * Users can specify Docker build stages with prerequisites.
14
+ * Artifacts can be exported from stages
15
+ * Stages' build steps can be customized
16
+ * Shell tasks are automatically provided for every stage
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ gem install rumrunner
22
+ ```
23
+
24
+ ## Example
25
+
26
+ Imagine a simple multi-stage Dockerfile:
27
+
28
+ ```Dockerfile
29
+ FROM ruby AS build
30
+ # Run build steps here...
31
+
32
+ FROM ruby AS test
33
+ # Run test steps here...
34
+
35
+ FROM ruby AS deploy
36
+ # Run deploy steps here...
37
+ ```
38
+
39
+ Create `Rumfile` and describe your build:
40
+
41
+ ```ruby
42
+ rum :image_name do
43
+ tag "1.2.3"
44
+
45
+ stage :build
46
+ stage :test => :build
47
+ stage :deploy => :test
48
+ end
49
+ ```
50
+
51
+ Run `bundle exec rum --tasks` to view the installed tasks:
52
+
53
+ ```bash
54
+ rum build # Build `build` stage
55
+ rum build:clean # Remove any temporary images and products from `build` stage
56
+ rum build:shell[shell] # Shell into `build` stage
57
+ rum clean # Remove any temporary images and products
58
+ rum clobber # Remove any generated files
59
+ rum deploy # Build `deploy` stage
60
+ rum deploy:clean # Remove any temporary images and products from `deploy` stage
61
+ rum deploy:shell[shell] # Shell into `deploy` stage
62
+ rum test # Build `test` stage
63
+ rum test:clean # Remove any temporary images and products from `test` stage
64
+ rum test:shell[shell] # Shell into `test` stage
65
+ ```
66
+
67
+ Run the `<stage>` task to build the image up to that stage and cache the image digest.
68
+
69
+ Run the `<stage>:shell` task to build the image and then shell into an instance of the image running as a temporary container.
70
+
71
+ The default shell is `/bin/sh`, but this can be overridden at runtime with the task arg, eg `bundle exec rum build:shell[/bin/bash]`
72
+
73
+ The name of the images are taken from the name of the initial block and appended with the name of the stage. The above example would build:
74
+
75
+ - `image_name:1.2.3-build`
76
+ - `image_name:1.2.3-test`
77
+ - `image_name:1.2.3-deploy`
78
+
79
+ The default location for the digests is in `.docker`, but that can be modified:
80
+
81
+ ```ruby
82
+ rum :image_name => "tmp" do |c|
83
+ # ...
84
+ end
85
+ ```
86
+
87
+ ## Customize Stages
88
+
89
+ Stages can be customized with blocks. Methods invoked on the stage are (with a few exceptions) passed onto the `docker build` command.
90
+
91
+ ```ruby
92
+ rum :image_name do
93
+ tag "1.2.3"
94
+
95
+ stage :build
96
+
97
+ stage :test => :build
98
+
99
+ stage :deploy => :test do
100
+ build_arg :AWS_ACCESS_KEY_ID
101
+ build_arg :AWS_SECRET_ACCESS_KEY
102
+ build_arg :AWS_DEFAULT_REGION => "us-east-1"
103
+ label :Fizz
104
+ end
105
+ end
106
+ ```
107
+
108
+ ## Export Artifacts
109
+
110
+ Use the `artifact` method to specify an artifact to be exported from the image.
111
+
112
+ ```ruby
113
+ rum :image_name do
114
+ stage :build
115
+
116
+ artifact "package.zip" => :build
117
+ end
118
+ ```
119
+
120
+ By default the container simply `cat`s the file from the container to the local file system, but more complex exports can be defined:
121
+
122
+ ```ruby
123
+ rum :image_name do
124
+ stage :build
125
+
126
+ artifact "package.zip" => :build do
127
+ workdir "/var/task/"
128
+ cmd %w[zip -r - .]
129
+ end
130
+ end
131
+ ```
132
+
133
+ ## Customize Shells
134
+
135
+ By default, all stages have a `:shell` task that can be invoked to build and shell into a container for a stage. By default the container is run as an ephemeral container (`--rm`) in interactive with TTY allocated and a bash shell open.
136
+
137
+ Customize the shell for a stage with the `shell` method:
138
+
139
+ ```ruby
140
+ rum :image_name do
141
+ stage :dev
142
+
143
+ shell :dev do
144
+ entrypoint "/bin/zsh"
145
+ rm false
146
+ volume "#{Dir.pwd}:/var/task/"
147
+ end
148
+ end
149
+ ```
150
+
151
+ ## Default Task
152
+
153
+ Use the `default` method to set a default task when running `bundle exec rum`:
154
+
155
+
156
+ ```ruby
157
+ rum :image_name do
158
+ stage :build
159
+
160
+ artifact "package.zip" => :build
161
+
162
+ default "package.zip"
163
+ end
164
+ ```
data/bin/rum ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require "rumrunner"
3
+ Rake.application = Rum::Application.new
4
+ Rake.application.run
@@ -0,0 +1,24 @@
1
+ require "rake"
2
+
3
+ module Rum
4
+ class Application < Rake::Application
5
+ DEFAULT_RAKEFILES = [
6
+ "rumfile",
7
+ "Rumfile",
8
+ "rumfile.rb",
9
+ "Rumfile.rb",
10
+ ]
11
+
12
+ # Initialize a Rumfile::Application object.
13
+ def initialize
14
+ super
15
+ @name = "rum"
16
+ @rakefiles = DEFAULT_RAKEFILES.dup
17
+ end
18
+
19
+ # Initialize the command line parameters and app name.
20
+ def init(app_name="rum", argv = ARGV)
21
+ super "rum", argv
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,184 @@
1
+ require "forwardable"
2
+
3
+ module Rum
4
+ module Docker
5
+ module AttrCallable
6
+ def attr_method_accessor(*args)
7
+ args.each do |var|
8
+ define_method var do |value = nil|
9
+ if value.nil?
10
+ instance_variable_get :"@#{var}"
11
+ else
12
+ instance_variable_set :"@#{var}", value
13
+ self
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ module Executable
21
+ include Enumerable
22
+
23
+ attr_reader :options
24
+
25
+ def initialize(options:nil, &block)
26
+ @options = options || Options.new
27
+ instance_eval(&block) if block_given?
28
+ end
29
+
30
+ def each
31
+ self.class.name.split(/::/)[1..-1].each{|x| yield x.downcase }
32
+ @options.each{|x| yield x }
33
+ end
34
+
35
+ def method_missing(m, *args, &block)
36
+ @options.send(m, *args, &block)
37
+ args.any? ? self : @options[m]
38
+ end
39
+
40
+ def to_s
41
+ to_a.join(" ")
42
+ end
43
+
44
+ def with_defaults(options = {}, &block)
45
+ options.reject{|k,v| @options.include? k }.each{|k,v| @options[k] << v }
46
+ self
47
+ end
48
+ end
49
+
50
+ class Options
51
+ extend Forwardable
52
+ include Enumerable
53
+
54
+ attr_reader :data
55
+
56
+ def_delegators :@data, :[], :[]=, :include?, :to_h, :update
57
+
58
+ def initialize(options = {}, &block)
59
+ @data = Hash.new{|hash, key| hash[key] = [] }.update(options)
60
+ instance_eval(&block) if block_given?
61
+ end
62
+
63
+ def method_missing(m, *args, &block)
64
+ @data[m] += args unless args.empty?
65
+ self
66
+ end
67
+
68
+ def each
69
+ @data.each do |name, values|
70
+ option = name.length == 1 ? "-#{name}" : "--#{name.to_s.gsub(/_/, "-")}"
71
+ yield option if values.empty?
72
+ values.each do |value|
73
+ if value.is_a?(Hash)
74
+ value.map{|kv| kv.join("=") }.each do |val|
75
+ yield option
76
+ yield val
77
+ end
78
+ elsif [true, false].include? value
79
+ yield option
80
+ else
81
+ yield option
82
+ yield value.to_s
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ def to_s
89
+ to_a.join(" ")
90
+ end
91
+ end
92
+
93
+ class Build
94
+ extend AttrCallable
95
+ include Executable
96
+
97
+ attr_method_accessor :path
98
+
99
+ def initialize(options:nil, path:nil, &block)
100
+ @path = path
101
+ super options: options, &block
102
+ end
103
+
104
+ def each
105
+ super{|x| yield x }
106
+ yield @path || "."
107
+ end
108
+ end
109
+
110
+ class Run
111
+ extend AttrCallable
112
+ include Executable
113
+
114
+ attr_method_accessor :image, :cmd
115
+
116
+ def initialize(options:nil, image:nil, cmd:nil, &block)
117
+ @image = image
118
+ @cmd = cmd
119
+ super options: options, &block
120
+ end
121
+
122
+ def each
123
+ super{|x| yield x }
124
+ yield @image
125
+ @cmd.is_a?(Array) ? @cmd.each{|x| yield x } : yield(@cmd) unless @cmd.nil?
126
+ end
127
+ end
128
+
129
+ class Image
130
+ extend AttrCallable
131
+ include Enumerable
132
+
133
+ attr_method_accessor :registry, :username, :name, :tag
134
+
135
+ def initialize(name:, registry:nil, username:nil, tag:nil, &block)
136
+ @registry = registry
137
+ @username = username
138
+ @name = name
139
+ @tag = tag
140
+ instance_eval(&block) if block_given?
141
+ end
142
+
143
+ def each
144
+ [@registry, @username, @name, @tag].compact.each{|x| yield x }
145
+ end
146
+
147
+ def family
148
+ File.join *[@registry, @username, @name].compact.map(&:to_s)
149
+ end
150
+
151
+ def to_s
152
+ "#{family}:#{@tag || :latest}"
153
+ end
154
+
155
+ class << self
156
+ def parse(string_or_symbol)
157
+ string = string_or_symbol.to_s
158
+ if string.count("/").zero? && string.count(":").zero?
159
+ # image
160
+ new name: string
161
+ elsif string.count("/").zero?
162
+ # image:tag
163
+ name, tag = string.split(/:/)
164
+ new name: name, tag: tag
165
+ elsif string.count("/") == 1 && string.count(":").zero?
166
+ # username/image
167
+ username, name = string.split(/\//)
168
+ new name: name, username: username
169
+ elsif string.count("/") == 1
170
+ # username/image:tag
171
+ username, name_tag = string.split(/\//)
172
+ name, tag = name_tag.split(/:/)
173
+ new name: name, username: username, tag: tag
174
+ else
175
+ # registry/username/image[:tag]
176
+ registry, username, name_tag = string.split(/\//)
177
+ name, tag = name_tag.split(/:/)
178
+ new name: name, registry: registry, username: username, tag: tag
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,22 @@
1
+ require "rake"
2
+
3
+ require "rumrunner/manifest"
4
+
5
+ module Rum
6
+ module DSL
7
+
8
+ private
9
+
10
+ # :call-seq:
11
+ # rum image_name
12
+ # rum image_name: digest_dir
13
+ #
14
+ def rum(*args, &block)
15
+ name, _, deps = Rake.application.resolve_args(args)
16
+ root = deps.first || :".docker"
17
+ Manifest.new(name: name, root: root, &block).install
18
+ end
19
+ end
20
+ end
21
+
22
+ self.extend Rum::DSL
@@ -0,0 +1,171 @@
1
+ require "forwardable"
2
+ require "rake"
3
+
4
+ module Rum
5
+ class Manifest
6
+ extend Forwardable
7
+ include Rake::DSL if defined? Rake::DSL
8
+
9
+ attr_reader :image
10
+
11
+ def_delegator :@env, :<<, :env
12
+ def_delegator :@root, :to_s, :root
13
+ def_delegators :@image, :registry, :username, :name, :tag
14
+
15
+ def initialize(name:, root:nil, &block)
16
+ @name = name
17
+ @root = root || :".docker"
18
+ @image = Docker::Image.parse(name)
19
+ @env = []
20
+ instance_eval(&block) if block_given?
21
+ end
22
+
23
+ def default(*args, &block)
24
+ name = Rake.application.resolve_args(args).first
25
+ task :default => name
26
+ end
27
+
28
+ def build(*args, &block)
29
+ name, _, deps = Rake.application.resolve_args(args)
30
+ task name => deps do
31
+ sh Docker::Build.new(&block).to_s
32
+ end
33
+ end
34
+
35
+ def run(*args, &block)
36
+ name, _, deps = Rake.application.resolve_args(args)
37
+ task name => deps do
38
+ sh Docker::Run.new(&block).to_s
39
+ end
40
+ end
41
+
42
+ def stage(*args, &block)
43
+ name, _, deps = Rake.application.resolve_args(args)
44
+
45
+ # Assemble image/iidfile from manifest/stage name
46
+ image = "#{@image}-#{name}"
47
+ iidfile = File.join(root, image)
48
+ iidpath = File.split(iidfile).first
49
+
50
+ # Ensure path to iidfile exists
51
+ iiddeps = if deps.empty?
52
+ directory iidpath
53
+ iidpath
54
+ else
55
+ deps.map{|x| File.join(root, "#{@image}-#{x}") }
56
+ end
57
+
58
+ # Build stage and save digest in iidfile
59
+ file iidfile => iiddeps do
60
+ build = Docker::Build.new(options: build_options, &block)
61
+ build.with_defaults(iidfile: iidfile, tag: image, target: name)
62
+ sh build.to_s
63
+ end
64
+
65
+ # Shortcut to build stage by name
66
+ desc "Build `#{name}` stage"
67
+ task name => iidfile
68
+
69
+ # Shell into stage
70
+ desc "Shell into `#{name}` stage"
71
+ task :"#{name}:shell", [:shell] => iidfile do |t,args|
72
+ digest = File.read(iidfile)
73
+ shell = args.any? ? args.to_a.join(" ") : "/bin/sh"
74
+ run = Docker::Run.new(options: run_options)
75
+ .entrypoint(shell)
76
+ .interactive(true)
77
+ .rm(true)
78
+ .tty(true)
79
+ .image(digest)
80
+ sh run.to_s
81
+ end
82
+
83
+ # Clean stage
84
+ desc "Remove any temporary images and products from `#{name}` stage"
85
+ task :"#{name}:clean" do
86
+ if File.exists? iidfile
87
+ sh "docker", "image", "rm", "--force", File.read(iidfile)
88
+ rm iidfile
89
+ end
90
+ end
91
+
92
+ # Add stage to general clean
93
+ task :clean => :"#{name}:clean"
94
+
95
+ # Ensure subsequent stages are cleaned before this one
96
+ deps.each{|dep| task :"#{dep}:clean" => :"#{name}:clean" }
97
+ end
98
+
99
+ def artifact(*args, &block)
100
+ name, _, deps = Rake.application.resolve_args(args)
101
+
102
+ target = deps.first
103
+ image = "#{@image}-#{target}"
104
+ iidfile = File.join(root, image)
105
+ path = File.split(name).first
106
+ deps = [iidfile]
107
+
108
+ unless path == "."
109
+ directory path
110
+ deps << path
111
+ end
112
+
113
+ desc "Build `#{name}`"
114
+ file name => deps do
115
+ digest = File.read(iidfile)
116
+ run = Docker::Run.new(options: run_options, image: digest, cmd: ["cat", name], &block)
117
+ run.with_defaults(rm: true)
118
+ sh "#{run} > #{name}"
119
+ end
120
+
121
+ desc "Remove any generated files"
122
+ task :clobber do
123
+ rm name if File.exists?(name)
124
+ rm_r path if Dir.exists?(path) && path != "."
125
+ end
126
+ end
127
+
128
+ def shell(*args, &block)
129
+ target = Rake.application.resolve_args(args).first
130
+ name = :"#{target}:shell"
131
+ image = "#{@image}-#{target}"
132
+ iidfile = File.join(root, image)
133
+
134
+ Rake::Task[name].clear if Rake::Task.task_defined?(name)
135
+
136
+ desc "Shell into `#{target}` stage"
137
+ task name, [:shell] => iidfile do |t,args|
138
+ digest = File.read(iidfile)
139
+ shell = args.any? ? args.to_a.join(" ") : "/bin/sh"
140
+ run = Docker::Run.new(options: run_options, image: digest, &block)
141
+ run.with_defaults(entrypoint: shell, interactive:true, rm: true, tty: true)
142
+ sh run.to_s
143
+ end
144
+ end
145
+
146
+ def install
147
+ install_clean
148
+ end
149
+
150
+ private
151
+
152
+ def build_options
153
+ Docker::Options.new(build_arg: @env) unless @env.empty?
154
+ end
155
+
156
+ def run_options
157
+ Docker::Options.new(env: @env) unless @env.empty?
158
+ end
159
+
160
+ def install_clean
161
+ desc "Remove any temporary images and products"
162
+ task :clean do
163
+ Dir[File.join root, "**/*"].reverse.each do |name|
164
+ sh "docker", "image", "rm", "--force", File.read(name) if File.file?(name)
165
+ rm_r name
166
+ end
167
+ rm_r root if Dir.exists?(root)
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,3 @@
1
+ module Rum
2
+ VERSION = "0.2.0"
3
+ end
data/lib/rumrunner.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "rumrunner/version"
2
+ require "rumrunner/docker"
3
+ require "rumrunner/manifest"
4
+ require "rumrunner/dsl_definition"
5
+ require "rumrunner/application"
6
+
7
+ module Rum
8
+ class Error < StandardError
9
+ end
10
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rumrunner
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Mancevice
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-07-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '12.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '12.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: codecov
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: gems
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.12'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.12'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.16'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.16'
111
+ description: |
112
+ Rumfile is a Rake-based utility for building projects using multi-stage Dockerfiles.
113
+
114
+ Rumfile allows users to minimally annotate builds using a Rake-like DSL
115
+ and execute them with a rake-like CLI.
116
+
117
+ Carfofile has the following features:
118
+ * Rumfiles are completely defined in standard Ruby syntax, like Rakefiles.
119
+ * Users can specify Docker build stages with prerequisites.
120
+ * Artifacts can be exported from stages
121
+ * Stages' build steps can be customized
122
+ * Shell tasks are automatically provided for every stage
123
+ email:
124
+ - smallweirdnum@gmail.com
125
+ executables:
126
+ - rum
127
+ extensions: []
128
+ extra_rdoc_files: []
129
+ files:
130
+ - LICENSE
131
+ - README.md
132
+ - bin/rum
133
+ - lib/rumrunner.rb
134
+ - lib/rumrunner/application.rb
135
+ - lib/rumrunner/docker.rb
136
+ - lib/rumrunner/dsl_definition.rb
137
+ - lib/rumrunner/manifest.rb
138
+ - lib/rumrunner/version.rb
139
+ homepage: https://github.com/amancevice/rumrunner.git
140
+ licenses:
141
+ - MIT
142
+ metadata: {}
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: 2.3.0
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubyforge_project:
159
+ rubygems_version: 2.7.7
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: Rumfile is a Rake-based utility for building projects using multi-stage Dockerfiles
163
+ test_files: []