znz-gitpub 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +5 -0
- data/gitpub.rb +219 -0
- data/gitpub_spec.rb +208 -0
- data/linux-2.6.ru +3 -0
- metadata +63 -0
data/README
ADDED
data/gitpub.rb
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# = gitpub.rb
|
4
|
+
#
|
5
|
+
# Web application to publish static files based on git and rack.
|
6
|
+
#
|
7
|
+
# Pub means 'publish' and supporting only static files like publicfile of DJB.
|
8
|
+
#
|
9
|
+
# == Example Usage
|
10
|
+
#
|
11
|
+
# execute some commands:
|
12
|
+
# gem install rack
|
13
|
+
# git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
|
14
|
+
# rackup -d linux-2.6.ru
|
15
|
+
# and open http://localhost:9292/ with your browser.
|
16
|
+
#
|
17
|
+
# linux-2.6.ru is:
|
18
|
+
# require 'gitpub'
|
19
|
+
# run GitPub.new('linux-2.6/.git', /\Av2\.6\.\d+\z/)
|
20
|
+
#
|
21
|
+
#
|
22
|
+
# == License (The MIT License)
|
23
|
+
#
|
24
|
+
# Copyright (c) 2009 Kazuhiro NISHIYAMA
|
25
|
+
#
|
26
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
27
|
+
# of this software and associated documentation files (the "Software"), to deal
|
28
|
+
# in the Software without restriction, including without limitation the rights
|
29
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
30
|
+
# copies of the Software, and to permit persons to whom the Software is
|
31
|
+
# furnished to do so, subject to the following conditions:
|
32
|
+
#
|
33
|
+
# The above copyright notice and this permission notice shall be included in
|
34
|
+
# all copies or substantial portions of the Software.
|
35
|
+
#
|
36
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
37
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
38
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
39
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
40
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
41
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
42
|
+
# THE SOFTWARE.
|
43
|
+
#
|
44
|
+
|
45
|
+
|
46
|
+
require 'erb'
|
47
|
+
require 'rack/mime'
|
48
|
+
|
49
|
+
class GitPub
|
50
|
+
include ERB::Util
|
51
|
+
|
52
|
+
# path to git command
|
53
|
+
GIT_BIN = "git"
|
54
|
+
|
55
|
+
# Create GitPub instance.
|
56
|
+
#
|
57
|
+
# git_dir :: path to .git or git bare repository.
|
58
|
+
# pub_tag_regexp :: Regexp of publish tag.
|
59
|
+
# Recommends use \A and \z instead of ^ and $.
|
60
|
+
# title :: HTML title prefix. Default is repository's directory name.
|
61
|
+
def initialize(git_dir, pub_tag_regexp=/\A([^\/:]+)\z/, title=nil)
|
62
|
+
@git_dir = git_dir
|
63
|
+
@pub_tag_regexp = pub_tag_regexp
|
64
|
+
unless title
|
65
|
+
title = File.basename(git_dir)
|
66
|
+
if title == ".git"
|
67
|
+
title = File.basename(File.dirname(git_dir))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
@title = title
|
71
|
+
end
|
72
|
+
|
73
|
+
# Wrapper of git command.
|
74
|
+
def git(*args)
|
75
|
+
IO.popen("-", "r") do |io|
|
76
|
+
if io
|
77
|
+
yield io
|
78
|
+
else
|
79
|
+
#STDERR.puts [GIT_BIN, "--git-dir", @git_dir, *args].inspect
|
80
|
+
exec(GIT_BIN, "--git-dir", @git_dir, *args)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
private :git
|
85
|
+
|
86
|
+
# List public tags.
|
87
|
+
def list_pub_tag(env, res)
|
88
|
+
tags = []
|
89
|
+
git("tag") do |io|
|
90
|
+
io.each_line do |line|
|
91
|
+
line.chomp!
|
92
|
+
if @pub_tag_regexp =~ line
|
93
|
+
tags << $&
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
tags.sort!
|
98
|
+
E_list_pub_tag.result(binding)
|
99
|
+
end
|
100
|
+
|
101
|
+
# ERB template of list_pub_tag.
|
102
|
+
E_list_pub_tag = ERB.new(<<-ERUBY, 1, '-')
|
103
|
+
<html>
|
104
|
+
<head>
|
105
|
+
<title><%=h @title %></title>
|
106
|
+
</head>
|
107
|
+
<body>
|
108
|
+
<h1><%=h @title %></h1>
|
109
|
+
<ul>
|
110
|
+
<%- tags.each do |tag| -%>
|
111
|
+
<li><a href="<%=h tag %>/"><%=h tag %></a></li>
|
112
|
+
<%- end -%>
|
113
|
+
</ul>
|
114
|
+
</body>
|
115
|
+
</html>
|
116
|
+
ERUBY
|
117
|
+
|
118
|
+
# List files in the blob (tag or directory)
|
119
|
+
def list_files(env, res, tag, path)
|
120
|
+
files = []
|
121
|
+
git("ls-tree", "-z", "#{tag}:#{path}") do |io|
|
122
|
+
io.each_line("\0") do |line|
|
123
|
+
line.chomp!("\0")
|
124
|
+
#STDERR.puts line
|
125
|
+
info, file = line.split(/\t/, 2)
|
126
|
+
mode, type, object = info.split(/ /)
|
127
|
+
files << {
|
128
|
+
:mode => mode,
|
129
|
+
:type => type,
|
130
|
+
:object => object,
|
131
|
+
:file => file,
|
132
|
+
}
|
133
|
+
end
|
134
|
+
end
|
135
|
+
files = files.sort_by{|h| h[:file] }
|
136
|
+
E_list_files.result(binding)
|
137
|
+
end
|
138
|
+
|
139
|
+
# ERB template of list_files.
|
140
|
+
E_list_files = ERB.new(<<-ERUBY, 1, '-')
|
141
|
+
<html>
|
142
|
+
<head>
|
143
|
+
<title><%=h @title %> <%=h tag %>:<%=h path %></title>
|
144
|
+
</head>
|
145
|
+
<body>
|
146
|
+
<h1><%=h @title %> <%=h tag %>:<%=h path %></h1>
|
147
|
+
<ol>
|
148
|
+
<li><a href="..">..</a></li>
|
149
|
+
<%- files.each do |h| -%>
|
150
|
+
<%- case h[:type] -%>
|
151
|
+
<%- when "tree" -%>
|
152
|
+
<li><a href="<%=h h[:file] %>/"><%=h h[:file] %>/</a></li>
|
153
|
+
<%- when "blob" -%>
|
154
|
+
<li><a href="<%=h h[:file] %>"><%=h h[:file] %></a></li>
|
155
|
+
<%- else -%>
|
156
|
+
<li><%=h h[:file] %></li>
|
157
|
+
<%- end -%>
|
158
|
+
<%- end -%>
|
159
|
+
</ol>
|
160
|
+
</body>
|
161
|
+
</html>
|
162
|
+
ERUBY
|
163
|
+
|
164
|
+
# Show file content of object.
|
165
|
+
# Content-Type choose by Rack::Mime.mime_type of file extension.
|
166
|
+
# Default is text/plain.
|
167
|
+
def show_file(env, res, tag, path)
|
168
|
+
body = "(empty)"
|
169
|
+
git("show", "#{tag}:#{path}") do |io|
|
170
|
+
body = io.read
|
171
|
+
end
|
172
|
+
mime_type = Rack::Mime.mime_type(File.extname(path), "text/plain")
|
173
|
+
if mime_type != "text/plain"
|
174
|
+
res.write body
|
175
|
+
res['Content-Type'] = mime_type
|
176
|
+
res['Content-Length'] = (body.bytesize rescue body.size).to_s
|
177
|
+
return
|
178
|
+
end
|
179
|
+
E_show_file.result(binding)
|
180
|
+
end
|
181
|
+
|
182
|
+
# ERB template of show_file.
|
183
|
+
E_show_file = ERB.new(<<-ERUBY, 1, '-')
|
184
|
+
<html>
|
185
|
+
<head>
|
186
|
+
<title><%=h @title %> <%=h tag %>:<%=h path %></title>
|
187
|
+
</head>
|
188
|
+
<body>
|
189
|
+
<h1><%=h @title %> <%=h tag %>:<%=h path %></h1>
|
190
|
+
<p><a href=".">back</a><p>
|
191
|
+
<pre><%=h body %></pre>
|
192
|
+
</body>
|
193
|
+
</html>
|
194
|
+
ERUBY
|
195
|
+
|
196
|
+
# Rack interface.
|
197
|
+
def call(env)
|
198
|
+
res = Rack::Response.new
|
199
|
+
body = nil
|
200
|
+
if /\A\/([^\/:]+)\// =~ env['PATH_INFO']
|
201
|
+
tag, rest = $1, $'
|
202
|
+
end
|
203
|
+
if tag && @pub_tag_regexp =~ tag
|
204
|
+
if /\/\z/ =~ env['PATH_INFO']
|
205
|
+
body = list_files(env, res, tag, rest)
|
206
|
+
else
|
207
|
+
body = show_file(env, res, tag, rest)
|
208
|
+
end
|
209
|
+
else
|
210
|
+
body = list_pub_tag(env, res)
|
211
|
+
end
|
212
|
+
if body
|
213
|
+
res.write body
|
214
|
+
res['Content-Type'] = 'text/html; charset=utf-8'
|
215
|
+
res['Content-Length'] = (body.bytesize rescue body.size).to_s
|
216
|
+
end
|
217
|
+
res.finish
|
218
|
+
end
|
219
|
+
end
|
data/gitpub_spec.rb
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#!/usr/bin/env spec
|
3
|
+
require "gitpub"
|
4
|
+
require "rack"
|
5
|
+
require "tempfile"
|
6
|
+
|
7
|
+
describe GitPub, "with linux-2.6" do
|
8
|
+
before do
|
9
|
+
@git_dir = File.expand_path("linux-2.6/.git")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "list all tags without PATH_INFO" do
|
13
|
+
gitpub = GitPub.new(@git_dir)
|
14
|
+
code, headers, res = gitpub.call({'PATH_INFO' => nil})
|
15
|
+
code.should == 200
|
16
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
17
|
+
headers["Content-Length"].should be_instance_of String
|
18
|
+
headers["Content-Length"].to_i.should > 0
|
19
|
+
body = res.body.to_s
|
20
|
+
/\.\./.should_not =~ body
|
21
|
+
/<pre>/.should_not =~ body
|
22
|
+
end
|
23
|
+
|
24
|
+
it "list all tags with PATH_INFO=/" do
|
25
|
+
gitpub = GitPub.new(@git_dir)
|
26
|
+
code, headers, res0 = gitpub.call({'PATH_INFO' => nil})
|
27
|
+
code, headers, res1 = gitpub.call({'PATH_INFO' => "/"})
|
28
|
+
code.should == 200
|
29
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
30
|
+
headers["Content-Length"].should be_instance_of String
|
31
|
+
headers["Content-Length"].to_i.should > 0
|
32
|
+
res0.body.should == res1.body
|
33
|
+
body = res1.body.to_s
|
34
|
+
/\.\./.should_not =~ body
|
35
|
+
/<pre>/.should_not =~ body
|
36
|
+
end
|
37
|
+
|
38
|
+
it "list all tags with PATH_INFO=/invalid-tag" do
|
39
|
+
gitpub = GitPub.new(@git_dir)
|
40
|
+
code, headers, res0 = gitpub.call({'PATH_INFO' => nil})
|
41
|
+
code, headers, res1 = gitpub.call({'PATH_INFO' => "/invalid-tag"})
|
42
|
+
code.should == 200
|
43
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
44
|
+
headers["Content-Length"].should be_instance_of String
|
45
|
+
headers["Content-Length"].to_i.should > 0
|
46
|
+
res0.body.should == res1.body
|
47
|
+
body = res1.body.to_s
|
48
|
+
/\.\./.should_not =~ body
|
49
|
+
/<pre>/.should_not =~ body
|
50
|
+
end
|
51
|
+
|
52
|
+
it "list no files with PATH_INFO=/invalid-tag/" do
|
53
|
+
gitpub = GitPub.new(@git_dir)
|
54
|
+
code, headers, res0 = gitpub.call({'PATH_INFO' => nil})
|
55
|
+
|
56
|
+
temp_stderr = Tempfile.new("stderr")
|
57
|
+
orig_stderr = STDERR.dup
|
58
|
+
STDERR.reopen(temp_stderr)
|
59
|
+
code, headers, res1 = gitpub.call({'PATH_INFO' => "/invalid-tag/"})
|
60
|
+
STDERR.reopen(orig_stderr)
|
61
|
+
temp_stderr.rewind
|
62
|
+
error = temp_stderr.read
|
63
|
+
temp_stderr.close
|
64
|
+
error.should == "fatal: Not a valid object name invalid-tag:\n"
|
65
|
+
|
66
|
+
code.should == 200
|
67
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
68
|
+
headers["Content-Length"].should be_instance_of String
|
69
|
+
headers["Content-Length"].to_i.should > 0
|
70
|
+
res0.body.should_not == res1.body
|
71
|
+
body = res1.body.to_s
|
72
|
+
/\.\./.should =~ body
|
73
|
+
/<pre>/.should_not =~ body
|
74
|
+
end
|
75
|
+
|
76
|
+
it "list pub tags only without PATH_INFO" do
|
77
|
+
gitpub = GitPub.new(@git_dir)
|
78
|
+
code, headers, res = gitpub.call({'PATH_INFO' => nil})
|
79
|
+
all_tags_length = headers["Content-Length"].to_i
|
80
|
+
gitpub = GitPub.new(@git_dir, /\Av2\.6\.\d+\z/)
|
81
|
+
code, headers, res = gitpub.call({'PATH_INFO' => nil})
|
82
|
+
code.should == 200
|
83
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
84
|
+
headers["Content-Length"].should be_instance_of String
|
85
|
+
headers["Content-Length"].to_i.should > 0
|
86
|
+
headers["Content-Length"].to_i.should < all_tags_length
|
87
|
+
body = res.body.to_s
|
88
|
+
/\.\./.should_not =~ body
|
89
|
+
/<pre>/.should_not =~ body
|
90
|
+
end
|
91
|
+
|
92
|
+
it "list pub tags only with PATH_INFO=/" do
|
93
|
+
gitpub = GitPub.new(@git_dir)
|
94
|
+
code, headers, res = gitpub.call({'PATH_INFO' => "/"})
|
95
|
+
all_tags_length = headers["Content-Length"].to_i
|
96
|
+
gitpub = GitPub.new(@git_dir, /\Av2\.6\.\d+\z/)
|
97
|
+
code, headers, res = gitpub.call({'PATH_INFO' => "/"})
|
98
|
+
code.should == 200
|
99
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
100
|
+
headers["Content-Length"].should be_instance_of String
|
101
|
+
headers["Content-Length"].to_i.should > 0
|
102
|
+
headers["Content-Length"].to_i.should < all_tags_length
|
103
|
+
body = res.body.to_s
|
104
|
+
/\.\./.should_not =~ body
|
105
|
+
/<pre>/.should_not =~ body
|
106
|
+
end
|
107
|
+
|
108
|
+
it "list pub tags with PATH_INFO=/invalid-tag/" do
|
109
|
+
gitpub = GitPub.new(@git_dir, /\Av2\.6\.\d+\z/)
|
110
|
+
code, headers, res0 = gitpub.call({'PATH_INFO' => nil})
|
111
|
+
code, headers, res1 = gitpub.call({'PATH_INFO' => "/invalid-tag/"})
|
112
|
+
code.should == 200
|
113
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
114
|
+
headers["Content-Length"].should be_instance_of String
|
115
|
+
headers["Content-Length"].to_i.should > 0
|
116
|
+
res0.body.should == res1.body
|
117
|
+
body = res1.body.to_s
|
118
|
+
/\.\./.should_not =~ body
|
119
|
+
/<pre>/.should_not =~ body
|
120
|
+
end
|
121
|
+
|
122
|
+
it "list no files with PATH_INFO=/v2.6.10/" do
|
123
|
+
gitpub = GitPub.new(@git_dir, /\Av2\.6\.\d+\z/)
|
124
|
+
|
125
|
+
temp_stderr = Tempfile.new("stderr")
|
126
|
+
orig_stderr = STDERR.dup
|
127
|
+
STDERR.reopen(temp_stderr)
|
128
|
+
code, headers, res = gitpub.call({'PATH_INFO' => "/v2.6.10/"})
|
129
|
+
STDERR.reopen(orig_stderr)
|
130
|
+
temp_stderr.rewind
|
131
|
+
error = temp_stderr.read
|
132
|
+
temp_stderr.close
|
133
|
+
error.should == "fatal: Not a valid object name v2.6.10:\n"
|
134
|
+
|
135
|
+
code.should == 200
|
136
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
137
|
+
headers["Content-Length"].should be_instance_of String
|
138
|
+
headers["Content-Length"].to_i.should > 0
|
139
|
+
res.body.to_s.scan(/<li>/).size.should == 1
|
140
|
+
body = res.body.to_s
|
141
|
+
/\.\./.should =~ body
|
142
|
+
/<pre>/.should_not =~ body
|
143
|
+
end
|
144
|
+
|
145
|
+
it "list files with PATH_INFO=/v2.6.11/" do
|
146
|
+
gitpub = GitPub.new(@git_dir, /\Av2\.6\.\d+\z/)
|
147
|
+
code, headers, res = gitpub.call({'PATH_INFO' => "/v2.6.11/"})
|
148
|
+
code.should == 200
|
149
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
150
|
+
headers["Content-Length"].should be_instance_of String
|
151
|
+
headers["Content-Length"].to_i.should > 0
|
152
|
+
body = res.body.to_s
|
153
|
+
body.scan(/<li>/).size.should > 1
|
154
|
+
/\.\./.should =~ body
|
155
|
+
/<pre>/.should_not =~ body
|
156
|
+
end
|
157
|
+
|
158
|
+
it "list files with PATH_INFO=/v2.6.11/" do
|
159
|
+
gitpub = GitPub.new(@git_dir, /\Av2\.6\.\d+\z/)
|
160
|
+
code, headers, res = gitpub.call({'PATH_INFO' => "/v2.6.11/"})
|
161
|
+
code.should == 200
|
162
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
163
|
+
headers["Content-Length"].should be_instance_of String
|
164
|
+
headers["Content-Length"].to_i.should > 0
|
165
|
+
body = res.body.to_s
|
166
|
+
body.scan(/<li>/).size.should > 1
|
167
|
+
/\.\./.should =~ body
|
168
|
+
/<pre>/.should_not =~ body
|
169
|
+
end
|
170
|
+
|
171
|
+
it "show file with PATH_INFO=/v2.6.11/COPYING" do
|
172
|
+
gitpub = GitPub.new(@git_dir, /\Av2\.6\.\d+\z/)
|
173
|
+
code, headers, res = gitpub.call({'PATH_INFO' => "/v2.6.11/COPYING"})
|
174
|
+
code.should == 200
|
175
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
176
|
+
headers["Content-Length"].should be_instance_of String
|
177
|
+
headers["Content-Length"].to_i.should > 0
|
178
|
+
body = res.body.to_s
|
179
|
+
/<pre>/.should =~ body
|
180
|
+
/GNU GENERAL PUBLIC LICENSE/.should =~ body
|
181
|
+
end
|
182
|
+
|
183
|
+
it "list files with PATH_INFO=/v2.6.11/Documentation/" do
|
184
|
+
gitpub = GitPub.new(@git_dir, /\Av2\.6\.\d+\z/)
|
185
|
+
code, headers, res = gitpub.call({'PATH_INFO' => "/v2.6.11/Documentation/"})
|
186
|
+
code.should == 200
|
187
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
188
|
+
headers["Content-Length"].should be_instance_of String
|
189
|
+
headers["Content-Length"].to_i.should > 0
|
190
|
+
body = res.body.to_s
|
191
|
+
body.scan(/<li>/).size.should > 1
|
192
|
+
/\.\./.should =~ body
|
193
|
+
/<pre>/.should_not =~ body
|
194
|
+
end
|
195
|
+
|
196
|
+
it "show file with PATH_INFO=/v2.6.11/Documentation/CodingStyle" do
|
197
|
+
gitpub = GitPub.new(@git_dir, /\Av2\.6\.\d+\z/)
|
198
|
+
code, headers, res = gitpub.call({'PATH_INFO' => "/v2.6.11/Documentation/CodingStyle"})
|
199
|
+
code.should == 200
|
200
|
+
headers["Content-Type"].should == "text/html; charset=utf-8"
|
201
|
+
headers["Content-Length"].should be_instance_of String
|
202
|
+
headers["Content-Length"].to_i.should > 0
|
203
|
+
body = res.body.to_s
|
204
|
+
/<pre>/.should =~ body
|
205
|
+
/Linux kernel coding style/.should =~ body
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
data/linux-2.6.ru
ADDED
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: znz-gitpub
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kazuhiro NISHIYAMA
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-30 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rack
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.9.0
|
23
|
+
version:
|
24
|
+
description:
|
25
|
+
email: zn@mbf.nifty.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files: []
|
31
|
+
|
32
|
+
files:
|
33
|
+
- README
|
34
|
+
- gitpub.rb
|
35
|
+
- gitpub_spec.rb
|
36
|
+
- linux-2.6.ru
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/znz/gitpub
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths: .
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: "0"
|
48
|
+
version:
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 1.2.0
|
59
|
+
signing_key:
|
60
|
+
specification_version: 2
|
61
|
+
summary: web application to publish static files based on git and rack
|
62
|
+
test_files: []
|
63
|
+
|