performa 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f6435a998ab87cdad87f5dceb1ff410c8f081aabe5ef10fc360479d7bd1e97fc
4
+ data.tar.gz: 2f3a401bae1c21ef9d3bb42d084b19b79dc4e61486028f2a42b9e7dc44d632e9
5
+ SHA512:
6
+ metadata.gz: 7792a8296acd422c3d6cd0819f00b509311f57de99b042917e99232d31be9c8c17f76805dd6d501dd28b19ab128b81dd69b4ca7eb0046145bac9be8df21cb405
7
+ data.tar.gz: fe0205c9b1cf8cfb9bacf9b5b2afaa0a1f077f54e1ba5faa591c1613b67adf29eb82b362782696473c5910e0174b917c3ef41a4557c139adb29a214c2b8aefdd
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ !/tmp/.keep
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
13
+
14
+ /.byebug_history
15
+ /performa-results
16
+
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,33 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+
4
+ Metrics/LineLength:
5
+ Max: 130
6
+ AllowHeredoc: true
7
+ AllowURI: true
8
+ IgnoreCopDirectives: true
9
+ Exclude:
10
+ - "spec/**/*"
11
+
12
+ # This cop checks the line count inside blocks.
13
+ # All RSpec code is in the same block for each file.
14
+ # Enabling this for spec/ would require cutting up the spec files in several parts.
15
+
16
+ Metrics/BlockLength:
17
+ Exclude:
18
+ - "spec/**/*"
19
+
20
+ Style/StringLiterals:
21
+ Enabled: true
22
+ EnforcedStyle: "double_quotes"
23
+
24
+ # This cop checks for missing top-level documentation of classes and modules.
25
+ # Classes with no body are exempt from the check and so are namespace modules -
26
+ # modules that have nothing in their bodies except classes, other modules,
27
+ # or constant definitions.
28
+
29
+ Style/Documentation:
30
+ Enabled: false
31
+
32
+ Metrics/MethodLength:
33
+ Max: 30
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.6.0-dev
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.5.3
7
+ before_install: gem install bundler -v 1.17.1
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # CHANGELOG
2
+
3
+ WIP
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in performa.gemspec
8
+ gemspec
9
+
10
+ gem "bundler"
11
+ gem "byebug"
12
+ gem "rake"
13
+ gem "rspec"
14
+ gem "rubocop", github: "rubocop-hq/rubocop"
data/Gemfile.lock ADDED
@@ -0,0 +1,62 @@
1
+ GIT
2
+ remote: https://github.com/rubocop-hq/rubocop
3
+ revision: e74002ce0cf4367b3cebd580523b07ea2a59bf55
4
+ specs:
5
+ rubocop (0.60.0)
6
+ jaro_winkler (~> 1.5.1)
7
+ parallel (~> 1.10)
8
+ parser (>= 2.5, != 2.5.1.1)
9
+ powerpack (~> 0.1)
10
+ rainbow (>= 2.2.2, < 4.0)
11
+ ruby-progressbar (~> 1.7)
12
+ unicode-display_width (~> 1.4.0)
13
+
14
+ PATH
15
+ remote: .
16
+ specs:
17
+ performa (0.1.0)
18
+ colorize (~> 0.8)
19
+
20
+ GEM
21
+ remote: https://rubygems.org/
22
+ specs:
23
+ ast (2.4.0)
24
+ byebug (10.0.2)
25
+ colorize (0.8.1)
26
+ diff-lcs (1.3)
27
+ jaro_winkler (1.5.1)
28
+ parallel (1.12.1)
29
+ parser (2.5.3.0)
30
+ ast (~> 2.4.0)
31
+ powerpack (0.1.2)
32
+ rainbow (3.0.0)
33
+ rake (10.5.0)
34
+ rspec (3.8.0)
35
+ rspec-core (~> 3.8.0)
36
+ rspec-expectations (~> 3.8.0)
37
+ rspec-mocks (~> 3.8.0)
38
+ rspec-core (3.8.0)
39
+ rspec-support (~> 3.8.0)
40
+ rspec-expectations (3.8.2)
41
+ diff-lcs (>= 1.2.0, < 2.0)
42
+ rspec-support (~> 3.8.0)
43
+ rspec-mocks (3.8.0)
44
+ diff-lcs (>= 1.2.0, < 2.0)
45
+ rspec-support (~> 3.8.0)
46
+ rspec-support (3.8.0)
47
+ ruby-progressbar (1.10.0)
48
+ unicode-display_width (1.4.0)
49
+
50
+ PLATFORMS
51
+ ruby
52
+
53
+ DEPENDENCIES
54
+ bundler
55
+ byebug
56
+ performa!
57
+ rake
58
+ rspec
59
+ rubocop!
60
+
61
+ BUNDLED WITH
62
+ 2.0.0.pre.1
data/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # Performa
2
+
3
+ Automate scripts on multiple docker setups.
4
+
5
+ ## Usage
6
+
7
+ TODO: ...
8
+
9
+ ## Development
10
+
11
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
12
+
13
+ ## Contributing
14
+
15
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/christophemaximin/performa](https://github.com/christophemaximin/performa).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "performa"
6
+ require "byebug"
7
+
8
+ # You can add fixtures and/or initialization code here to make experimenting
9
+ # with your gem easier. You can also use a different console, if you like.
10
+
11
+ # (If you use this, don't forget to add pry to your Gemfile!)
12
+ # require "pry"
13
+ # Pry.start
14
+
15
+ require "irb"
16
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/performa ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ lib = File.expand_path("../lib", __dir__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+
7
+ require "byebug" if ENV["DEBUG"]
8
+ require "performa"
9
+ require "optionparser"
10
+
11
+ options = Struct.new(:config_file).new
12
+
13
+ OptionParser.new do |opts|
14
+ opts.banner = [
15
+ "Usage: performa [-c config-file.yml]",
16
+ "Default config files considered: #{Performa::Configuration::DEFAULT_FILES.join(', ')}\n\n"
17
+ ].join("\n")
18
+
19
+ opts.on("-c", "--config-file [file]", "Performa config file to use") do |file|
20
+ options.config_file = file
21
+ end
22
+
23
+ opts.on("--clear-cached", "Remove all Performa generated docker images (#{Performa::Images::CACHED_IMAGES_NAME}:*)") do
24
+ Performa::Images.clear_cached
25
+ exit 0
26
+ end
27
+
28
+ opts.on("-h", "--help", "Prints this help") do
29
+ puts opts
30
+ exit 0
31
+ end
32
+ end.parse!
33
+
34
+ begin
35
+ config = Performa::Configuration.new(options.config_file)
36
+ Performa::Coordinator.run(config)
37
+ rescue StandardError => e
38
+ Performa::LOG.error(e.message)
39
+ Performa::LOG.error(e.backtrace.join("\n")) if ENV["DEBUG"]
40
+ exit 1
41
+ end
data/lib/performa.rb ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "performa/version"
4
+ require "performa/logger"
5
+ require "performa/configuration"
6
+ require "performa/shell_helper"
7
+ require "performa/container_registry"
8
+ require "performa/environment"
9
+ require "performa/container_id"
10
+ require "performa/images"
11
+ require "performa/stages"
12
+ require "performa/coordinator"
13
+ require "performa/results_helper"
14
+
15
+ module Performa
16
+ Error = Class.new(StandardError)
17
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+
5
+ module Performa
6
+ class Configuration
7
+ DEFAULT_FILES = %w[
8
+ performa.yml config/performa.yml
9
+ spec/performa.yml test/performa.yml
10
+ ].freeze
11
+
12
+ ERR_READING_CONFIG_FILE = "Could not read config file %s (%s)"
13
+ ERR_INVALID_FILE = "Invalid YAML file %s: %s"
14
+ ERR_NO_FILE = "Could not find a default config file (#{DEFAULT_FILES.join(', ')})"
15
+
16
+ InvalidDataError = Class.new(StandardError)
17
+
18
+ attr_reader :data
19
+
20
+ def initialize(config_file)
21
+ config_file ||= find_default_config_file
22
+ raise(Error, ERR_NO_FILE) unless config_file
23
+
24
+ @data = load_config_file(config_file)
25
+ validate_data
26
+ end
27
+
28
+ def load_config_file(config_file)
29
+ YAML.safe_load(File.read(config_file))
30
+ rescue Errno::EACCES => error
31
+ raise Error, format(ERR_READING_CONFIG_FILE, config_file, error.message)
32
+ rescue Psych::SyntaxError => error
33
+ raise Error, format(ERR_INVALID_FILE, config_file, error.message)
34
+ end
35
+
36
+ def find_default_config_file
37
+ DEFAULT_FILES.find do |file|
38
+ File.exist?(file)
39
+ end
40
+ end
41
+
42
+ def validate_data
43
+ raise InvalidDataError if @data["version"].nil? ||
44
+ !@data["images"]&.is_a?(Array) ||
45
+ @data["command"]&.empty?
46
+ rescue InvalidDataError
47
+ raise Error, "Invalid config"
48
+ end
49
+
50
+ def [](name)
51
+ @data[name]
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Performa
4
+ class ContainerId < String
5
+ attr_accessor :from_cache
6
+
7
+ def initialize(*args)
8
+ @from_cache = false
9
+ super
10
+ end
11
+
12
+ def self.from_cache(string)
13
+ str = new(string)
14
+ str.from_cache = true
15
+ str
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
5
+ module Performa
6
+ module ContainerRegistry
7
+ module_function
8
+
9
+ extend ShellHelper
10
+
11
+ def add(container_id)
12
+ containers << container_id
13
+ end
14
+
15
+ def kill_all
16
+ containers.each do |container_id|
17
+ kill(container_id)
18
+ end
19
+ end
20
+
21
+ def kill(container_id)
22
+ run_command("docker kill #{container_id}")
23
+ containers.delete(container_id)
24
+ end
25
+
26
+ def containers
27
+ Thread.current[:performa_containers] ||= Set.new
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Performa
4
+ module Coordinator
5
+ module_function
6
+
7
+ extend ShellHelper
8
+
9
+ def run(config)
10
+ envs = Environment.all(config)
11
+ results = {}
12
+
13
+ envs.each do |env|
14
+ results[env.name] = process_env(env, config: config)
15
+ end
16
+
17
+ ResultsHelper.process(results, config: config)
18
+ ensure
19
+ ContainerRegistry.kill_all
20
+ end
21
+
22
+ def process_env(env, config:)
23
+ container_id = Images.process(env, config: config)
24
+ unless container_id.from_cache
25
+ Stages.process(env, container_id: container_id)
26
+ Images.cache_container(container_id, tag: env.hash) unless config["cache_environments"] == false
27
+ end
28
+
29
+ result = run_command("docker container exec #{container_id} #{config['command']}")
30
+ ContainerRegistry.kill(container_id)
31
+ result
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest"
4
+
5
+ module Performa
6
+ class Environment
7
+ def self.all(config)
8
+ unless config["stages"]
9
+ return config["images"].map do |image|
10
+ new(image: image, volumes: config["volumes"])
11
+ end
12
+ end
13
+
14
+ config["images"].product(config["stages"].to_a).map do |image, stage|
15
+ new(image: image, stage: stage, volumes: config["volumes"])
16
+ end
17
+ end
18
+
19
+ attr_reader :image, :stage, :volumes, :name, :hash
20
+
21
+ def initialize(image:, stage: nil, volumes: nil)
22
+ @image = image
23
+ @stage = stage
24
+ @volumes = volumes || []
25
+ assign_name
26
+ assign_hash
27
+ end
28
+
29
+ def assign_name
30
+ @name = @image.tr(":", "_") + ("-#{@stage[0]}" if @stage).to_s
31
+ end
32
+
33
+ def assign_hash
34
+ @hash = Digest::SHA1.hexdigest(@image + @stage.to_s)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Performa
4
+ module Images
5
+ module_function
6
+
7
+ extend ShellHelper
8
+ CACHED_IMAGES_NAME = "performa_env"
9
+
10
+ def process(env, config:)
11
+ unless config["cache_environments"] == false
12
+ container_id = container_id_for_cached_image(env)
13
+ return container_id if container_id
14
+ end
15
+
16
+ pull_if_missing(env.image)
17
+ id = start_image_container(env.image, volumes: env.volumes)
18
+ ContainerId.new(id)
19
+ end
20
+
21
+ def container_id_for_cached_image(env)
22
+ cached_image = "#{CACHED_IMAGES_NAME}:#{env.hash}"
23
+ return unless exists?(cached_image)
24
+
25
+ id = start_image_container(cached_image, volumes: env.volumes)
26
+ ContainerId.from_cache(id)
27
+ end
28
+
29
+ def pull(image)
30
+ run_command("docker pull #{image}", no_capture: true)
31
+ end
32
+
33
+ def pull_if_missing(image)
34
+ pull(image) unless exists?(image)
35
+ end
36
+
37
+ def exists?(image)
38
+ !run_command("docker images -q #{image}").empty?
39
+ end
40
+
41
+ def start_image_container(image, volumes: [])
42
+ volumes_options = volumes.map do |volume|
43
+ volume[0] = Dir.pwd if volume[0] == "."
44
+ " -v #{volume}"
45
+ end.join
46
+
47
+ command = "docker run #{volumes_options} -d #{image} tail -f /dev/null"
48
+
49
+ run_command(command).strip.tap do |container_id|
50
+ ContainerRegistry.add(container_id)
51
+ end
52
+ end
53
+
54
+ def cache_container(container_id, tag:)
55
+ run_command("docker commit #{container_id} #{CACHED_IMAGES_NAME}:#{tag}")
56
+ end
57
+
58
+ def clear_cached
59
+ ids = run_command("docker images --filter=reference='#{CACHED_IMAGES_NAME}' --format '{{.ID}}'").split("\n")
60
+ ids.each do |id|
61
+ run_command("docker rmi -f #{id.strip}")
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
4
+ require "time"
5
+ require "colorize"
6
+
7
+ module Performa
8
+ LOG = Logger.new(STDOUT)
9
+ LOG.level = Logger::INFO
10
+ LOG.formatter = proc do |severity, datetime, _progname, message|
11
+ line = "[#{datetime.strftime('%Y-%m-%d %H:%M:%S')}] #{severity} -- #{message}\n"
12
+
13
+ case severity
14
+ when "ERROR"
15
+ line.colorize(:red)
16
+ else
17
+ line
18
+ end
19
+ end
20
+
21
+ def LOG.success(message)
22
+ LOG.info(message.colorize(:green))
23
+ end
24
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "colorize"
5
+
6
+ module Performa
7
+ module ResultsHelper
8
+ module_function
9
+
10
+ def process(results, config:)
11
+ if config["output"].nil? || config["output"] == "STDOUT"
12
+ output_to_stdout(results)
13
+ else
14
+ output_to_directory(results, directory: config["output"])
15
+ end
16
+ end
17
+
18
+ def output_to_stdout(results)
19
+ results.each_pair do |env_name, result|
20
+ puts
21
+ puts "== Output for #{env_name}".colorize(:green)
22
+ puts
23
+ puts result
24
+ end
25
+ puts
26
+ end
27
+
28
+ def output_to_directory(results, directory:)
29
+ FileUtils.mkdir_p(directory)
30
+ filenames = []
31
+ results.each_pair do |env_name, result|
32
+ filename = File.join(directory, env_name + ".txt")
33
+ filenames << filename
34
+
35
+ File.open(filename, "w+") do |file|
36
+ file.write(result)
37
+ end
38
+ end
39
+
40
+ message = +"Command outputs are now present in the following files:\n"
41
+ message << filenames.join("\n")
42
+
43
+ puts
44
+ puts message.colorize(:green)
45
+ puts
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pty"
4
+ require "English"
5
+
6
+ module Performa
7
+ module ShellHelper
8
+ def run_command(command, success_only: true, no_capture: false)
9
+ LOG.success("Running `#{command}` ...")
10
+
11
+ if no_capture
12
+ system(command)
13
+ result = ""
14
+ else
15
+ result = pty_spawn(command)
16
+ end
17
+
18
+ raise "(non-zero exit code)" if success_only && !$CHILD_STATUS.success?
19
+
20
+ result
21
+ rescue StandardError => e
22
+ raise Error, <<~MSG
23
+ Error running the command `#{command}`:
24
+ => error: #{e.message}
25
+ => command output: #{result}
26
+ MSG
27
+ end
28
+
29
+ def pty_spawn(command)
30
+ result = +""
31
+ PTY.spawn(command) do |stdout, _stdin, _pid|
32
+ stdout.each do |line|
33
+ LOG.info(line.strip)
34
+ result << line
35
+ end
36
+ end
37
+
38
+ Process.wait unless $CHILD_STATUS.exited?
39
+
40
+ result
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Performa
4
+ module Stages
5
+ module_function
6
+
7
+ extend ShellHelper
8
+
9
+ def process(env, container_id:)
10
+ return unless env.stage
11
+
12
+ env.stage[1].each do |command|
13
+ run_command("docker container exec #{container_id} #{command}")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Performa
4
+ VERSION = "0.1.0"
5
+ end
data/performa.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "performa/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "performa"
9
+ spec.version = Performa::VERSION
10
+ spec.authors = ["Christophe Maximin"]
11
+ spec.email = ["christophe.maximin@gmail.com"]
12
+
13
+ spec.summary = "PLACEHOLDER"
14
+ spec.description = "PLACEHOLDER"
15
+ spec.homepage = "https://github.com/christophemaximin/performa"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/christophemaximin/performa"
19
+ spec.metadata["changelog_uri"] = "https://github.com/christophemaximin/performa/CHANGELOG.md"
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_runtime_dependency "colorize", "~> 0.8"
31
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: performa
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Christophe Maximin
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-11-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.8'
27
+ description: PLACEHOLDER
28
+ email:
29
+ - christophe.maximin@gmail.com
30
+ executables:
31
+ - performa
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - ".rspec"
37
+ - ".rubocop.yml"
38
+ - ".ruby-version"
39
+ - ".travis.yml"
40
+ - CHANGELOG.md
41
+ - Gemfile
42
+ - Gemfile.lock
43
+ - README.md
44
+ - Rakefile
45
+ - bin/console
46
+ - bin/setup
47
+ - exe/performa
48
+ - lib/performa.rb
49
+ - lib/performa/configuration.rb
50
+ - lib/performa/container_id.rb
51
+ - lib/performa/container_registry.rb
52
+ - lib/performa/coordinator.rb
53
+ - lib/performa/environment.rb
54
+ - lib/performa/images.rb
55
+ - lib/performa/logger.rb
56
+ - lib/performa/results_helper.rb
57
+ - lib/performa/shell_helper.rb
58
+ - lib/performa/stages.rb
59
+ - lib/performa/version.rb
60
+ - performa.gemspec
61
+ homepage: https://github.com/christophemaximin/performa
62
+ licenses: []
63
+ metadata:
64
+ homepage_uri: https://github.com/christophemaximin/performa
65
+ source_code_uri: https://github.com/christophemaximin/performa
66
+ changelog_uri: https://github.com/christophemaximin/performa/CHANGELOG.md
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 3.0.0.beta2
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: PLACEHOLDER
87
+ test_files: []