kibo 0.3.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  spec.old
2
2
  pkg
3
+ coverage
data/Gemfile CHANGED
@@ -4,6 +4,9 @@ gem "trollop"
4
4
  gem "thor"
5
5
  gem 'rake'
6
6
  gem 'netrc'
7
+ gem 'mash'
8
+ gem 'foreman'
9
+ gem 'heroku'
7
10
 
8
11
  group :development do
9
12
  gem 'ronn'
@@ -12,5 +15,9 @@ group :development do
12
15
  gem 'rspec', '~> 2.0'
13
16
  gem "simplecov", :require => false
14
17
  gem 'timecop'
18
+ gem 'ruby-debug19'
19
+ gem 'test-unit'
20
+ gem 'mocha'
21
+ gem 'awesome_print'
15
22
  # gem 'yard'
16
23
  end
data/Gemfile.lock CHANGED
@@ -1,14 +1,40 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
+ addressable (2.3.2)
5
+ archive-tar-minitar (0.5.2)
6
+ awesome_print (1.1.0)
7
+ columnize (0.3.6)
4
8
  diff-lcs (1.1.3)
9
+ excon (0.16.4)
5
10
  fakefs (0.3.2)
11
+ foreman (0.60.0)
12
+ thor (>= 0.13.6)
13
+ heroku (2.32.6)
14
+ heroku-api (~> 0.3.5)
15
+ launchy (>= 0.3.2)
16
+ netrc (~> 0.7.7)
17
+ rest-client (~> 1.6.1)
18
+ rubyzip
19
+ heroku-api (0.3.5)
20
+ excon (~> 0.16.1)
6
21
  hpricot (0.8.6)
22
+ launchy (2.1.2)
23
+ addressable (~> 2.3)
24
+ linecache19 (0.5.12)
25
+ ruby_core_source (>= 0.1.4)
26
+ mash (0.1.1)
27
+ metaclass (0.0.1)
28
+ mime-types (1.19)
29
+ mocha (0.12.4)
30
+ metaclass (~> 0.0.1)
7
31
  multi_json (1.3.6)
8
32
  mustache (0.99.4)
9
33
  netrc (0.7.7)
10
34
  rake (0.9.2.2)
11
35
  rdiscount (1.6.8)
36
+ rest-client (1.6.7)
37
+ mime-types (>= 1.16)
12
38
  ronn (0.7.3)
13
39
  hpricot (>= 0.8.2)
14
40
  mustache (>= 0.7.0)
@@ -22,10 +48,22 @@ GEM
22
48
  rspec-expectations (2.11.3)
23
49
  diff-lcs (~> 1.1.3)
24
50
  rspec-mocks (2.11.2)
51
+ ruby-debug-base19 (0.11.25)
52
+ columnize (>= 0.3.1)
53
+ linecache19 (>= 0.5.11)
54
+ ruby_core_source (>= 0.1.4)
55
+ ruby-debug19 (0.11.6)
56
+ columnize (>= 0.3.1)
57
+ linecache19 (>= 0.5.11)
58
+ ruby-debug-base19 (>= 0.11.19)
59
+ ruby_core_source (0.1.5)
60
+ archive-tar-minitar (>= 0.5.2)
61
+ rubyzip (0.9.9)
25
62
  simplecov (0.6.4)
26
63
  multi_json (~> 1.0)
27
64
  simplecov-html (~> 0.5.3)
28
65
  simplecov-html (0.5.3)
66
+ test-unit (2.5.2)
29
67
  thor (0.16.0)
30
68
  timecop (0.5.0)
31
69
  trollop (2.0)
@@ -34,13 +72,20 @@ PLATFORMS
34
72
  ruby
35
73
 
36
74
  DEPENDENCIES
75
+ awesome_print
37
76
  fakefs (~> 0.3.2)
77
+ foreman
78
+ heroku
79
+ mash
80
+ mocha
38
81
  netrc
39
82
  rake
40
83
  ronn
41
84
  rr (~> 1.0.2)
42
85
  rspec (~> 2.0)
86
+ ruby-debug19
43
87
  simplecov
88
+ test-unit
44
89
  thor
45
90
  timecop
46
91
  trollop
