git-webby 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -27,7 +27,7 @@ task :build => "#{spec.name}.gemspec" do
27
27
  end
28
28
 
29
29
  desc "Release #{spec.file_name}"
30
- task :release do
30
+ task :release => :build do
31
31
  sh "gem push #{spec.file_name}"
32
32
  end
33
33
 
@@ -38,7 +38,7 @@ end
38
38
 
39
39
  desc "Uninstall gem #{spec.name} v#{spec.version}"
40
40
  task :uninstall do
41
- sh "gem uninstall -l #{spec.name} -v #{spec.version}"
41
+ sh "gem uninstall #{spec.name} -v #{spec.version}"
42
42
  end
43
43
 
44
44
  task :default => :test
@@ -0,0 +1,24 @@
1
+ == Git-Webby v0.2.0
2
+
3
+ Implementation of viewer for browsing of source code:
4
+
5
+ - Fixes in tasks.
6
+ - Adding of classes for handle repositories.
7
+ - Improvements in all helpers.
8
+ - Base controller for shared settings
9
+ - The project handler has been improved to find a repository and run the
10
+ command line for get files and informations.
11
+ - The HTTP Backend class has been updated for use the new changes in project
12
+ handler.
13
+ - Fixes in RPC service to POST git-upload-pack
14
+ - The repository was passed as current directory instead of the full path.
15
+ - Adding of tree in project handler
16
+ - Adding of viewer for browsing of source code
17
+ - The recursive tree has been removed for improve performance.
18
+ - Small improvements in helpers and tests.
19
+
20
+ This is a beta version. For more informations about this release,
21
+ please visit <http://github.com/codigorama/git-webby>.
22
+
23
+
24
+
@@ -1,6 +1,9 @@
1
1
  # See <b>Git::Webby</b> for documentation.
2
2
  module Git
3
3
 
4
+ # 3rd part requirements
5
+ require "sinatra/base"
6
+
4
7
  # Internal requirements
5
8
  require "git/webby/version"
6
9
 
@@ -12,37 +15,111 @@ module Git
12
15
  # - API to get information about repository.
13
16
  module Webby
14
17
 
