215 lines
4.4 KiB
Ruby
Executable File

#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
## brew server: Run a local webserver for browsing available and installed brews.
# Note: this external command is ruby, but set up as a shell script, so that it gets exec'd.
# This is required for sinatra's run-loop to take over.
$:.unshift(ENV['HOMEBREW_LIBRARY_PATH'])
require 'global'
require 'formula'
require 'cmd/search'
require 'rubygems'
begin
require 'sinatra'
rescue LoadError
onoe 'Sinatra required but not found'
puts 'To install: /usr/bin/gem install sinatra'
exit 1
end
require 'cgi'
def link_to_formula name
"<a href=\"/formula/#{CGI.escape(name)}\">#{name}</a>"
end
def css_style; <<-CSS
<link href="/bootstrap.min.css" rel="stylesheet"/>
<style>
.container {
text-align: center;
}
dl {
text-align: left;
width: 500px;
margin: 0 auto;
}
table.table {
width: 500px;
margin: 0 auto;
}
</style>
CSS
end
def search_form; <<-EOS
<form action="/search" class="form-search">
<div class="input-append">
<input id="search" name="q" type="text" class="input-large">
<button class="btn btn-medium" type="submit"><i class="icon-search"></i>&nbsp;Search</button>
</div>
</form>
EOS
end
def html_page(title)
body = <<-HTML
<!DOCTYPE html>
<html>
<head>
<title>#{title}</title>
#{css_style}
</head>
<body>
<div class="container">
<div id="header">
<h1><a href="/">Homebrew</a></h1>
<p id="subtitle" class="lead"><strong>The missing package manager for OS X</strong></p>
</div>
<div id="informations">
HTML
yield body
body << <<-HTML
</div>
</div>
</body>
</html>
HTML
body
end
get '/' do
html_page("Homebrew Menu") do |s|
s << <<-HTML
<div class="row">
<div class="span12"><div class="row">#{search_form}</div></div>
</div>
<div class="row">
<div class="span12"><p id="installed"><a class="btn btn-primary" href="/installed">Show installed packages</a></p></div>
</div>
<div class="row">
<ul>
HTML
Formula.names do |name|
s << "<li>#{link_to_formula(name)}</li>"
end
s << <<-HTML
</ul>
</div>
HTML
end
end
get '/search' do
q = params['q']
results = Homebrew.search_formulae(q)
html_page("Results") do |s|
s << <<-HTML
<div class="row">
<div class="span12">
<div class="row">#{search_form}</div>
</div>
</div>
<div class="row">
<div class="span12">
<div class="row"><h4>Searched for &ldquo;#{q}&rdquo;:</h4></div>
</div>
</div>
<div class="row">
<div class="span12">
<div class="row"> <table class="table"><tr><th>Name</th></tr>
HTML
results.each do |name|
s << "<tr><td>#{link_to_formula(name)}</td></tr>"
end
s << <<-HTML
</table>
</div>
</div>
</div>
HTML
end
end
get '/formula/:name' do
f = Formula.factory(params[:name])
installed = <<-EOS
<dt>Installed at</dt>
<dd><a href=\"file://#{f.prefix}\">#{f.prefix}</a></dd>
EOS
html_page("Formula: #{f.name}") do |s|
s << <<-HTML
<h1>#{f.name}</h1>
<dl class="dl-horizontal">
<dt>Version</dt>
<dd>#{f.version}</dd>
<dt>Homepage</dt>
<dd><a href="#{f.homepage}">#{f.homepage}</a></dd>
<dt>Download</dt>
<dd><a href="#{f.url}">#{f.url}</a></dd>
#{installed if f.installed?}
HTML
unless f.deps.empty?
s << <<-HTML
<dt>Depends on</td>
HTML
f.deps.each do |dep|
s << "<dd>#{link_to_formula(dep.name)}</dd>"
end
end
used_by = Formula.select { |ff| ff.deps.include?(f) }.map(&:name).flatten.uniq.sort
unless used_by.empty?
s << <<-HTML
<dt>Used by</td>
HTML
used_by.each do |name|
s << "<dd>#{link_to_formula(name)}</dd>"
end
end
s << <<-HTML
</dl>
HTML
end
end
get '/installed' do
html_page("Installed Formulae") do |s|
s << <<-HTML
<h3>Installed Formulae:</h3>
<table class="table"><tr><th>Name</th><th>Version</th></tr>
HTML
Formula.installed.each do |f|
s << "<tr><td>#{link_to_formula(f.name)}</td><td>#{f.version}</td></tr>"
end
s << <<-HTML
</table>
HTML
end
end
puts "View our tasting menu at http://localhost:4567/\nUse \"Control-C\" to exit.\n\n"