data/YUILICENSE.md ADDED
@@ -0,0 +1,29 @@
1
+ The yuicompressor-2.4.7.jar file is copyright © 2012 Yahoo! Inc. and is licensed under the following terms:
2
+
3
+ # Software License Agreement (BSD License)
4
+
5
+ ## Copyright © 2012 Yahoo! Inc. All rights reserved.
6
+
7
+ Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8
+
9
+ Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10
+
11
+ Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
12
+
13
+ Neither the name of Yahoo! Inc. nor the names of YUI's contributors may be used to endorse or promote products derived from this software without specific prior written permission of Yahoo! Inc.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
+
17
+ ## Sources of Intellectual Property Included in the YUI Library
18
+
19
+ YUI is issued by Yahoo! under the BSD license above. Below is a list of certain publicly available software that is the source of intellectual property in YUI, along with the licensing terms that pertain to those sources of IP. This list is for informational purposes only and is not intended to represent an exhaustive list of third party contributions to YUI.
20
+
21
+ - Douglas Crockford's JSON parsing and stringifying methods: In the JSON Utility, Douglas Crockford's JSON parsing and stringifying methods are adapted from work published at JSON.org. The adapted work is in the public domain.
22
+
23
+ - Robert Penner's animation-easing algorithms: In the Animation Utility, YUI makes use of Robert Penner's algorithms for easing.
24
+
25
+ - Geoff Stearns's SWFObject: In the Charts Control and the Uploader versions through 2.7.0, YUI makes use of Geoff Stearns's SWFObject v1.5 for Flash Player detection and embedding. More information on SWFObject can be found at http://blog.deconcept.com/swfobject/. SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License (http://www.opensource.org/licenses/mit-license.php).
26
+
27
+ - Diego Perini's IEContentLoaded technique: The Event Utility employs a technique developed by Diego Perini and licensed under GPL. YUI's use of this technique is included under our BSD license with the author's permission.
28
+
29
+ - Yehuda Katz's Handlebars.js: YUI includes a wrapped version of Handlebars in our distribution. Handlebars.js is licensed under the MIT license which is in compliance with YUI's BSD license.
@@ -39,8 +39,7 @@ where [options] are:
39
39
  EOS
40
40
 
41
41
  opt :environment, "Set environment", :short => 'e', :type => String, :default => "staging"
42
- opt :kibofile, "Set Kibofile name", :short => 'k', :type => String, :default => "Kibofile"
43
- opt :procfile, "Set Procfile name", :short => 'p', :type => String, :default => "Procfile"
42
+ opt :config, "Set Kibofile name", :short => 'c', :type => String, :default => "Kibofile"
44
43
 
45
44
  stop_on Kibo::Commands.commands
46
45
  end
@@ -1,21 +1,21 @@
1
+ #
2
+ #
1
3
  module Kibo::Commands
2
4
  subcommand :compress, "compress JS and CSS files" do
3
5
  opt :quiet, "Be less verbose.", :short => "q"
4
6
  end
5
7
 
6
8
  def compress
7
- dirs = Kibo.command_line.args
8
- dirs.each do |dir| compress_dir(dir) end
9
+ Kibo::CommandLine.args.each do |path|
10
+ compress_dir path
11
+ end
9
12
  end
10
13
 
11
14
  private
12
15
 
13
- def kibo_bin_path
14
- File.join(File.dirname(__FILE__), "..", "bin")
15
- end
16
-
17
16
  def yuicompressor(*args)
18
- yuicompressor = "#{kibo_bin_path}/yuicompressor-2.4.7.jar"
17
+ yuipath = File.join(File.dirname(__FILE__), "..", "bin")
18
+ yuicompressor = "#{yuipath}/yuicompressor-2.4.7.jar"
19
19
  Kibo::System.sys! "java", "-jar", yuicompressor, *args
20
20
  end
21
21
 
@@ -59,27 +59,32 @@ module Kibo::Commands
59
59
  log_file = lambda do |file|
60
60
  old_size, new_size = old_sizes[file], File.size(file)
61
61
 
62
- unless Kibo.command_line.quiet?
62
+ unless Kibo::CommandLine.quiet?
63
63
  info.line file, "#{old_size} -> #{new_size}"
64
64
  end
