strobe 0.1.0.beta.2 → 0.1.0.beta.3

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.
@@ -1,6 +1,14 @@
1
1
  module Strobe
2
2
  class CLI::Main < CLI
3
3
 
4
+ def help(*args)
5
+ if args.first == "users"
6
+ CLI::Users.start( [ "help" ] + args[1..-1] )
7
+ else
8
+ super
9
+ end
10
+ end
11
+
4
12
  action "users", 'manage users' do |*args|
5
13
  argv = $ARGV[1..-1]
6
14
  argv = [ 'list' ] + argv if args.empty?
@@ -55,7 +63,9 @@ module Strobe
55
63
  end
56
64
 
57
65
  application_path_option
58
- method_option :staging, :type => :boolean, :banner => "deploy to a staging environment"
66
+ method_option "staging", :type => :boolean, :banner => "deploy to a staging environment"
67
+ method_option "sc-build", :type => :boolean, :banner => "run `sc-build -c` before deploying"
68
+ method_option "no-sc-build", :type => :boolean, :banner => "skip the `sc-build -c` step"
59
69
  action "deploy", "deploy your application to Strobe" do
60
70
  ensure_computer_is_registered
61
71
 
@@ -77,17 +87,56 @@ module Strobe
77
87
  end
78
88
  end
79
89
 
80
- host = resource.deploy! :environment => options[:staging] && 'staging'
90
+ run_sc_build
91
+
92
+ if STDOUT.tty?
93
+ thread = nil
94
+ read, write = IO.pipe
95
+
96
+ upload_callback = lambda do |percentage|
97
+ if percentage
98
+ width = 50
99
+ left = ( percentage * width ).round
100
+ right = ( ( 1.0 - percentage ) * width ).round
101
+
102
+ if left < width
103
+ right -= 1
104
+ arrow = ">"
105
+ end
106
+
107
+ print "Uploading [#{'=' * left}#{arrow}#{' ' * right}]\r"
108
+ else
109
+ puts
110
+ thread = Thread.new do
111
+ print "Reticulating splines..."
112
+
113
+ while true
114
+ break if IO.select( [read ], nil, nil, 0.5 )
115
+ print "."
116
+ end
117
+
118
+ puts
119
+ end
120
+ end
121
+ end
122
+ else
123
+ upload_callback = nil
124
+ end
125
+
126
+ host = resource.deploy! :environment => options[:staging] && 'staging',
127
+ :upload_callback => upload_callback
128
+
129
+ if STDOUT.tty?
130
+ write << '1'
131
+ thread.join
132
+ end
133
+
81
134
  say "The application has successfully been deployed and is available at #{host}"
82
135
  end
83
136
 
84
137
  action "applications", "list all of your applications" do
85
138
  empty = "You do not have any applications. Try deploying one with `strobe deploy`."
86
- table Resources::Application.all, :empty => empty do |t|
87
- t.column :id
88
- t.column :name
89
- t.column :url
90
- end
139
+ list_applications :empty => empty
91
140
  end
92
141
 
93
142
  method_option "url", :type => :string
@@ -119,7 +168,7 @@ module Strobe
119
168
  end
120
169
 
121
170
  application_path_option
122
- method_option "id", :type => :numeric, :banner => "The ID of the remote application"
171
+ method_option "application-id", :type => :numeric, :banner => "The ID of the remote application"
123
172
  action "register", "registers a local application with an existing Strobe application" do
124
173
  if config[:application_id] && app = Application.get(config[:application_id])
125
174
  say "The directory is already registered with the application `#{app[:name]}`"
@@ -129,21 +178,81 @@ module Strobe
129
178
  config.delete
130
179
  end
131
180
 
132
- application = Application.get! options[:id]
181
+ application = options['application-id'] ? Application.get!(options['application-id']) : pick_application
182
+
133
183
  config[:application_id] = application[:id]
184
+
134
185
  say "You can now deploy to #{application[:name]} (http://#{application[:url]})"
135
186
  end
136
187
 
137
188
  private
138
189
 
190
+ def run_sc_build
191
+ return unless is_sproutcore? # Bail if this isn't a SC application
192
+
193
+ # Using both options at the same time makes no sense
194
+ if options["sc-build"] && options["no-sc-build"]
195
+ error! "--sc-build and --no-sc-build cannot be used at the same time"
196
+ end
197
+
198
+ # If the user explicitly says that they don't want to run sc-build,
199
+ # then just skip it
200
+ return if options["no-sc-build"]
201
+
202
+ # If the user doesn't ask either way, confirm first
203
+ unless options["sc-build"]
204
+ say "This appears to be a SproutCore application."
205
+ return unless agree "Run `sc-build -c`? [Yn] "
206
+ end
207
+
208
+ unless system "sc-build", "-c"
209
+ error! "Something went wrong while running `sc-build -c`"
210
+ end
211
+ end
212
+
213
+ def is_sproutcore?
214
+ File.exist?("#{path}/tmp/build")
215
+ end
216
+
139
217
  def determine_application_root
