ginatra 2.0.2 → 2.1.0
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.
- data/.gitignore +3 -0
- data/README.md +51 -44
- data/VERSION +1 -1
- data/ginatra.gemspec +6 -18
- data/lib/ginatra/config.rb +41 -1
- data/lib/ginatra/helpers.rb +130 -9
- data/lib/ginatra/repo.rb +40 -4
- data/lib/ginatra/repo_list.rb +42 -1
- data/lib/ginatra.rb +93 -2
- metadata +3 -16
- data/vendor/vegas/History.txt +0 -18
- data/vendor/vegas/LICENSE +0 -22
- data/vendor/vegas/Manifest.txt +0 -5
- data/vendor/vegas/README.rdoc +0 -45
- data/vendor/vegas/Rakefile +0 -32
- data/vendor/vegas/lib/vegas/runner.rb +0 -270
- data/vendor/vegas/lib/vegas.rb +0 -16
- data/vendor/vegas/test/test_app/bin/test_app +0 -9
- data/vendor/vegas/test/test_app/test_app.rb +0 -10
- data/vendor/vegas/test/test_apps.rb +0 -22
- data/vendor/vegas/test/test_helper.rb +0 -59
- data/vendor/vegas/test/test_vegas_runner.rb +0 -8
- data/vendor/vegas/vegas.gemspec +0 -45
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -6,14 +6,18 @@ repositories out of a set of specified directories using an array of glob-based
|
|
6
6
|
paths. I have plans to make it function just as gitweb does, including leeching
|
7
7
|
config files and suchlike.
|
8
8
|
|
9
|
-
Updating to
|
10
|
-
|
9
|
+
Updating to the Most Recent Release (Gem):
|
10
|
+
------------------------------------------
|
11
11
|
|
12
|
-
-
|
13
|
-
-
|
14
|
-
|
12
|
+
- ` $ gem install ginatra`
|
13
|
+
- (re)Move `~/.ginatra`
|
14
|
+
- Run the following to open an irb with Ginatra loaded: ` $ irb -r 'rubygems' -r 'rubygems'`
|
15
|
+
- In this irb session, run the following then close it: `>> Ginatra::Config.setup!`
|
15
16
|
|
16
|
-
|
17
|
+
**BEWARE**: The last method that you just called will dump a config to `~/.ginatra/config.yml`.
|
18
|
+
This ignores anything already there, so be careful. You have been warned.
|
19
|
+
|
20
|
+
You can now copy the contents your old `~/.ginatra/` file into `~/.ginatra/config.yml`.
|
17
21
|
|
18
22
|
Installation
|
19
23
|
------------
|
@@ -23,65 +27,68 @@ You should be using Git 1.6.3 or later just to be sure that it all works:
|
|
23
27
|
$ git --version
|
24
28
|
git version 1.6.3
|
25
29
|
|
26
|
-
|
30
|
+
Next, just do the following (your setup may require sudo):
|
31
|
+
|
32
|
+
$ gem install ginatra
|
27
33
|
|
28
|
-
|
34
|
+
This pulls down all the required dependencies too.
|
29
35
|
|
30
|
-
|
36
|
+
If you want to play around with the code, you can clone the repository. This also allows you
|
37
|
+
to use a special rackup file to mount it where you wish. I am yet to sort out some of the
|
38
|
+
details of running Ginatra from a gem with a rackup.ru file.
|
31
39
|
|
32
|
-
|
40
|
+
Usage
|
41
|
+
-----
|
33
42
|
|
34
|
-
|
43
|
+
If you're just using it in development, use the following to start, check and stop Ginatra
|
44
|
+
respectively:
|
35
45
|
|
36
|
-
$
|
37
|
-
$
|
38
|
-
|
39
|
-
Then clone this repository:
|
46
|
+
$ ginatra server start
|
47
|
+
$ ginatra server status
|
48
|
+
$ ginatra server stop
|
40
49
|
|
41
|
-
|
42
|
-
|
43
|
-
You'll also need to (`--bare`) clone `atmos/hancock-client` into the repos
|
44
|
-
directory and call it test: (don't ask, it was just a repo i chose at random)
|
50
|
+
Ginatra also runs on thin, with the approach outlined above.
|
45
51
|
|
46
|
-
|
52
|
+
**BEWARE:** There are issues running Ginatra on Passenger. We discourage Ginatra's use
|
53
|
+
on Passenger until we can make it stable.
|
47
54
|
|
48
|
-
|
55
|
+
Ginatra can also start a git-daemon serving all the repositories that ginatra serves:
|
49
56
|
|
50
|
-
$
|
51
|
-
|
52
|
-
|
53
|
-
-----
|
54
|
-
|
55
|
-
If you're just using it in development, use the following to run Ginatra:
|
57
|
+
$ ginatra daemon start
|
58
|
+
$ ginatra daemon status
|
59
|
+
$ ginatra daemon stop
|
56
60
|
|
57
|
-
|
58
|
-
|
59
|
-
Ginatra also runs on thin. **BEWARE:** There are issues running Ginatra on
|
60
|
-
Passenger. We discourage Ginatra's use on Passenger until we can make it stable.
|
61
|
+
This runs on the default git daemon port.
|
61
62
|
|
62
|
-
|
63
|
-
|
63
|
+
You can add a glob specified list of git repositories for ginatra to serve using the
|
64
|
+
following commands:
|
64
65
|
|
65
|
-
$
|
66
|
-
$
|
66
|
+
$ ginatra directory add '~/Git/ginatra/*'
|
67
|
+
$ ginatra directory list
|
68
|
+
$ ginatra directory remove '~/Git/ginatra/*'
|
67
69
|
|
68
|
-
|
69
|
-
|
70
|
+
These should be fairly self explanatory. Help is shown with either the --help option
|
71
|
+
or by not specifying a sub-command like start, status, stop, add, list or remove.
|
72
|
+
|
73
|
+
|
74
|
+
Attribution
|
75
|
+
-----------
|
70
76
|
|
71
77
|
**Authors:**
|
72
78
|
|
73
79
|
- Samuel Elliott (lenary)
|
74
80
|
- Ryan Bigg (radar)
|
75
81
|
|
82
|
+
**Patches**
|
83
|
+
|
84
|
+
- James Tucker (raggi)
|
85
|
+
- Elia Schito (elia)
|
86
|
+
- Scott Wisely (Syd)
|
87
|
+
- Jonathan Stott (namelessjon)
|
88
|
+
|
76
89
|
**Thanks**
|
77
90
|
|
78
|
-
|
79
|
-
- schacon - For help with Grit
|
80
|
-
- cirwin - For moral support and design help
|
81
|
-
- irc://irc.freenode.net/git - for any other problems I had
|
82
|
-
- Picol Project (http://picol.org) - for the icons
|
83
|
-
- sr - For help with a large sinatra error
|
84
|
-
- raggi - For a refactor and several feature suggestions
|
91
|
+
Too many to name. Thanks be to you all.
|
85
92
|
|
86
93
|
Screenshots
|
87
94
|
-----------
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0
|
1
|
+
2.1.0
|
data/ginatra.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ginatra}
|
8
|
-
s.version = "2.0
|
8
|
+
s.version = "2.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Sam Elliott", "Ryan Bigg"]
|
12
|
-
s.date = %q{2009-
|
12
|
+
s.date = %q{2009-12-28}
|
13
13
|
s.description = %q{Host your own git repository browser through the power of Sinatra and Grit}
|
14
14
|
s.email = %q{sam@lenary.co.uk}
|
15
15
|
s.executables = ["ginatra", "ginatra-daemon", "ginatra-directory", "ginatra-server"]
|
@@ -63,19 +63,6 @@ Gem::Specification.new do |s|
|
|
63
63
|
"spec/repo_list_spec.rb",
|
64
64
|
"spec/repo_spec.rb",
|
65
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
66
|
"views/_actor_box.erb",
|
80
67
|
"views/_commit_info_box.erb",
|
81
68
|
"views/_header.erb",
|
@@ -91,7 +78,7 @@ Gem::Specification.new do |s|
|
|
91
78
|
s.homepage = %q{http://lenary.github.com/ginatra}
|
92
79
|
s.rdoc_options = ["--charset=UTF-8"]
|
93
80
|
s.require_paths = ["lib"]
|
94
|
-
s.rubygems_version = %q{1.3.
|
81
|
+
s.rubygems_version = %q{1.3.5}
|
95
82
|
s.summary = %q{A Gitweb Clone in Sinatra and Grit}
|
96
83
|
s.test_files = [
|
97
84
|
"spec/repo_list_spec.rb",
|
@@ -118,3 +105,4 @@ Gem::Specification.new do |s|
|
|
118
105
|
s.add_dependency(%q<coderay>, [">= 0.8.0"])
|
119
106
|
end
|
120
107
|
end
|
108
|
+
|
data/lib/ginatra/config.rb
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
module Ginatra
|
2
|
+
|
3
|
+
# A Wrapper for the ginatra configuration variables,
|
4
|
+
# including methods to load, dump and lookup keys
|
5
|
+
# using just the class.
|
2
6
|
class Config
|
3
7
|
|
4
8
|
current_path = File.expand_path("#{File.dirname(__FILE__)}")
|
9
|
+
|
10
|
+
# A default path for our configuration variables!
|
5
11
|
CONFIG_PATH = File.expand_path("~/.ginatra/config.yml")
|
12
|
+
|
13
|
+
# A default config that we fall back to if no file is found.
|
6
14
|
DEFAULT_CONFIG = {
|
7
15
|
:git_dirs => [File.expand_path("#{current_path}/../../repos/*")],
|
8
16
|
:ignored_files => ['README.md'],
|
@@ -10,12 +18,26 @@ module Ginatra
|
|
10
18
|
:port => 9797
|
11
19
|
}
|
12
20
|
|
13
|
-
|
21
|
+
# Dumps the Default configuration to +CONFIG_PATH+,
|
22
|
+
# WITHOUT regard for what's already there.
|
23
|
+
#
|
24
|
+
# Very Destructive Method. Use with care!
|
25
|
+
def self.setup!
|
14
26
|
File.open(CONFIG_PATH, 'w') do |f|
|
15
27
|
YAML.dump(DEFAULT_CONFIG, f)
|
16
28
|
end
|
17
29
|
end
|
18
30
|
|
31
|
+
unless File.exist?(CONFIG_PATH)
|
32
|
+
require 'fileutils'
|
33
|
+
FileUtils.mkdir_p(File.dirname(CONFIG_PATH))
|
34
|
+
setup!
|
35
|
+
end
|
36
|
+
|
37
|
+
# Loads the configuration and merges it with
|
38
|
+
# the default configuration.
|
39
|
+
#
|
40
|
+
# @return [Hash] config a hash of the configuration options
|
19
41
|
def self.load!
|
20
42
|
@config = {}
|
21
43
|
begin
|
@@ -25,12 +47,26 @@ module Ginatra
|
|
25
47
|
@config = DEFAULT_CONFIG.merge(@config)
|
26
48
|
end
|
27
49
|
|
50
|
+
# Dumps the _current_ configuration to +CONFIG_PATH+
|
51
|
+
# again WITHOUT regard for what's already there.
|
52
|
+
#
|
53
|
+
# Very Destructive Method. Use with care!
|
28
54
|
def self.dump!
|
29
55
|
File.open(CONFIG_PATH, 'w') do |f|
|
30
56
|
YAML.dump(@config, f)
|
31
57
|
end
|
32
58
|
end
|
33
59
|
|
60
|
+
# Allows us to do many things.
|
61
|
+
#
|
62
|
+
# The first is respond to any hash methods
|
63
|
+
# and execute them on the +@config+ hash.
|
64
|
+
#
|
65
|
+
# The second is to do something like
|
66
|
+
# +Ginatra::Config.port+ instead of something
|
67
|
+
# like +Ginatra::Config[:port]+
|
68
|
+
#
|
69
|
+
# @return depends on what's in the config hash.
|
34
70
|
def self.method_missing(sym, *args, &block)
|
35
71
|
if @config.respond_to?(sym)
|
36
72
|
@config.send(sym, *args, &block)
|
@@ -41,6 +77,10 @@ module Ginatra
|
|
41
77
|
end
|
42
78
|
end
|
43
79
|
|
80
|
+
# This is so that we can be clever by using
|
81
|
+
# +#try()+ and so that this mirrors +method_missing+.
|
82
|
+
#
|
83
|
+
# @see Ginatra::Config.method_missing
|
44
84
|
def self.respond_to?(name)
|
45
85
|
if @config.respond_to?(name)
|
46
86
|
true
|
data/lib/ginatra/helpers.rb
CHANGED
@@ -1,21 +1,48 @@
|
|
1
1
|
require "digest/md5"
|
2
2
|
|
3
3
|
module Ginatra
|
4
|
-
#
|
4
|
+
# Helpers used in the views usually,
|
5
|
+
# but not exclusively.
|
5
6
|
module Helpers
|
6
7
|
|
8
|
+
# takes an email and returns a url to a secure gravatar
|
9
|
+
#
|
10
|
+
# @param [String] email the email address
|
11
|
+
# @return [String] the url to the gravatar
|
7
12
|
def gravatar_url(email)
|
8
13
|
"https://secure.gravatar.com/avatar/#{Digest::MD5.hexdigest(email)}?s=40"
|
9
14
|
end
|
10
15
|
|
16
|
+
# reformats the date into a user friendly date with html entities
|
17
|
+
#
|
18
|
+
# @param [#strftime] date object to format nicely
|
19
|
+
# @return [String] html string formatted using
|
20
|
+
# +"%b %d, %Y – %H:%M"+
|
11
21
|
def nicetime(date)
|
12
22
|
date.strftime("%b %d, %Y – %H:%M")
|
13
23
|
end
|
14
24
|
|
25
|
+
# displays the actor box easily.
|
26
|
+
#
|
27
|
+
# Internally, it calls the +#partial+ method
|
28
|
+
# @see Sinatra::Partials#partial
|
29
|
+
#
|
30
|
+
# @param [Grit::Actor] actor the Grit Actor Object
|
31
|
+
# @param [#to_s] role the role that the object has.
|
32
|
+
# @param [#strftime] date the date that the actor acted on.
|
33
|
+
#
|
34
|
+
# @return [String] a string that contains the box for the actor.
|
15
35
|
def actor_box(actor, role, date)
|
16
36
|
partial(:actor_box, :locals => { :actor => actor, :role => role, :date => date })
|
17
37
|
end
|
18
38
|
|
39
|
+
# works out what actor boxes need to be displayed.
|
40
|
+
#
|
41
|
+
# Will always display the committer box, and will only display
|
42
|
+
# the author box if it's different to the committer
|
43
|
+
#
|
44
|
+
# @param [Grit::Commit] commit the commit in question
|
45
|
+
# @return [String] a string representing the HTML actor boxes
|
19
46
|
def actor_boxes(commit)
|
20
47
|
o = actor_box(commit.committer, :committer, commit.committed_date)
|
21
48
|
if commit.author.name != commit.committer.name
|
@@ -23,26 +50,66 @@ module Ginatra
|
|
23
50
|
end
|
24
51
|
end
|
25
52
|
|
53
|
+
# spits out a link to a certain reference.
|
54
|
+
#
|
55
|
+
# @param [Grit::Ref] ref grit ref object
|
56
|
+
# @param [String] repo_param the url-sanitised-name for the repo
|
57
|
+
# (for the link path)
|
58
|
+
#
|
59
|
+
# @return [String] HTML link to the given ref with class attached.
|
26
60
|
def commit_ref(ref, repo_param)
|
27
61
|
ref_class = ref.class.to_s.split("::")[1].to_s
|
28
62
|
"<a class=\"ref #{ref_class}\" href=\"/#{repo_param}/#{ref.name}\">#{ref.name}</a>"
|
29
63
|
end
|
30
64
|
|
65
|
+
# calls +Ginatra::Helpers#commit_ref+ for each ref in the commit
|
66
|
+
#
|
67
|
+
# @see Ginatra::Helpers#commit_ref
|
68
|
+
#
|
69
|
+
# @param [Grit::Commit] commit grit commit object
|
70
|
+
# @param [String] repo_param the url-sanitised-name for the repo
|
71
|
+
# (for the link path)
|
72
|
+
#
|
73
|
+
# @return [String] HTML containing all the ref links
|
31
74
|
def commit_refs(commit, repo_param)
|
32
75
|
commit.refs.map{ |r| commit_ref(r, repo_param) }.join("\n")
|
33
76
|
end
|
34
77
|
|
78
|
+
# returns a string including the link to download a certain
|
79
|
+
# tree of the repo
|
80
|
+
#
|
81
|
+
# @param [Grit::Tree] tree the tree you want an archive link for
|
82
|
+
# @param [String] repo_param the url-sanitised-name of the repo
|
83
|
+
# (for the link path)
|
84
|
+
#
|
85
|
+
# @return [String] the HTML link to the archive.
|
35
86
|
def archive_link(tree, repo_param)
|
36
87
|
"<a class=\"download\" href=\"/#{repo_param}/archive/#{tree.id}.tar.gz\" title=\"Download a tar.gz snapshot of this Tree\">Download Archive</a>"
|
37
88
|
end
|
38
89
|
|
90
|
+
# returns a string including the link to download a patch for a certain
|
91
|
+
# commit to the repo
|
92
|
+
#
|
93
|
+
# @param [Grit::Commit] commit the commit you want a patch for
|
94
|
+
# @param [String] repo_param the url-sanitised name for the repo
|
95
|
+
# (for the link path)
|
96
|
+
#
|
97
|
+
# @return [String] the HTML link to the patch
|
39
98
|
def patch_link(commit, repo_param)
|
40
99
|
"<a class=\"download\" href=\"/#{repo_param}/commit/#{commit.id}.patch\" title=\"Download a patch file of this Commit\">Download Patch</a>"
|
41
100
|
end
|
42
101
|
|
43
|
-
#
|
44
|
-
#
|
102
|
+
# returns a HTML (+<ul>+) list of the files altered in a given commit.
|
103
|
+
#
|
104
|
+
# It includes classes for added/altered/deleted and also anchor links
|
105
|
+
# to the diffs for further down the page.
|
106
|
+
#
|
107
|
+
# @param [Grit::Commit] commit the commit you want the list of files for
|
108
|
+
#
|
109
|
+
# @return [String] a +<ul>+ with lots of +<li>+ children.
|
45
110
|
def file_listing(commit)
|
111
|
+
# The only reason this doesn't work 100% of the time is because grit doesn't :/
|
112
|
+
# if i find a fix, it'll go upstream :D
|
46
113
|
count = 0
|
47
114
|
out = commit.diffs.map do |diff|
|
48
115
|
count = count + 1
|
@@ -55,14 +122,25 @@ module Ginatra
|
|
55
122
|
end
|
56
123
|
"<ul id='files'>#{out.join}</ul>"
|
57
124
|
end
|
58
|
-
|
125
|
+
|
126
|
+
# returns some html containing the Coderay'd diff files.
|
127
|
+
#
|
128
|
+
# @param [String] diff the diff you want highlighted
|
129
|
+
# @return [String] the highlighted diff
|
59
130
|
def diff(diff)
|
60
131
|
diff = CodeRay.scan(diff, :diff).div(:line_numbers => :table, :css => :class)
|
61
132
|
end
|
62
133
|
|
134
|
+
# Formats the text to remove multiple spaces and newlines, and then inserts
|
135
|
+
# HTML linebreaks.
|
136
|
+
#
|
63
137
|
# Stolen from rails: ActionView::Helpers::TextHelper#simple_format
|
64
|
-
#
|
65
|
-
#
|
138
|
+
# and simplified to just use <p> tags without any options, then modified
|
139
|
+
# more later.
|
140
|
+
#
|
141
|
+
# @param [String] text the text you want formatted
|
142
|
+
#
|
143
|
+
# @return [String] the formatted text
|
66
144
|
def simple_format(text)
|
67
145
|
text.gsub!(/ +/, " ")
|
68
146
|
text.gsub!(/\r\n?/, "\n")
|
@@ -70,9 +148,27 @@ module Ginatra
|
|
70
148
|
text
|
71
149
|
end
|
72
150
|
|
151
|
+
# Cleans up the particularly volatile parts of HTML
|
152
|
+
# and replaces them with their entities. Replaces the following
|
153
|
+
# characters:
|
154
|
+
# - &
|
155
|
+
# - >
|
156
|
+
# - <
|
157
|
+
# - '
|
158
|
+
#
|
159
|
+
# If you are using this with #simple_format, do not forget to call
|
160
|
+
# this one first, then put in unsanitised linebreaks. The other way around
|
161
|
+
# is full of fail.
|
162
|
+
#
|
73
163
|
# stolen from rails: ERB::Util
|
74
|
-
|
75
|
-
|
164
|
+
#
|
165
|
+
# @see Ginatra::Helpers#simple_format
|
166
|
+
#
|
167
|
+
# @param [#to_s] clean_me the object to clean.
|
168
|
+
#
|
169
|
+
# @return [String] the cleaned html text.
|
170
|
+
def html_escape(clean_me)
|
171
|
+
clean_me.to_s.gsub(/[&"<>]/) do |special|
|
76
172
|
{ '&' => '&',
|
77
173
|
'>' => '>',
|
78
174
|
'<' => '<',
|
@@ -81,7 +177,15 @@ module Ginatra
|
|
81
177
|
end
|
82
178
|
alias :h :html_escape
|
83
179
|
|
180
|
+
# Truncates a given text to a certain number of letters, including a special ending if needed.
|
181
|
+
#
|
84
182
|
# Stolen and bastardised from rails
|
183
|
+
#
|
184
|
+
# @param [String] text the text to truncate
|
185
|
+
# @option options [Integer] :length (30) the length you want the output string
|
186
|
+
# @option options [String] :omission ("...") the string to show an omission.
|
187
|
+
#
|
188
|
+
# @return [String] the truncated text.
|
85
189
|
def truncate(text, options={})
|
86
190
|
options[:length] ||= 30
|
87
191
|
options[:omission] ||= "..."
|
@@ -94,19 +198,36 @@ module Ginatra
|
|
94
198
|
end
|
95
199
|
end
|
96
200
|
|
201
|
+
# Returns the rfc representation of a date, for use in the atom feeds.
|
202
|
+
#
|
97
203
|
# stolen from Marley
|
204
|
+
#
|
205
|
+
# @param [DateTime] datetime the date to format
|
206
|
+
# @return [String] the formatted datetime
|
98
207
|
def rfc_date(datetime)
|
99
208
|
datetime.strftime("%Y-%m-%dT%H:%M:%SZ") # 2003-12-13T18:30:02Z
|
100
209
|
end
|
101
210
|
|
211
|
+
# Returns the Hostname of the given install.
|
212
|
+
#
|
213
|
+
# @todo Where is this used?
|
214
|
+
#
|
102
215
|
# stolen from Marley
|
216
|
+
#
|
217
|
+
# @return [String] the hostname of the server. Respects HTTP-X-Forwarded-For
|
103
218
|
def hostname
|
104
219
|
(request.env['HTTP_X_FORWARDED_SERVER'] =~ /[a-z]*/) ? request.env['HTTP_X_FORWARDED_SERVER'] : request.env['HTTP_HOST']
|
105
220
|
end
|
106
221
|
|
222
|
+
# Spits out a HTML link to the atom feed for a given ref of a given repo
|
223
|
+
#
|
224
|
+
# @param [Sting] repo_param the url-sanitised-name of a given repo
|
225
|
+
# @param [String] ref the ref to link to.
|
226
|
+
#
|
227
|
+
# @return [String] the HTML containing the link to the feed.
|
107
228
|
def atom_feed_link(repo_param, ref=nil)
|
108
229
|
"<a href=\"/#{repo_param}#{"/#{ref}" if !ref.nil?}.atom\" title=\"Atom Feed\" class=\"atom\">Feed</a>"
|
109
230
|
end
|
110
231
|
|
111
232
|
end
|
112
|
-
end
|
233
|
+
end
|
data/lib/ginatra/repo.rb
CHANGED
@@ -1,16 +1,24 @@
|
|
1
|
-
# to make refs work!
|
2
1
|
module Grit
|
3
2
|
class Commit
|
3
|
+
# this lets us add a link between commits and refs directly
|
4
4
|
attr_accessor :refs
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
8
|
module Ginatra
|
9
|
-
#
|
9
|
+
# A thin wrapper to the Grit::repo class so that we can add a name and a url-sanitised-name
|
10
|
+
# to a repo, and also intercept and add refs to the commit objects.
|
10
11
|
class Repo
|
11
12
|
|
12
13
|
attr_reader :name, :param, :description
|
13
14
|
|
15
|
+
# Create a new repository, and sort out clever stuff including assigning
|
16
|
+
# the param, the name and the description.
|
17
|
+
#
|
18
|
+
# @todo cleanup!
|
19
|
+
#
|
20
|
+
# @param [String] path a path to the repository you want created
|
21
|
+
# @return [Ginatra::Repo] a repository instance
|
14
22
|
def initialize(path)
|
15
23
|
@repo = Grit::Repo.new(path)
|
16
24
|
@param = File.split(path).last
|
@@ -20,6 +28,15 @@ module Ginatra
|
|
20
28
|
@repo
|
21
29
|
end
|
22
30
|
|
31
|
+
# Return a commit corresponding to the commit to the repo,
|
32
|
+
# but with the refs already attached.
|
33
|
+
#
|
34
|
+
# @see Ginatra::Repo#add_refs
|
35
|
+
#
|
36
|
+
# @raise [Ginatra::InvalidCommit] if the commit doesn't exist.
|
37
|
+
#
|
38
|
+
# @param [String] id the commit id
|
39
|
+
# @return [Grit::Commit] the commit object.
|
23
40
|
def commit(id)
|
24
41
|
@commit = @repo.commit(id)
|
25
42
|
raise(Ginatra::InvalidCommit.new(id)) if @commit.nil?
|
@@ -27,6 +44,15 @@ module Ginatra
|
|
27
44
|
@commit
|
28
45
|
end
|
29
46
|
|
47
|
+
# Return a list of commits to a certain branch, including pagination options and all the refs.
|
48
|
+
#
|
49
|
+
# @param [String] start the branch to look for commits in
|
50
|
+
# @param [Integer] max_count the maximum count of commits
|
51
|
+
# @param [Integer] skip the number of commits in the branch to skip before taking the count.
|
52
|
+
#
|
53
|
+
# @raise [Ginatra::Error] if max_count is less than 0. silly billy!
|
54
|
+
#
|
55
|
+
# @return [Array<Grit::Commit>] the array of commits.
|
30
56
|
def commits(start = 'master', max_count = 10, skip = 0)
|
31
57
|
raise(Ginatra::Error.new("max_count cannot be less than 0")) if max_count < 0
|
32
58
|
@repo.commits(start, max_count, skip).each do |commit|
|
@@ -34,7 +60,12 @@ module Ginatra
|
|
34
60
|
end
|
35
61
|
end
|
36
62
|
|
37
|
-
#
|
63
|
+
# Adds the refs corresponding to Grit::Commit objects to the respective Commit objects.
|
64
|
+
#
|
65
|
+
# @todo Perhaps move into commit class.
|
66
|
+
#
|
67
|
+
# @param [Grit::Commit] commit the commit you want refs added to
|
68
|
+
# @return [Array] the array of refs added to the commit. they are also on the commit object.
|
38
69
|
def add_refs(commit)
|
39
70
|
commit.refs = []
|
40
71
|
refs = @repo.refs.select { |ref| ref.commit.id == commit.id }
|
@@ -42,9 +73,14 @@ module Ginatra
|
|
42
73
|
commit.refs.flatten!
|
43
74
|
end
|
44
75
|
|
76
|
+
# Catch all
|
77
|
+
#
|
78
|
+
# Warning! contains: Magic
|
79
|
+
#
|
80
|
+
# @todo update respond_to? method
|
45
81
|
def method_missing(sym, *args, &block)
|
46
82
|
@repo.send(sym, *args, &block)
|
47
83
|
end
|
48
84
|
|
49
85
|
end
|
50
|
-
end
|
86
|
+
end
|
data/lib/ginatra/repo_list.rb
CHANGED
@@ -1,21 +1,33 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
|
3
3
|
module Ginatra
|
4
|
-
#
|
4
|
+
# A singleton class that lets us make and use a constantly updating
|
5
|
+
# list of repositories.
|
5
6
|
class RepoList
|
6
7
|
include Singleton
|
7
8
|
attr_accessor :list
|
8
9
|
|
10
|
+
# This creates the list, then does the first refresh to
|
11
|
+
# populate it.
|
12
|
+
#
|
13
|
+
# It returns what refresh returns.
|
9
14
|
def initialize
|
10
15
|
self.list = []
|
11
16
|
self.refresh
|
12
17
|
end
|
13
18
|
|
19
|
+
# The preferred way to access the list publicly.
|
20
|
+
#
|
21
|
+
# @return [Array<Ginatra::Repo>] a list of ginatra repos.
|
14
22
|
def self.list
|
15
23
|
self.instance.refresh
|
16
24
|
self.instance.list
|
17
25
|
end
|
18
26
|
|
27
|
+
# searches through the configured directory globs to find all the repositories
|
28
|
+
# and adds them if they're not already there.
|
29
|
+
#
|
30
|
+
# @todo Docs: what the hell does this return?
|
19
31
|
def refresh
|
20
32
|
Ginatra::Config.git_dirs.map! do |git_dir|
|
21
33
|
files = Dir.glob(git_dir)
|
@@ -23,16 +35,36 @@ module Ginatra
|
|
23
35
|
end
|
24
36
|
end
|
25
37
|
|
38
|
+
# adds a Repo corresponding to the path it found a git repo at in the configured
|
39
|
+
# globs. Checks to see that it's not there first
|
40
|
+
#
|
41
|
+
# @param [String] path the path of the git repo
|
42
|
+
# @param [String] param the param of the repo if it differs,
|
43
|
+
# for looking to see if it's already on the list
|
44
|
+
#
|
45
|
+
# @todo Docs: what does this return?
|
26
46
|
def add(path, param = File.split(path).last)
|
27
47
|
unless self.has_repo?(param)
|
28
48
|
list << Repo.new(path)
|
29
49
|
end
|
30
50
|
end
|
31
51
|
|
52
|
+
# checks to see if the list contains a repo with a param
|
53
|
+
# matching the one passed in.
|
54
|
+
#
|
55
|
+
# @param [String] local_param param to check.
|
56
|
+
#
|
57
|
+
# @return [true, false]
|
32
58
|
def has_repo?(local_param)
|
33
59
|
!list.find { |r| r.param == local_param }.nil?
|
34
60
|
end
|
35
61
|
|
62
|
+
# quick way to look up if there is a repo with a given param in the list.
|
63
|
+
# If not, it refreshes the list and tries again.
|
64
|
+
#
|
65
|
+
# @param [String] local_param the param to lookup
|
66
|
+
#
|
67
|
+
# @return [Ginatra::Repo] the repository corresponding to that param.
|
36
68
|
def find(local_param)
|
37
69
|
if repo = list.find { |r| r.param == local_param }
|
38
70
|
repo
|
@@ -42,10 +74,19 @@ module Ginatra
|
|
42
74
|
end
|
43
75
|
end
|
44
76
|
|
77
|
+
# This just brings up the find method to the class scope.
|
78
|
+
#
|
79
|
+
# @see Ginatra::RepoList#find
|
45
80
|
def self.find(local_param)
|
46
81
|
self.instance.find(local_param)
|
47
82
|
end
|
48
83
|
|
84
|
+
# allows missing methods to cascade to the instance,
|
85
|
+
#
|
86
|
+
# @todo do we need this?
|
87
|
+
# @todo update the respond_to? method if we do.
|
88
|
+
#
|
89
|
+
# Caution! contains: Magic
|
49
90
|
def self.method_missing(sym, *args, &block)
|
50
91
|
instance.send(sym, *args, &block)
|
51
92
|
end
|