65
65
  old_sum += old_size
66
66
  new_sum += new_size
67
67
  end
68
68
 
69
- info.head "JS" unless Kibo.command_line.quiet?
69
+ info.head "JS" unless Kibo::CommandLine.quiet?
70
70
 
71
71
  js_files.sort.each do |file|
72
72
  log_file.call(file)
73
73
  end
74
74
 
75
- info.head "CSS" unless Kibo.command_line.quiet?
75
+ info.head "CSS" unless Kibo::CommandLine.quiet?
76
76
 
77
77
  css_files.sort.each do |file|
78
78
  log_file.call(file)
79
79
  end
80
80
 
81
- info.head "Summary" unless Kibo.command_line.quiet?
82
- info.line "#{files.length} files", "#{old_sum} -> #{new_sum} byte: #{(new_sum * 100.0 / old_sum).round(1)} %"
81
+ info.head "Summary" unless Kibo::CommandLine.quiet?
82
+
83
+ if old_sum > 0
84
+ info.line "#{files.length} files", "#{old_sum} -> #{new_sum} byte: #{(new_sum * 100.0 / old_sum).round(1)} %"
85
+ else
86
+ info.line "#{files.length} files", "#{old_sum} -> #{new_sum} byte"
87
+ end
83
88
  end
84
89
  end
85
90
  end
@@ -1,15 +1,7 @@
1
1
  module Kibo::Commands
2
- subcommand :deploy, "updates all remote instances" do
3
- opt :force, "Ignore outstanding changes.", :short => "f"
4
- end
2
+ subcommand :deploy, "updates all remote instances"
5
3
 
6
4
  def deploy
7
- if Kibo.command_line.force?
8
- h.check_missing_remotes(:warn)
9
- else
10
- h.check_missing_remotes(:error)
11
- end
12
-
13
5
  ENV["ENVIRONMENT"] = Kibo.environment
14
6
 
15
7
  #
@@ -20,9 +12,9 @@ module Kibo::Commands
20
12
  in_branch "kibo.#{Kibo.environment}" do
21
13
  git "merge", "master"
22
14
 
23
- with_commands :deployment do
24
- h.configured_remotes.each do |remote|
25
- deploy_remote! remote
15
+ with_commands :arena do
16
+ Kibo.config.instances.each do |instance|
17
+ git "push", "--force", instance, "HEAD:master"
26
18
  end
27
19
  end
28
20
  end
@@ -34,6 +26,10 @@ module Kibo::Commands
34
26
 
35
27
  private
36
28
 
29
+ # Run the commands under "<key>.pre",
30
+ # then yield the block,
31
+ # then run the commands under "<key>.success", if the block was successful,
32
+ # then run the commands under "<key>.final".
37
33
  def with_commands(sym, &block)
38
34
  commands_hash = Kibo.config.send(sym) || {}
39
35
 
@@ -42,7 +38,7 @@ module Kibo::Commands
42
38
 
43
39
  W "Running #{sym}.#{key} commands"
44
40
  [ *commands ].each do |command|
45
- Kibo::System.sh! command
41
+ Kibo::System.sys! command
46
42
  end
47
43
  }
48
44
 
@@ -52,7 +48,7 @@ module Kibo::Commands
52
48
 
53
49
  run.call("success")
54
50
  ensure
55
- run.call("final")
51
+ run.call("final") if run
56
52
  end
57
53
 
58
54
  #
@@ -60,6 +56,8 @@ module Kibo::Commands
60
56
  def in_branch(name, &block)
61
57
  previous_branch = current_branch
62
58
 
59
+ git "stash"
60
+
63
61
  if name != previous_branch
64
62
  git "branch", name unless branches.include?(name)
65
63
  git "checkout", name
@@ -74,6 +72,8 @@ module Kibo::Commands
74
72
  git "reset", "--hard"
75
73
  git "checkout", previous_branch
76
74
  end
75
+
76
+ git "stash", "pop"
77
77
  end
78
78
 
79
79
  def current_branch
@@ -84,8 +84,4 @@ module Kibo::Commands
84
84
  branches = `git branch`
85
85
  ("\n" + branches).split(/\n[\* ]+/).reject(&:empty?)
86
86
  end