140
- if File.exist?("#{path}/tmp/build")
218
+ if is_sproutcore?
141
219
  return "#{path}/tmp/build"
142
220
  end
143
221
 
144
222
  path
145
223
  end
146
224
 
225
+ def list_applications(*args)
226
+ options = Hash === args.last ? args.pop : {}
227
+ applications = args.first || Resources::Application.all
228
+
229
+ table applications, options do |t|
230
+ t.column :id
231
+ t.column :name
232
+ t.column :url
233
+ end
234
+ end
235
+
236
+ def pick_application
237
+ applications = Resources::Application.all
238
+
239
+ if applications.empty?
240
+ error! "You currently do not have any applications. Create some with `strobe deploy`"
241
+ end
242
+
243
+ list_applications applications, :index => true
244
+
245
+ while true
246
+ index = ask "Pick an application: ", :direct => true
247
+
248
+ if index.to_i > 0 and application = applications[index.to_i - 1]
249
+ return application
250
+ end
251
+
252
+ say "Invalid entry. Please enter one of the numbers in brackets"
253
+ end
254
+ end
255
+
147
256
  def ensure_computer_is_registered
148
257
  unless settings[:token]
149
258
  say "This computer is not yet registered with a Strobe account."
@@ -1,10 +1,16 @@
1
1
  module Strobe
2
2
  class CLI::Table
3
+ class Index ; end
4
+
3
5
  def initialize(collection, opts = {})
4
6
  @collection = collection
5
7
  @columns = []
6
8
  @computed = []
7
9
  @opts = opts
10
+
11
+ if opts[:index]
12
+ @columns.unshift({ :key => Index, :max => 0 })
13
+ end
8
14
  end
9
15
 
10
16
  def column(key)
@@ -14,7 +20,8 @@ module Strobe
14
20
  def to_s
15
21
  @collection.each do |obj|
16
22
  @computed << @columns.map do |col|
17
- cell = obj[ col[:key] ].to_s
23
+ cell = obj [ col[:key] ] unless col[:key] == Index
24
+ cell = cell.to_s
18
25
  col[:max] = [ cell.length, col[:max] ].max
19
26
  cell
20
27
  end
@@ -27,14 +34,15 @@ module Strobe
27
34
  str = ""
28
35
 
29
36
  @columns.each do |col|
30
- str << cell_to_s(col, col[:key].to_s.upcase)
37
+ cell = col[:key].to_s.upcase unless col[:key] == Index
38
+ str << cell_to_s(col, cell)
31
39
  end
32
40
 
33
41
  str << "\n"
34
42
 
35
- @computed.each do |cells|
36
- cells.each_with_index do |cell, i|
37
- str << cell_to_s(@columns[i], cell)
43
+ @computed.each_with_index do |cells, i|
44
+ cells.each_with_index do |cell, j|
45
+ str << cell_to_s(@columns[j], cell, i)
38
46
  end
39
47
  str << "\n"
40
48
  end
@@ -43,9 +51,13 @@ module Strobe
43
51
 
44
52
  private
45
53
 
46
- def cell_to_s(col, cell)
54
+ def cell_to_s(col, cell, index = nil)
55
+ if index && col[:key] == Index
56
+ cell = "[#{index + 1}]"
57
+ end
58
+
47
59
  width = [ col[:max], 25 ].max + 5
48
- cell.ljust(width)
60
+ cell.to_s.ljust(width)
49
61
  end
50
62
  end
51
63
  end
data/lib/strobe/cli.rb CHANGED
@@ -27,7 +27,8 @@ module Strobe
27
27
  def self.action(name, *args, &blk)
28
28
  @haxliases ||= []
29
29
  @haxliases << name.to_s
30
- desc name, *args
30
+ usage = self == Users ? "users #{name}" : name
31
+ desc usage, *args
31
32
  define_method("__hax__#{name}", &blk)
32
33
  map name => "__hax__#{name}"
33
34
  end
@@ -119,6 +120,10 @@ module Strobe
119
120
  STDERR.puts "[ERROR] #{what}"
120
121
  end
121
122
 
123
+ def error!(what)
124
+ abort what
125
+ end
126
+
122
127
  def agree(msg, *args)
123
128
  @highline.agree(msg, *args) do |q|
124
129
  next unless STDIN.tty? # For testing
@@ -160,6 +165,8 @@ module Strobe
160
165
  end
161
166
 
162
167
  def input(key, options)
168
+ return yield key if options[:direct]
169
+
163
170
  into = options[:into] || key
164
171
 
165
172
  validation_group into do
@@ -27,6 +27,10 @@ module Strobe
27
27
  to_a.each { |r| yield r }
28
28
  end
29
29
 
30
+ def empty?
31
+ to_a.empty?
32
+ end
33
+
30
34
  def all
31
35
  self
32
36
  end
@@ -108,20 +108,18 @@ module Strobe
108
108
 
109
109
  if headers['content-type'] == 'application/json'
