gembox 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +15 -0
- data/Manifest.txt +41 -0
- data/PostInstall.txt +4 -0
- data/README.rdoc +35 -0
- data/Rakefile +35 -0
- data/bin/gembox +11 -0
- data/gembox.gemspec +56 -0
- data/lib/extensions.rb +21 -0
- data/lib/gembox.rb +13 -0
- data/lib/gembox/app.rb +87 -0
- data/lib/gembox/config.ru +8 -0
- data/lib/gembox/gem_list.rb +41 -0
- data/lib/gembox/gems.rb +44 -0
- data/lib/gembox/view_helpers.rb +69 -0
- data/public/images/edit.png +0 -0
- data/public/images/folder.png +0 -0
- data/public/images/git.gif +0 -0
- data/public/images/page.png +0 -0
- data/public/images/page_white_text.png +0 -0
- data/public/images/rubygems-125x125t.png +0 -0
- data/public/javascripts/base.js +212 -0
- data/public/javascripts/gembox.js +75 -0
- data/public/javascripts/jquery.form.js +632 -0
- data/public/javascripts/jquery.js +4241 -0
- data/public/javascripts/jquery.metadata.js +121 -0
- data/public/javascripts/jquery.ui.js +273 -0
- data/public/swf/clippy.swf +0 -0
- data/test/.bacon +0 -0
- data/test/test_gembox_app.rb +133 -0
- data/test/test_gembox_gems.rb +61 -0
- data/test/test_helper.rb +68 -0
- data/views/doc.haml +17 -0
- data/views/file_tree.haml +9 -0
- data/views/gem.haml +48 -0
- data/views/gembox.sass +188 -0
- data/views/gems_columns.haml +16 -0
- data/views/gems_header.haml +17 -0
- data/views/gems_table.haml +19 -0
- data/views/index.haml +1 -0
- data/views/layout.haml +43 -0
- data/views/no_results.haml +3 -0
- metadata +169 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe 'Gembox::Gems' do
|
4
|
+
|
5
|
+
describe '#load' do
|
6
|
+
before do
|
7
|
+
Gembox::Gems.load
|
8
|
+
end
|
9
|
+
|
10
|
+
should "load local gems" do
|
11
|
+
Gembox::Gems.local_gems.should.be.an instance_of(Array)
|
12
|
+
end
|
13
|
+
|
14
|
+
should "load source index into source_index" do
|
15
|
+
Gembox::Gems.source_index.should.be.an instance_of(Gem::SourceIndex)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#local_gems" do
|
20
|
+
before do
|
21
|
+
Gembox::Gems.load
|
22
|
+
@gems = Gembox::Gems.local_gems
|
23
|
+
end
|
24
|
+
|
25
|
+
should "return array of array of gems" do
|
26
|
+
@gems.should.be.an instance_of(Gembox::GemList)
|
27
|
+
end
|
28
|
+
|
29
|
+
should "only have one entry per gem" do
|
30
|
+
@gems.should.has_key? 'sinatra'
|
31
|
+
@gems.should.not.has_key? 'sinatra-0.9.0.5'
|
32
|
+
end
|
33
|
+
|
34
|
+
should "have an array of spec versions per gem name" do
|
35
|
+
@gems['sinatra'].should.be.an instance_of(Array)
|
36
|
+
@gems['sinatra'].first.should.be.an instance_of(Gem::Specification)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#search' do
|
41
|
+
before do
|
42
|
+
Gembox::Gems.load
|
43
|
+
@gems = Gembox::Gems.search 'sin'
|
44
|
+
end
|
45
|
+
|
46
|
+
should "return a list of gem specs" do
|
47
|
+
@gems.should.be.an instance_of(Gembox::GemList)
|
48
|
+
end
|
49
|
+
|
50
|
+
should "only have one entry per gem" do
|
51
|
+
@gems.should.has_key? 'sinatra'
|
52
|
+
@gems.should.not.has_key? 'sinatra-0.9.0.5'
|
53
|
+
end
|
54
|
+
|
55
|
+
should "return gems that match the specname" do
|
56
|
+
@gems.should.not.has_key? 'rack'
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sinatra'
|
3
|
+
require 'bacon'
|
4
|
+
require 'rack/test'
|
5
|
+
require 'mocha'
|
6
|
+
|
7
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'gembox.rb')
|
8
|
+
|
9
|
+
require 'nokogiri'
|
10
|
+
|
11
|
+
module TestHelper
|
12
|
+
|
13
|
+
def app
|
14
|
+
Gembox::App.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def body
|
18
|
+
last_response.body
|
19
|
+
end
|
20
|
+
|
21
|
+
def should
|
22
|
+
last_response.should
|
23
|
+
end
|
24
|
+
|
25
|
+
def instance_of(klass)
|
26
|
+
lambda {|obj| obj.is_a?(klass) }
|
27
|
+
end
|
28
|
+
|
29
|
+
# HTML matcher for bacon
|
30
|
+
#
|
31
|
+
# it 'should display document' do
|
32
|
+
# body.should have_element('#document')
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# With content matching:
|
36
|
+
#
|
37
|
+
# it 'should display loaded document' do
|
38
|
+
# body.should have_element('#document .title', /My Document/)
|
39
|
+
# end
|
40
|
+
def have_element(search, content = nil)
|
41
|
+
lambda do |obj|
|
42
|
+
doc = Nokogiri.parse(obj.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
|
+
|
60
|
+
def html_body
|
61
|
+
body =~ /^\<html/ ? body : "<html><body>#{body}</body></html>"
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
Bacon::Context.send(:include, TestHelper)
|
68
|
+
Bacon::Context.send(:include, Rack::Test::Methods)
|
data/views/doc.haml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
%html{:xmlns=> "http://www.w3.org/1999/xhtml", 'xml:lang' => "en", :lang => "en"}
|
2
|
+
%head
|
3
|
+
%meta{'http-equiv' => "Content-Type", 'content' => "text/html; charset=utf-8"}
|
4
|
+
%title Gembox
|
5
|
+
%link{'href' => '/stylesheets/gembox.css', 'rel' => 'stylesheet', 'type' => 'text/css', 'media' => 'screen'}
|
6
|
+
-['jquery', 'jquery.ui', 'jquery.metadata', 'jquery.form', 'base', 'gembox'].each do |jslib|
|
7
|
+
%script{'type' => 'text/javascript', 'src' => "/javascripts/#{jslib}.js"}
|
8
|
+
%body
|
9
|
+
#container
|
10
|
+
#smallnav
|
11
|
+
.back_link=link_to_gem(@gem, :text => '« Back to Gembox')
|
12
|
+
.viewing
|
13
|
+
Viewing RDoc for
|
14
|
+
=@gem.name
|
15
|
+
|
16
|
+
=@gem.version
|
17
|
+
%iframe#docframe{:src => "#{request.path_info}/index.html"}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
-subdirs = (files && !files.empty?)
|
2
|
+
%li.dir
|
3
|
+
%img{'src' => "/images/#{(subdirs ? 'folder.png' : 'page.png')}"}
|
4
|
+
%span.file{'data' => "{subdirs: #{!!subdirs}, filename:\'#{parent}\', url: \'#{url_for(:file => parent)}\', github: #{@gem.on_github? ? "\'" + @gem.homepage + "/blob/master/#{parent}\'" : false}}"}
|
5
|
+
=dir
|
6
|
+
-if subdirs
|
7
|
+
%ul{'style' => 'display:none'}
|
8
|
+
-files.each do |dir, files|
|
9
|
+
=haml(:file_tree, :locals => {:dir => dir, :files => files, :parent => File.join(parent, dir)}, :layout => false)
|
data/views/gem.haml
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#gem
|
2
|
+
%h2
|
3
|
+
=@gem.name
|
4
|
+
%span.version=@gem.version
|
5
|
+
|
6
|
+
.description
|
7
|
+
%p=@gem.description
|
8
|
+
.meta
|
9
|
+
%p.authors
|
10
|
+
By
|
11
|
+
=@gem.authors.join(', ')
|
12
|
+
='(' + link_to(@gem.email, "mailto:#{@gem.email}") + ')'
|
13
|
+
%p.url
|
14
|
+
Homepage:
|
15
|
+
=link_to(@gem.homepage)
|
16
|
+
-if @gem.has_rdoc?
|
17
|
+
%p.url
|
18
|
+
Docs:
|
19
|
+
=link_to("View Local RDoc", "/gems/doc/#{@gem.name}/#{@gem.version}")
|
20
|
+
-unless @gem.rubyforge_project.blank?
|
21
|
+
%p.url
|
22
|
+
Rubyforge:
|
23
|
+
=link_to("http://rubyforge.org/projects/#{@gem.rubyforge_project}")
|
24
|
+
%p.released
|
25
|
+
Released
|
26
|
+
=ts(@gem.date)
|
27
|
+
%h3.toggler Dependencies
|
28
|
+
#dependencies.toggle_area
|
29
|
+
-@gem.dependencies.each do |dependency|
|
30
|
+
.gem
|
31
|
+
=link_to(dependency.name, "/gems/#{dependency.name}")
|
32
|
+
%span.version=dependency.version_requirements
|
33
|
+
%h3.toggler Other Versions
|
34
|
+
#versions.toggle_area
|
35
|
+
%table
|
36
|
+
%tbody
|
37
|
+
-@gem_versions.each do |spec|
|
38
|
+
%tr
|
39
|
+
%td=link_to(spec.version, "/gems/#{spec.name}/#{spec.version}")
|
40
|
+
%td=ts(spec.date)
|
41
|
+
|
42
|
+
%h3.toggler Files
|
43
|
+
#files.toggle_area
|
44
|
+
%ul.files
|
45
|
+
=haml(:file_tree, :locals => {:dir => '/', :files => {}, :parent => ''}, :layout => false)
|
46
|
+
-@gem.files_tree.each do |dir, files|
|
47
|
+
=haml(:file_tree, :locals => {:dir => dir, :files => files, :parent => dir}, :layout => false)
|
48
|
+
|
data/views/gembox.sass
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
!red = #BA2818
|
2
|
+
!light_red = #EB9281
|
3
|
+
!dark_red = #871D1A
|
4
|
+
!light_grey = #CCCCCC
|
5
|
+
!light_grey_bg = #EFEFEF
|
6
|
+
!grey = #666
|
7
|
+
!highlight = #F4F6E6
|
8
|
+
!fonts = "'Franklin Gothic', 'Franklin Gothic Medium', Helvetica, sans-serif"
|
9
|
+
//
|
10
|
+
|
11
|
+
body
|
12
|
+
:font-family = !fonts
|
13
|
+
:background #FFFFFF
|
14
|
+
:margin 0px
|
15
|
+
:padding 0px
|
16
|
+
:text-align center
|
17
|
+
|
18
|
+
a:link,
|
19
|
+
a:visited
|
20
|
+
:color = !red
|
21
|
+
:text-decoration none
|
22
|
+
a:hover
|
23
|
+
:color = !light_red
|
24
|
+
:text-decoration underline
|
25
|
+
|
26
|
+
a img
|
27
|
+
:border none
|
28
|
+
|
29
|
+
.contained
|
30
|
+
:width 960px
|
31
|
+
:margin 0px auto
|
32
|
+
:text-align left
|
33
|
+
:position relative
|
34
|
+
|
35
|
+
#header
|
36
|
+
.contained
|
37
|
+
:width 250px
|
38
|
+
#logo
|
39
|
+
:position absolute
|
40
|
+
:top -20px
|
41
|
+
:left -135px
|
42
|
+
h1
|
43
|
+
:color = !dark_red
|
44
|
+
:font-size 50px
|
45
|
+
:margin 20px 0px 0px 0px
|
46
|
+
a
|
47
|
+
:color = !dark_red
|
48
|
+
a:hover
|
49
|
+
:text-decoration none
|
50
|
+
|
51
|
+
#nav
|
52
|
+
:background = !dark_red
|
53
|
+
:padding 15px
|
54
|
+
.search
|
55
|
+
:margin-top 20px
|
56
|
+
:width 100%
|
57
|
+
:text-align center
|
58
|
+
input
|
59
|
+
:font-family = !fonts
|
60
|
+
:font-size 18px
|
61
|
+
:padding 4px
|
62
|
+
.search_field
|
63
|
+
:width 400px
|
64
|
+
|
65
|
+
#stats
|
66
|
+
:background = !light_grey_bg
|
67
|
+
:margin 0px 0px 10px 0px
|
68
|
+
:padding 2px
|
69
|
+
p
|
70
|
+
:text-align center
|
71
|
+
:color = !grey
|
72
|
+
|
73
|
+
#main
|
74
|
+
h2
|
75
|
+
:position relative
|
76
|
+
span.view_options
|
77
|
+
:font-size 14px
|
78
|
+
:font-weight normal
|
79
|
+
:color = !grey
|
80
|
+
:position absolute
|
81
|
+
:top 5px
|
82
|
+
:right 20px
|
83
|
+
strong
|
84
|
+
:color #333
|
85
|
+
:font-weight normal
|
86
|
+
.num
|
87
|
+
:color = !light_grey
|
88
|
+
.column
|
89
|
+
:width 460px
|
90
|
+
:float left
|
91
|
+
.gem
|
92
|
+
:font-size 14px
|
93
|
+
:margin 5px 0px
|
94
|
+
:padding 5px 0px
|
95
|
+
.name
|
96
|
+
:font-size 16px
|
97
|
+
:margin 0px
|
98
|
+
:padding 0px 0px 2px 0px
|
99
|
+
.description
|
100
|
+
:font-size 12px
|
101
|
+
:padding 2px 0px
|
102
|
+
:color #999
|
103
|
+
.versions
|
104
|
+
:color = !light_grey
|
105
|
+
a
|
106
|
+
:color = !grey
|
107
|
+
table#gems
|
108
|
+
:border-collapse collapse
|
109
|
+
:font-size 14px
|
110
|
+
:width 100%
|
111
|
+
th
|
112
|
+
:color = !grey
|
113
|
+
:text-align left
|
114
|
+
:font-size 12px
|
115
|
+
:font-weight normal
|
116
|
+
:border-bottom 1px solid #CCC
|
117
|
+
td
|
118
|
+
:padding 4px 4px 4px 0px
|
119
|
+
:vertical-align top
|
120
|
+
tr.summary td
|
121
|
+
:padding-top 0px
|
122
|
+
|
123
|
+
#gem
|
124
|
+
.description
|
125
|
+
:font-size 18px
|
126
|
+
:color = #333
|
127
|
+
.meta
|
128
|
+
:color = !grey
|
129
|
+
ul.files,
|
130
|
+
ul.files li ul
|
131
|
+
:list-style none
|
132
|
+
:font-size 14px
|
133
|
+
:font-weight normal
|
134
|
+
:margin 0px
|
135
|
+
:padding 4px 0px 0px
|
136
|
+
ul.files
|
137
|
+
li
|
138
|
+
:padding 4px 0px
|
139
|
+
li ul li
|
140
|
+
:padding-left 10px
|
141
|
+
img
|
142
|
+
:vertical-align top
|
143
|
+
.controls a
|
144
|
+
:padding 0px 4px 0px 0px
|
145
|
+
.file_hover
|
146
|
+
:background = !highlight
|
147
|
+
|
148
|
+
.pagination
|
149
|
+
:font-size 12px
|
150
|
+
:color = !grey
|
151
|
+
:width 100%
|
152
|
+
:background = !light_grey_bg
|
153
|
+
:padding 4px
|
154
|
+
:text-align right
|
155
|
+
a
|
156
|
+
:color = !dark_red
|
157
|
+
a,
|
158
|
+
span
|
159
|
+
:padding 0px 4px
|
160
|
+
|
161
|
+
#footer
|
162
|
+
:margin 20px
|
163
|
+
:padding 10px
|
164
|
+
:border-top = 1px solid !light_grey
|
165
|
+
.copyright
|
166
|
+
:font-size 12px
|
167
|
+
|
168
|
+
#smallnav
|
169
|
+
:background = !dark_red
|
170
|
+
:text-align center
|
171
|
+
:width auto
|
172
|
+
:padding 5px
|
173
|
+
a
|
174
|
+
:color #FFF
|
175
|
+
.back_link
|
176
|
+
:float left
|
177
|
+
.viewing
|
178
|
+
:color = !light_grey
|
179
|
+
#docframe
|
180
|
+
:border none
|
181
|
+
:padding none
|
182
|
+
:margin none
|
183
|
+
:width 100%
|
184
|
+
:height 95%
|
185
|
+
.clear
|
186
|
+
:clear both
|
187
|
+
:line-height 0px
|
188
|
+
:height 0px
|
@@ -0,0 +1,16 @@
|
|
1
|
+
=haml(:gems_header, :layout => false)
|
2
|
+
- unless @gems.empty?
|
3
|
+
#gems
|
4
|
+
-@gems.in_groups_of((@gems.length + 1)/ 2).each do |gems|
|
5
|
+
.column
|
6
|
+
-gems.compact.each do |gem_name, specs|
|
7
|
+
.gem
|
8
|
+
%h4.name=link_to_gem(specs.first)
|
9
|
+
.description=specs.first.summary
|
10
|
+
.versions
|
11
|
+
%span
|
12
|
+
=specs.collect {|spec| link_to_gem(spec, :text => spec.version) }.join(', ')
|
13
|
+
.clear
|
14
|
+
=will_paginate(@gems)
|
15
|
+
- else
|
16
|
+
=haml(:no_results, :layout => false)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
%h2
|
2
|
+
-if @search
|
3
|
+
Gems matching
|
4
|
+
%em=@search
|
5
|
+
%span.num="(#{@gems.length})"
|
6
|
+
-else
|
7
|
+
Installed Gems
|
8
|
+
%span.num="(#{@gems.total_entries})"
|
9
|
+
%span.view_options
|
10
|
+
View as
|
11
|
+
=(@show_as == 'columns') ? '<strong>Columns</strong>' : link_to('Columns', {'as' => 'columns'})
|
12
|
+
=' / '
|
13
|
+
=(@show_as == 'table') ? '<strong>Table</strong>' : link_to('Table', {'as' => 'table'})
|
14
|
+
/ |
|
15
|
+
/=link_to('Summaries', {'summaries' => 'false'})
|
16
|
+
|
17
|
+
=will_paginate(@gems)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
=haml(:gems_header, :layout => false)
|
2
|
+
- unless @gems.empty?
|
3
|
+
%table#gems
|
4
|
+
%thead
|
5
|
+
%th Name
|
6
|
+
%th Versions
|
7
|
+
%th Homepage
|
8
|
+
%tbody
|
9
|
+
-@gems.each do |gem_name, specs|
|
10
|
+
%tr.gem
|
11
|
+
%td.name=link_to_gem(specs.first)
|
12
|
+
%td.versions=specs.collect {|spec| link_to_gem(spec, :text => spec.version) }.join(', ')
|
13
|
+
%td=link_to(specs.first.homepage)
|
14
|
+
%tr.gem.summary
|
15
|
+
%td/
|
16
|
+
%td.description{:colspan => 2}=specs.first.summary
|
17
|
+
=will_paginate(@gems)
|
18
|
+
- else
|
19
|
+
=haml(:no_results, :layout => false)
|