87
-
88
- def deploy_remote!(remote)
89
- git "push", "--force", remote, "HEAD:master"
90
- end
91
87
  end
@@ -0,0 +1,15 @@
1
+ require "forwardable"
2
+ require_relative "../system"
3
+
4
+
5
+ module Kibo::Commands
6
+
7
+ private
8
+
9
+ extend Forwardable
10
+
11
+ delegate [:git, :heroku, :sys, :sh] => Kibo::System
12
+
13
+ # -- which remotes are defined, present and configured --------------
14
+
15
+ end
@@ -1,3 +1,5 @@
1
+ require_relative "../helpers/info"
2
+
1
3
  module Kibo::Commands
2
4
  subcommand :info, "show information about the current settings"
3
5
 
@@ -5,33 +7,34 @@ module Kibo::Commands
5
7
  Kibo::Helpers::Info.print do |info|
6
8
  info.head "general"
7
9
  info.line "environment", Kibo.environment
8
-
10
+ info.line "namespace", Kibo.namespace
11
+
9
12
  info.head "heroku"
10
- info.line "current account", h.whoami
11
- info.line "expected account", Kibo.config.account
13
+ info.line "current account", Kibo::Heroku.whoami
14
+ info.line "expected account", Kibo.config.heroku.account
12
15
 
13
16
  info.head "processes"
17
+ info.line "mode", Kibo.config.heroku.mode
14
18
  Kibo.config.processes.each do |key, value|
15
19
  info.line key, value
16
20
  end
17
21
 
18
- info.head "remotes"
19
- info.line "remotes", h.expected_remotes
20
- info.line "configured", h.configured_remotes
21
- info.line "missing", h.missing_remotes
22
+ # info.head "remotes"
23
+ #
24
+ # info.line "expected", Kibo.expected_remotes
25
+ # info.line "configured", Kibo.configured_remotes
26
+ # info.line "missing", Kibo.missing_remotes
27
+
28
+ info.head "instances"
29
+
30
+ info.line "expected", Kibo.config.instances
31
+ info.line "configured", configured_instances
22
32
  end
23
33
  end
24
34
 
25
- subcommand :logs, "Show log files for current instances"
26
- def logs
27
- h.configured_remotes.each do |remote|
28
- fork do
29
- cmd = "heroku logs --tail --app #{remote} | sed s/^/\\\\[#{remote}\\\\]\\ /"
30
- W cmd
31
- exec(cmd)
32
- end
33
- end
34
-
35
- Process.waitall
35
+ def configured_instances
36
+ sys("git remote").split("\n").select { |line|
37
+ line =~ /^#{Kibo.namespace}-/
38
+ }
36
39
  end
37
40
  end
