peas-cli 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ff74c389b73f05511fcb56a51176657987e7ae09
4
+ data.tar.gz: 04c3d0be0dd5937c4dfa1763802bc38b00891561
5
+ SHA512:
6
+ metadata.gz: bae333e4865553e1ae60b250a3320c8a77dce3103dbad72fbcaba58a296fdb4f3769d0847bf0d519419dbaa0eb82d032a44268a58da65bd874208cde6bd35751
7
+ data.tar.gz: 5cfc06bd6a5d240dcc4e9d7096f904c69d88d6a62870555da1fbaf5ee6cc5c48463edf7f86a188a584ea5f6745c67a14ba354dff12ff1e61e6f534be9ff16ae1
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format=documentation
3
+
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'gli'
4
+ gem 'httparty'
5
+ gem 'rainbow'
6
+
7
+ group :test do
8
+ gem 'rspec'
9
+ gem 'webmock'
10
+ end
11
+
12
+ group :development do
13
+ gem 'jeweler'
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,80 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ addressable (2.3.5)
5
+ builder (3.2.2)
6
+ crack (0.4.2)
7
+ safe_yaml (~> 1.0.0)
8
+ descendants_tracker (0.0.4)
9
+ thread_safe (~> 0.3, >= 0.3.1)
10
+ diff-lcs (1.2.5)
11
+ faraday (0.9.0)
12
+ multipart-post (>= 1.2, < 3)
13
+ git (1.2.6)
14
+ github_api (0.11.3)
15
+ addressable (~> 2.3)
16
+ descendants_tracker (~> 0.0.1)
17
+ faraday (~> 0.8, < 0.10)
18
+ hashie (>= 1.2)
19
+ multi_json (>= 1.7.5, < 2.0)
20
+ nokogiri (~> 1.6.0)
21
+ oauth2
22
+ gli (2.9.0)
23
+ hashie (2.0.5)
24
+ highline (1.6.21)
25
+ httparty (0.12.0)
26
+ json (~> 1.8)
27
+ multi_xml (>= 0.5.2)
28
+ jeweler (2.0.1)
29
+ builder
30
+ bundler (>= 1.0)
31
+ git (>= 1.2.5)
32
+ github_api
33
+ highline (>= 1.6.15)
34
+ nokogiri (>= 1.5.10)
35
+ rake
36
+ rdoc
37
+ json (1.8.1)
38
+ jwt (0.1.11)
39
+ multi_json (>= 1.5)
40
+ mini_portile (0.5.3)
41
+ multi_json (1.9.2)
42
+ multi_xml (0.5.5)
43
+ multipart-post (2.0.0)
44
+ nokogiri (1.6.1)
45
+ mini_portile (~> 0.5.0)
46
+ oauth2 (0.9.3)
47
+ faraday (>= 0.8, < 0.10)
48
+ jwt (~> 0.1.8)
49
+ multi_json (~> 1.3)
50
+ multi_xml (~> 0.5)
51
+ rack (~> 1.2)
52
+ rack (1.5.2)
53
+ rainbow (2.0.0)
54
+ rake (10.2.2)
55
+ rdoc (4.1.1)
56
+ json (~> 1.4)
57
+ rspec (2.14.1)
58
+ rspec-core (~> 2.14.0)
59
+ rspec-expectations (~> 2.14.0)
60
+ rspec-mocks (~> 2.14.0)
61
+ rspec-core (2.14.8)
62
+ rspec-expectations (2.14.5)
63
+ diff-lcs (>= 1.1.3, < 2.0)
64
+ rspec-mocks (2.14.6)
65
+ safe_yaml (1.0.1)
66
+ thread_safe (0.3.2)
67
+ webmock (1.17.4)
68
+ addressable (>= 2.2.7)
69
+ crack (>= 0.3.2)
70
+
71
+ PLATFORMS
72
+ ruby
73
+
74
+ DEPENDENCIES
75
+ gli
76
+ httparty
77
+ jeweler
78
+ rainbow
79
+ rspec
80
+ webmock
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ Peas CLI
2
+ ========
3
+
4
+ Command line client for Peas.
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ require './lib/peas/version.rb'
16
+ Jeweler::Tasks.new do |gem|
17
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
18
+ gem.name = "peas-cli"
19
+ gem.homepage = "http://github.com/tombh/peas"
20
+ gem.license = "GPL v2"
21
+ gem.version = Peas::VERSION
22
+ gem.summary = %Q{CLI client for Peas}
23
+ gem.description = %Q{Peas is an open source Heroku-style PaaS written in Ruby and using Docker}
24
+ gem.email = "tom@tombh.co.uk"
25
+ gem.authors = ["Tom Buckley-Houston"]
26
+ gem.files.include 'VERSION'
27
+ # dependencies defined in Gemfile
28
+ end
29
+ Jeweler::RubygemsDotOrgTasks.new
30
+
31
+ desc "Code coverage detail"
32
+ task :simplecov do
33
+ ENV['COVERAGE'] = "true"
34
+ Rake::Task['test'].execute
35
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
data/bin/peas ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gli'
3
+ require 'peas'
4
+
5
+ @api = API.new
6
+
7
+ include GLI::App
8
+ reset # Used when this file is repetitively loaded by rspec
9
+
10
+ program_desc 'CLI client for Peas'
11
+
12
+ version Peas::VERSION
13
+
14
+ desc 'Create an app'
15
+ command :create do |c|
16
+ c.action do |global_options, options, args|
17
+ @api.request :post, :create, {
18
+ first_sha: Git.first_sha,
19
+ remote: Git.remote
20
+ }
21
+ end
22
+ end
23
+
24
+ desc 'Deploy an app'
25
+ command :deploy do |c|
26
+ c.action do |global_options, options, args|
27
+ @api.request :get, :deploy, {first_sha: Git.first_sha}
28
+ end
29
+ end
30
+
31
+ desc 'Scale an app'
32
+ long_desc <<-EOF
33
+ For example: peas scale web=3 worker=2
34
+ EOF
35
+ command :scale do |c|
36
+ c.action do |global_options, options, args|
37
+ if args.length == 0
38
+ exit_now! "Please provide scaling arguments in the form: web=3 worker=2"
39
+ end
40
+ scaling_hash = {}
41
+ args.each do |arg|
42
+ parts = arg.split('=')
43
+ process_type = parts[0]
44
+ quantity = parts[1]
45
+ scaling_hash[process_type] = quantity
46
+ end
47
+ @api.request :put, :scale, {
48
+ first_sha: Git.first_sha,
49
+ scaling_hash: scaling_hash.to_json
50
+ }
51
+ end
52
+ end
53
+
54
+ desc 'Set Peas global settings'
55
+ command :settings do |c|
56
+ c.flag 'domain',
57
+ type: String,
58
+ desc: 'The FQDN for the Peas server'
59
+ c.action do |global_options, options, args|
60
+ if options['domain']
61
+ if !options['domain'].start_with? 'http://'
62
+ options['domain'] = "http://#{options['domain']}"
63
+ end
64
+ end
65
+ # Gli seems to provide a String and Symbol key for every option, so the options hash needs
66
+ # de-duplicating
67
+ deduped = {}
68
+ options.each do |k, v|
69
+ deduped[k] = v if k.is_a? String
70
+ end
71
+ # Merge existing settings with current settings
72
+ content = Peas.config.merge(deduped).to_json
73
+ File.open(Peas.config_file, 'w+'){|f| f.write(content) }
74
+ # Save the settings on the server as well
75
+ @api.request :put, :settings, options
76
+ puts "New settings:"
77
+ puts JSON.pretty_generate(Peas.config)
78
+ end
79
+ desc 'Display the current settings'
80
+ c.command :display do |c|
81
+ c.action do |global_options, options, args|
82
+ puts JSON.pretty_generate(Peas.config)
83
+ end
84
+ end
85
+ end
86
+
87
+ pre do |global, command, options, args|
88
+ # Pre logic here
89
+ # Return true to proceed; false to abort and not call the
90
+ # chosen command
91
+ # Use skips_pre before a command to skip this block
92
+ # on that command only
93
+ true
94
+ end
95
+
96
+ post do |global, command, options, args|
97
+ # Post logic here
98
+ # Use skips_post before a command to skip this
99
+ # block on that command only
100
+ end
101
+
102
+ on_error do |exception|
103
+ # Error logic here
104
+ # return false to skip default error handling
105
+ true
106
+ end
107
+
108
+ exit_status = run(ARGV)
109
+ exit exit_status if ENV['GLI_ENV'] != 'test'
data/lib/peas/api.rb ADDED
@@ -0,0 +1,71 @@
1
+ require 'httparty'
2
+
3
+ class API
4
+ include HTTParty
5
+
6
+ LONG_POLL_TIMEOUT = 10 * 60
7
+ LONG_POLL_INTERVAL = 0.5
8
+
9
+ # This allows base_uri to be dynamically set. Useful for testing
10
+ def initialize
11
+ self.class.base_uri Peas.config['domain'] || 'localhost:4000'
12
+ end
13
+
14
+ # Generic wrapper to the Peas API
15
+ def request verb, method, params
16
+ response = self.class.send(verb, "/#{method}", {query: params}).body
17
+ if response
18
+ json = JSON.parse(response)
19
+ else
20
+ json = {}
21
+ end
22
+ # If there was an HTTP-level error
23
+ raise json['error'].color(:red) if json.has_key? 'error'
24
+ # Successful responses
25
+ if json.has_key? 'job'
26
+ # Long-running jobs need to poll a job status endpoint
27
+ long_running_output json['job']
28
+ else
29
+ # Normal API repsonse
30
+ puts json['message']
31
+ end
32
+ end
33
+
34
+ # Rudimentary long-polling to stream the status of a job.
35
+ def long_running_output job
36
+ count = 0
37
+ begin
38
+ sleep LONG_POLL_INTERVAL
39
+ # API request to the /status endpoint
40
+ status = JSON.parse self.class.send(:get, '/status', {query: {job: job}}).body
41
+ if status['status'] != 'failed'
42
+ if status['output']
43
+ # Don't output the accumulated progress log every time. Just output the difference
44
+ output_diff status['output']
45
+ end
46
+ # Theoretically all worker errors should be caught and handled gracefully
47
+ if status['error']
48
+ puts
49
+ raise status['error'].color(:red)
50
+ end
51
+ else
52
+ # Uncaught error or production environment error
53
+ raise "Long-running job failed. See worker logs for details.".color(:red)
54
+ end
55
+ count += 1
56
+ end while status['status'] == 'working' && (count * LONG_POLL_INTERVAL) < LONG_POLL_TIMEOUT
57
+ end
58
+
59
+ # The Sidekiq status gem allows you to set custom variables associated with a job. So the worker
60
+ # appends to an 'output' variable that accumulates the total log data. So we don't want to output
61
+ # the 'total' output on every long-polled request. We just want to output any *new* log lines.
62
+ def output_diff log_so_far
63
+ @accumulated_output ||= ''
64
+ old_count = @accumulated_output.lines.length
65
+ new_count = log_so_far.lines.length
66
+ diff = log_so_far.lines[old_count..new_count]
67
+ @accumulated_output = log_so_far
68
+ puts diff.join if diff.length > 0
69
+ end
70
+
71
+ end
@@ -0,0 +1,12 @@
1
+ module Peas
2
+ def self.config
3
+ file = File.open config_file, "a+"
4
+ contents = file.read
5
+ contents = '{}' if contents == ''
6
+ JSON.parse contents
7
+ end
8
+
9
+ def self.config_file
10
+ "#{ENV['HOME']}/.peas"
11
+ end
12
+ end
data/lib/peas/git.rb ADDED
@@ -0,0 +1,17 @@
1
+ class Git
2
+ def self.sh cmd
3
+ `#{cmd}`.strip
4
+ end
5
+
6
+ def self.root_path
7
+ sh 'git rev-parse --show-toplevel'
8
+ end
9
+
10
+ def self.remote
11
+ sh 'git config --get remote.origin.url'
12
+ end
13
+
14
+ def self.first_sha
15
+ sh 'git rev-list --max-parents=0 HEAD'
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module Peas
2
+ VERSION = File.read File.expand_path("../../../VERSION", __FILE__)
3
+ end
data/lib/peas.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'json'
2
+ require 'peas/version.rb'
3
+ require 'peas/config.rb'
4
+ require 'peas/git.rb'
5
+ require 'peas/api.rb'
6
+ require 'rainbow'
7
+ require 'rainbow/ext/string'
8
+
data/peas-cli.gemspec ADDED
@@ -0,0 +1,63 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "peas-cli"
8
+ s.version = "0.0.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Tom Buckley-Houston"]
12
+ s.date = "2014-04-06"
13
+ s.description = "Peas is an open source Heroku-style PaaS written in Ruby and using Docker"
14
+ s.email = "tom@tombh.co.uk"
15
+ s.executables = ["peas"]
16
+ s.extra_rdoc_files = [
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".rspec",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "bin/peas",
27
+ "lib/peas.rb",
28
+ "lib/peas/api.rb",
29
+ "lib/peas/config.rb",
30
+ "lib/peas/git.rb",
31
+ "lib/peas/version.rb",
32
+ "peas-cli.gemspec",
33
+ "spec/cli_spec.rb",
34
+ "spec/spec_helper.rb"
35
+ ]
36
+ s.homepage = "http://github.com/tombh/peas"
37
+ s.licenses = ["GPL v2"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = "2.0.14"
40
+ s.summary = "CLI client for Peas"
41
+
42
+ if s.respond_to? :specification_version then
43
+ s.specification_version = 4
44
+
45
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
46
+ s.add_runtime_dependency(%q<gli>, [">= 0"])
47
+ s.add_runtime_dependency(%q<httparty>, [">= 0"])
48
+ s.add_runtime_dependency(%q<rainbow>, [">= 0"])
49
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
50
+ else
51
+ s.add_dependency(%q<gli>, [">= 0"])
52
+ s.add_dependency(%q<httparty>, [">= 0"])
53
+ s.add_dependency(%q<rainbow>, [">= 0"])
54
+ s.add_dependency(%q<jeweler>, [">= 0"])
55
+ end
56
+ else
57
+ s.add_dependency(%q<gli>, [">= 0"])
58
+ s.add_dependency(%q<httparty>, [">= 0"])
59
+ s.add_dependency(%q<rainbow>, [">= 0"])
60
+ s.add_dependency(%q<jeweler>, [">= 0"])
61
+ end
62
+ end
63
+
data/spec/cli_spec.rb ADDED
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Peas CLI' do
4
+ before :each do
5
+ Git.stub(:sh).and_return(nil)
6
+ Git.stub(:remote).and_return('git@github.com:test/test.git')
7
+ Git.stub(:first_sha).and_return('fakesha')
8
+ API.any_instance.stub(:sleep).and_return(nil)
9
+ Peas.stub(:config_file).and_return('/tmp/.peas')
10
+ end
11
+
12
+ describe 'Settings' do
13
+ it 'should set settings' do
14
+ File.delete '/tmp/.peas' if File.exists? '/tmp/.peas'
15
+ stub_request(:put, /settings\?domain=new-domain\.com/)
16
+ output = cli %w(settings --domain=new-domain.com:4000)
17
+ expect(output).to eq "\nNew settings:\n{\n \"domain\": \"http://new-domain.com:4000\"\n}\n"
18
+ config = JSON.parse File.open('/tmp/.peas').read
19
+ expect(config).to eq ({"domain"=>"http://new-domain.com:4000"})
20
+ end
21
+
22
+ it 'should use the domain setting' do
23
+ File.open('/tmp/.peas', 'w'){|f| f.write('{"domain":"test.com"}') }
24
+ stub_request(:get, /test.com/)
25
+ cli %w(deploy)
26
+ end
27
+ end
28
+
29
+ describe 'API methods' do
30
+ it 'should create an app' do
31
+ stub_request(:post, /create\?first_sha=fakesha&remote=git@github\.com:test\/test\.git/)
32
+ .to_return(body: '{"message": "App \'test\' successfully created\n"}')
33
+ output = cli ['create']
34
+ expect(output).to eq "App 'test' successfully created\n"
35
+ end
36
+
37
+ it 'should deploy an app' do
38
+ stub_request(:get, /deploy/).to_return(body: '{"job": "123"}')
39
+ stub_request(:get, /status/).to_return(
40
+ {body: '{"status": "working", "output": "deploying\n"}'}
41
+ )
42
+ output = cli ['deploy']
43
+ expect(output).to eq "deploying\n"
44
+ end
45
+
46
+ it 'should scale an app' do
47
+ stub_request(
48
+ :put,
49
+ /scale\?first_sha=fakesha&scaling_hash=%7B%22web%22:%223%22,%22worker%22:%222%22%7D/
50
+ ).to_return(body: '{"job": "123"}')
51
+ stub_request(:get, /status/).to_return(
52
+ {body: '{"status": "working", "output": "scaling\n"}'}
53
+ )
54
+ output = cli %w(scale web=3 worker=2)
55
+ expect(output).to eq "scaling\n"
56
+ end
57
+ end
58
+
59
+ it 'should retrieve and output a long-running command' do
60
+ stub_request(:get, /deploy/).to_return(body: '{"job": "123"}')
61
+ stub_request(:get, /status/).to_return(
62
+ {body: '{"status": "working", "output": "doing\n"}'},
63
+ {body: '{"status": "working", "output": "doing\nsomething\n"}'},
64
+ {body: '{"status": "working", "output": "doing\nsomething\n"}'},
65
+ {body: '{"status": "complete", "output": "doing\nsomething\ndone\n"}'}
66
+ )
67
+ output = cli ['deploy']
68
+ expect(output).to eq "doing\nsomething\ndone\n"
69
+ end
70
+ end
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'stringio'
3
+ require 'webmock/rspec'
4
+ require 'peas'
5
+
6
+ ENV['GLI_ENV'] = 'test'
7
+ ROOT = File.join(File.expand_path(File.dirname(__FILE__)), '..')
8
+ $LOAD_PATH.unshift(File.join(ROOT, 'lib'))
9
+
10
+ RSpec.configure do |config|
11
+ config.mock_with :rspec
12
+ config.expect_with :rspec
13
+ end
14
+
15
+ # Execute a block that triggers STDOUT and test output
16
+ def capture_stdout(&blk)
17
+ old = $stdout
18
+ $stdout = fake = StringIO.new
19
+ blk.call
20
+ fake.string
21
+ ensure
22
+ $stdout = old
23
+ end
24
+
25
+ # Clever little function to simulate CLI requests.
26
+ # Usage: cli(['create', '--flag', '--switch']).
27
+ # Output is suppressed, captured and returned.
28
+ def cli args
29
+ stub_const "ARGV", args
30
+ capture_stdout do
31
+ ENV['GLI_DEBUG'] = 'true'
32
+ load File.join(ROOT, 'bin/peas')
33
+ end
34
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: peas-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Tom Buckley-Houston
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gli
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: httparty
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rainbow
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: jeweler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Peas is an open source Heroku-style PaaS written in Ruby and using Docker
70
+ email: tom@tombh.co.uk
71
+ executables:
72
+ - peas
73
+ extensions: []
74
+ extra_rdoc_files:
75
+ - README.md
76
+ files:
77
+ - .rspec
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - README.md
81
+ - Rakefile
82
+ - VERSION
83
+ - bin/peas
84
+ - lib/peas.rb
85
+ - lib/peas/api.rb
86
+ - lib/peas/config.rb
87
+ - lib/peas/git.rb
88
+ - lib/peas/version.rb
89
+ - peas-cli.gemspec
90
+ - spec/cli_spec.rb
91
+ - spec/spec_helper.rb
92
+ homepage: http://github.com/tombh/peas
93
+ licenses:
94
+ - GPL v2
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.0.14
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: CLI client for Peas
116
+ test_files: []