lenary-ginatra 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.gitattributes +2 -0
  2. data/.gitignore +13 -0
  3. data/.gitmodules +3 -0
  4. data/README.md +127 -0
  5. data/Rakefile +86 -0
  6. data/TODO.md +10 -0
  7. data/VERSION +1 -0
  8. data/bin/ginatra +60 -0
  9. data/bin/ginatra-daemon +81 -0
  10. data/bin/ginatra-directory +60 -0
  11. data/bin/ginatra-server +28 -0
  12. data/config.ru +7 -0
  13. data/features/pages.feature +33 -0
  14. data/features/step_definitions/page_steps.rb +36 -0
  15. data/features/support/env.rb +12 -0
  16. data/ginatra.gemspec +120 -0
  17. data/lib/ginatra.rb +185 -0
  18. data/lib/ginatra/config.rb +55 -0
  19. data/lib/ginatra/helpers.rb +112 -0
  20. data/lib/ginatra/repo.rb +50 -0
  21. data/lib/ginatra/repo_list.rb +53 -0
  22. data/lib/sinatra/partials.rb +17 -0
  23. data/public/favicon.ico +0 -0
  24. data/rackup.ru +7 -0
  25. data/repos/README.md +8 -0
  26. data/spec/repo_list_spec.rb +22 -0
  27. data/spec/repo_spec.rb +58 -0
  28. data/spec/spec_helper.rb +30 -0
  29. data/vendor/vegas/History.txt +18 -0
  30. data/vendor/vegas/LICENSE +22 -0
  31. data/vendor/vegas/Manifest.txt +5 -0
  32. data/vendor/vegas/README.rdoc +45 -0
  33. data/vendor/vegas/Rakefile +32 -0
  34. data/vendor/vegas/lib/vegas.rb +16 -0
  35. data/vendor/vegas/lib/vegas/runner.rb +270 -0
  36. data/vendor/vegas/test/test_app/bin/test_app +9 -0
  37. data/vendor/vegas/test/test_app/test_app.rb +10 -0
  38. data/vendor/vegas/test/test_apps.rb +22 -0
  39. data/vendor/vegas/test/test_helper.rb +59 -0
  40. data/vendor/vegas/test/test_vegas_runner.rb +8 -0
  41. data/vendor/vegas/vegas.gemspec +45 -0
  42. data/views/_actor_box.erb +13 -0
  43. data/views/_commit_info_box.erb +27 -0
  44. data/views/_header.erb +6 -0
  45. data/views/_tree_part.erb +11 -0
  46. data/views/atom.builder +32 -0
  47. data/views/blob.erb +9 -0
  48. data/views/commit.erb +20 -0
  49. data/views/index.erb +12 -0
  50. data/views/layout.erb +35 -0
  51. data/views/log.erb +64 -0
  52. data/views/tree.erb +24 -0
  53. metadata +158 -0
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ current_path = File.expand_path(File.dirname(__FILE__))
4
+
5
+ require "#{current_path}/../lib/ginatra"
6
+ require "#{current_path}/../vendor/vegas/lib/vegas"
7
+ Vegas::Runner.new(Ginatra::App, 'ginatra-server', :port => Ginatra::Config.port) do |runner, opts, app|
8
+
9
+ opts.banner = "Usage: ginatra-server [[options] start | stop | status]"
10
+
11
+ opts.separator " start - Start the Ginatra HTTP Server"
12
+ opts.separator " stop - Stop the Ginatra Server"
13
+ opts.separator " status - How's your Ginatra Server holding up?"
14
+
15
+ if ARGV[-1] == "start"
16
+ elsif ARGV[-1] == "stop"
17
+ runner.kill!
18
+ exit
19
+ elsif ARGV[-1] == "status"
20
+ runner.status
21
+ exit!
22
+ elsif ARGV.length == 0 || ARGV[-1] !~ /^(start|stop|status)$/
23
+ runner.options[:start] = false
24
+ at_exit { puts opts }
25
+ end
26
+
27
+ end
28
+
data/config.ru ADDED
@@ -0,0 +1,7 @@
1
+ current_path = File.expand_path(File.dirname(__FILE__))
2
+
3
+ require "#{current_path}/lib/ginatra"
4
+
5
+ map '/' do
6
+ run Ginatra::App
7
+ end
@@ -0,0 +1,33 @@
1
+ Feature: Page
2
+ In order to use multiple repositories
3
+ As a browser
4
+ I want to see the home page
5
+
6
+ Scenario:
7
+ When I open '/'
8
+ Then I should see "Ginatra"
9
+ And I should see "View My Git Repositories"
10
+ And I should see "test"
11
+ And I should see "description file for this repository and set the description for it."
12
+ Scenario:
13
+ When I open '/test'
14
+ Then I should see "Ginatra"
15
+ And I should see "test"
16
+ And I should see "description file for this repository and set the description for it."
17
+ And I should see "Commits"
18
+ And I should see "(author)"
19
+ Scenario:
20
+ When I open '/test/commit/eefb4c3'
21
+ Then I should see "Ginatra"
22
+ And I should see "test"
23
+ And I should see "description file for this repository and set the description for it."
24
+ And I should see "Commit: eefb4c3"
25
+ And I should see "doh, thanks lenary for reminding me of the files i'd forgotten"
26
+ Scenario:
27
+ When I open '/test/tree/24f701fd'
28
+ Then I should see "Ginatra"
29
+ And I should see "test"
30
+ And I should see "description file for this repository and set the description for it."
31
+ And I should see "Tree: 24f701fd"
32
+ And I should see "README.md"
33
+ And I should see ".gitignore"
@@ -0,0 +1,36 @@
1
+ Given /^I am on '([^\']*)'$/ do |path|
2
+ get path
3
+ end
4
+
5
+ When /^I open '([^\']*)'$/ do |path|
6
+ get path
7
+ end
8
+
9
+ When /^I press "([^\"]*)"$/ do |button|
10
+ click_button(button)
11
+ end
12
+
13
+ When /^I follow "([^\"]*)"$/ do |link|
14
+ click_link(link)
15
+ end
16
+
17
+ When /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
18
+ fill_in(field, :with => value)
19
+ end
20
+
21
+ Then /^I should see "([^\"]*)"$/ do |text|
22
+ last_response.should contain(text)
23
+ end
24
+
25
+ Then /^I should not see "([^\"]*)"$/ do |text|
26
+ last_response.should_not contain(text)
27
+ end
28
+
29
+ Then /^I should be on (.+)$/ do |page_name|
30
+ URI.parse(current_url).path.should == path_to(page_name)
31
+ end
32
+
33
+ Then /^Save and View$/ do
34
+ save_and_open_page
35
+ end
36
+
@@ -0,0 +1,12 @@
1
+ current_path = File.expand_path(File.dirname(__FILE__))
2
+ require "#{current_path}/../../spec/spec_helper"
3
+
4
+ World do
5
+ def app
6
+ Ginatra::App
7
+ end
8
+ include Rack::Test::Methods
9
+ include Webrat::Methods
10
+ include Webrat::Matchers
11
+ end
12
+
data/ginatra.gemspec ADDED
@@ -0,0 +1,120 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{ginatra}
8
+ s.version = "2.0.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Sam Elliott", "Ryan Bigg"]
12
+ s.date = %q{2009-08-26}
13
+ s.description = %q{Host your own git repository browser through the power of Sinatra and Grit}
14
+ s.email = %q{sam@lenary.co.uk}
15
+ s.executables = ["ginatra", "ginatra-daemon", "ginatra-directory", "ginatra-server"]
16
+ s.extra_rdoc_files = [
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".gitattributes",
21
+ ".gitignore",
22
+ ".gitmodules",
23
+ "README.md",
24
+ "Rakefile",
25
+ "TODO.md",
26
+ "VERSION",
27
+ "bin/ginatra",
28
+ "bin/ginatra-daemon",
29
+ "bin/ginatra-directory",
30
+ "bin/ginatra-server",
31
+ "config.ru",
32
+ "features/pages.feature",
33
+ "features/step_definitions/page_steps.rb",
34
+ "features/support/env.rb",
35
+ "ginatra.gemspec",
36
+ "lib/ginatra.rb",
37
+ "lib/ginatra/config.rb",
38
+ "lib/ginatra/helpers.rb",
39
+ "lib/ginatra/repo.rb",
40
+ "lib/ginatra/repo_list.rb",
41
+ "lib/sinatra/partials.rb",
42
+ "public/favicon.ico",
43
+ "public/img/add.png",
44
+ "public/img/diff.png",
45
+ "public/img/doc.png",
46
+ "public/img/rm.png",
47
+ "public/img/tree.png",
48
+ "public/src/blank.gif",
49
+ "public/src/colour.css",
50
+ "public/src/commit.css",
51
+ "public/src/default.css",
52
+ "public/src/ginatra.js",
53
+ "public/src/highlight.pack.js",
54
+ "public/src/iepngfix.htc",
55
+ "public/src/index.css",
56
+ "public/src/jquery-1.3.2.min.js",
57
+ "public/src/lists.css",
58
+ "public/src/reset.css",
59
+ "public/src/table.css",
60
+ "public/src/type.css",
61
+ "rackup.ru",
62
+ "repos/README.md",
63
+ "spec/repo_list_spec.rb",
64
+ "spec/repo_spec.rb",
65
+ "spec/spec_helper.rb",
66
+ "vendor/vegas/History.txt",
67
+ "vendor/vegas/LICENSE",
68
+ "vendor/vegas/Manifest.txt",
69
+ "vendor/vegas/README.rdoc",
70
+ "vendor/vegas/Rakefile",
71
+ "vendor/vegas/lib/vegas.rb",
72
+ "vendor/vegas/lib/vegas/runner.rb",
73
+ "vendor/vegas/test/test_app/bin/test_app",
74
+ "vendor/vegas/test/test_app/test_app.rb",
75
+ "vendor/vegas/test/test_apps.rb",
76
+ "vendor/vegas/test/test_helper.rb",
77
+ "vendor/vegas/test/test_vegas_runner.rb",
78
+ "vendor/vegas/vegas.gemspec",
79
+ "views/_actor_box.erb",
80
+ "views/_commit_info_box.erb",
81
+ "views/_header.erb",
82
+ "views/_tree_part.erb",
83
+ "views/atom.builder",
84
+ "views/blob.erb",
85
+ "views/commit.erb",
86
+ "views/index.erb",
87
+ "views/layout.erb",
88
+ "views/log.erb",
89
+ "views/tree.erb"
90
+ ]
91
+ s.homepage = %q{http://lenary.github.com/ginatra}
92
+ s.rdoc_options = ["--charset=UTF-8"]
93
+ s.require_paths = ["lib"]
94
+ s.rubygems_version = %q{1.3.4}
95
+ s.summary = %q{A Gitweb Clone in Sinatra and Grit}
96
+ s.test_files = [
97
+ "spec/repo_list_spec.rb",
98
+ "spec/repo_spec.rb",
99
+ "spec/spec_helper.rb"
100
+ ]
101
+
102
+ if s.respond_to? :specification_version then
103
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
104
+ s.specification_version = 3
105
+
106
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
107
+ s.add_runtime_dependency(%q<sinatra>, [">= 0.9.4"])
108
+ s.add_runtime_dependency(%q<grit>, [">= 1.1.1"])
109
+ s.add_runtime_dependency(%q<coderay>, [">= 0.8.0"])
110
+ else
111
+ s.add_dependency(%q<sinatra>, [">= 0.9.4"])
112
+ s.add_dependency(%q<grit>, [">= 1.1.1"])
113
+ s.add_dependency(%q<coderay>, [">= 0.8.0"])
114
+ end
115
+ else
116
+ s.add_dependency(%q<sinatra>, [">= 0.9.4"])
117
+ s.add_dependency(%q<grit>, [">= 1.1.1"])
118
+ s.add_dependency(%q<coderay>, [">= 0.8.0"])
119
+ end
120
+ end
data/lib/ginatra.rb ADDED
@@ -0,0 +1,185 @@
1
+ require 'sinatra/base'
2
+ require 'grit'
3
+ require 'coderay'
4
+
5
+ current_path = File.expand_path(File.dirname(__FILE__))
6
+
7
+ module Ginatra; end
8
+
9
+ # Loading in reverse because RepoList needs to be loaded before MultiRepoList
10
+ Dir.glob("#{current_path}/ginatra/*.rb").reverse.each { |f| require f }
11
+
12
+ require "#{current_path}/sinatra/partials"
13
+
14
+ # Written myself. i know, what the hell?!
15
+ module Ginatra
16
+
17
+ class Error < StandardError; end
18
+ class CommitsError < Error; end
19
+
20
+ class InvalidCommit < Error
21
+ def initialize(id)
22
+ super("Could not find a commit with the id of #{id}")
23
+ end
24
+ end
25
+
26
+ current_path = File.expand_path(File.dirname(__FILE__))
27
+ VERSION = File.new("#{current_path}/../VERSION").read
28
+
29
+ class App < Sinatra::Base
30
+
31
+ configure do
32
+ current_path = File.expand_path(File.dirname(__FILE__))
33
+ Config.load!
34
+ set :port, Ginatra::Config[:port]
35
+ set :raise_errors, Proc.new { test? }
36
+ set :show_exceptions, Proc.new { development? }
37
+ set :dump_errors, true
38
+ set :logging, Proc.new { !test? }
39
+ set :static, true
40
+ set :public, "#{current_path}/../public"
41
+ set :views, "#{current_path}/../views"
42
+ end
43
+
44
+ helpers do
45
+ include Helpers
46
+ include ::Sinatra::Partials
47
+ end
48
+
49
+ error CommitsError do
50
+ 'No commits were returned for ' + request.uri
51
+ end
52
+
53
+ get '/' do
54
+ erb :index
55
+ end
56
+
57
+ get '/:repo.atom' do
58
+ @repo = RepoList.find(params[:repo])
59
+ @commits = @repo.commits
60
+ return "" if @commits.empty?
61
+ etag(@commits.first.id)
62
+ builder :atom, :layout => nil
63
+ end
64
+
65
+ get '/:repo' do
66
+ @repo = RepoList.find(params[:repo])
67
+ @commits = @repo.commits
68
+ etag(@commits.first.id)
69
+ erb :log
70
+ end
71
+
72
+ get '/:repo/:ref.atom' do
73
+ @repo = RepoList.find(params[:repo])
74
+ @commits = @repo.commits(params[:ref])
75
+ return "" if @commits.empty?
76
+ etag(@commits.first.id)
77
+ builder :atom, :layout => nil
78
+ end
79
+
80
+ get '/:repo/:ref' do
81
+ params[:page] = 1
82
+ @repo = RepoList.find(params[:repo])
83
+ @commits = @repo.commits(params[:ref])
84
+ etag(@commits.first.id)
85
+ erb :log
86
+ end
87
+
88
+ get '/:repo/commit/:commit.patch' do
89
+ response['Content-Type'] = "text/plain"
90
+ @repo = RepoList.find(params[:repo])
91
+ @repo.git.format_patch({}, "--stdout", "-1", params[:commit])
92
+ end
93
+
94
+ get '/:repo/commit/:commit' do
95
+ @repo = RepoList.find(params[:repo])
96
+ @commit = @repo.commit(params[:commit]) # can also be a ref
97
+ etag(@commit.id)
98
+ erb(:commit)
99
+ end
100
+
101
+ get '/:repo/archive/:tree.tar.gz' do
102
+ response['Content-Type'] = "application/x-tar-gz"
103
+ @repo = RepoList.find(params[:repo])
104
+ @repo.archive_tar_gz(params[:tree])
105
+ end
106
+
107
+ get '/:repo/tree/:tree' do
108
+ @repo = RepoList.find(params[:repo])
109
+
110
+ if (tag = @repo.git.method_missing('rev_parse', {}, '--verify', "#{params[:tree]}^{tree}")).empty?
111
+ # we don't have a tree.
112
+ not_found
113
+ else
114
+ etag(tag)
115
+ end
116
+
117
+ @tree = @repo.tree(params[:tree]) # can also be a ref (i think)
118
+ @path = {}
119
+ @path[:tree] = "/#{params[:repo]}/tree/#{params[:tree]}"
120
+ @path[:blob] = "/#{params[:repo]}/blob/#{params[:tree]}"
121
+ erb(:tree)
122
+ end
123
+
124
+ get '/:repo/tree/:tree/*' do # for when we specify a path
125
+ @repo = RepoList.find(params[:repo])
126
+ @tree = @repo.tree(params[:tree])/params[:splat].first # can also be a ref (i think)
127
+ if @tree.is_a?(Grit::Blob)
128
+ # we need @tree to be a tree. if it's a blob, send it to the blob page
129
+ # this allows people to put in the remaining part of the path to the file, rather than endless clicks like you need in github
130
+ redirect "/#{params[:repo]}/blob/#{params[:tree]}/#{params[:splat].first}"
131
+ else
132
+ etag(@tree.id)
133
+ @path = {}
134
+ @path[:tree] = "/#{params[:repo]}/tree/#{params[:tree]}/#{params[:splat].first}"
135
+ @path[:blob] = "/#{params[:repo]}/blob/#{params[:tree]}/#{params[:splat].first}"
136
+ erb(:tree)
137
+ end
138
+ end
139
+
140
+ get '/:repo/blob/:blob' do
141
+ @repo = RepoList.find(params[:repo])
142
+ @blob = @repo.blob(params[:blob])
143
+ etag(@blob.id)
144
+ erb(:blob)
145
+ end
146
+
147
+ get '/:repo/blob/:tree/*' do
148
+ @repo = RepoList.find(params[:repo])
149
+ @blob = @repo.tree(params[:tree])/params[:splat].first
150
+ if @blob.is_a?(Grit::Tree)
151
+ # as above, we need @blob to be a blob. if it's a tree, send it to the tree page
152
+ # this allows people to put in the remaining part of the path to the folder, rather than endless clicks like you need in github
153
+ redirect "/#{params[:repo]}/tree/#{params[:tree]}/#{params[:splat].first}"
154
+ else
155
+ etag(@blob.id)
156
+ extension = params[:splat].first.split(".").last
157
+ @highlighter = case extension
158
+ when 'js'
159
+ 'javascript'
160
+ when 'css'
161
+ 'css'
162
+ end
163
+
164
+ @highlighter ||= 'ruby'
165
+
166
+ erb(:blob)
167
+ end
168
+ end
169
+
170
+ get '/:repo/:ref/:page' do
171
+ pass unless params[:page] =~ /^(\d)+$/
172
+ params[:page] = params[:page].to_i
173
+ @repo = RepoList.find(params[:repo])
174
+ @commits = @repo.commits(params[:ref], 10, (params[:page] - 1) * 10)
175
+ @next_commits = !@repo.commits(params[:ref], 10, params[:page] * 10).empty?
176
+ if params[:page] - 1 > 0
177
+ @previous_commits = !@repo.commits(params[:ref], 10, (params[:page] - 1) * 10).empty?
178
+ end
179
+ @separator = @next_commits && @previous_commits
180
+ erb :log
181
+ end
182
+
183
+ end # App
184
+
185
+ end # Ginatra
@@ -0,0 +1,55 @@
1
+ module Ginatra
2
+ class Config
3
+
4
+ current_path = File.expand_path("#{File.dirname(__FILE__)}")
5
+ CONFIG_PATH = File.expand_path("~/.ginatra/config.yml")
6
+ DEFAULT_CONFIG = {
7
+ :git_dirs => [File.expand_path("#{current_path}/../../repos/*")],
8
+ :ignored_files => ['README.md'],
9
+ :description => "View My Git Repositories",
10
+ :port => 9797
11
+ }
12
+
13
+ def self.setup! # Very Destructive Method. Use with care!
14
+ File.open(CONFIG_PATH, 'w') do |f|
15
+ YAML.dump(DEFAULT_CONFIG, f)
16
+ end
17
+ end
18
+
19
+ def self.load!
20
+ @config = {}
21
+ begin
22
+ @config = YAML.load_file(CONFIG_PATH)
23
+ rescue Errno::ENOENT
24
+ end
25
+ @config = DEFAULT_CONFIG.merge(@config)
26
+ end
27
+
28
+ def self.dump!
29
+ File.open(CONFIG_PATH, 'w') do |f|
30
+ YAML.dump(@config, f)
31
+ end
32
+ end
33
+
34
+ def self.method_missing(sym, *args, &block)
35
+ if @config.respond_to?(sym)
36
+ @config.send(sym, *args, &block)
37
+ elsif @config.has_key?(sym)
38
+ @config[sym]
39
+ else
40
+ super
41
+ end
42
+ end
43
+
44
+ def self.respond_to?(name)
45
+ if @config.respond_to?(name)
46
+ true
47
+ elsif @config.has_key?(name)
48
+ true
49
+ else
50
+ super
51
+ end
52
+ end
53
+
54
+ end
55
+ end