lenary-ginatra 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitattributes +2 -0
- data/.gitignore +13 -0
- data/.gitmodules +3 -0
- data/README.md +127 -0
- data/Rakefile +86 -0
- data/TODO.md +10 -0
- data/VERSION +1 -0
- data/bin/ginatra +60 -0
- data/bin/ginatra-daemon +81 -0
- data/bin/ginatra-directory +60 -0
- data/bin/ginatra-server +28 -0
- data/config.ru +7 -0
- data/features/pages.feature +33 -0
- data/features/step_definitions/page_steps.rb +36 -0
- data/features/support/env.rb +12 -0
- data/ginatra.gemspec +120 -0
- data/lib/ginatra.rb +185 -0
- data/lib/ginatra/config.rb +55 -0
- data/lib/ginatra/helpers.rb +112 -0
- data/lib/ginatra/repo.rb +50 -0
- data/lib/ginatra/repo_list.rb +53 -0
- data/lib/sinatra/partials.rb +17 -0
- data/public/favicon.ico +0 -0
- data/rackup.ru +7 -0
- data/repos/README.md +8 -0
- data/spec/repo_list_spec.rb +22 -0
- data/spec/repo_spec.rb +58 -0
- data/spec/spec_helper.rb +30 -0
- data/vendor/vegas/History.txt +18 -0
- data/vendor/vegas/LICENSE +22 -0
- data/vendor/vegas/Manifest.txt +5 -0
- data/vendor/vegas/README.rdoc +45 -0
- data/vendor/vegas/Rakefile +32 -0
- data/vendor/vegas/lib/vegas.rb +16 -0
- data/vendor/vegas/lib/vegas/runner.rb +270 -0
- data/vendor/vegas/test/test_app/bin/test_app +9 -0
- data/vendor/vegas/test/test_app/test_app.rb +10 -0
- data/vendor/vegas/test/test_apps.rb +22 -0
- data/vendor/vegas/test/test_helper.rb +59 -0
- data/vendor/vegas/test/test_vegas_runner.rb +8 -0
- data/vendor/vegas/vegas.gemspec +45 -0
- data/views/_actor_box.erb +13 -0
- data/views/_commit_info_box.erb +27 -0
- data/views/_header.erb +6 -0
- data/views/_tree_part.erb +11 -0
- data/views/atom.builder +32 -0
- data/views/blob.erb +9 -0
- data/views/commit.erb +20 -0
- data/views/index.erb +12 -0
- data/views/layout.erb +35 -0
- data/views/log.erb +64 -0
- data/views/tree.erb +24 -0
- metadata +158 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
%w[rubygems rake rake/clean hoe fileutils newgem rubigen].each { |f| require f }
|
2
|
+
require File.dirname(__FILE__) + '/lib/vegas'
|
3
|
+
|
4
|
+
# Generate all the Rake tasks
|
5
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
6
|
+
$hoe = Hoe.spec('vegas') do |p|
|
7
|
+
p.version = Vegas::VERSION
|
8
|
+
p.developer('Aaron Quint', 'aaron@quirkey.com')
|
9
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
10
|
+
p.summary = "Vegas aims to solve the simple problem of creating executable versions of Sinatra/Rack apps."
|
11
|
+
p.description = %{Vegas aims to solve the simple problem of creating executable versions of Sinatra/Rack apps. It includes a class Vegas::Runner that wraps Rack/Sinatra applications and provides a simple command line interface and launching mechanism.}
|
12
|
+
p.rubyforge_name = 'quirkey'
|
13
|
+
p.extra_deps = [
|
14
|
+
['sinatra','>= 0.9.1']
|
15
|
+
]
|
16
|
+
p.extra_dev_deps = [
|
17
|
+
['newgem', ">= #{::Newgem::VERSION}"],
|
18
|
+
['nokogiri', ">= 1.0.6"],
|
19
|
+
['bacon', ">= 1.1.0"]
|
20
|
+
]
|
21
|
+
|
22
|
+
p.clean_globs |= %w[**/.DS_Store tmp *.log]
|
23
|
+
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
24
|
+
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
|
25
|
+
p.rsync_args = '-av --delete --ignore-errors'
|
26
|
+
end
|
27
|
+
|
28
|
+
require 'newgem/tasks' # load /tasks/*.rake
|
29
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
30
|
+
|
31
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
32
|
+
# task :default => [:spec, :features]
|
@@ -0,0 +1,16 @@
|
|
1
|
+
begin
|
2
|
+
require 'sinatra'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems'
|
5
|
+
require 'sinatra'
|
6
|
+
end
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
9
|
+
|
10
|
+
module Vegas
|
11
|
+
VERSION = "0.0.4.1"
|
12
|
+
WINDOWS = !!(RUBY_PLATFORM =~ /(mingw|bccwin|wince|mswin32)/i)
|
13
|
+
|
14
|
+
autoload :Runner, 'vegas/runner'
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,270 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'logger'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
if Vegas::WINDOWS
|
6
|
+
begin
|
7
|
+
require 'win32/process'
|
8
|
+
rescue
|
9
|
+
puts "Sorry, in order to use Vegas on Windows you need the win32-process gem:\n gem install win32-process"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Vegas
|
14
|
+
class Runner
|
15
|
+
attr_reader :app, :app_name, :rack_handler, :port, :host, :options
|
16
|
+
|
17
|
+
ROOT_DIR = File.expand_path(File.join('~', '.vegas'))
|
18
|
+
PORT = 5678
|
19
|
+
HOST = WINDOWS ? 'localhost' : '0.0.0.0'
|
20
|
+
|
21
|
+
def initialize(app, app_name, set_options = {}, &block)
|
22
|
+
# initialize
|
23
|
+
@app = app
|
24
|
+
@app_name = app_name
|
25
|
+
@options = set_options || {}
|
26
|
+
@rack_handler = @app.send :detect_rack_handler
|
27
|
+
# load options from opt parser
|
28
|
+
define_options do |opts|
|
29
|
+
if block_given?
|
30
|
+
opts.separator ''
|
31
|
+
opts.separator "#{app_name} options:"
|
32
|
+
yield(self, opts, app)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
# set app options
|
36
|
+
@host = options[:host] || HOST
|
37
|
+
@app.set options
|
38
|
+
# initialize app dir
|
39
|
+
FileUtils.mkdir_p(app_dir)
|
40
|
+
|
41
|
+
return if options[:start] === false
|
42
|
+
|
43
|
+
logger.info "Running with Windows Settings" if WINDOWS
|
44
|
+
logger.info "Starting #{app_name}"
|
45
|
+
|
46
|
+
check_for_running
|
47
|
+
find_port
|
48
|
+
write_url
|
49
|
+
start
|
50
|
+
end
|
51
|
+
|
52
|
+
def app_dir
|
53
|
+
File.join(ROOT_DIR, app_name)
|
54
|
+
end
|
55
|
+
|
56
|
+
def pid_file
|
57
|
+
File.join(app_dir, "#{app_name}.pid")
|
58
|
+
end
|
59
|
+
|
60
|
+
def url_file
|
61
|
+
File.join(app_dir, "#{app_name}.url")
|
62
|
+
end
|
63
|
+
|
64
|
+
def url
|
65
|
+
"http://#{host}:#{port}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def log_file
|
69
|
+
File.join(app_dir, "#{app_name}.log")
|
70
|
+
end
|
71
|
+
|
72
|
+
def handler_name
|
73
|
+
rack_handler.name.gsub(/.*::/, '')
|
74
|
+
end
|
75
|
+
|
76
|
+
def find_port
|
77
|
+
if @port = options[:port]
|
78
|
+
if !port_open?
|
79
|
+
logger.warn "Port #{port} is already in use. Please try another or don't use -P, for auto-port"
|
80
|
+
end
|
81
|
+
else
|
82
|
+
@port = PORT
|
83
|
+
logger.info "Trying to start #{app_name} on Port #{port}"
|
84
|
+
while !port_open?
|
85
|
+
@port += 1
|
86
|
+
logger.info "Trying to start #{app_name} on Port #{port}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def port_open?(check_url = nil)
|
92
|
+
begin
|
93
|
+
open(check_url || url)
|
94
|
+
false
|
95
|
+
rescue Errno::ECONNREFUSED => e
|
96
|
+
true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def write_url
|
101
|
+
File.open(url_file, 'w') {|f| f << url }
|
102
|
+
end
|
103
|
+
|
104
|
+
def check_for_running
|
105
|
+
if File.exists?(pid_file) && File.exists?(url_file)
|
106
|
+
running_url = File.read(url_file)
|
107
|
+
if !port_open?(running_url)
|
108
|
+
logger.warn "#{app_name} is already running at #{running_url}"
|
109
|
+
launch!(running_url)
|
110
|
+
exit!
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def run!
|
116
|
+
rack_handler.run app, :Host => host, :Port => port do |server|
|
117
|
+
trap(kill_command) do
|
118
|
+
## Use thins' hard #stop! if available, otherwise just #stop
|
119
|
+
server.respond_to?(:stop!) ? server.stop! : server.stop
|
120
|
+
logger.info "#{app_name} received INT ... stopping"
|
121
|
+
delete_pid!
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Adapted from Rackup
|
127
|
+
def daemonize!
|
128
|
+
if RUBY_VERSION < "1.9"
|
129
|
+
logger.debug "Parent Process: #{Process.pid}"
|
130
|
+
exit! if fork
|
131
|
+
logger.debug "Child Process: #{Process.pid}"
|
132
|
+
Dir.chdir "/"
|
133
|
+
File.umask 0000
|
134
|
+
FileUtils.touch(log_file)
|
135
|
+
STDIN.reopen log_file
|
136
|
+
STDOUT.reopen log_file, "a"
|
137
|
+
STDERR.reopen log_file, "a"
|
138
|
+
else
|
139
|
+
Process.daemon
|
140
|
+
end
|
141
|
+
logger.debug "Child Process: #{Process.pid}"
|
142
|
+
|
143
|
+
File.open(pid_file, 'w') {|f| f.write("#{Process.pid}") }
|
144
|
+
at_exit { delete_pid! }
|
145
|
+
end
|
146
|
+
|
147
|
+
def launch!(specific_url = nil)
|
148
|
+
return if options[:skip_launch]
|
149
|
+
cmd = WINDOWS ? "start" : "sleep 2 && open"
|
150
|
+
system "#{cmd} #{specific_url || url}"
|
151
|
+
end
|
152
|
+
|
153
|
+
def kill!
|
154
|
+
pid = File.read(pid_file)
|
155
|
+
logger.warn "Sending INT to #{pid.to_i}"
|
156
|
+
Process.kill(kill_command, pid.to_i)
|
157
|
+
rescue => e
|
158
|
+
logger.warn "pid not found at #{pid_file} : #{e}"
|
159
|
+
end
|
160
|
+
|
161
|
+
def start
|
162
|
+
begin
|
163
|
+
launch!
|
164
|
+
daemonize! unless options[:foreground]
|
165
|
+
run!
|
166
|
+
rescue RuntimeError => e
|
167
|
+
logger.warn "There was an error starting #{app_name}: #{e}"
|
168
|
+
exit
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def status
|
173
|
+
if File.exists?(pid_file)
|
174
|
+
logger.info "#{app_name} running"
|
175
|
+
logger.info "PID #{File.read(pid_file)}"
|
176
|
+
logger.info "URL #{File.read(url_file)}" if File.exists?(url_file)
|
177
|
+
else
|
178
|
+
logger.info "#{app_name} not running!"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def logger
|
183
|
+
return @logger if @logger
|
184
|
+
@logger = Logger.new(STDOUT)
|
185
|
+
@logger.level = options[:debug] ? Logger::DEBUG : Logger::INFO
|
186
|
+
@logger.formatter = Proc.new {|s, t, n, msg| "[#{t}] #{msg}\n"}
|
187
|
+
@logger
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
def define_options
|
192
|
+
OptionParser.new("", 24, ' ') { |opts|
|
193
|
+
opts.banner = "Usage: #{app_name} [options]"
|
194
|
+
|
195
|
+
opts.separator ""
|
196
|
+
opts.separator "Vegas options:"
|
197
|
+
|
198
|
+
opts.on("-s", "--server SERVER", "serve using SERVER (webrick/mongrel)") { |s|
|
199
|
+
@rack_handler = Rack::Handler.get(s)
|
200
|
+
}
|
201
|
+
|
202
|
+
opts.on("-o", "--host HOST", "listen on HOST (default: #{HOST})") { |host|
|
203
|
+
@options[:host] = host
|
204
|
+
}
|
205
|
+
|
206
|
+
opts.on("-p", "--port PORT", "use PORT (default: #{PORT})") { |port|
|
207
|
+
@options[:port] = port
|
208
|
+
}
|
209
|
+
|
210
|
+
opts.on("-e", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: development)") { |e|
|
211
|
+
@options[:environment] = e
|
212
|
+
}
|
213
|
+
|
214
|
+
opts.on("-F", "--foreground", "don't daemonize, run in the foreground") { |f|
|
215
|
+
@options[:foreground] = true
|
216
|
+
}
|
217
|
+
|
218
|
+
opts.on("-L", "--no-launch", "don't launch the browser") { |f|
|
219
|
+
@options[:skip_launch] = true
|
220
|
+
}
|
221
|
+
|
222
|
+
opts.on('-K', "--kill", "kill the running process and exit") {|k|
|
223
|
+
kill!
|
224
|
+
exit
|
225
|
+
}
|
226
|
+
|
227
|
+
opts.on('-S', "--status", "display the current running PID and URL then quit") {|s|
|
228
|
+
status
|
229
|
+
exit!
|
230
|
+
}
|
231
|
+
|
232
|
+
opts.on('-d', "--debug", "raise the log level to :debug (default: :info)") {|s|
|
233
|
+
@options[:debug] = true
|
234
|
+
}
|
235
|
+
|
236
|
+
yield opts if block_given?
|
237
|
+
|
238
|
+
opts.separator ""
|
239
|
+
opts.separator "Common options:"
|
240
|
+
|
241
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
242
|
+
puts opts
|
243
|
+
exit
|
244
|
+
end
|
245
|
+
|
246
|
+
opts.on_tail("--version", "Show version") do
|
247
|
+
if app.respond_to?(:version)
|
248
|
+
puts "#{app_name} #{app.version}"
|
249
|
+
end
|
250
|
+
puts "sinatra #{Sinatra::VERSION}"
|
251
|
+
puts "vegas #{Vegas::VERSION}"
|
252
|
+
exit
|
253
|
+
end
|
254
|
+
|
255
|
+
opts.parse! ARGV
|
256
|
+
}
|
257
|
+
rescue OptionParser::MissingArgument => e
|
258
|
+
logger.warn "#{e}, run -h for options"
|
259
|
+
exit
|
260
|
+
end
|
261
|
+
|
262
|
+
def kill_command
|
263
|
+
WINDOWS ? 1 : :INT
|
264
|
+
end
|
265
|
+
|
266
|
+
def delete_pid!
|
267
|
+
File.delete(pid_file) if File.exist?(pid_file)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created on 2009-2-27.
|
4
|
+
# Copyright (c) 2009. All rights reserved.
|
5
|
+
|
6
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_app.rb'))
|
7
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'lib','vegas.rb'))
|
8
|
+
|
9
|
+
Vegas::Runner.new(TestApp, 'test_app')
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class TestApp1 < Sinatra::Default
|
2
|
+
|
3
|
+
get '/' do
|
4
|
+
'TestApp1 Index'
|
5
|
+
end
|
6
|
+
|
7
|
+
get '/route' do
|
8
|
+
'TestApp1 route'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
class TestApp2 < Sinatra::Default
|
14
|
+
|
15
|
+
get '/' do
|
16
|
+
'TestApp2 Index'
|
17
|
+
end
|
18
|
+
|
19
|
+
get '/route' do
|
20
|
+
'TestApp2 route'
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
dependencies = %w{
|
2
|
+
bacon
|
3
|
+
sinatra
|
4
|
+
rack/test
|
5
|
+
nokogiri
|
6
|
+
}
|
7
|
+
|
8
|
+
begin
|
9
|
+
dependencies.each {|f| require f }
|
10
|
+
rescue LoadError
|
11
|
+
require 'rubygems'
|
12
|
+
dependencies.each {|f| require f }
|
13
|
+
end
|
14
|
+
|
15
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'vegas.rb')
|
16
|
+
|
17
|
+
module TestHelper
|
18
|
+
def rackup(app)
|
19
|
+
Rack::Test::Session.new(app)
|
20
|
+
end
|
21
|
+
|
22
|
+
def body
|
23
|
+
last_response.body.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def instance_of(klass)
|
27
|
+
lambda {|obj| obj.is_a?(klass) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def html_body
|
31
|
+
body =~ /^\<html/ ? body : "<html><body>#{body}</body></html>"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
Bacon::Context.send(:include, TestHelper)
|
37
|
+
|
38
|
+
class Should
|
39
|
+
|
40
|
+
def have_element(search, content = nil)
|
41
|
+
satisfy "have element matching #{search}" do
|
42
|
+
doc = Nokogiri.parse(@object.to_s)
|
43
|
+
node_set = doc.search(search)
|
44
|
+
if node_set.empty?
|
45
|
+
false
|
46
|
+
else
|
47
|
+
collected_content = node_set.collect {|t| t.content }.join(' ')
|
48
|
+
case content
|
49
|
+
when Regexp
|
50
|
+
collected_content =~ content
|
51
|
+
when String
|
52
|
+
collected_content.include?(content)
|
53
|
+
when nil
|
54
|
+
true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{vegas}
|
5
|
+
s.version = "0.0.4.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Aaron Quint"]
|
9
|
+
s.date = %q{2009-08-09}
|
10
|
+
s.description = %q{Vegas aims to solve the simple problem of creating executable versions of Sinatra/Rack apps. It includes a class Vegas::Runner that wraps Rack/Sinatra applications and provides a simple command line interface and launching mechanism.}
|
11
|
+
s.email = ["aaron@quirkey.com"]
|
12
|
+
s.extra_rdoc_files = ["History.txt"]
|
13
|
+
s.files = ["History.txt", "LICENSE", "README.rdoc", "lib/vegas.rb", "lib/vegas/runner.rb", "test/test_app/test_app.rb", "test/test_apps.rb", "test/test_helper.rb", "test/test_vegas_runner.rb"]
|
14
|
+
s.rdoc_options = ["--main", "README.txt"]
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
s.rubyforge_project = %q{quirkey}
|
17
|
+
s.rubygems_version = %q{1.3.5}
|
18
|
+
s.summary = %q{Vegas aims to solve the simple problem of creating executable versions of Sinatra/Rack apps.}
|
19
|
+
s.test_files = ["test/test_app/test_app.rb", "test/test_apps.rb", "test/test_helper.rb", "test/test_vegas_runner.rb"]
|
20
|
+
|
21
|
+
if s.respond_to? :specification_version then
|
22
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
26
|
+
s.add_runtime_dependency(%q<sinatra>, [">= 0.9.1"])
|
27
|
+
s.add_development_dependency(%q<newgem>, [">= 1.5.1"])
|
28
|
+
s.add_development_dependency(%q<nokogiri>, [">= 1.0.6"])
|
29
|
+
s.add_development_dependency(%q<bacon>, [">= 1.1.0"])
|
30
|
+
s.add_development_dependency(%q<hoe>, [">= 2.3.3"])
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<sinatra>, [">= 0.9.1"])
|
33
|
+
s.add_dependency(%q<newgem>, [">= 1.5.1"])
|
34
|
+
s.add_dependency(%q<nokogiri>, [">= 1.0.6"])
|
35
|
+
s.add_dependency(%q<bacon>, [">= 1.1.0"])
|
36
|
+
s.add_dependency(%q<hoe>, [">= 2.3.3"])
|
37
|
+
end
|
38
|
+
else
|
39
|
+
s.add_dependency(%q<sinatra>, [">= 0.9.1"])
|
40
|
+
s.add_dependency(%q<newgem>, [">= 1.5.1"])
|
41
|
+
s.add_dependency(%q<nokogiri>, [">= 1.0.6"])
|
42
|
+
s.add_dependency(%q<bacon>, [">= 1.1.0"])
|
43
|
+
s.add_dependency(%q<hoe>, [">= 2.3.3"])
|
44
|
+
end
|
45
|
+
end
|