slotbox 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ Slotbox CLI
2
+ ===========
3
+
4
+ Command line tool for interacting with Slotbox.
5
+
6
+ # Installation
7
+ `gem install slotbox`
8
+
9
+ # Usage
10
+
11
+ It has exactly the same usage as the [Heroku CLi client](https://devcenter.heroku.com/categories/command-line), except for one extra command and a few unsupported commands.
12
+
13
+ ## Extra commands
14
+
15
+ `slotbox deploy`
16
+
17
+ Slotbox enforces the use of public Github repos to ensure that funders can always scrutinise the code in which they are investing. Therefore deployment
18
+ is done by the Slotbox API rather a `git push`.
19
+
20
+ ## Unsupported commands
21
+
22
+ `addons, certs, db, drains, keys, labs, pg, pgbackups, ssl, stack`
23
+
24
+ # Caveats
25
+
26
+ The Slotbox gem piggybacks off the Heroku gem using Heroku's plugin architecture. As such it overrides IO#puts in order
27
+ to replace all occurrences of 'heroku' with 'slotbox'! But until the Slotbox client is a bonafide fork of the Heroku client
28
+ this will have to do.
data/bin/slotbox ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'slotbox'
4
+
5
+ # Cross-platform way of finding an executable in the $PATH.
6
+ #
7
+ # which('ruby') #=> /usr/bin/ruby
8
+ def which(cmd)
9
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
10
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
11
+ exts.each { |ext|
12
+ exe = "#{path}/#{cmd}#{ext}"
13
+ return exe if File.executable? exe
14
+ }
15
+ end
16
+ return nil
17
+ end
18
+
19
+ # Install the Heroku Toolbelt
20
+ if ! which "heroku"
21
+ puts "The Heroku Toolbelt isn't installed on your system."
22
+ if RUBY_PLATFORM =~ /linux/
23
+ puts "Would you like to install it now? (y/n)"
24
+ begin
25
+ system("stty raw -echo")
26
+ answer = STDIN.getc
27
+ ensure
28
+ system("stty -raw echo")
29
+ end
30
+ if ['y', 'yes'].include? answer
31
+ system "wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh"
32
+ end
33
+ else
34
+ puts "Please visit https://toolbelt.heroku.com/ to install"
35
+ end
36
+ exit 1
37
+ end
38
+
39
+ # Make sure the Heroku-Slotbox plugin is installed
40
+ if !File.exists? Slotbox::PLUGIN_DIR + "/init.rb"
41
+ puts "Installing Slotbox-Heroku plugin..."
42
+ require 'rubygems'
43
+ spec = Gem::Specification.find_by_name("slotbox")
44
+ system "mkdir -p #{Slotbox::PLUGIN_DIR}"
45
+ system "cp -rf #{spec.gem_dir}/plugin/* #{Slotbox::PLUGIN_DIR}"
46
+ puts "Slotbox-Heroku plugin installed. It will automatically be removed when you uninstall this gem."
47
+ end
48
+
49
+ if ARGV.length > 0
50
+ if Slotbox::UNSUPPORTED_COMMANDS.select{ |c| ARGV.first.start_with? c }.length > 0
51
+ $stderr.puts " ! Slotbox does not currently support this command."
52
+ exit 1
53
+ end
54
+ end
55
+
56
+ slotbox_host = ENV["SLOTBOX_HOST"] || "slotbox.es"
57
+
58
+ system <<-EOF
59
+
60
+ export HEROKU_HOST=${HEROKU_HOST:-http://#{slotbox_host}:5000/}
61
+ export HEROKU_STATUS_HOST=${HEROKU_STATUS_HOST:-"#{slotbox_host}"}
62
+ export HEROKU_SSL_VERIFY=${HEROKU_SSL_VERIFY:-"disable"}
63
+
64
+ exec heroku #{ARGV.join(" ")}
65
+
66
+ EOF
@@ -0,0 +1,12 @@
1
+ require "rubygems"
2
+ require 'slotbox'
3
+
4
+ # I can't believe this runs *every* time *any* (yes, any) gem is unisntalled
5
+ # And that it isn't documented!
6
+ Gem.post_uninstall do |uninstaller|
7
+ if uninstaller.spec.name == 'slotbox'
8
+ puts "Uninstalling Slotbox-Heroku plugin..."
9
+ system "rm -rf #{Slotbox::PLUGIN_DIR}"
10
+ puts "Slotbox-Heroku plugin uninstalled."
11
+ end
12
+ end
data/lib/slotbox.rb ADDED
@@ -0,0 +1,4 @@
1
+ module Slotbox
2
+ UNSUPPORTED_COMMANDS = %w[addons certs db drains keys labs pg pgbackups ssl stack update version]
3
+ PLUGIN_DIR = "~/.heroku/plugins/slotbox"
4
+ end
data/plugin/init.rb ADDED
@@ -0,0 +1,9 @@
1
+ if ENV['HEROKU_HOST'] =~ /slotbox/
2
+
3
+ require 'slotbox'
4
+
5
+ Dir[ File.dirname(__FILE__) + '/lib/slotbox/**/*.rb'].each do |file|
6
+ require file
7
+ end
8
+
9
+ end
@@ -0,0 +1,15 @@
1
+ module Heroku
2
+ class API
3
+
4
+ # PUT /apps/:app/deploy
5
+ def put_app_deploy(app, github_url)
6
+ request(
7
+ :expects => 200,
8
+ :method => :put,
9
+ :path => "/apps/#{app}/deploy",
10
+ :query => app_params({"github_url" => github_url})
11
+ )
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,62 @@
1
+ # Here we disbale the ability to manually name apps
2
+ # And remove other functionality not present in Slotbox
3
+
4
+ class Heroku::Command::Apps
5
+
6
+ # apps:create
7
+ #
8
+ # create a new app
9
+ #
10
+ # --addons ADDONS # a comma-delimited list of addons to install
11
+ # -b, --buildpack BUILDPACK # a buildpack url to use for this app
12
+ # -r, --remote REMOTE # the git remote to create, first github.com is default
13
+ #
14
+ #Examples:
15
+ #
16
+ # $ heroku apps:create
17
+ # Creating slotbox-nodejs-hello-world... done, stack is cedar
18
+ # http://slotbox-nodejs-hello-world.slotbox.es/
19
+ #
20
+ def create
21
+ name = app
22
+ validate_arguments!
23
+
24
+ info = api.post_app({
25
+ "name" => name,
26
+ "region" => options[:region]
27
+ }).body
28
+ begin
29
+ action("Creating #{info['name']}") do
30
+ if info['create_status'] == 'creating'
31
+ Timeout::timeout(options[:timeout].to_i) do
32
+ loop do
33
+ break if api.get_app(info['name']).body['create_status'] == 'complete'
34
+ sleep 1
35
+ end
36
+ end
37
+ end
38
+ status("stack is #{info['stack']}")
39
+ end
40
+
41
+ (options[:addons] || "").split(",").each do |addon|
42
+ addon.strip!
43
+ action("Adding #{addon} to #{info["name"]}") do
44
+ api.post_addon(info["name"], addon)
45
+ end
46
+ end
47
+
48
+ if buildpack = options[:buildpack]
49
+ api.put_config_vars(info["name"], "BUILDPACK_URL" => buildpack)
50
+ display("BUILDPACK_URL=#{buildpack}")
51
+ end
52
+
53
+ hputs(info["web_url"])
54
+ rescue Timeout::Error
55
+ hputs("Timed Out! Run `heroku status` to check for known platform issues.")
56
+ end
57
+
58
+ end
59
+
60
+ alias_command "create", "apps:create"
61
+
62
+ end
@@ -0,0 +1,79 @@
1
+ # Here we formalise the naming of Slotbox apps.
2
+ #
3
+ # Names consist of the Github user and the repo name, so;
4
+ # git@github.com:slotbox/nodejs-hello-world.git becomes
5
+ # => slotbox-nodejs-hello-world
6
+ # Errors are thrown if there is not a github.com remote on the local repo.
7
+
8
+ require "addressable/uri"
9
+
10
+ class Heroku::Command::Base
11
+
12
+ def app
13
+ @app ||= if options[:confirm].is_a?(String)
14
+ if options[:app] && (options[:app] != options[:confirm])
15
+ error("Mismatch between --app and --confirm")
16
+ end
17
+ options[:confirm]
18
+ elsif options[:app].is_a?(String)
19
+ options[:app]
20
+ elsif ENV.has_key?('SLOTBOX_APP')
21
+ ENV['SLOTBOX_APP']
22
+ elsif app_from_dir = extract_app_in_dir(Dir.pwd)
23
+ app_from_dir
24
+ else
25
+ # raise instead of using error command to enable rescuing when app is optional
26
+ raise Heroku::Command::CommandFailed.new("No app specified.\nRun this command from an app folder or specify which app to use with --app APP.")
27
+ end
28
+ end
29
+
30
+ protected
31
+ def extract_app_in_dir(dir)
32
+ return unless remotes = git_remotes(dir)
33
+
34
+ if remote = options[:remote]
35
+ extract_app_name_from_remote remotes[remote]
36
+ elsif remote = extract_app_from_git_config
37
+ extract_app_name_from_remote remotes[remote]
38
+ else
39
+ apps = remotes.values.uniq
40
+ if apps.size == 1
41
+ extract_app_name_from_remote apps.first
42
+ else
43
+ raise(Heroku::Command::CommandFailed, "Multiple apps in folder and no app specified.\nSpecify app with --app APP.")
44
+ end
45
+ end
46
+ end
47
+
48
+ def extract_app_from_git_config
49
+ remote = git("config slotbox.remote")
50
+ remote == "" ? nil : remote
51
+ end
52
+
53
+ def extract_app_name_from_remote remote
54
+ path = Addressable::URI.parse(remote).path.gsub(/\.git$/, '').split('/')
55
+ "#{path[-2]}-#{path[-1]}"
56
+ end
57
+
58
+ def git_remotes(base_dir=Dir.pwd)
59
+ remotes = {}
60
+ original_dir = Dir.pwd
61
+ Dir.chdir(base_dir)
62
+
63
+ return unless File.exists?(".git")
64
+ git("remote -v").split("\n").each do |remote|
65
+ name, url = remote.split(/\s/)
66
+ if url =~ /github\.com/
67
+ remotes[name] = url
68
+ end
69
+ end
70
+
71
+ Dir.chdir(original_dir)
72
+ if remotes.empty?
73
+ raise(Heroku::Command::CommandFailed, "You must have a git remote hosted on github.com")
74
+ else
75
+ remotes
76
+ end
77
+ end
78
+
79
+ end
@@ -0,0 +1,58 @@
1
+ require "addressable/uri"
2
+
3
+ module Heroku::Command
4
+
5
+ # deploy the app from its Github repo
6
+ class Deploy < BaseWithApp
7
+
8
+ def index
9
+ # Pick the first
10
+ remote = git "config --get remote.origin.url"
11
+ if remote.nil? || !remote.include?("github.com")
12
+ raise(CommandFailed, "A Github repo must be in a remote called 'origin'")
13
+ end
14
+ # Ensure that we have a non-SSH version of the repo, so we don't have to
15
+ # 'ensure the authenticity of the host' when pulling.
16
+ # Note that only Addressable::URI seems to be able to handle ssh-style URIs
17
+ path = Addressable::URI.parse(remote).path.split('/')
18
+ remote = "https://github.com/#{path[-2]}/#{path[-1]}"
19
+
20
+ app = git "config --get slotbox.app"
21
+ if app.nil?
22
+ raise(CommandFailed, "Cannot find Slotbox app name from git config")
23
+ end
24
+
25
+ process_data = action("Starting deploy", :success => "connected") do
26
+ process_data = api.put_app_deploy(app, remote).body
27
+ status(process_data["process"])
28
+ process_data
29
+ end
30
+ rendezvous_session(process_data["rendezvous_url"])
31
+ end
32
+
33
+ protected
34
+ def rendezvous_session(rendezvous_url, &on_connect)
35
+ begin
36
+ set_buffer(false)
37
+ rendezvous = Heroku::Client::Rendezvous.new(
38
+ :rendezvous_url => rendezvous_url,
39
+ :connect_timeout => (ENV["HEROKU_CONNECT_TIMEOUT"] || 120).to_i,
40
+ :activity_timeout => nil,
41
+ :input => nil,
42
+ :output => $stdout)
43
+ rendezvous.on_connect(&on_connect)
44
+ rendezvous.start
45
+ rescue Timeout::Error
46
+ error "\nTimeout awaiting process"
47
+ rescue OpenSSL::SSL::SSLError
48
+ error "Authentication error"
49
+ rescue Errno::ECONNREFUSED, Errno::ECONNRESET
50
+ error "\nError connecting to process"
51
+ rescue Interrupt
52
+ ensure
53
+ set_buffer(true)
54
+ end
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,12 @@
1
+ class Heroku::Command::Help
2
+
3
+ def skip_namespace?(ns)
4
+ return true if ns[:description] =~ /DEPRECATED:/
5
+ return true if ns[:description] =~ /HIDDEN:/
6
+ return true if Slotbox::UNSUPPORTED_COMMANDS.include? ns[:name]
7
+ false
8
+ end
9
+
10
+ end
11
+
12
+
@@ -0,0 +1,8 @@
1
+ # Oh god this is profound hack.
2
+ # It would be slightly more acceptable to just override Heroku's display(), error(), ets functions.
3
+ # But until the Heroku client is forked to Slotbox this will have to do :(
4
+ class IO
5
+ def puts(output="")
6
+ super(output.gsub("heroku", "slotbox").gsub("Heroku", "Slotbox"))
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: slotbox
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tom BUckley-Houston
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-12 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Command-line tool to deploy and manage apps on Slotbox.
15
+ email: tom@tombh.co.uk
16
+ executables:
17
+ - slotbox
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - README.md
22
+ - bin/slotbox
23
+ - lib/rubygems_plugin.rb
24
+ - lib/slotbox.rb
25
+ - plugin/init.rb
26
+ - plugin/lib/slotbox/api/deploying.rb
27
+ - plugin/lib/slotbox/command/apps.rb
28
+ - plugin/lib/slotbox/command/base.rb
29
+ - plugin/lib/slotbox/command/deploy.rb
30
+ - plugin/lib/slotbox/command/help.rb
31
+ - plugin/lib/slotbox/ruby/puts.rb
32
+ homepage: http://slotbox.es
33
+ licenses:
34
+ - MIT
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubyforge_project:
53
+ rubygems_version: 1.8.24
54
+ signing_key:
55
+ specification_version: 3
56
+ summary: CLI to deploy and manage apps on Slotbox.
57
+ test_files: []