110
110
  body = ActiveSupport::JSON.encode(body)
111
- else
112
- body = body.to_s
113
111
  end
114
112
  end
115
113
 
114
+ http = build_http
115
+ request = Net::HTTPGenericRequest.new(
116
+ method.to_s.upcase, !!body, true, path, headers)
117
+
116
118
  if body.respond_to?(:read)
117
119
  request.body_stream = body
118
120
  body = nil
119
121
  end
120
122
 
121
- http = build_http
122
- request = Net::HTTPGenericRequest.new(
123
- method.to_s.upcase, !!body, true, path, headers)
124
-
125
123
  Response.new(http.request(request, body))
126
124
  end
127
125
 
@@ -1,3 +1,4 @@
1
+ require 'zlib'
1
2
  require 'digest/sha1'
2
3
  require 'mime/types'
3
4
 
@@ -22,8 +23,8 @@ module Strobe
22
23
 
23
24
  request do
24
25
  qs = "?environment=#{environment}" if environment
25
- packfile = build_packfile
26
- connection.put("#{http_uri}/deploy#{qs}", packfile.to_s, packfile.headers)
26
+ packfile = build_packfile(opts)
27
+ connection.put("#{http_uri}/deploy#{qs}", packfile, packfile.headers)
27
28
  end
28
29
 
29
30
  [ environment, self['url'] ].compact.join('.')
@@ -46,9 +47,9 @@ module Strobe
46
47
  end
47
48
  end
48
49
 
49
- def build_packfile
50
+ def build_packfile(opts)
50
51
  Dir.chdir self[:path] do
51
- PackFile.build do |m|
52
+ PackFile.build(opts) do |m|
52
53
  Dir["**/*"].each do |filename|
53
54
  next unless File.file?(filename)
54
55
 
@@ -91,13 +92,14 @@ module Strobe
91
92
  end
92
93
 
93
94
  class PackFile
94
- def self.build
95
- inst = new
95
+ def self.build(opts)
96
+ inst = new(opts)
96
97
  yield inst
97
98
  inst
98
99
  end
99
100
 
100
- def initialize
101
+ def initialize(opts)
102
+ @opts = opts
101
103
  @files = []
102
104
  end
103
105
 
@@ -106,20 +108,66 @@ module Strobe
106
108
  end
107
109
 
108
110
  def headers
109
- { 'Content-Type' => 'application/x-strobe-deploy' }
111
+ { 'Content-Type' => 'application/x-strobe-deploy',
112
+ 'Content-Length' => size.to_s,
113
+ 'Content-Encoding' => 'deflate' }
110
114
  end
111
115
 
112
- def to_s
113
- head = ""
114
- body = ""
116
+ def each(*args, &blk)
117
+ to_io.each(*args, &blk)
118
+ end
119
+
120
+ def read(*args)
121
+ ret = to_io.read(*args)
115
122
 
116
- @files.each do |path, type, data|
117
- size = data.respond_to?(:bytesize) ? data.bytesize : data.size
118
- head << "#{Digest::SHA1.hexdigest(data)} #{size} #{path} #{type}\n"
119
- body << data
123
+ if callback = @opts[:upload_callback]
124
+ ret ? callback.call(pos.to_f / size.to_f) : callback.call(nil)
120
125
  end
121
126
 
122
- "#{head}\n#{body}"
127
+ ret
128
+ end
129
+
130
+ def rewind
131
+ to_io.rewind
132
+ end
133
+
134
+ def seek(*args)
135
+ to_io.seek(*args)
136
+ end
137
+
138
+ def pos
139
+ to_io.pos
140
+ end
141
+
142
+ def size
143
+ to_io.size
144
+ end
145
+
146
+ def eof
147
+ to_io.eof
148
+ end
149
+
150
+ alias eof? eof
151
+
152
+ def to_io
153
+ @to_io ||= StringIO.new(to_s)
154
+ end
155
+
156
+ private
157
+
158
+ def to_s
159
+ @to_s ||= begin
160
+ head = ""
161
+ body = ""
162
+
163
+ @files.each do |path, type, data|
164
+ size = data.respond_to?(:bytesize) ? data.bytesize : data.size
165
+ head << "#{Digest::SHA1.hexdigest(data)} #{size} #{path} #{type}\n"
166
+ body << data
167
+ end
168
+
169
+ Zlib::Deflate.deflate("#{head}\n#{body}", 9)
170
+ end
123
171
  end
124
172
  end
125
173
  end
metadata CHANGED
@@ -7,8 +7,8 @@ version: !ruby/object:Gem::Version
7
7
  - 1
8
8
  - 0
9
9
  - beta
10
- - 2
11
- version: 0.1.0.beta.2
10
+ - 3
11
+ version: 0.1.0.beta.3
12
12
  platform: ruby
13
13
  authors:
14
14
  - Yehuda Katz
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2011-01-02 00:00:00 -08:00
20
+ date: 2011-01-03 00:00:00 -08:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency