pf-command 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ session.json
2
+ *.gem
3
+ .bundle
4
+ pkg/*
5
+
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use default@pf-command
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in pf-command.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ pf-command
2
+ ==========
3
+
4
+ <img src="https://phpfog.com/images/logo.png" />
5
+
6
+ pf-command is a command-line utility that allows PHP Fog users to mange their
7
+ PHP Fog accounts from the command line. It offers commands to create and edit
8
+ apps, manage environment variables, set ssh keys, and more.
9
+
10
+
11
+ ## Setup ##
12
+
13
+ Install it like any Ruby Gem:
14
+
15
+ $ gem install pf-command
16
+
17
+
18
+ ## Usage ##
19
+
20
+ $ pf <command>
21
+
22
+
23
+ ## Meta ##
24
+
25
+ Maintained by Tim Santeford and Richard Howard.
26
+
27
+ Released under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/pf ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require 'rubygems'
7
+ require 'pf-command'
8
+ require 'json'
9
+
10
+ unless Commandline::run!(ARGV)
11
+ abort File.read(__FILE__).split('__END__').last
12
+ end
13
+
14
+ __END__
15
+ Usage: pf list <list_command>
16
+ pf clone <app_id>
17
+ pf create <cloud_id>
18
+ pf delete <app_id>
19
+ pf logout
20
+ pf view app_id
21
+
22
+ LIST COMMAND
23
+
24
+ cloud
25
+ List all clouds
26
+
27
+ apps <cloud_id>
28
+ List all apps in the specifed cloud
29
+
data/config/.empty ADDED
File without changes
@@ -0,0 +1,13 @@
1
+ module Commands
2
+ def clone(argv)
3
+ app_id = argv.shift
4
+
5
+ return false if app_id.nil?
6
+
7
+ phpfog = PHPfog.new
8
+ apps = phpfog.get_app(app_id)
9
+ # this could be dangerous
10
+ exec(apps['repo'])
11
+ true
12
+ end
13
+ end
@@ -0,0 +1,52 @@
1
+ module Commands
2
+ def create(argv)
3
+ command = argv.shift
4
+
5
+ case command
6
+ when "app"
7
+
8
+ cloud_id = argv.shift
9
+
10
+ if cloud_id == '1' || cloud_id == 'shared'
11
+ cloud_id = ''
12
+ end
13
+
14
+ phpfog = PHPfog.new
15
+
16
+ mysql_password = prompt 'MySQL Password: '
17
+ if mysql_password.empty?
18
+ puts 'New app canceled'
19
+ exit
20
+ end
21
+
22
+ domain_name = nil
23
+ while domain_name == nil
24
+ temp_domain_name = prompt 'Domain Name: '
25
+
26
+ if temp_domain_name.empty?
27
+ puts bwhite 'New app canceled'
28
+ exit
29
+ end
30
+
31
+ if phpfog.domain_available?(temp_domain_name)
32
+ domain_name = temp_domain_name
33
+ else
34
+ puts bwhite 'Domain name not available. Try again.'
35
+ end
36
+ end
37
+
38
+ app_id = phpfog.new_app(cloud_id, 16, domain_name, mysql_password)
39
+ if !app_id.nil?
40
+ puts bwhite 'New app created.' + "(ID:#{red app_id})"
41
+ else
42
+ puts bwhite 'New app failed to be created.'
43
+ end
44
+
45
+ else
46
+ puts "Unknown Command: " + (command || '')
47
+ return false
48
+ end
49
+
50
+ true
51
+ end
52
+ end
@@ -0,0 +1,18 @@
1
+ module Commands
2
+ def delete(argv)
3
+ command = argv.shift
4
+
5
+ case command
6
+ when "app"
7
+ app_id = argv.shift
8
+
9
+ phpfog = PHPfog.new
10
+ apps = phpfog.app_delete(app_id)
11
+ else
12
+ puts "Unknown Command: " + command
13
+ return false
14
+ end
15
+
16
+ true
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ module Commands
2
+ def env(argv)
3
+
4
+ end
5
+ end
@@ -0,0 +1,37 @@
1
+ module Commands
2
+ def list(argv)
3
+ command = argv.shift
4
+
5
+ case command
6
+ when "clouds"
7
+
8
+ phpfog = PHPfog.new
9
+ clouds = phpfog.get_clouds
10
+ clouds.each do |cloud|
11
+ puts "#{bwhite(cloud['name'])} - #{cloud['description']} (ID:#{red cloud['id']})"
12
+ end
13
+
14
+ when "apps"
15
+
16
+ cloud_id = argv.shift
17
+
18
+ phpfog = PHPfog.new
19
+
20
+ apps = phpfog.get_apps(cloud_id)
21
+ apps.each do |app|
22
+ app_status = app['status']
23
+ case app['status']
24
+ when "Running"
25
+ app_status = green(app_status)
26
+ end
27
+ puts "#{bwhite(app['name'])} - #{app_status} (ID:#{red app['id']})"
28
+ end
29
+
30
+ else
31
+ puts "Unknown Command: " + (command || '')
32
+ return false
33
+ end
34
+
35
+ true
36
+ end
37
+ end
@@ -0,0 +1,11 @@
1
+ module Commands
2
+ def logout(argv)
3
+ if File.exists? SESSION_PATH
4
+ File.delete SESSION_PATH
5
+ puts bright 'Successfully logged out.'
6
+ else
7
+ puts bwhite 'Already logged out.'
8
+ end
9
+ true
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ module Commands
2
+ def view(argv)
3
+ command = argv.shift
4
+
5
+ phpfog = PHPfog.new
6
+ case command
7
+ when "app"
8
+ app_id = argv.shift
9
+ apps = phpfog.get_app(app_id)
10
+ system("open", apps["site_address"])
11
+ else
12
+ puts "Unknown Command: " + command
13
+ return false
14
+ end
15
+
16
+ true
17
+ end
18
+ end
data/lib/pf-command.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "pf-command/colorize"
2
+ require "pf-command/commandline"
3
+ require "pf-command/phpfog"
4
+ require "pf-command/prompt"
5
+ require "pf-command/rest"
6
+ require "pf-command/version"
@@ -0,0 +1,78 @@
1
+ def colorize(str, beginColor, endColor = 0)
2
+ "\e[#{beginColor}m#{str}\e[#{endColor}m"
3
+ end
4
+
5
+ #30 Black
6
+ def black(str, endColor = 0)
7
+ colorize(str, "30", endColor)
8
+ end
9
+
10
+ #31 Red
11
+ def red(str, endColor = 0)
12
+ colorize(str, "31", endColor)
13
+ end
14
+
15
+ #31 Red
16
+ def bred(str, endColor = 0)
17
+ colorize(str, "1;31", endColor)
18
+ end
19
+
20
+ #32 Green
21
+ def green(str, endColor = 0)
22
+ colorize(str, "32", endColor)
23
+ end
24
+
25
+ #32 Bright Green
26
+ def bgreen(str, endColor = 0)
27
+ colorize(str, "1;32", endColor)
28
+ end
29
+
30
+ #33 Yellow
31
+ def yellow(str, endColor = 0)
32
+ colorize(str, "33", endColor)
33
+ end
34
+
35
+ #33 Yellow
36
+ def byellow(str, endColor = 0)
37
+ colorize(str, "1;33", endColor)
38
+ end
39
+
40
+ #34 Blue
41
+ def blue(str, endColor = 0)
42
+ colorize(str, "34", endColor)
43
+ end
44
+
45
+ #34 Blue
46
+ def bblue(str, endColor = 0)
47
+ colorize(str, "1;34", endColor)
48
+ end
49
+
50
+ #35 Magenta
51
+ def magenta(str, endColor = 0)
52
+ colorize(str, "35", endColor)
53
+ end
54
+
55
+ #35 Magenta
56
+ def bmagenta(str, endColor = 0)
57
+ colorize(str, "1;35", endColor)
58
+ end
59
+
60
+ #36 Cyan
61
+ def cyan(str, endColor = 0)
62
+ colorize(str, "36", endColor)
63
+ end
64
+
65
+ #36 Bright Cyan
66
+ def bcyan(str, endColor = 0)
67
+ colorize(str, "1;36", endColor)
68
+ end
69
+
70
+ #37 White
71
+ def white(str, endColor = 0)
72
+ colorize(str, "37", endColor)
73
+ end
74
+
75
+ #37 Bright White
76
+ def bwhite(str, endColor = 0)
77
+ colorize(str, "1;37", endColor)
78
+ end
@@ -0,0 +1,44 @@
1
+ require 'yaml'
2
+
3
+ module Commandline
4
+
5
+ class CommandHelper
6
+ @metadata = []
7
+ end
8
+
9
+ def run!(argv)
10
+ if argv.nil? || !argv.is_a?(Array) || argv.length < 1
11
+ puts "Invalid Command"
12
+ return false
13
+ end
14
+
15
+ Dir[File.expand_path(File.dirname(__FILE__) + '/../commands') + '/*.rb'].each {|file| require file }
16
+
17
+ command = argv.shift
18
+
19
+ if command == 'help'
20
+ help_command = argv.shift
21
+
22
+ unless help_command.nil? || help_command.empty?
23
+ show_command_help(help_command)
24
+ return true
25
+ end
26
+
27
+ puts "Help expects an argument"
28
+ return false
29
+ end
30
+
31
+ if Commands.method_defined?(command) then
32
+ c = CommandHelper.new
33
+ c.extend Commands
34
+ required_method = Commands.instance_method(command)
35
+ return required_method.bind(c).call(argv)
36
+ else
37
+ puts "Invalid Command '#{command}'"
38
+ return false
39
+ end
40
+
41
+ true
42
+ end
43
+ module_function :run
44
+ end
@@ -0,0 +1,210 @@
1
+ require 'nokogiri'
2
+ require 'open-uri'
3
+
4
+ class PHPfog
5
+
6
+ $phpfog = nil
7
+ $session = nil
8
+ $isLoggedIn = false
9
+
10
+ def initialize
11
+ $phpfog = Rest.new("https://www.phpfog.com")
12
+
13
+ load_session
14
+ $phpfog.cookies = $session['cookies'].clone unless $session['cookies'].nil?
15
+ end
16
+
17
+ def get_clouds
18
+ authorize!
19
+
20
+ resp = rpeek $phpfog.get("/account")
21
+
22
+ doc = Nokogiri::HTML(resp.body)
23
+
24
+ clouds = Array.new
25
+ cloud_items = doc.css("li.cloud")
26
+ cloud_items.each do |cloud_item|
27
+ cloud_link = cloud_item.at_css("h4 a")
28
+ cloud_name = !cloud_link.nil? ? cloud_link.text.strip : 'Shared Cloud'
29
+ cloud_href = !cloud_link.nil? ? cloud_link.attr('href') : ''
30
+ cloud_desc = cloud_item.at_css(".title p").text.strip
31
+
32
+ cloudIdRe = /\/(\d+)/
33
+ m = cloudIdRe.match(cloud_href)
34
+ cloud_id = m.captures.shift unless m.nil?
35
+
36
+ clouds << { 'id' => cloud_id || 1, 'link' => cloud_href, 'name' => cloud_name, 'description' => cloud_desc }
37
+ end
38
+
39
+ clouds
40
+ end
41
+
42
+ def get_apps(cloud_id)
43
+ authorize!
44
+
45
+ apps_url = nil
46
+ app_item_selector = nil
47
+
48
+
49
+ if cloud_id == '1' || cloud_id == 'shared'
50
+ apps_url = '/account'
51
+ app_item_selector = '#clouds li:last .drop-down li'
52
+ app_link_selector = 'a'
53
+ app_status_selector = nil
54
+ else
55
+ apps_url = "/clouds/#{cloud_id}"
56
+ app_item_selector = '#apps li.app'
57
+ app_link_selector = 'h4 a'
58
+ app_status_selector = '.title span'
59
+ end
60
+
61
+ resp = rpeek $phpfog.get(apps_url)
62
+
63
+ doc = Nokogiri::HTML(resp.body)
64
+
65
+ apps = Array.new
66
+ app_items = doc.css(app_item_selector)
67
+ app_items.each do |app_item|
68
+ app_link = app_item.at_css(app_link_selector)
69
+ app_name = app_link.text.strip
70
+ app_href = app_link.attr('href')
71
+ app_status = app_item.at_css(app_status_selector).text.strip unless app_status_selector.nil?
72
+
73
+ appIdRe = /\/(\d+)/
74
+ m = appIdRe.match(app_href)
75
+ app_id = m.captures.shift unless m.nil?
76
+
77
+ apps << { 'id' => app_id || 1, 'link' => app_href, 'name' => app_name, 'status' => app_status }
78
+ end
79
+
80
+ apps
81
+ end
82
+
83
+ def get_app(app_id)
84
+ authorize!
85
+
86
+ app = {}
87
+
88
+ resp = rpeek $phpfog.get("/apps/#{app_id}")
89
+ doc = Nokogiri::HTML(resp.body)
90
+
91
+ app['site_address'] = doc.css("#app-view-live a").attr('href')
92
+ app['repo'] = doc.css("#source_code ul code").text.strip[2..-1]
93
+
94
+ app
95
+ end
96
+
97
+ def app_delete(app_id)
98
+ authorize!
99
+
100
+ resp = rpeek $phpfog.get("/apps/#{app_id}")
101
+ resp = rpeek $phpfog.delete("/apps/#{app_id}", { 'authenticity_token' => get_auth_token(resp.body) })
102
+
103
+ resp.code == "200"
104
+ end
105
+
106
+ def domain_available?(domain_name)
107
+ authorize!
108
+ resp = rpeek $phpfog.get("/apps/subdomain_available?app[domain_name]=#{domain_name}", nil, { 'Accept' => 'application/json, text/javascript, */*; q=0.01', 'X-Requested-With' => 'XMLHttpRequest', 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 'Connection' => 'keep-alive' })
109
+ return resp.code == '200' && resp.body == 'true'
110
+ end
111
+
112
+ def new_app(cloud_id, jumpstart_id, domain_name, mysql_password)
113
+ authorize!
114
+
115
+ resp = rpeek $phpfog.get("/apps/new?cloud_id=#{cloud_id}")
116
+ resp = rpeek $phpfog.post("/apps", { 'authenticity_token' => get_auth_token(resp.body),
117
+ 'cloud_id' => cloud_id,
118
+ 'app[jump_start_id]' => jumpstart_id,
119
+ 'app[login]' => 'Custom App',
120
+ 'app[password]' => mysql_password,
121
+ 'app[domain_name]' => domain_name })
122
+
123
+
124
+ if resp.code == "302"
125
+ appIdRe = /\/(\d+)/
126
+ m = appIdRe.match(resp['location'])
127
+ return m.captures.shift unless m.nil?
128
+ end
129
+ nil
130
+ end
131
+
132
+ def loggedin?
133
+ if $isLoggedIn == false
134
+ rpeek $phpfog.get("/login") # required to establish session
135
+ resp = rpeek $phpfog.get("/account")
136
+ $isLoggedIn = resp.code == "200"
137
+ end
138
+ $isLoggedIn
139
+ end
140
+
141
+ def login()
142
+ username = (prompt "Username: ").strip
143
+ password = (prompt "Password: ", true).strip
144
+
145
+ # open session
146
+ resp = rpeek $phpfog.get("/login")
147
+ resp = rpeek $phpfog.post("/user_session",
148
+ { 'authenticity_token' => get_auth_token(resp.body),
149
+ 'user_session[login]' => username,
150
+ 'user_session[password]' => password,
151
+ 'user_session[remember_me]' => '0',
152
+ 'commit' => 'login' })
153
+
154
+ if resp.code == '302'
155
+ puts cyan "Login Successfull."
156
+ $isLoggedIn = true
157
+ else
158
+ puts red "Login Failed."
159
+ end
160
+
161
+ resp = rpeek $phpfog.get("/account")
162
+ resp.code == "200"
163
+ end
164
+
165
+ def authorize!
166
+ unless loggedin? || login()
167
+ throw(:halt, "Not logged in")
168
+ end
169
+ end
170
+
171
+ private
172
+
173
+ def rpeek(resp)
174
+ # look for cookie change
175
+ if $session['cookies'].nil? || $phpfog.cookies.to_s != $session['cookies'].to_s
176
+ $session['cookies'] = $phpfog.cookies.clone
177
+ save_session
178
+ end
179
+ resp
180
+ end
181
+
182
+ def load_session
183
+ begin
184
+ session_file = File.open("../config/session.json", 'r')
185
+ session_json = session_file.readlines.to_s
186
+ $session = JSON.parse(session_json)
187
+ rescue
188
+ $session = {}
189
+ end
190
+ end
191
+
192
+ def save_session
193
+ puts File.expand_path('../config/session.json')
194
+ session_file = File.new(SESSION_PATH, "w+")
195
+ session_file.puts(JSON.generate($session))
196
+ session_file.close
197
+ end
198
+
199
+ def get_auth_token(html)
200
+ #<input name="authenticity_token" type="hidden" value="CSldCthWb3MLTncXJOWiZQOa0R94c0hnnP9ijCM6Dy4=" />
201
+ authTokenRe = /authenticity_token" type="hidden" value="(.*?)"/
202
+ m = authTokenRe.match(html)
203
+ if !m.nil?
204
+ m.captures.shift
205
+ else
206
+ ''
207
+ end
208
+ end
209
+
210
+ end
@@ -0,0 +1,10 @@
1
+ def prompt(msg, isPassword = false)
2
+ print(msg)
3
+ system "stty -echo" if isPassword
4
+ input = gets
5
+ if isPassword
6
+ system "stty echo"
7
+ puts ''
8
+ end
9
+ input.strip
10
+ end
@@ -0,0 +1,102 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'uri'
4
+ require 'cgi'
5
+
6
+ class Rest
7
+
8
+ $user = nil
9
+ $password = nil
10
+ $http = nil
11
+ $cookies = {}
12
+ $last_resp = nil
13
+ $last_params = nil
14
+
15
+ $useragent = ''
16
+
17
+ def initialize(url, user = nil, password = nil)
18
+ $user = user
19
+ $password = password
20
+
21
+ uri = URI(url)
22
+ $http = Net::HTTP.new(uri.host, uri.port)
23
+
24
+ if uri.scheme == 'https'
25
+ $http.use_ssl = true
26
+ $http.verify_mode = OpenSSL::SSL::VERIFY_NONE
27
+ else
28
+ $http.use_ssl = false
29
+ end
30
+ end
31
+
32
+ def get(url, params = nil, additional_header = nil)
33
+ header = { 'Cookie' => cookie_to_s, 'User-Agent' => $useragent }
34
+ header = header.merge(additional_header) unless additional_header.nil?
35
+ req = Net::HTTP::Get.new(url, header)
36
+ make_request(req, params)
37
+ end
38
+
39
+ def post(url, params, payload = nil, additional_header = nil)
40
+ header = { 'Cookie' => cookie_to_s, 'User-Agent' => $useragent }
41
+ header = header.merge(additional_header) unless additional_header.nil?
42
+ req = Net::HTTP::Post.new(url, { 'Cookie' => cookie_to_s, 'User-Agent' => $useragent })
43
+ make_request(req, params, payload)
44
+ end
45
+
46
+ def put(url, params, payload = nil)
47
+ req = Net::HTTP::Put.new(url, { 'Cookie' => cookie_to_s, 'User-Agent' => $useragent })
48
+ make_request(req, params, payload)
49
+ end
50
+
51
+ def delete(url, params = nil, payload = nil)
52
+ req = Net::HTTP::Delete.new(url, { 'Cookie' => cookie_to_s, 'User-Agent' => $useragent })
53
+ make_request(req, params, payload)
54
+ end
55
+
56
+ def cookies
57
+ $cookies
58
+ end
59
+ def cookies=(dough)
60
+ $cookies = dough
61
+ end
62
+
63
+ def inspect
64
+ puts "#{bwhite(resp.code)} - #{$last_resp.message}"
65
+ puts $last_params.inspect
66
+ puts "Cookies: " + $cookies.inspect
67
+ puts $last_resp.body
68
+ end
69
+
70
+ private
71
+
72
+ def cookie_to_s
73
+ cookiestr = ''
74
+ $cookies.each do |key, value|
75
+ cookiestr += "#{key}=#{value}, "
76
+ end
77
+ cookiestr[0..-2]
78
+ end
79
+
80
+ def make_request(req, params = nil, payload = nil)
81
+ $last_params = params
82
+ req.basic_auth($user, $password) unless $user.nil?
83
+ req.set_form_data(params, ';') unless params.nil?
84
+
85
+ unless payload.nil?
86
+ req.body = payload
87
+ req.set_content_type('multipart/form-data')
88
+ end
89
+
90
+ $last_resp = $http.request(req)
91
+
92
+ unless $last_resp['set-cookie'].nil?
93
+ $last_resp['set-cookie'].split(', ').each do |cookie|
94
+ key, value = cookie.split('=')
95
+ $cookies[key] = value
96
+ end
97
+ end
98
+
99
+ $last_resp
100
+ end
101
+
102
+ end
@@ -0,0 +1,5 @@
1
+ module Pf
2
+ module Command
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "pf-command/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{pf-command}
7
+ s.version = Pf::Command::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Tim Santeford"]
10
+ s.email = ["tim@phpfog.com"]
11
+ s.homepage = %q{http://www.phpfog.com}
12
+ s.default_executable = %q{pf}
13
+ s.summary = %q{Command line interface for PHP Fog}
14
+ s.description = %q{Allows users to mange their PHP Fog accounts from the command line}
15
+
16
+ s.rubyforge_project = "pf-command"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ # specify any dependencies here; for example:
24
+ # s.add_development_dependency "rspec"
25
+ s.add_runtime_dependency "nokogiri"
26
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pf-command
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Tim Santeford
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-01-11 00:00:00 -08:00
18
+ default_executable: pf
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: nokogiri
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ description: Allows users to mange their PHP Fog accounts from the command line
33
+ email:
34
+ - tim@phpfog.com
35
+ executables:
36
+ - pf
37
+ extensions: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ files:
42
+ - .gitignore
43
+ - .rvmrc
44
+ - Gemfile
45
+ - README.md
46
+ - Rakefile
47
+ - bin/pf
48
+ - config/.empty
49
+ - lib/commands/clone.rb
50
+ - lib/commands/create.rb
51
+ - lib/commands/delete.rb
52
+ - lib/commands/env.rb
53
+ - lib/commands/list.rb
54
+ - lib/commands/logout.rb
55
+ - lib/commands/view.rb
56
+ - lib/pf-command.rb
57
+ - lib/pf-command/colorize.rb
58
+ - lib/pf-command/commandline.rb
59
+ - lib/pf-command/phpfog.rb
60
+ - lib/pf-command/prompt.rb
61
+ - lib/pf-command/rest.rb
62
+ - lib/pf-command/version.rb
63
+ - pf-command.gemspec
64
+ has_rdoc: true
65
+ homepage: http://www.phpfog.com
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options: []
70
+
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ requirements: []
88
+
89
+ rubyforge_project: pf-command
90
+ rubygems_version: 1.3.6
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Command line interface for PHP Fog
94
+ test_files: []
95
+