15
- module RepositoryUtils # :nodoc:
16
- def project_path_to(*args)
17
- File.join(settings.project_root.to_s, *(args.map(&:to_s)))
18
+ class ProjectHandler #:nodoc:
19
+
20
+ # Path to git comamnd
21
+ attr_reader :path
22
+
23
+ attr_reader :project_root
24
+
25
+ attr_reader :repository
26
+
27
+ def initialize(project_root, path = "/usr/bin/git", options = {})
28
+ @config = {
29
+ :get_any_file => true,
30
+ :upload_pack => true,
31
+ :receive_pack => false
32
+ }.update(options)
33
+ @repository = nil
34
+ @path = File.expand_path(path)
35
+ @project_root = File.expand_path(project_root)
36
+ check_path @path
37
+ check_path @project_root
38
+ end
39
+
40
+ def path_to(*args)
41
+ File.join(@repository || @project_root, *(args.compact.map(&:to_s)))
42
+ end
43
+
44
+ def repository=(name)
45
+ @repository = check_path(path_to(name))
46
+ end
47
+
48
+ def cli(command, *args)
49
+ %Q[#{@path} #{args.unshift(command.to_s.gsub("_","-")).compact.join(" ")}]
50
+ end
51
+
52
+ def run(command, *args)
53
+ chdir{ %x[#{cli command, *args}] }
54
+ end
55
+
56
+ def read_file(*file)
57
+ File.read(path_to(*file))
58
+ end
59
+
60
+ def loose_object_path(*hash)
61
+ path_to(:objects, *hash)
62
+ end
63
+
64
+ def pack_idx_path(pack)
65
+ path_to(:objects, :pack, pack)
66
+ end
67
+
68
+ def info_packs_path
69
+ path_to(:objects, :info, :packs)
18
70
  end
19
71
 
20
- def git_dir(name)
21
- unless name =~ /\w\.git/ # not bare directory
22
- File.join(name, ".git")
72
+ def tree(ref = "HEAD", path = "")
73
+ list = run("ls-tree --abbrev=6 --full-tree --long #{ref}:#{path}")
74
+ if list
75
+ tree = []
76
+ list.scan %r{^(\d{3})(\d)(\d)(\d) (\w.*?) (.{6})[ \t]{0,}(.*?)\t(.*?)\n}m do
77
+ tree << {
78
+ :ftype => ftype[$1],
79
+ :fperm => "#{fperm[$2.to_i]}#{fperm[$3.to_i]}#{fperm[$4.to_i]}",
80
+ :otype => $5,
81
+ :ohash => $6,
82
+ :fsize => fsize($7, 2),
83
+ :fname => $8
84
+ }
85
+ end
86
+ tree
23
87
  else
24
- name
88
+ nil
25
89
  end
26
90
  end
27
91
 
28
- def path_to(name, *args)
29
- project_path_to(git_dir(name), *args)
92
+ private
93
+
94
+ def repository_path(name)
95
+ bare = name =~ /\w\.git/ ? name : %W[#{name} .git]
96
+ check_path(path_to(*bare))
97
+ end
98
+
99
+ def check_path(path)
100
+ path && !path.empty? && File.ftype(path) && path
30
101
  end
31
102
 
32
- def read_file(dirname, *file)
33
- File.read(path_to(dirname, *file))
103
+ def chdir(&block)
104
+ Dir.chdir(@repository || @project_root, &block)
34
105
  end
35
106
 
36
- def chdir(dirname, &block)
37
- Dir.chdir(path_to(dirname), &block)
107
+ def ftype
108
+ { "120" => "l", "100" => "-", "040" => "d" }
38
109
  end
39
110
 
40
- def git_cli(command, *args)
41
- %Q[#{settings.git_path} #{args.unshift(command.to_s.gsub("_","-")).compact.join(" ")}]
111
+ def fperm
112
+ [ "---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx" ]
42
113
  end
43
114
 
44
- def git_run(command, *args)
45
- %x[#{git_cli command, *args}]
115
+ def fsize(str, scale = 1)
116
+ units = [ :b, :kb, :mb, :gb, :tb ]
117
+ value = str.to_f
118
+ size = 0.0
119
+ units.each_index do |i|
120
+ size = value / 1024**i
121
+ return [format("%.#{scale}f", size).to_f, units[i].to_s.upcase] if size <= 10
122
+ end
46
123
  end
47
124
 
48
125
  end
@@ -78,18 +155,18 @@ module Git
78
155
  end
79
156
 
80
157
  class Htgroup #:nodoc:
81
- require "webrick/httpauth/htgroup"
82
158
 
83
159
  def initialize(file)
160
+ require "webrick/httpauth/htgroup"
84
161
  @handler = WEBrick::HTTPAuth::Htgroup.new(file)
85
162
  yield self if block_given?
86
163
  end
87
164
  end
88
165
 
89
166
  class Htpasswd #:nodoc:
90
- require "webrick/httpauth/htpasswd"
91
167
 
92
168
  def initialize(file)
169
+ require "webrick/httpauth/htpasswd"
93
170
  @handler = WEBrick::HTTPAuth::Htpasswd.new(file)
94
171
  yield self if block_given?
95
172
  end
@@ -137,8 +214,38 @@ module Git
137
214
  end
138
215
  end
139
216
 
217
+ module GitHelpers
218
+
219
+ def git
220
+ @git ||= ProjectHandler.new(settings.project_root, settings.git_path)
221
+ end
222
+
223
+ def repository
224
+ git.repository ||= (params[:repository] || params[:captures].first)
225
+ git
226
+ end
227
+
228
+ def content_type_for_git(name, *suffixes)
229
+ content_type("application/x-git-#{name}-#{suffixes.compact.join("-")}")
230
+ end
231
+
232
+ end
233
+
234
+ class Controller < Sinatra::Base
235
+
236
+ set :project_root, "/home/git"
237
+ set :git_path, "/usr/bin/git"
238
+ set :authenticate, false
239
+
240
+ def self.configure(*envs, &block)
241
+ super(*envs, &block)
242
+ self
243
+ end
244
+ end
245
+
140
246
  # Applications
141
247
  autoload :HttpBackend, "git/webby/http_backend"
248
+ autoload :Viewer, "git/webby/viewer"
142
249
 
143
250
  end
144
251
 
@@ -1,16 +1,8 @@
1
1
  module Git::Webby
2
2
 
3
- module HttpBackendUtils #:nodoc:
3
+ module HttpBackendHelpers #:nodoc:
4
4
 
5
- include RepositoryUtils
6
-
7
- def repository
8
- params[:repository]
9
- end
10
-
11
- def content_type_for_git(name, *suffixes)
12
- content_type("application/x-git-#{name}-#{suffixes.compact.join("-")}")
13
- end
5
+ include GitHelpers
14
6
 
15
7
  def service_request?
16
8
  not params[:service].nil?
@@ -57,72 +49,68 @@ module Git::Webby
57
49
  end
58
50
 
59
51
  # get_text_file feature
60
- def read_text_file(repository, *file)
52
+ def read_text_file(*file)
61
53
  read_any_file
62
54
  header_nocache
63
55
  content_type "text/plain"
64
- read_file(repository, *file)
56
+ repository.read_file(*file)
65
57
  end
66
58
 
67
59
  # get_loose_object feature
68
- def send_loose_object(repository, hash_prefix, hash_suffix)
60
+ def send_loose_object(prefix, suffix)
69
61
  read_any_file
70
62
  header_cache_forever
71
63
  content_type_for_git :loose, :object
72
- send_file(path_to(repository, "objects", hash_prefix, hash_suffix))
64
+ send_file(repository.loose_object_path(prefix, suffix))
73
65
  end
74
66
 
75
67
  # get_pack_file and get_idx_file
76
- def send_pack_idx_file(repository, pack, idx = false)
68
+ def send_pack_idx_file(pack, idx = false)
77
69
  read_any_file
78
70
  header_cache_forever
79
71
  content_type_for_git :packed, :objects, (idx ? :toc : nil)
80
- send_file(path_to(repository, "objects", "pack", pack))
72
+ send_file(repository.pack_idx_path(pack))
81
73
  end
82
74
 
83
- def send_info_packs(repository)
75
+ def send_info_packs
84
76
  read_any_file
85
77
  header_nocache
86
78
  content_type "text/plain; charset=utf-8"
87
- send_file(path_to(repository, "objects", "info", "packs"))
79
+ send_file(repository.info_packs_path)
88
80
  end
89
81
 
90
82
  # run_service feature
91
- def run_advertisement(repository, service)
83
+ def run_advertisement(service)
92
84
  header_nocache
93
85
  content_type_for_git service, :advertisement
94
- chdir repository do
95
- response.body = ""
96
- response.body += packet_write("# service=git-#{service}\n")
97
- response.body += packet_flush
98
- response.body += git_run(service, "--stateless-rpc --advertise-refs .")
99
- response.finish
100
- end
86
+ response.body = ""
87
+ response.body += packet_write("# service=git-#{service}\n")
88
+ response.body += packet_flush
89
+ response.body += repository.run(service, "--stateless-rpc --advertise-refs .")
90
+ response.finish
101
91
  end
102
92
 
103
- def run_process(repository, service)
93
+ def run_process(service)
104
94
  content_type_for_git service, :result
105
95
  input = request.body.read
106
- command = git_cli(service, "--stateless-rpc .")
107
- chdir repository do
108
- # This source has extracted from Grack written by Scott Chacon.
109
- IO.popen(command, File::RDWR) do |pipe|
110
- pipe.write(input)
111
- while !pipe.eof?
112
- block = pipe.read(8192) # 8M at a time
113
- response.write block # steam it to the client
114
- end
115
- end # IO
116
- response.finish
117
- end
96
+ command = repository.cli(service, "--stateless-rpc #{git.repository}")
97
+ # This source has extracted from Grack written by Scott Chacon.
98
+ IO.popen(command, File::RDWR) do |pipe|
99
+ pipe.write(input)
100
+ while !pipe.eof?
101
+ block = pipe.read(8192) # 8M at a time
102
+ response.write block # steam it to the client
103
+ end
104
+ end # IO
105
+ response.finish
118
106
  end
119
107
 
120
- end # HttpBackendUtils
108
+ end # HttpBackendHelpers
121
109
 
122
110
  module HttpBackendAuthentication #:nodoc:
123
111
 
124
112
  def htpasswd
125
- @htpasswd ||= Htpasswd.new(project_path_to("htpasswd"))
113
+ @htpasswd ||= Htpasswd.new(git.path_to("htpasswd"))
126
114
  end
127
115
 
128
116
  def authentication
@@ -168,8 +156,6 @@ module Git::Webby
168
156
 
169
157
  end
170
158
 
171
- require "sinatra/base"
172
-
173
159
  # The Smart HTTP handler server. This is the main Web application which respond to following requests:
174
160
  #
175
161
  # <repo.git>/HEAD :: HEAD contents
@@ -180,62 +166,54 @@ module Git::Webby
180
166
  # <repo.git>/receive-pack :: Post a receive packets.
181
167
  #
182
168
  # See ::configure for more details.
183
- class HttpBackend < Sinatra::Base
169
+ class HttpBackend < Controller
184
170
 
185
- helpers HttpBackendUtils
171
+ helpers HttpBackendHelpers
186
172
 
187
- set :project_root, File.expand_path("#{File.dirname(__FILE__)}/git")
188
- set :git_path, "/usr/bin/git"
189
173
  set :get_any_file, true
190
174
  set :upload_pack, true
191
175
  set :receive_pack, false
192
- set :authenticate, false
193
-
194
- def self.configure(*envs, &block)
195
- super(*envs, &block)
196
- self
197
- end
198
176
 
199
177
  before do
200
178
  authenticate! if settings.authenticate
201
179
  end
202
180
 
203
181
  # implements the get_text_file function
204
- get "/:repository/HEAD" do |repository|
205
- read_text_file(repository, "HEAD")
182
+ get "/:repository/HEAD" do
183
+ read_text_file("HEAD")
206
184
  end
207
185
 
208
186
  # implements the get_info_refs function
209
- get "/:repository/info/refs" do |repository|
187
+ get "/:repository/info/refs" do
210
188
  if service_request? # by URL query parameters
211
- run_advertisement repository, service
189
+ run_advertisement service
212
190
  else
213
- read_text_file(repository, :info, :refs)
191
+ read_text_file(:info, :refs)
214
192
  end
215
193
  end
216
194
 
217
195
  # implements the get_text_file and get_info_packs functions
218
196
  get %r{/(.*?)/objects/info/(packs|alternates|http-alternates)$} do |repository, file|
219
197
  if file == "packs"
220
- send_info_packs(repository)
198
+ send_info_packs
221
199
  else
222
- read_text_file(repository, :objects, :info, file)
200
+ read_text_file(:objects, :info, file)
223
201
  end
224
202
  end
225
203
 
226
204
  # implements the get_loose_object function
227
205
  get %r{/(.*?)/objects/([0-9a-f]{2})/([0-9a-f]{38})$} do |repository, prefix, suffix|
228
- send_loose_object(repository, prefix, suffix)
206
+ send_loose_object(prefix, suffix)
229
207
  end
230
208
 
231
209
  # implements the get_pack_file and get_idx_file functions
232
210
  get %r{/(.*?)/objects/pack/(pack-[0-9a-f]{40}.(pack|idx))$} do |repository, pack, ext|
233
- send_pack_idx_file(repository, pack, ext == "idx")
211
+ send_pack_idx_file(pack, ext == "idx")
234
212
  end
235
213
 
236
214
  # implements the service_rpc function
237
- post "/:repository/:service" do |repository, rpc|
238
- run_process repository, service
215
+ post "/:repository/:service" do
216
+ run_process service
239
217
  end
240
218
 
241
219
  private
@@ -2,8 +2,8 @@
2
2
  # Semantic Versioning Specification (see reference[http://semver.org/]).
3
3
  module Git::Webby #:nodoc:
4
4
 
5
- VERSION = "0.1.0"
6
- RELEASE = "2011-07-13"
5
+ VERSION = "0.2.0"
6
+ RELEASE = "2011-07-16"
7
7
  TIMESTAMP = "2011-07-05 12:32:36 -04:00"
8
8
 
9
9
  def self.info
@@ -0,0 +1,30 @@
1
+ module Git::Webby
2
+
3
+ module ViewerHelpers
4
+
5
+ include GitHelpers
6
+
7
+ end
8
+
9
+ class Viewer < Controller
10
+
11
+ require "json"
12
+
13
+ helpers ViewerHelpers
14
+
15
+ set :project_root, File.expand_path("#{File.dirname(__FILE__)}/git")
16
+
17
+ mime_type :json, "application/json"
18
+
19
+ get %r{/(.*?)/(.*?/{0,1}.*)$} do |name, path|
20
+ content_type :json
21
+ path = path.split("/")
22
+ ref = path.shift
23
+ tree = repository.tree(ref, path.join("/"))
24
+ tree.to_json(:max_nesting => tree.size*6)
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
@@ -0,0 +1,2 @@
1
+ x��M� F]s���
2
+ �][npp֪֝�z���!5���$ʘ���jR�
@@ -1 +1 @@
1
- 5e54a0767e0c380f3baab17938d68c7f464cf171
1
+ 0deed0a56fa8f5f2a788d58b3ea235afd547b828
@@ -0,0 +1,51 @@
1
+ require "test/unit"
2
+ require "test/helpers"
3
+ require "git/webby"
4
+
5
+ class ProjectHandlerTest < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @git = Git::Webby::ProjectHandler.new(fixtures, "/usr/bin/git")
9
+ @objects = [
10
+ "HEAD",
11
+ "info/refs",
12
+ "objects/info/packs",
13
+ "objects/02/83eb96425444e17b97182e1ba9f216cc67c132",
14
+ "objects/03/9927042df267a1bc606fc4485b7a79b6a9e3cd",
15
+ "objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904",
16
+ "objects/5e/54a0767e0c380f3baab17938d68c7f464cf171",
17
+ "objects/71/6e9568eed27d5ee4378b3ecf6dd095a547bde9",
18
+ "objects/be/118435b9d908fd4a689cd8b0cc98059911a31a",
19
+ "objects/db/aefcb5bde664671c73b99515c386dcbc7f22b6",
20
+ "objects/eb/669b878d2013ac70aa5dee75e6357ea81d16ea",
21
+ "objects/ed/10cfcf72862e140c97fe899cba2a55f4cb4c20",
22
+ "objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.idx",
23
+ "objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.pack"
24
+ ]
25
+ @git.repository = "mycode.git"
26
+ end
27
+
28
+ should "check basic attributes" do
29
+ assert_equal fixtures, @git.project_root
30
+ assert_equal "/usr/bin/git", @git.path
31
+ end
32
+
33
+ should "config repository path" do
34
+ assert_equal fixtures("mycode.git"), @git.repository
35
+ end
36
+
37
+ should "find repository objects" do
38
+ @objects.each do |object|
39
+ assert_equal fixtures("mycode.git", object), @git.path_to(object)
40
+ assert File.exist?(@git.path_to(object))
41
+ end
42
+ end
43
+
44
+ should "list tree files" do
45
+ assert_equal 3, @git.tree.size
46
+ assert_equal "README.txt", @git.tree[1][:fname]
47
+ assert_equal "lib", @git.tree.last[:fname]
48
+ assert_equal "mycode.rb", @git.tree("HEAD", "lib").first[:fname]
49
+ end
50
+
51
+ end
@@ -0,0 +1,46 @@
1
+ require "test/unit"
2
+ require "test/helpers"
3
+ require "rack"
4
+ require "rack/test"
5
+ require "git/webby"
6
+ require "json"
7
+
8
+ class ViewerTest < Test::Unit::TestCase
9
+ include Rack::Test::Methods
10
+
11
+ def setup
12
+ end
13
+
14
+ def app
15
+ @app = Git::Webby::Viewer.configure do |server|
16
+ server.project_root = fixtures
17
+ end
18
+ @app
19
+ end
20
+
21
+ should "get tree of project from reference" do
22
+ get "/mycode.git/HEAD" do
23
+ assert_equal 200, response.status, request.env["sinatra.error"]
24
+ assert_equal "application/json", response.content_type
25
+ assert_match "README.txt", response.body
26
+ assert_equal 3, JSON.parse(response.body).size
27
+ end
28
+ end
29
+
30
+ should "get tree of project from reference and path" do
31
+ get "/mycode.git/HEAD/lib" do
32
+ assert_equal 200, response.status, request.env["sinatra.error"]
33
+ assert_equal "application/json", response.content_type
34
+ assert_match "mycode.rb", response.body
35
+ assert_equal "mycode.rb", JSON.parse(response.body).first["fname"]
36
+ assert_equal 1, JSON.parse(response.body).size
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ alias request last_request
43
+
44
+ alias response last_response
45
+
46
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-webby
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Hallison Batista
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-13 00:00:00 -04:00
18
+ date: 2011-07-16 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -49,10 +49,12 @@ files:
49
49
  - README.rdoc
50
50
  - Rakefile
51
51
  - doc/releases/v0.1.0.rdoc
52
+ - doc/releases/v0.2.0.rdoc
52
53
  - git-webby.gemspec
53
54
  - lib/git/webby.rb
54
55
  - lib/git/webby/http_backend.rb
55
56
  - lib/git/webby/version.rb
57
+ - lib/git/webby/viewer.rb
56
58
  - test/config_test.rb
57
59
  - test/fixtures/config.yml
58
60
  - test/fixtures/htpasswd
@@ -73,13 +75,17 @@ files:
73
75
  - test/fixtures/mycode.git/info/refs
74
76
  - test/fixtures/mycode.git/objects/02/83eb96425444e17b97182e1ba9f216cc67c132
75
77
  - test/fixtures/mycode.git/objects/03/9927042df267a1bc606fc4485b7a79b6a9e3cd
78
+ - test/fixtures/mycode.git/objects/0d/eed0a56fa8f5f2a788d58b3ea235afd547b828
76
79
  - test/fixtures/mycode.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
77
80
  - test/fixtures/mycode.git/objects/5e/54a0767e0c380f3baab17938d68c7f464cf171
81
+ - test/fixtures/mycode.git/objects/63/9b96262e7e19ca2169575e797b234098b8a72e
78
82
  - test/fixtures/mycode.git/objects/71/6e9568eed27d5ee4378b3ecf6dd095a547bde9
83
+ - test/fixtures/mycode.git/objects/b6/f3f0fabeaaaaf2db22b8ef98f59115baec7ef9
79
84
  - test/fixtures/mycode.git/objects/be/118435b9d908fd4a689cd8b0cc98059911a31a
80
85
  - test/fixtures/mycode.git/objects/db/aefcb5bde664671c73b99515c386dcbc7f22b6
81
86
  - test/fixtures/mycode.git/objects/eb/669b878d2013ac70aa5dee75e6357ea81d16ea
82
87
  - test/fixtures/mycode.git/objects/ed/10cfcf72862e140c97fe899cba2a55f4cb4c20
88
+ - test/fixtures/mycode.git/objects/ed/1c3a255ab3fce056dc31cd82df9f61a4d9fa22
83
89
  - test/fixtures/mycode.git/objects/info/packs
84
90
  - test/fixtures/mycode.git/objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.idx
85
91
  - test/fixtures/mycode.git/objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.pack
@@ -90,13 +96,15 @@ files:
90
96
  - test/htpasswd_test.rb
91
97
  - test/http_backend_authentication_test.rb
92
98
  - test/http_backend_test.rb
99
+ - test/project_handler_test.rb
100
+ - test/viewer_test.rb
93
101
  has_rdoc: true
94
102
  homepage: http://github.com/codigorama/git-webby
95
103
  licenses: []
96
104
 
97
105
  post_install_message: |
98
106
  ------------------------------------------------------------------------------
99
- Git::Webby v0.1.0
107
+ Git::Webby v0.2.0
100
108
 
101
109
  Thanks for use Git::Webby.
102
110
  ------------------------------------------------------------------------------