ginatra 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 */
|