ginatra 2.0.1
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/.gitattributes +2 -0
- data/.gitignore +13 -0
- data/.gitmodules +3 -0
- data/README.md +127 -0
- data/Rakefile +85 -0
- data/TODO.md +10 -0
- data/VERSION +1 -0
- data/bin/ginatra +60 -0
- data/bin/ginatra-daemon +81 -0
- data/bin/ginatra-directory +60 -0
- data/bin/ginatra-server +28 -0
- data/config.ru +7 -0
- data/features/pages.feature +33 -0
- data/features/step_definitions/page_steps.rb +36 -0
- data/features/support/env.rb +12 -0
- data/ginatra.gemspec +107 -0
- data/lib/ginatra/config.rb +55 -0
- data/lib/ginatra/helpers.rb +112 -0
- data/lib/ginatra/repo.rb +50 -0
- data/lib/ginatra/repo_list.rb +53 -0
- data/lib/ginatra.rb +185 -0
- data/lib/sinatra/partials.rb +17 -0
- data/public/favicon.ico +0 -0
- data/public/img/add.png +0 -0
- data/public/img/diff.png +0 -0
- data/public/img/doc.png +0 -0
- data/public/img/rm.png +0 -0
- data/public/img/tree.png +0 -0
- data/public/src/blank.gif +0 -0
- data/public/src/colour.css +85 -0
- data/public/src/commit.css +211 -0
- data/public/src/default.css +115 -0
- data/public/src/ginatra.js +9 -0
- data/public/src/highlight.pack.js +1 -0
- data/public/src/iepngfix.htc +103 -0
- data/public/src/index.css +92 -0
- data/public/src/jquery-1.3.2.min.js +19 -0
- data/public/src/lists.css +25 -0
- data/public/src/reset.css +49 -0
- data/public/src/table.css +33 -0
- data/public/src/type.css +30 -0
- data/rackup.ru +7 -0
- data/repos/README.md +8 -0
- data/spec/repo_list_spec.rb +22 -0
- data/spec/repo_spec.rb +58 -0
- data/spec/spec_helper.rb +30 -0
- data/views/_actor_box.erb +13 -0
- data/views/_commit_info_box.erb +27 -0
- data/views/_header.erb +6 -0
- data/views/_tree_part.erb +11 -0
- data/views/atom.builder +32 -0
- data/views/blob.erb +9 -0
- data/views/commit.erb +20 -0
- data/views/index.erb +12 -0
- data/views/layout.erb +35 -0
- data/views/log.erb +64 -0
- data/views/tree.erb +24 -0
- metadata +146 -0
@@ -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
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require "digest/md5"
|
2
|
+
|
3
|
+
module Ginatra
|
4
|
+
# Actually useful stuff
|
5
|
+
module Helpers
|
6
|
+
|
7
|
+
def gravatar_url(email)
|
8
|
+
"https://secure.gravatar.com/avatar/#{Digest::MD5.hexdigest(email)}?s=40"
|
9
|
+
end
|
10
|
+
|
11
|
+
def nicetime(date)
|
12
|
+
date.strftime("%b %d, %Y – %H:%M")
|
13
|
+
end
|
14
|
+
|
15
|
+
def actor_box(actor, role, date)
|
16
|
+
partial(:actor_box, :locals => { :actor => actor, :role => role, :date => date })
|
17
|
+
end
|
18
|
+
|
19
|
+
def actor_boxes(commit)
|
20
|
+
o = actor_box(commit.committer, :committer, commit.committed_date)
|
21
|
+
if commit.author.name != commit.committer.name
|
22
|
+
o = actor_box(commit.author, :author, commit.authored_date) + o
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def commit_ref(ref, repo_param)
|
27
|
+
ref_class = ref.class.to_s.split("::")[1].to_s
|
28
|
+
"<a class=\"ref #{ref_class}\" href=\"/#{repo_param}/#{ref.name}\">#{ref.name}</a>"
|
29
|
+
end
|
30
|
+
|
31
|
+
def commit_refs(commit, repo_param)
|
32
|
+
commit.refs.map{ |r| commit_ref(r, repo_param) }.join("\n")
|
33
|
+
end
|
34
|
+
|
35
|
+
def archive_link(tree, repo_param)
|
36
|
+
"<a class=\"download\" href=\"/#{repo_param}/archive/#{tree.id}.tar.gz\" title=\"Download a tar.gz snapshot of this Tree\">Download Archive</a>"
|
37
|
+
end
|
38
|
+
|
39
|
+
def patch_link(commit, repo_param)
|
40
|
+
"<a class=\"download\" href=\"/#{repo_param}/commit/#{commit.id}.patch\" title=\"Download a patch file of this Commit\">Download Patch</a>"
|
41
|
+
end
|
42
|
+
|
43
|
+
# The only reason this doesn't work 100% of the time is because grit doesn't :/
|
44
|
+
# if i find a fix, it'll go upstream :D
|
45
|
+
def file_listing(commit)
|
46
|
+
count = 0
|
47
|
+
out = commit.diffs.map do |diff|
|
48
|
+
count = count + 1
|
49
|
+
if diff.deleted_file
|
50
|
+
%(<li class='file_rm'><a href='#file_#{count}'>#{diff.a_path}</a></li>)
|
51
|
+
else
|
52
|
+
cla = diff.new_file ? "add" : "diff"
|
53
|
+
%(<li class='file_#{cla}'><a href='#file_#{count}'>#{diff.a_path}</a></li>)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
"<ul id='files'>#{out.join}</ul>"
|
57
|
+
end
|
58
|
+
|
59
|
+
def diff(diff)
|
60
|
+
diff = CodeRay.scan(diff, :diff).div(:line_numbers => :table, :css => :class)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Stolen from rails: ActionView::Helpers::TextHelper#simple_format
|
64
|
+
# and simplified to just use <p> tags without any options
|
65
|
+
# modified since
|
66
|
+
def simple_format(text)
|
67
|
+
text.gsub!(/ +/, " ")
|
68
|
+
text.gsub!(/\r\n?/, "\n")
|
69
|
+
text.gsub!(/\n/, "<br />\n")
|
70
|
+
text
|
71
|
+
end
|
72
|
+
|
73
|
+
# stolen from rails: ERB::Util
|
74
|
+
def html_escape(s)
|
75
|
+
s.to_s.gsub(/[&"<>]/) do |special|
|
76
|
+
{ '&' => '&',
|
77
|
+
'>' => '>',
|
78
|
+
'<' => '<',
|
79
|
+
'"' => '"' }[special]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
alias :h :html_escape
|
83
|
+
|
84
|
+
# Stolen and bastardised from rails
|
85
|
+
def truncate(text, options={})
|
86
|
+
options[:length] ||= 30
|
87
|
+
options[:omission] ||= "..."
|
88
|
+
|
89
|
+
if text
|
90
|
+
l = options[:length] - options[:omission].length
|
91
|
+
chars = text
|
92
|
+
stop = options[:separator] ? (chars.rindex(options[:separator], l) || l) : l
|
93
|
+
(chars.length > options[:length] ? chars[0...stop] + options[:omission] : text).to_s
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# stolen from Marley
|
98
|
+
def rfc_date(datetime)
|
99
|
+
datetime.strftime("%Y-%m-%dT%H:%M:%SZ") # 2003-12-13T18:30:02Z
|
100
|
+
end
|
101
|
+
|
102
|
+
# stolen from Marley
|
103
|
+
def hostname
|
104
|
+
(request.env['HTTP_X_FORWARDED_SERVER'] =~ /[a-z]*/) ? request.env['HTTP_X_FORWARDED_SERVER'] : request.env['HTTP_HOST']
|
105
|
+
end
|
106
|
+
|
107
|
+
def atom_feed_link(repo_param, ref=nil)
|
108
|
+
"<a href=\"/#{repo_param}#{"/#{ref}" if !ref.nil?}.atom\" title=\"Atom Feed\" class=\"atom\">Feed</a>"
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
data/lib/ginatra/repo.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# to make refs work!
|
2
|
+
module Grit
|
3
|
+
class Commit
|
4
|
+
attr_accessor :refs
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module Ginatra
|
9
|
+
# Convenience class for me!
|
10
|
+
class Repo
|
11
|
+
|
12
|
+
attr_reader :name, :param, :description
|
13
|
+
|
14
|
+
def initialize(path)
|
15
|
+
@repo = Grit::Repo.new(path)
|
16
|
+
@param = File.split(path).last
|
17
|
+
@name = @param
|
18
|
+
@description = @repo.description
|
19
|
+
@description = "Please edit the #{@repo.path}/description file for this repository and set the description for it." if /^Unnamed repository;/.match(@description)
|
20
|
+
@repo
|
21
|
+
end
|
22
|
+
|
23
|
+
def commit(id)
|
24
|
+
@commit = @repo.commit(id)
|
25
|
+
raise(Ginatra::InvalidCommit.new(id)) if @commit.nil?
|
26
|
+
add_refs(@commit)
|
27
|
+
@commit
|
28
|
+
end
|
29
|
+
|
30
|
+
def commits(start = 'master', max_count = 10, skip = 0)
|
31
|
+
raise(Ginatra::Error.new("max_count cannot be less than 0")) if max_count < 0
|
32
|
+
@repo.commits(start, max_count, skip).each do |commit|
|
33
|
+
add_refs(commit)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# TODO: Perhaps move into commit class.
|
38
|
+
def add_refs(commit)
|
39
|
+
commit.refs = []
|
40
|
+
refs = @repo.refs.select { |ref| ref.commit.id == commit.id }
|
41
|
+
commit.refs << refs
|
42
|
+
commit.refs.flatten!
|
43
|
+
end
|
44
|
+
|
45
|
+
def method_missing(sym, *args, &block)
|
46
|
+
@repo.send(sym, *args, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module Ginatra
|
4
|
+
# Convenience class for me!
|
5
|
+
class RepoList
|
6
|
+
include Singleton
|
7
|
+
attr_accessor :list
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
self.list = []
|
11
|
+
self.refresh
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.list
|
15
|
+
self.instance.refresh
|
16
|
+
self.instance.list
|
17
|
+
end
|
18
|
+
|
19
|
+
def refresh
|
20
|
+
Ginatra::Config.git_dirs.map! do |git_dir|
|
21
|
+
files = Dir.glob(git_dir)
|
22
|
+
files.each { |e| add(e) unless Ginatra::Config.ignored_files.include?(File.split(e).last) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def add(path, param = File.split(path).last)
|
27
|
+
unless self.has_repo?(param)
|
28
|
+
list << Repo.new(path)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def has_repo?(local_param)
|
33
|
+
!list.find { |r| r.param == local_param }.nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
def find(local_param)
|
37
|
+
if repo = list.find { |r| r.param == local_param }
|
38
|
+
repo
|
39
|
+
else
|
40
|
+
refresh
|
41
|
+
list.find { |r| r.param == local_param }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.find(local_param)
|
46
|
+
self.instance.find(local_param)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.method_missing(sym, *args, &block)
|
50
|
+
instance.send(sym, *args, &block)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
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,17 @@
|
|
1
|
+
# stolen from http://github.com/cschneid/irclogger/blob/master/lib/partials.rb
|
2
|
+
module Sinatra::Partials
|
3
|
+
def partial(template, *args)
|
4
|
+
template_array = template.to_s.split('/')
|
5
|
+
template = template_array[0..-2].join('/') + "/_#{template_array[-1]}"
|
6
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
7
|
+
options.merge!(:layout => false)
|
8
|
+
if collection = options.delete(:collection) then
|
9
|
+
collection.inject([]) do |buffer, member|
|
10
|
+
buffer << erb(:"#{template}", options.merge(:layout =>
|
11
|
+
false, :locals => {template_array[-1].to_sym => member}))
|
12
|
+
end.join("\n")
|
13
|
+
else
|
14
|
+
erb(:"#{template}", options)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/public/favicon.ico
ADDED
File without changes
|
data/public/img/add.png
ADDED
Binary file
|
data/public/img/diff.png
ADDED
Binary file
|
data/public/img/doc.png
ADDED
Binary file
|
data/public/img/rm.png
ADDED
Binary file
|
data/public/img/tree.png
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,85 @@
|
|
1
|
+
/* Main Colours */
|
2
|
+
body {
|
3
|
+
background: #fff;
|
4
|
+
}
|
5
|
+
#footer {
|
6
|
+
border-top: 1px solid #eee;
|
7
|
+
background: #EFEFF7;
|
8
|
+
}
|
9
|
+
h3{
|
10
|
+
background: #F2F2F2;
|
11
|
+
color: #224FBA;
|
12
|
+
font-weight: bold;
|
13
|
+
}
|
14
|
+
div.active{
|
15
|
+
border-top: 3px solid #dde;
|
16
|
+
background: #EFEFF7;
|
17
|
+
}
|
18
|
+
a { color: #333; }
|
19
|
+
a:visited { color: #555; }
|
20
|
+
a:hover,
|
21
|
+
a:active { color: #333; }
|
22
|
+
.quiet { color: #7F7F7F; }
|
23
|
+
/* End Main Colours */
|
24
|
+
|
25
|
+
/* Type Colours */
|
26
|
+
body { color: #222; }
|
27
|
+
h1 { color: #224FBA; background: #E6E6F2;}
|
28
|
+
h1 a, h1 a:visited, h1 a:hover, h1 a:active { color: #224fba; text-decoration: none; }
|
29
|
+
h2 a, h2 a:visited, h2 a:hover, h2 a:active { text-decoration: none; }
|
30
|
+
/* End Type Colours */
|
31
|
+
|
32
|
+
/* Table Colours */
|
33
|
+
td {
|
34
|
+
border-top: 1px solid #7F7F7F;
|
35
|
+
}
|
36
|
+
.repo-info, .ginatra-info, dl, td {
|
37
|
+
background: #E6E6F2;
|
38
|
+
}
|
39
|
+
.repo-list dl dt:first-child{
|
40
|
+
border-top: none;
|
41
|
+
}
|
42
|
+
/* End Table Colours */
|
43
|
+
|
44
|
+
/* Commit Colours */
|
45
|
+
#commit #info,
|
46
|
+
#commit #author,
|
47
|
+
#commit #committer,
|
48
|
+
.short-commit-message,
|
49
|
+
.commit-tree,
|
50
|
+
.commit-diff,
|
51
|
+
div.blob {
|
52
|
+
background: #E6E6F2;
|
53
|
+
}
|
54
|
+
.commit-author img,
|
55
|
+
.commit-committer img {
|
56
|
+
border: 1px solid #7F7F7F;
|
57
|
+
}
|
58
|
+
.commit-tree .tree {
|
59
|
+
background: url('../img/tree.png') no-repeat top left;
|
60
|
+
}
|
61
|
+
.commit-tree .blob {
|
62
|
+
background: url('../img/doc.png') no-repeat top left;
|
63
|
+
}
|
64
|
+
.commit-diff h4,
|
65
|
+
div.blob h4 {
|
66
|
+
background: #e7e7e7;
|
67
|
+
}
|
68
|
+
li.diff { background: url('../../img/diff.png') no-repeat center left; }
|
69
|
+
li.add a{ color: #080; }
|
70
|
+
li.add { background: url('../../img/add.png') no-repeat center left; }
|
71
|
+
li.rm {
|
72
|
+
color: #800;
|
73
|
+
background: url('../../img/rm.png') no-repeat center left;
|
74
|
+
}
|
75
|
+
a.ref { background-color: #7782FC; color: #fff; }
|
76
|
+
a.download { background-color: #7782FC; color: #fff; }
|
77
|
+
a.atom { background-color: #7782FC; color: #fff; }
|
78
|
+
a.head { background-color: #7782FC; }
|
79
|
+
a.tag { background-color: #d95959; }
|
80
|
+
a.remote { background-color: #fafa78; }
|
81
|
+
|
82
|
+
.commit, .list div, .single-commit #message {
|
83
|
+
background: #dcdcdc;
|
84
|
+
}
|
85
|
+
/* End Commit Colours */
|