lenary-ginatra 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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