kibo 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile +15 -0
- data/README.md +14 -0
- data/Rakefile +10 -0
- data/bin/kibo +4 -0
- data/kibo.gemspec +46 -0
- data/lib/kibo/commandline.rb +92 -0
- data/lib/kibo/config.rb +95 -0
- data/lib/kibo/log.rb +18 -0
- data/lib/kibo/system.rb +35 -0
- data/lib/kibo/version.rb +3 -0
- data/lib/kibo.rb +221 -0
- data/man/kibo.1 +65 -0
- data/man/kibo.1.html +138 -0
- data/man/kibo.1.markdown +63 -0
- data/man/kibo.1.ronn +52 -0
- data/tasks/doc.rake +30 -0
- metadata +130 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "heroku"
|
4
|
+
gem "trollop"
|
5
|
+
gem 'rake'
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem 'ronn'
|
9
|
+
gem 'fakefs', '~> 0.3.2'
|
10
|
+
gem 'rr', '~> 1.0.2'
|
11
|
+
gem 'rspec', '~> 2.0'
|
12
|
+
gem "simplecov", :require => false
|
13
|
+
gem 'timecop'
|
14
|
+
# gem 'yard'
|
15
|
+
end
|
data/README.md
ADDED
data/Rakefile
ADDED
data/bin/kibo
ADDED
data/kibo.gemspec
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
2
|
+
require "kibo/version"
|
3
|
+
|
4
|
+
class Gem::Specification
|
5
|
+
class GemfileEvaluator
|
6
|
+
def initialize(scope)
|
7
|
+
@scope = scope
|
8
|
+
end
|
9
|
+
|
10
|
+
def load_dependencies(path)
|
11
|
+
instance_eval File.read(path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def source(*args); end
|
15
|
+
def group(*args); end
|
16
|
+
|
17
|
+
def gem(name, options = {})
|
18
|
+
@scope.add_dependency(name)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def load_dependencies(file)
|
23
|
+
GemfileEvaluator.new(self).load_dependencies(file)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Gem::Specification.new do |gem|
|
28
|
+
gem.name = "kibo"
|
29
|
+
gem.version = Kibo::VERSION
|
30
|
+
|
31
|
+
gem.authors = ["radiospiel"]
|
32
|
+
gem.email = ["eno@radiospiel.org"]
|
33
|
+
gem.homepage = "http://github.com/radiospiel/kibo"
|
34
|
+
gem.summary = "Manage heroku instances with ease"
|
35
|
+
|
36
|
+
gem.description = gem.summary
|
37
|
+
|
38
|
+
gem.load_dependencies "Gemfile"
|
39
|
+
|
40
|
+
gem.files = `git ls-files`.split($\)
|
41
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
42
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
43
|
+
gem.require_paths = ["lib"]
|
44
|
+
|
45
|
+
gem.add_dependency 'heroku'
|
46
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require "trollop"
|
2
|
+
|
3
|
+
module Kibo::CommandLine
|
4
|
+
def self.method_missing(sym, *args, &block)
|
5
|
+
if block_given? || !args.empty?
|
6
|
+
super
|
7
|
+
elsif options.key?(sym)
|
8
|
+
options[sym]
|
9
|
+
elsif (sym.to_s =~ /(.*)\?/) && options.key?($1.to_sym)
|
10
|
+
!! options[$1.to_sym]
|
11
|
+
else
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.options
|
17
|
+
parse unless @options
|
18
|
+
@options
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.subcommand
|
22
|
+
parse unless @options
|
23
|
+
@subcommand
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.args
|
27
|
+
parse unless @options
|
28
|
+
@args
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.parse_and_get(name)
|
32
|
+
parse unless @options
|
33
|
+
instance_variable_get "@#{name}"
|
34
|
+
end
|
35
|
+
|
36
|
+
SUBCOMMANDS = %w(create deploy spinup spindown reconfigure)
|
37
|
+
|
38
|
+
def self.parse
|
39
|
+
@options = Trollop::options do
|
40
|
+
version "test 1.2.3 (c) 2008 William Morgan"
|
41
|
+
banner <<-EOS
|
42
|
+
kibo is an awesome program that does something very, very important.
|
43
|
+
|
44
|
+
Usage:
|
45
|
+
|
46
|
+
kibo [options] create ... create missing targets
|
47
|
+
kibo [options] deploy ... updates all remote instances
|
48
|
+
kibo [options] spinup ... starts all remote instances
|
49
|
+
kibo [options] spindown ... stops all remote instances
|
50
|
+
kibo [options] reconfigure ... reconfigure all existing targets
|
51
|
+
|
52
|
+
where [options] are:
|
53
|
+
|
54
|
+
EOS
|
55
|
+
|
56
|
+
opt :environment, "Set environment", :short => 'e', :type => String, :default => "staging"
|
57
|
+
opt :kibofile, "Set Kibofile name", :short => 'k', :type => String, :default => "Kibofile"
|
58
|
+
opt :procfile, "Set Procfile name", :short => 'p', :type => String, :default => "Procfile"
|
59
|
+
opt :dry, "Do nothing", :short => 'n'
|
60
|
+
|
61
|
+
stop_on SUBCOMMANDS
|
62
|
+
end
|
63
|
+
|
64
|
+
@subcommand = ARGV.shift # get the subcommand
|
65
|
+
|
66
|
+
unless SUBCOMMANDS.include?(@subcommand)
|
67
|
+
Trollop::die(@subcommand ? "Unknown subcommand #{@subcommand.inspect}" : "Missing subcommand")
|
68
|
+
end
|
69
|
+
|
70
|
+
# Is there a specific subcommand options configuration?
|
71
|
+
|
72
|
+
subcommand_options =
|
73
|
+
case @subcommand
|
74
|
+
when "spinup"
|
75
|
+
Trollop::options do
|
76
|
+
opt :force, "Ignore missing targets.", :short => "f"
|
77
|
+
end
|
78
|
+
when "deploy"
|
79
|
+
Trollop::options do
|
80
|
+
opt :force, "Ignore outstanding changes.", :short => "f"
|
81
|
+
end
|
82
|
+
when "create"
|
83
|
+
Trollop::options do
|
84
|
+
opt :all, "Create all missing targets.", :short => "a"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
@options.update subcommand_options if subcommand_options
|
89
|
+
|
90
|
+
@args = ARGV.dup
|
91
|
+
end
|
92
|
+
end
|
data/lib/kibo/config.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
class Kibo::Configfile < Hash
|
4
|
+
attr :path
|
5
|
+
|
6
|
+
def initialize(path)
|
7
|
+
@path = path
|
8
|
+
|
9
|
+
File.read(path).
|
10
|
+
split("\n").
|
11
|
+
each_with_index do |line, lineno|
|
12
|
+
next if line =~ /^\s*#/
|
13
|
+
die(lineno, "Can't parse line: #{line.inspect}") unless line =~ /\s*([a-z]+):\s*(.*)$/
|
14
|
+
key, value = $1, $2.gsub(/\s+$/, "")
|
15
|
+
|
16
|
+
die(lineno, "Multiple entries for #{key.inspect}") if key?(key)
|
17
|
+
|
18
|
+
update key => value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def die(lineno, msg)
|
23
|
+
E "#{path}:#{lineno}", msg
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Kibo::Config
|
28
|
+
attr :procfile
|
29
|
+
|
30
|
+
DEFAULTS = {
|
31
|
+
"procfile" => "Procfile"
|
32
|
+
}
|
33
|
+
|
34
|
+
def [](key)
|
35
|
+
@data[key]
|
36
|
+
end
|
37
|
+
|
38
|
+
def environment
|
39
|
+
Kibo.environment
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(path)
|
43
|
+
super()
|
44
|
+
|
45
|
+
@data = Hash.new do |hash, key|
|
46
|
+
W "#{key}: missing setting for #{environment.inspect} environment, using default."
|
47
|
+
hash[key] = DEFAULTS[key]
|
48
|
+
end
|
49
|
+
|
50
|
+
begin
|
51
|
+
kibo = YAML.load File.read(path)
|
52
|
+
@data.update(kibo["defaults"] || {})
|
53
|
+
@data.update(kibo[environment] || {})
|
54
|
+
rescue Errno::ENOENT
|
55
|
+
W "No such file", path
|
56
|
+
@data = DEFAULTS
|
57
|
+
end
|
58
|
+
|
59
|
+
@procfile = Kibo::Configfile.new(self["procfile"] || "Procfile")
|
60
|
+
end
|
61
|
+
|
62
|
+
# processes are defined in the Procfile. The scaling, however, is defined in
|
63
|
+
# the Kibofile.
|
64
|
+
def processes
|
65
|
+
@processes ||= procfile.keys.inject({}) do |hash, key|
|
66
|
+
hash.update key => (self[key] || 1)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# we need namespace-ENVIRONMENT-process<1>
|
72
|
+
|
73
|
+
def namespace
|
74
|
+
self["namespace"] || raise("Please define a namespace in your Kibofile.")
|
75
|
+
end
|
76
|
+
|
77
|
+
def heroku
|
78
|
+
self["heroku"] || raise("Please defined the heroku entry in your Kibofile")
|
79
|
+
end
|
80
|
+
|
81
|
+
def remotes_by_process
|
82
|
+
remotes = Kibo.git("remote", :quiet).split("\n")
|
83
|
+
|
84
|
+
@remotes_by_process ||= remotes.group_by do |remote|
|
85
|
+
case remote
|
86
|
+
when /^#{namespace}-#{environment}-(\w+)(\d+)/
|
87
|
+
$1
|
88
|
+
when /^#{namespace}-#{environment}-/
|
89
|
+
W "#{remote.inspect}: Ignoring target..."
|
90
|
+
nil
|
91
|
+
else
|
92
|
+
end
|
93
|
+
end.tap { |hash| hash.delete(nil) }
|
94
|
+
end
|
95
|
+
end
|
data/lib/kibo/log.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
def log_message(msg, *args)
|
2
|
+
return msg if args.empty?
|
3
|
+
"#{msg}: " + args.map(&:inspect).join(", ")
|
4
|
+
end
|
5
|
+
|
6
|
+
def D(*args)
|
7
|
+
STDERR.puts log_message(*args)
|
8
|
+
end
|
9
|
+
|
10
|
+
def W(*args)
|
11
|
+
STDERR.puts log_message(*args)
|
12
|
+
end
|
13
|
+
|
14
|
+
def E(*args)
|
15
|
+
STDERR.puts log_message(*args)
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
|
data/lib/kibo/system.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Kibo::System
|
2
|
+
extend self
|
3
|
+
|
4
|
+
def heroku(*args)
|
5
|
+
sys! "heroku", *args
|
6
|
+
end
|
7
|
+
|
8
|
+
def git(*args)
|
9
|
+
sys! "git", *args
|
10
|
+
end
|
11
|
+
|
12
|
+
def sys(*args)
|
13
|
+
quiet = args.pop if args.last == :quiet
|
14
|
+
cmd = args.map(&:to_s).join(" ")
|
15
|
+
W cmd unless quiet
|
16
|
+
|
17
|
+
# A command is run because it either is "quiet", i.e. is non-obstrusive anyway,
|
18
|
+
# or we are not in a dry. Dry run mode could go with some improvements, though.
|
19
|
+
if quiet || !Kibo::CommandLine.dry?
|
20
|
+
stdout = Kernel.send "`", "bash -c \"#{cmd}\""
|
21
|
+
stdout.chomp if $?.exitstatus == 0
|
22
|
+
else
|
23
|
+
""
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def sys!(*args)
|
28
|
+
sys(*args) || E("Command failed: " + args.join(" "))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module Kibo
|
33
|
+
extend System
|
34
|
+
end
|
35
|
+
|
data/lib/kibo/version.rb
ADDED
data/lib/kibo.rb
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
require "pp"
|
2
|
+
require "heroku"
|
3
|
+
|
4
|
+
module Kibo
|
5
|
+
end
|
6
|
+
|
7
|
+
require_relative "kibo/log"
|
8
|
+
require_relative "kibo/system"
|
9
|
+
require_relative "kibo/config"
|
10
|
+
require_relative "kibo/commandline"
|
11
|
+
|
12
|
+
module Kibo
|
13
|
+
extend self
|
14
|
+
|
15
|
+
def config
|
16
|
+
@config ||= Config.new(CommandLine.kibofile)
|
17
|
+
end
|
18
|
+
|
19
|
+
def environment
|
20
|
+
Kibo::CommandLine.environment
|
21
|
+
end
|
22
|
+
|
23
|
+
def expected_remotes
|
24
|
+
config.processes.inject([]) do |ary, (name, count)|
|
25
|
+
ary.concat 1.upto(count).map { |idx| "#{config.namespace}-#{environment}-#{name}#{idx}" }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def configured_remotes
|
30
|
+
config.remotes_by_process.values.flatten
|
31
|
+
end
|
32
|
+
|
33
|
+
def missing_remotes
|
34
|
+
expected_remotes - configured_remotes
|
35
|
+
end
|
36
|
+
|
37
|
+
# -- configure a remote
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def instance_for_remote(remote)
|
42
|
+
remote[config.namespace.length + 1 .. -1]
|
43
|
+
end
|
44
|
+
|
45
|
+
public
|
46
|
+
|
47
|
+
def configure_remote!(remote)
|
48
|
+
heroku "config:set",
|
49
|
+
"RACK_ENV=#{environment}",
|
50
|
+
"RAILS_ENV=#{environment}",
|
51
|
+
"INSTANCE=#{instance_for_remote(remote)}",
|
52
|
+
"--app", remote
|
53
|
+
end
|
54
|
+
|
55
|
+
def configure_remote(remote)
|
56
|
+
# the correct value for the INSTANCE configuration setting is the
|
57
|
+
# name of the of the remote without the namespace part; e.g. the
|
58
|
+
# INSTANCE for the remote named "bountyhill-staging-twirl2" is
|
59
|
+
# "staging-twirl2".
|
60
|
+
instance = remote[config.namespace.length + 1 .. -1]
|
61
|
+
current_instance = heroku "config:get", "INSTANCE", "--app", remote
|
62
|
+
return if instance == current_instance
|
63
|
+
end
|
64
|
+
|
65
|
+
# --spin up/spin down remotes
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def spin(processes)
|
70
|
+
config.remotes_by_process.each do |name, remotes|
|
71
|
+
number_of_processes = processes[name] || 0
|
72
|
+
|
73
|
+
remotes.each do |remote|
|
74
|
+
if number_of_processes > 0
|
75
|
+
configure_remote remote
|
76
|
+
heroku "ps:scale", "#{name}=1", "--app", remote
|
77
|
+
number_of_processes -= 1
|
78
|
+
else
|
79
|
+
heroku "ps:scale", "#{name}=0", "--app", remote
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
if number_of_processes > 0
|
84
|
+
W "Missing #{name} remote(s)", number_of_processes
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
public
|
90
|
+
|
91
|
+
def spinup
|
92
|
+
check_missing_remotes(CommandLine.force? ? :warn : :error)
|
93
|
+
spin config.processes
|
94
|
+
end
|
95
|
+
|
96
|
+
def spindown
|
97
|
+
spin({})
|
98
|
+
end
|
99
|
+
|
100
|
+
# reconfigure existing remotes
|
101
|
+
public
|
102
|
+
|
103
|
+
# kibo [options] reconfigure ... reconfigure all existing remotes
|
104
|
+
def reconfigure
|
105
|
+
check_missing_remotes :warn
|
106
|
+
|
107
|
+
configured_remotes.each do |remote|
|
108
|
+
configure_remote! remote
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
def prepare_deployment
|
115
|
+
end
|
116
|
+
|
117
|
+
def deploy_remote!(remote)
|
118
|
+
git "push", remote, "master"
|
119
|
+
end
|
120
|
+
|
121
|
+
public
|
122
|
+
|
123
|
+
def deploy
|
124
|
+
check_missing_remotes(CommandLine.force? ? :warn : :error)
|
125
|
+
|
126
|
+
prepare_deployment
|
127
|
+
configured_remotes.each do |remote|
|
128
|
+
deploy_remote! remote
|
129
|
+
end
|
130
|
+
|
131
|
+
W "Deployment succeeded."
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def check_missing_remotes(mode = :warn)
|
137
|
+
return if missing_remotes.empty?
|
138
|
+
|
139
|
+
if mode == :warn
|
140
|
+
W "Ignoring missing remote(s)", *missing_remotes
|
141
|
+
return
|
142
|
+
end
|
143
|
+
|
144
|
+
E <<-MSG
|
145
|
+
Missing remote(s): #{missing_remotes.map(&:inspect).join(", ")}. Run
|
146
|
+
|
147
|
+
kibo --environment #{environment} create --all # ... to create all missing remotes.
|
148
|
+
kibo --environment #{environment} spinup --force # ... to ignore missing remotes.
|
149
|
+
|
150
|
+
MSG
|
151
|
+
end
|
152
|
+
|
153
|
+
public
|
154
|
+
|
155
|
+
def create
|
156
|
+
verify_heroku_login
|
157
|
+
|
158
|
+
if CommandLine.all?
|
159
|
+
instances = missing_remotes
|
160
|
+
if instances.empty?
|
161
|
+
W "Nothing to do."
|
162
|
+
exit 0
|
163
|
+
end
|
164
|
+
else
|
165
|
+
instances = CommandLine.args
|
166
|
+
if instances.empty?
|
167
|
+
W "Add the names of the remotes to create on the command line or use the --all parameter."
|
168
|
+
exit 0
|
169
|
+
end
|
170
|
+
|
171
|
+
# only create instances that are actually missing.
|
172
|
+
extra_instances = instances - missing_remotes
|
173
|
+
unless extra_instances.empty?
|
174
|
+
E <<-MSG
|
175
|
+
kibo cannot create these instances for you: #{extra_instances.map(&:inspect).join(", ")}, because I don't not know anything about these.
|
176
|
+
MSG
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
confirm! <<-MSG
|
181
|
+
I am going to create these instances: #{instances.map(&:inspect).join(", ")}. Is this what you want? Note:
|
182
|
+
You are logged in at heroku as #{config.heroku}.
|
183
|
+
MSG
|
184
|
+
|
185
|
+
instances.each do |instance|
|
186
|
+
create_instance(instance)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def confirm!(msg)
|
191
|
+
puts msg
|
192
|
+
puts "\n\nPress ^C to abort or return to continue."
|
193
|
+
|
194
|
+
STDIN.read
|
195
|
+
end
|
196
|
+
|
197
|
+
private
|
198
|
+
|
199
|
+
def verify_heroku_login
|
200
|
+
(Heroku::Auth.read_credentials || []).first.tap do |whoami|
|
201
|
+
msg = if !whoami
|
202
|
+
"Please log into heroku as #{config.heroku.inspect}."
|
203
|
+
elsif whoami != config.heroku
|
204
|
+
"You are currently logged into heroku as #{whoami.inspect}; please log in as #{config.heroku.inspect}."
|
205
|
+
end
|
206
|
+
|
207
|
+
E "#{msg}\n\n\theroku auth:login" if msg
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def create_instance(remote)
|
212
|
+
# TODO: Test whether these instances already exist, using `heroku apps`
|
213
|
+
heroku "apps:create", remote, "--remote", remote
|
214
|
+
end
|
215
|
+
|
216
|
+
public
|
217
|
+
|
218
|
+
def run
|
219
|
+
self.send CommandLine.subcommand
|
220
|
+
end
|
221
|
+
end
|
data/man/kibo.1
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
.\" generated with Ronn/v0.7.3
|
2
|
+
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
3
|
+
.
|
4
|
+
.TH "KIBO" "1" "August 2012" "Kibo 0.1.2" "Kibo Manual"
|
5
|
+
.
|
6
|
+
.SH "NAME"
|
7
|
+
\fBkibo\fR \- manage heroku applications
|
8
|
+
.
|
9
|
+
.SH "SYNOPSIS"
|
10
|
+
\fBkibo [options] create\fR
|
11
|
+
.
|
12
|
+
.br
|
13
|
+
\fBkibo [options] deploy\fR
|
14
|
+
.
|
15
|
+
.br
|
16
|
+
\fBkibo [options] spinup\fR
|
17
|
+
.
|
18
|
+
.br
|
19
|
+
\fBkibo [options] spindown\fR
|
20
|
+
.
|
21
|
+
.br
|
22
|
+
\fBkibo [options] reconfigure\fR
|
23
|
+
.
|
24
|
+
.SH "DESCRIPTION"
|
25
|
+
kibo is an awesome program that does something very, very important\.
|
26
|
+
.
|
27
|
+
.SH "DESCRIPTION"
|
28
|
+
Foreman is a manager for Procfile\-based applications\. Its aim is to abstract away the details of the Procfile format, and allow you to either run your application directly or export it to some other process management format\.
|
29
|
+
.
|
30
|
+
.SH "GLOBAL OPTIONS"
|
31
|
+
The following options control how kibo is run:
|
32
|
+
.
|
33
|
+
.TP
|
34
|
+
\fB\-e\fR, \fB\-\-environment\fR
|
35
|
+
Set the target environment\.
|
36
|
+
.
|
37
|
+
.TP
|
38
|
+
\fB\-k\fR, \fB\-\-kibofile\fR
|
39
|
+
Specify the Kibofile to use\.
|
40
|
+
.
|
41
|
+
.TP
|
42
|
+
\fB\-p\fR, \fB\-\-procfile\fR
|
43
|
+
Specify an alternate Procfile to load\.
|
44
|
+
.
|
45
|
+
.SH "Kibofile"
|
46
|
+
An example Kibofile is this:
|
47
|
+
.
|
48
|
+
.IP "" 4
|
49
|
+
.
|
50
|
+
.nf
|
51
|
+
|
52
|
+
defaults:
|
53
|
+
procfile: Procfile
|
54
|
+
namespace: radiospiel
|
55
|
+
staging:
|
56
|
+
twirl: 1
|
57
|
+
production:
|
58
|
+
twirl: 2
|
59
|
+
.
|
60
|
+
.fi
|
61
|
+
.
|
62
|
+
.IP "" 0
|
63
|
+
.
|
64
|
+
.SH "COPYRIGHT"
|
65
|
+
Kibo is Copyright (C) 2012 Enrico Thierbach \fIhttp://radiospiel\.org\fR
|
data/man/kibo.1.html
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv='content-type' value='text/html;charset=utf8'>
|
5
|
+
<meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
|
6
|
+
<title>kibo(1) - manage heroku applications</title>
|
7
|
+
<style type='text/css' media='all'>
|
8
|
+
/* style: man */
|
9
|
+
body#manpage {margin:0}
|
10
|
+
.mp {max-width:100ex;padding:0 9ex 1ex 4ex}
|
11
|
+
.mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
|
12
|
+
.mp h2 {margin:10px 0 0 0}
|
13
|
+
.mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
|
14
|
+
.mp h3 {margin:0 0 0 4ex}
|
15
|
+
.mp dt {margin:0;clear:left}
|
16
|
+
.mp dt.flush {float:left;width:8ex}
|
17
|
+
.mp dd {margin:0 0 0 9ex}
|
18
|
+
.mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
|
19
|
+
.mp pre {margin-bottom:20px}
|
20
|
+
.mp pre+h2,.mp pre+h3 {margin-top:22px}
|
21
|
+
.mp h2+pre,.mp h3+pre {margin-top:5px}
|
22
|
+
.mp img {display:block;margin:auto}
|
23
|
+
.mp h1.man-title {display:none}
|
24
|
+
.mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
|
25
|
+
.mp h2 {font-size:16px;line-height:1.25}
|
26
|
+
.mp h1 {font-size:20px;line-height:2}
|
27
|
+
.mp {text-align:justify;background:#fff}
|
28
|
+
.mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
|
29
|
+
.mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
|
30
|
+
.mp u {text-decoration:underline}
|
31
|
+
.mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
|
32
|
+
.mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
|
33
|
+
.mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
|
34
|
+
.mp b.man-ref {font-weight:normal;color:#434241}
|
35
|
+
.mp pre {padding:0 4ex}
|
36
|
+
.mp pre code {font-weight:normal;color:#434241}
|
37
|
+
.mp h2+pre,h3+pre {padding-left:0}
|
38
|
+
ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
|
39
|
+
ol.man-decor {width:100%}
|
40
|
+
ol.man-decor li.tl {text-align:left}
|
41
|
+
ol.man-decor li.tc {text-align:center;letter-spacing:4px}
|
42
|
+
ol.man-decor li.tr {text-align:right;float:right}
|
43
|
+
</style>
|
44
|
+
<style type='text/css' media='all'>
|
45
|
+
/* style: toc */
|
46
|
+
.man-navigation {display:block !important;position:fixed;top:0;left:113ex;height:100%;width:100%;padding:48px 0 0 0;border-left:1px solid #dbdbdb;background:#eee}
|
47
|
+
.man-navigation a,.man-navigation a:hover,.man-navigation a:link,.man-navigation a:visited {display:block;margin:0;padding:5px 2px 5px 30px;color:#999;text-decoration:none}
|
48
|
+
.man-navigation a:hover {color:#111;text-decoration:underline}
|
49
|
+
</style>
|
50
|
+
</head>
|
51
|
+
<!--
|
52
|
+
The following styles are deprecated and will be removed at some point:
|
53
|
+
div#man, div#man ol.man, div#man ol.head, div#man ol.man.
|
54
|
+
|
55
|
+
The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
|
56
|
+
.man-navigation should be used instead.
|
57
|
+
-->
|
58
|
+
<body id='manpage'>
|
59
|
+
<div class='mp' id='man'>
|
60
|
+
|
61
|
+
<div class='man-navigation' style='display:none'>
|
62
|
+
<a href="#NAME">NAME</a>
|
63
|
+
<a href="#SYNOPSIS">SYNOPSIS</a>
|
64
|
+
<a href="#DESCRIPTION">DESCRIPTION</a>
|
65
|
+
<a href="#DESCRIPTION">DESCRIPTION</a>
|
66
|
+
<a href="#GLOBAL-OPTIONS">GLOBAL OPTIONS</a>
|
67
|
+
<a href="#Kibofile">Kibofile</a>
|
68
|
+
<a href="#COPYRIGHT">COPYRIGHT</a>
|
69
|
+
</div>
|
70
|
+
|
71
|
+
<ol class='man-decor man-head man head'>
|
72
|
+
<li class='tl'>kibo(1)</li>
|
73
|
+
<li class='tc'>Kibo Manual</li>
|
74
|
+
<li class='tr'>kibo(1)</li>
|
75
|
+
</ol>
|
76
|
+
|
77
|
+
<h2 id="NAME">NAME</h2>
|
78
|
+
<p class="man-name">
|
79
|
+
<code>kibo</code> - <span class="man-whatis">manage heroku applications</span>
|
80
|
+
</p>
|
81
|
+
|
82
|
+
<h2 id="SYNOPSIS">SYNOPSIS</h2>
|
83
|
+
|
84
|
+
<p><code>kibo [options] create</code><br />
|
85
|
+
<code>kibo [options] deploy</code><br />
|
86
|
+
<code>kibo [options] spinup</code><br />
|
87
|
+
<code>kibo [options] spindown</code><br />
|
88
|
+
<code>kibo [options] reconfigure</code></p>
|
89
|
+
|
90
|
+
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
91
|
+
|
92
|
+
<p>kibo is an awesome program that does something very, very important.</p>
|
93
|
+
|
94
|
+
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
95
|
+
|
96
|
+
<p>Foreman is a manager for Procfile-based applications. Its aim is to
|
97
|
+
abstract away the details of the Procfile format, and allow you to either run
|
98
|
+
your application directly or export it to some other process management
|
99
|
+
format.</p>
|
100
|
+
|
101
|
+
<h2 id="GLOBAL-OPTIONS">GLOBAL OPTIONS</h2>
|
102
|
+
|
103
|
+
<p>The following options control how kibo is run:</p>
|
104
|
+
|
105
|
+
<dl>
|
106
|
+
<dt><code>-e</code>, <code>--environment</code></dt><dd><p>Set the target environment.</p></dd>
|
107
|
+
<dt><code>-k</code>, <code>--kibofile</code></dt><dd><p>Specify the Kibofile to use.</p></dd>
|
108
|
+
<dt><code>-p</code>, <code>--procfile</code></dt><dd><p>Specify an alternate Procfile to load.</p></dd>
|
109
|
+
</dl>
|
110
|
+
|
111
|
+
|
112
|
+
<h2 id="Kibofile">Kibofile</h2>
|
113
|
+
|
114
|
+
<p>An example Kibofile is this:</p>
|
115
|
+
|
116
|
+
<pre><code>defaults:
|
117
|
+
procfile: Procfile
|
118
|
+
namespace: radiospiel
|
119
|
+
staging:
|
120
|
+
twirl: 1
|
121
|
+
production:
|
122
|
+
twirl: 2
|
123
|
+
</code></pre>
|
124
|
+
|
125
|
+
<h2 id="COPYRIGHT">COPYRIGHT</h2>
|
126
|
+
|
127
|
+
<p>Kibo is Copyright (C) 2012 Enrico Thierbach <a href="http://radiospiel.org" data-bare-link="true">http://radiospiel.org</a></p>
|
128
|
+
|
129
|
+
|
130
|
+
<ol class='man-decor man-foot man foot'>
|
131
|
+
<li class='tl'>Kibo 0.1.2</li>
|
132
|
+
<li class='tc'>August 2012</li>
|
133
|
+
<li class='tr'>kibo(1)</li>
|
134
|
+
</ol>
|
135
|
+
|
136
|
+
</div>
|
137
|
+
</body>
|
138
|
+
</html>
|
data/man/kibo.1.markdown
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
kibo(1) -- manage heroku applications
|
2
|
+
================================================
|
3
|
+
|
4
|
+
## SYNOPSIS
|
5
|
+
|
6
|
+
`kibo [options] create`<br>
|
7
|
+
`kibo [options] deploy`<br>
|
8
|
+
`kibo [options] spinup`<br>
|
9
|
+
`kibo [options] spindown`<br>
|
10
|
+
`kibo [options] reconfigure`
|
11
|
+
|
12
|
+
## DESCRIPTION
|
13
|
+
|
14
|
+
kibo is an awesome program that does something very, very important.
|
15
|
+
|
16
|
+
## DESCRIPTION
|
17
|
+
|
18
|
+
Foreman is a manager for Procfile-based applications. Its aim is to
|
19
|
+
abstract away the details of the Procfile format, and allow you to either run
|
20
|
+
your application directly or export it to some other process management
|
21
|
+
format.
|
22
|
+
|
23
|
+
## GLOBAL OPTIONS
|
24
|
+
|
25
|
+
|
26
|
+
The following options control how kibo is run:
|
27
|
+
|
28
|
+
* `-e`, `--environment`:
|
29
|
+
Set the target environment.
|
30
|
+
|
31
|
+
* `-k`, `--kibofile`:
|
32
|
+
Specify the Kibofile to use.
|
33
|
+
|
34
|
+
* `-p`, `--procfile`:
|
35
|
+
Specify an alternate Procfile to load.
|
36
|
+
|
37
|
+
|
38
|
+
## Kibofile
|
39
|
+
|
40
|
+
An example Kibofile is this:
|
41
|
+
|
42
|
+
defaults:
|
43
|
+
procfile: Procfile
|
44
|
+
namespace: radiospiel
|
45
|
+
staging:
|
46
|
+
twirl: 1
|
47
|
+
production:
|
48
|
+
twirl: 2
|
49
|
+
|
50
|
+
## COPYRIGHT
|
51
|
+
|
52
|
+
Kibo is Copyright (C) 2012 Enrico Thierbach <http://radiospiel.org>
|
53
|
+
|
54
|
+
|
55
|
+
[SYNOPSIS]: #SYNOPSIS "SYNOPSIS"
|
56
|
+
[DESCRIPTION]: #DESCRIPTION "DESCRIPTION"
|
57
|
+
[DESCRIPTION]: #DESCRIPTION "DESCRIPTION"
|
58
|
+
[GLOBAL OPTIONS]: #GLOBAL-OPTIONS "GLOBAL OPTIONS"
|
59
|
+
[Kibofile]: #Kibofile "Kibofile"
|
60
|
+
[COPYRIGHT]: #COPYRIGHT "COPYRIGHT"
|
61
|
+
|
62
|
+
|
63
|
+
[kibo(1)]: kibo.1.html
|
data/man/kibo.1.ronn
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
kibo(1) -- manage heroku applications
|
2
|
+
================================================
|
3
|
+
|
4
|
+
## SYNOPSIS
|
5
|
+
|
6
|
+
`kibo [options] create`<br>
|
7
|
+
`kibo [options] deploy`<br>
|
8
|
+
`kibo [options] spinup`<br>
|
9
|
+
`kibo [options] spindown`<br>
|
10
|
+
`kibo [options] reconfigure`
|
11
|
+
|
12
|
+
## DESCRIPTION
|
13
|
+
|
14
|
+
kibo is an awesome program that does something very, very important.
|
15
|
+
|
16
|
+
## DESCRIPTION
|
17
|
+
|
18
|
+
Foreman is a manager for Procfile-based applications. Its aim is to
|
19
|
+
abstract away the details of the Procfile format, and allow you to either run
|
20
|
+
your application directly or export it to some other process management
|
21
|
+
format.
|
22
|
+
|
23
|
+
## GLOBAL OPTIONS
|
24
|
+
|
25
|
+
|
26
|
+
The following options control how kibo is run:
|
27
|
+
|
28
|
+
* `-e`, `--environment`:
|
29
|
+
Set the target environment.
|
30
|
+
|
31
|
+
* `-k`, `--kibofile`:
|
32
|
+
Specify the Kibofile to use.
|
33
|
+
|
34
|
+
* `-p`, `--procfile`:
|
35
|
+
Specify an alternate Procfile to load.
|
36
|
+
|
37
|
+
|
38
|
+
## Kibofile
|
39
|
+
|
40
|
+
An example Kibofile is this:
|
41
|
+
|
42
|
+
defaults:
|
43
|
+
procfile: Procfile
|
44
|
+
namespace: radiospiel
|
45
|
+
staging:
|
46
|
+
twirl: 1
|
47
|
+
production:
|
48
|
+
twirl: 2
|
49
|
+
|
50
|
+
## COPYRIGHT
|
51
|
+
|
52
|
+
Kibo is Copyright (C) 2012 Enrico Thierbach <http://radiospiel.org>
|
data/tasks/doc.rake
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "time"
|
2
|
+
|
3
|
+
namespace :doc do
|
4
|
+
desc "Build the manual"
|
5
|
+
task :build do
|
6
|
+
ENV['RONN_MANUAL'] = "Kibo Manual"
|
7
|
+
ENV['RONN_ORGANIZATION'] = "Kibo #{Kibo::VERSION}"
|
8
|
+
sh "ronn -w -s toc -r5 --markdown man/*.ronn"
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Commit the manual to git"
|
12
|
+
task :commit => :build do
|
13
|
+
sh "git add README.md"
|
14
|
+
sh "git commit -am 'update docs' || echo 'nothing to commit'"
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Generate the Github docs"
|
18
|
+
task :gh_pages => :commit do
|
19
|
+
sh %{
|
20
|
+
cp man/foreman.1.html /tmp/foreman.1.html
|
21
|
+
git checkout gh-pages
|
22
|
+
rm ./index.html
|
23
|
+
cp /tmp/foreman.1.html ./index.html
|
24
|
+
git add -u index.html
|
25
|
+
git commit -m "saving man page to github docs"
|
26
|
+
git push origin -f gh-pages
|
27
|
+
git checkout master
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kibo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- radiospiel
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: heroku
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: trollop
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: heroku
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: Manage heroku instances with ease
|
79
|
+
email:
|
80
|
+
- eno@radiospiel.org
|
81
|
+
executables:
|
82
|
+
- kibo
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- .gitignore
|
87
|
+
- Gemfile
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- bin/kibo
|
91
|
+
- kibo.gemspec
|
92
|
+
- lib/kibo.rb
|
93
|
+
- lib/kibo/commandline.rb
|
94
|
+
- lib/kibo/config.rb
|
95
|
+
- lib/kibo/log.rb
|
96
|
+
- lib/kibo/system.rb
|
97
|
+
- lib/kibo/version.rb
|
98
|
+
- man/kibo.1
|
99
|
+
- man/kibo.1.html
|
100
|
+
- man/kibo.1.markdown
|
101
|
+
- man/kibo.1.ronn
|
102
|
+
- tasks/doc.rake
|
103
|
+
homepage: http://github.com/radiospiel/kibo
|
104
|
+
licenses: []
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
require_paths:
|
108
|
+
- lib
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
segments:
|
116
|
+
- 0
|
117
|
+
hash: -1679562379441555646
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ! '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 1.8.24
|
127
|
+
signing_key:
|
128
|
+
specification_version: 3
|
129
|
+
summary: Manage heroku instances with ease
|
130
|
+
test_files: []
|