@@ -0,0 +1,30 @@
1
+ module Kibo::Commands
2
+ subcommand :logs, "Show log files for current instances"
3
+ def logs
4
+ require "foreman/engine/cli"
5
+
6
+ cli = Foreman::Engine::CLI.new
7
+
8
+ Kibo.config.instances.map do |remote|
9
+ cli.register remote.split("-", 3).last, "#{Kibo.binary} log #{remote}"
10
+ end
11
+
12
+ cli.start
13
+ end
14
+
15
+ subcommand :log, "Show log file for a single instance"
16
+ def log
17
+ require "heroku"
18
+
19
+ instance = Kibo::CommandLine.args.first
20
+
21
+ $stdout.sync = true
22
+
23
+ heroku = Heroku::Auth.client
24
+ heroku.read_logs(instance, [ "tail=1" ]) do |chunk|
25
+ chunk.split("\n").each do |line|
26
+ $stdout.puts line.split(": ", 2)[1]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,67 @@
1
+ #
2
+ #
3
+
4
+ require_relative "../heroku"
5
+
6
+ module Kibo::Commands
7
+ subcommand :setup, "Setup and configure application instances" do
8
+ opt :force, "Reconfigure existing instances, too.", :short => "f"
9
+ end
10
+
11
+ def setup
12
+ verify_heroku_login
13
+
14
+ # create all apps on heroku or make sure that they
15
+ # exist as remotes in the local git configuration.
16
+ instances.each do |instance|
17
+ next unless create_instance(instance) || Kibo::CommandLine.force?
18
+
19
+ # The following only when forced (--force) to do so or when
20
+ # a new instance has been created.
21
+ collaborate_instance instance
22
+ provide_instance instance
23
+ configure_instance instance
24
+ end
25
+ end
26
+
27
+ def create_instance(instance)
28
+ return false if sys("git remote | grep #{instance}", :quiet)
29
+
30
+ heroku_url = "git@heroku.com:#{instance}.git"
31
+
32
+ if Kibo::Heroku.apps.include?(instance)
33
+ git :remote, :add, instance, heroku_url
34
+ else
35
+ heroku "apps:create", instance, "--remote", instance
36
+ end
37
+
38
+ true
39
+ end
40
+
41
+ def collaborate_instance(instance)
42
+ Kibo.config.collaborators.each do |email|
43
+ heroku "sharing:add", email, "--app", instance
44
+ end
45
+ end
46
+
47
+ def provide_instance(instance)
48
+ instance.addons.each do |addon|
49
+ heroku "addons:add", addon
50
+ end
51
+ end
52
+
53
+ def configure_instance(instance)
54
+ heroku "config:set", "INSTANCE=#{instance}"
55
+ end
56
+
57
+ def verify_heroku_login
58
+ whoami = Kibo::Heroku.whoami
59
+ return if whoami == Kibo.config.heroku.account
60
+
61
+ if !whoami
62
+ E "Please log in ('heroku auth:login') as #{Kibo.config.heroku.account}."
63
+ elsif whoami != Kibo.config.heroku.account
64
+ E "You are currently logged in as #{whoami}; please log in ('heroku auth:login') as #{Kibo.config.heroku.account}."
65
+ end
66
+ end
67
+ end
@@ -1,39 +1,22 @@
1
1
  # --spin up/spin down remotes
2
2
  module Kibo::Commands
3
- subcommand :spinup, "starts all remote instances" do
4
- opt :force, "Ignore missing targets.", :short => "f"
5
- end
6
-
3
+ subcommand :spinup, "starts all remote instances"
7
4
  subcommand :spindown, "stops all remote instances"
8
5
 
9
6
  def spinup
10
- h.check_missing_remotes(Kibo.command_line.force? ? :warn : :error)
11
- spin Kibo.config.processes
7
+ spin :up
12
8
  end
13
9
 
14
10
  def spindown
15
- spin({})
11
+ spin :down
16
12
  end
17
13
 
18
14
  private
19
15
 
20
- def spin(processes)
21
- Kibo.config.remotes_by_process.each do |name, remotes|
22
- number_of_processes = processes[name] || 0
23
-
24
- remotes.each do |remote|
25
- if number_of_processes > 0
26
- h.configure_remote remote
27
- heroku "ps:scale", "#{name}=1", "--app", remote
28
- number_of_processes -= 1
29
- else
30
- heroku "ps:scale", "#{name}=0", "--app", remote
31
- end
32
- end
33
-
34
- if number_of_processes > 0
35
- W "Missing #{name} remote(s)", number_of_processes
36
- end
16
+ def spin(mode)
17
+ Kibo.config.instances.each do |instance|
18
+ count = mode == :up ? instance.count : 0
19
+ heroku "ps:scale", "#{instance.role}=#{count}", "--app", instance
37
20
  end
38
21
  end
39
22
  end
data/lib/kibo/commands.rb CHANGED
@@ -1,6 +1,3 @@
1
- require_relative "helpers"
2
- require_relative "system"
3
-
4
1
  module Kibo::Commands
5
2
  extend self
6
3
 
@@ -20,24 +17,6 @@ module Kibo::Commands
20
17
  def self.commands
21
18
  public_instance_methods.map(&:to_s)
22
19
  end
23
-
24
- private
25
-
26
- def h
27
- Kibo::Helpers
28
- end
29
-
30
- def sys
31
- Kibo::System
32
- end
33
-
34
- def git(*args)
35
- sys.git *args
36
- end
37
-
38
- def heroku(*args)
39
- sys.heroku *args
40
- end
41
20
  end
42
21
 
43
22
  subfiles = Dir.glob( __FILE__.gsub(/\.rb$/, "/*.rb")).sort