ghoul 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +39 -0
- data/LICENSE +20 -0
- data/README.md +46 -0
- data/Rakefile +1 -0
- data/bin/ghoul +19 -0
- data/config.ru +30 -0
- data/ghoul.gemspec +51 -0
- data/lib/ghoul/app.rb +119 -0
- data/lib/ghoul/lib/helpers.rb +64 -0
- data/lib/ghoul/lib/repository.rb +41 -0
- data/lib/ghoul/lib/url_helpers.rb +53 -0
- data/lib/ghoul/public/css/buttons.css +38 -0
- data/lib/ghoul/public/css/coderay.css +136 -0
- data/lib/ghoul/public/css/github-buttons.css +393 -0
- data/lib/ghoul/public/flash/clippy.swf +0 -0
- data/lib/ghoul/public/images/bg.png +0 -0
- data/lib/ghoul/public/images/big_logo.png +0 -0
- data/lib/ghoul/public/images/dir.png +0 -0
- data/lib/ghoul/public/images/gh-icons.png +0 -0
- data/lib/ghoul/public/images/logo-hover.png +0 -0
- data/lib/ghoul/public/images/logo.png +0 -0
- data/lib/ghoul/public/images/txt.png +0 -0
- data/lib/ghoul/views/404.erb +10 -0
- data/lib/ghoul/views/app.sass +316 -0
- data/lib/ghoul/views/blob.erb +11 -0
- data/lib/ghoul/views/commits.erb +11 -0
- data/lib/ghoul/views/diff.erb +16 -0
- data/lib/ghoul/views/error.erb +6 -0
- data/lib/ghoul/views/layout.erb +25 -0
- data/lib/ghoul/views/new_repo.erb +16 -0
- data/lib/ghoul/views/no_commits.erb +34 -0
- data/lib/ghoul/views/partials/_breadcrumbs.erb +6 -0
- data/lib/ghoul/views/partials/_commit.erb +10 -0
- data/lib/ghoul/views/partials/_footer.erb +5 -0
- data/lib/ghoul/views/partials/_repo_header.erb +17 -0
- data/lib/ghoul/views/partials/_repo_top_bar.erb +8 -0
- data/lib/ghoul/views/repo_settings.erb +18 -0
- data/lib/ghoul/views/repositories.erb +73 -0
- data/lib/ghoul/views/setup_repos_path.erb +8 -0
- data/lib/ghoul/views/tree.erb +17 -0
- data/lib/ghoul.rb +24 -0
- data/lib/server.rb +39 -0
- data/lib/version.rb +3 -0
- data/sample +0 -0
- data/spec/ghoul_helpers_spec.rb +62 -0
- data/spec/spec_helper.rb +0 -0
- data/spec/url_helper_spec.rb +56 -0
- metadata +195 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ghoul (0.0.3)
|
5
|
+
coderay
|
6
|
+
georgedrummond_sinatra_helpers
|
7
|
+
ghoul_grack (= 0.0.1)
|
8
|
+
grit
|
9
|
+
redcarpet
|
10
|
+
sass
|
11
|
+
sinatra (= 1.3.1)
|
12
|
+
|
13
|
+
GEM
|
14
|
+
remote: http://rubygems.org/
|
15
|
+
specs:
|
16
|
+
coderay (1.0.1)
|
17
|
+
diff-lcs (1.1.3)
|
18
|
+
georgedrummond_sinatra_helpers (0.0.7)
|
19
|
+
ghoul_grack (0.0.1)
|
20
|
+
grit (2.4.1)
|
21
|
+
diff-lcs (~> 1.1)
|
22
|
+
mime-types (~> 1.15)
|
23
|
+
mime-types (1.17.1)
|
24
|
+
rack (1.3.5)
|
25
|
+
rack-protection (1.1.4)
|
26
|
+
rack
|
27
|
+
redcarpet (1.17.2)
|
28
|
+
sass (3.1.10)
|
29
|
+
sinatra (1.3.1)
|
30
|
+
rack (~> 1.3, >= 1.3.4)
|
31
|
+
rack-protection (~> 1.1, >= 1.1.2)
|
32
|
+
tilt (~> 1.3, >= 1.3.3)
|
33
|
+
tilt (1.3.3)
|
34
|
+
|
35
|
+
PLATFORMS
|
36
|
+
ruby
|
37
|
+
|
38
|
+
DEPENDENCIES
|
39
|
+
ghoul!
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 George Drummond, george@accountsapp.com
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Ghoul - Prettier Git For Everyone :)
|
2
|
+
|
3
|
+
Ghoul is a simple yet good looking interface for your git repositories written in sinatra. It is currently only for demonstration purposes and use on your secure local machine as it does not enforce any authentication as of yet.InstallationGhoul can be run either using the ghoul gem or by downloading the git repository and running through the rackup command.
|
4
|
+
|
5
|
+
|
6
|
+
## Installing via rubygems
|
7
|
+
|
8
|
+
gem install ghoul
|
9
|
+
ghoul server
|
10
|
+
|
11
|
+
|
12
|
+
## Installing from the git repository
|
13
|
+
|
14
|
+
git clone http://github.com/georgedrummond/ghoul
|
15
|
+
cd ghoul
|
16
|
+
bundle install
|
17
|
+
rackup
|
18
|
+
|
19
|
+
|
20
|
+
## How it works
|
21
|
+
|
22
|
+
Ghoul uses the grit, written by the guys at github for parsing your repositories which are located in a folder named "repos" within your home folder e.g. /Users/georgedrummond/repos. For git push, ghoul uses grack. Grack has no authentication so ghoul should only be used on your local machine.
|
23
|
+
|
24
|
+
|
25
|
+
## License
|
26
|
+
|
27
|
+
Copyright (c) 2011 George Drummond, george@accountsapp.com
|
28
|
+
|
29
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
30
|
+
a copy of this software and associated documentation files (the
|
31
|
+
"Software"), to deal in the Software without restriction, including
|
32
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
33
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
34
|
+
permit persons to whom the Software is furnished to do so, subject to
|
35
|
+
the following conditions:
|
36
|
+
|
37
|
+
The above copyright notice and this permission notice shall be
|
38
|
+
included in all copies or substantial portions of the Software.
|
39
|
+
|
40
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
41
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
42
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
43
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
44
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
45
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
46
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/ghoul
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__) , "..", "/lib", "server")
|
4
|
+
|
5
|
+
command = ARGV[0]
|
6
|
+
|
7
|
+
if command == "server"
|
8
|
+
Ghoul::Server.start
|
9
|
+
else
|
10
|
+
puts <<-END_MESSAGE
|
11
|
+
|
12
|
+
Usage:
|
13
|
+
|
14
|
+
ghoul server
|
15
|
+
# => Starts the ghoul server
|
16
|
+
|
17
|
+
|
18
|
+
END_MESSAGE
|
19
|
+
end
|
data/config.ru
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#require './lib/little_git.rb'
|
2
|
+
#require './lib/little_git/lib/grack.rb'
|
3
|
+
require File.join(File.dirname(__FILE__), "lib", "ghoul")
|
4
|
+
#require File.join(File.dirname(__FILE__), "lib", "ghoul", "lib", "grack")
|
5
|
+
require "ghoul_grack"
|
6
|
+
|
7
|
+
# use Rack::ShowExceptions
|
8
|
+
|
9
|
+
# As a default, we wil store our repositories at
|
10
|
+
#
|
11
|
+
# ~/repos
|
12
|
+
# => /User/georgedrummond/repos
|
13
|
+
project_root = File.join(ENV['HOME'], "repos")
|
14
|
+
|
15
|
+
config = {
|
16
|
+
:project_root => project_root,
|
17
|
+
:git_path => '/usr/bin/git',
|
18
|
+
:upload_pack => true,
|
19
|
+
:receive_pack => true,
|
20
|
+
}
|
21
|
+
::MAIN_APP = self
|
22
|
+
|
23
|
+
map "/repo" do
|
24
|
+
run GhoulGrack::GitHttp::App.new(config)
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
map "/" do
|
29
|
+
run Ghoul::Application
|
30
|
+
end
|
data/ghoul.gemspec
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ghoul"
|
7
|
+
s.version = Ghoul::VERSION
|
8
|
+
s.authors = ["George Drummond"]
|
9
|
+
s.email = ["george@accountsapp.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Ghoul is a simple yet good looking interface for your git repositories written in sinatra. It is currently only for demonstration purposes and use on your secure local machine as it does not enforce any authentication as of yet.}
|
12
|
+
s.description = %q{Ghoul is a simple yet good looking interface for your git repositories written in sinatra. It is currently only for demonstration purposes and use on your secure local machine as it does not enforce any authentication as of yet.}
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_dependency "rack", ">= 1.0.0"
|
20
|
+
s.add_dependency "sinatra", "1.3.1"
|
21
|
+
s.add_dependency "sass"
|
22
|
+
s.add_dependency "grit"
|
23
|
+
s.add_dependency "georgedrummond_sinatra_helpers"
|
24
|
+
s.add_dependency "ghoul_grack", "0.0.1"
|
25
|
+
s.add_dependency "coderay"
|
26
|
+
s.add_dependency "redcarpet"
|
27
|
+
|
28
|
+
s.post_install_message = <<-message
|
29
|
+
|
30
|
+
#################################################
|
31
|
+
#
|
32
|
+
# Thanks for installing Ghoul and giving it a go!
|
33
|
+
#
|
34
|
+
# This is a proof of concept release and in the
|
35
|
+
# next few months I hope to add to Ghoul and
|
36
|
+
# make it more fully featured.
|
37
|
+
#
|
38
|
+
# I think the idea behind Ghoul is kind of cool
|
39
|
+
# and if you do too, why not contribute and
|
40
|
+
# check out our github page.
|
41
|
+
#
|
42
|
+
# => http://github.com/georgedrummond/ghoul
|
43
|
+
#
|
44
|
+
#################################################
|
45
|
+
|
46
|
+
To Start the Ghoul server run:
|
47
|
+
|
48
|
+
ghoul server
|
49
|
+
|
50
|
+
message
|
51
|
+
end
|
data/lib/ghoul/app.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
module Ghoul
|
2
|
+
class Application < Sinatra::Base
|
3
|
+
include GeorgeDrummond::Sinatra::Helpers
|
4
|
+
include Ghoul::Helpers
|
5
|
+
include Ghoul::Repository
|
6
|
+
include Ghoul::UrlHelpers
|
7
|
+
|
8
|
+
set :public_folder, File.join(File.dirname(__FILE__), 'public')
|
9
|
+
set :views, File.join(File.dirname(__FILE__), 'views')
|
10
|
+
|
11
|
+
disable :logging, :dump_errors, :raise_errors, :show_exceptions
|
12
|
+
|
13
|
+
before '/:path' do
|
14
|
+
unless repos_path_exists? && params[:path] != "css/app.css"
|
15
|
+
puts 'doesnt exist'
|
16
|
+
halt erb(:setup_repos_path)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
get "/css/app.css" do
|
21
|
+
sass :app
|
22
|
+
end
|
23
|
+
|
24
|
+
get "/" do
|
25
|
+
redirect "/repositories"
|
26
|
+
end
|
27
|
+
|
28
|
+
get '/new_repo' do
|
29
|
+
erb :new_repo
|
30
|
+
end
|
31
|
+
|
32
|
+
post '/new_repo' do
|
33
|
+
@name = params[:name]
|
34
|
+
if create_repository(@name)
|
35
|
+
redirect repository_path(params[:name])
|
36
|
+
else
|
37
|
+
"Not possible"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
before '/repository/:repository/:commit/*' do
|
42
|
+
@repository = params[:repository]
|
43
|
+
@newest_commit = commit_from_repository(@repository, "trunk")
|
44
|
+
@commit = commit_from_repository(@repository, params[:commit])
|
45
|
+
end
|
46
|
+
|
47
|
+
get "/repository/:repository/settings" do
|
48
|
+
@repository = params[:repository]
|
49
|
+
@hide_breadcrumbs = true
|
50
|
+
erb :repo_settings
|
51
|
+
end
|
52
|
+
|
53
|
+
post "/repository/:repository/delete" do
|
54
|
+
require "FileUtils"
|
55
|
+
FileUtils.rm_rf File.join(repos_path, params[:repository])
|
56
|
+
redirect("/")
|
57
|
+
end
|
58
|
+
|
59
|
+
get "/repository/:repository/:commit/diff/?" do
|
60
|
+
@hide_breadcrumbs = true
|
61
|
+
erb :diff
|
62
|
+
end
|
63
|
+
|
64
|
+
get "/repository/:repository/commits/?" do
|
65
|
+
@repository = params[:repository]
|
66
|
+
@commits = repository(@repository).commits
|
67
|
+
@commit = commit_from_repository @repository, "trunk"
|
68
|
+
@newest_commit = commit_from_repository(@repository, "trunk")
|
69
|
+
@hide_breadcrumbs = true
|
70
|
+
erb :commits
|
71
|
+
end
|
72
|
+
|
73
|
+
get "/repository/:repository/commits/:commit/?" do
|
74
|
+
@repository = params[:repository]
|
75
|
+
@commit = repository(@repository).commit(params[:commit])
|
76
|
+
erb :diffs
|
77
|
+
end
|
78
|
+
|
79
|
+
get "/repositories" do
|
80
|
+
@repositories = repositories
|
81
|
+
erb :repositories
|
82
|
+
end
|
83
|
+
|
84
|
+
get '/repository/:repository/:commit/raw/*' do
|
85
|
+
resource = repository(@repository).tree(@commit.id)/params[:splat][0]
|
86
|
+
halt 200, {'Content-Type' => 'text/plain'}, resource.data
|
87
|
+
end
|
88
|
+
|
89
|
+
get '/repository/:repository/:commit/tree/?*' do
|
90
|
+
if params[:splat][0] != ""
|
91
|
+
resource = repository(@repository).tree(@commit.id)/params[:splat][0]
|
92
|
+
else
|
93
|
+
resource = repository(@repository).tree
|
94
|
+
end
|
95
|
+
|
96
|
+
if resource.is_a?(Grit::Tree) || params[:splat][0] == ""
|
97
|
+
@resource = resource
|
98
|
+
@splat = params[:splat]
|
99
|
+
erb :tree
|
100
|
+
else
|
101
|
+
@blob = resource
|
102
|
+
@syntaxer = CodeRay.scan(@blob.data, :plain).div(:line_numbers => :table)
|
103
|
+
erb :blob
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
error 404 do
|
108
|
+
erb :'404'
|
109
|
+
end
|
110
|
+
|
111
|
+
error do
|
112
|
+
#erb :'error'
|
113
|
+
end
|
114
|
+
|
115
|
+
error NoCommits do
|
116
|
+
erb :no_commits
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Ghoul
|
2
|
+
module Helpers
|
3
|
+
def human_file_size(filesize)
|
4
|
+
if filesize <= 1023
|
5
|
+
return "#{filesize} bytes"
|
6
|
+
elsif filesize <= 1024*1024
|
7
|
+
return "#{filesize/1024} KB"
|
8
|
+
else
|
9
|
+
return "#{filesize/1024/1024} MB"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def title(title)
|
14
|
+
@title = title
|
15
|
+
end
|
16
|
+
|
17
|
+
def breadcrumbs_from_splat(repository, commit, splat)
|
18
|
+
crumbs = splat.split("/")
|
19
|
+
html = []
|
20
|
+
path = []
|
21
|
+
crumbs.each do |crumb|
|
22
|
+
path << crumb
|
23
|
+
html << "#{link_to( crumb, tree_for_commit_path(repository, commit, splat, path.join('/')) )}"
|
24
|
+
end
|
25
|
+
return html.join("/")
|
26
|
+
end
|
27
|
+
|
28
|
+
def partial(template, locals = {})
|
29
|
+
template = ('partials/_' + template.to_s).to_sym
|
30
|
+
erb(template, :layout => false, :locals => locals)
|
31
|
+
end
|
32
|
+
|
33
|
+
def date_format(datetime)
|
34
|
+
datetime.strftime("%d %b %Y @ %H:%M")
|
35
|
+
end
|
36
|
+
|
37
|
+
def clippy(text, bgcolor='#FFFFFF')
|
38
|
+
html = <<-EOF
|
39
|
+
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
|
40
|
+
width="110"
|
41
|
+
height="14"
|
42
|
+
id="clippy" >
|
43
|
+
<param name="movie" value="#{url('/flash/clippy.swf')}"/>
|
44
|
+
<param name="allowScriptAccess" value="always" />
|
45
|
+
<param name="quality" value="high" />
|
46
|
+
<param name="scale" value="noscale" />
|
47
|
+
<param NAME="FlashVars" value="text=#{text}">
|
48
|
+
<param name="bgcolor" value="#{bgcolor}">
|
49
|
+
<embed src="/flash/clippy.swf"
|
50
|
+
width="110"
|
51
|
+
height="14"
|
52
|
+
name="clippy"
|
53
|
+
quality="high"
|
54
|
+
allowScriptAccess="always"
|
55
|
+
type="application/x-shockwave-flash"
|
56
|
+
pluginspage="http://www.macromedia.com/go/getflashplayer"
|
57
|
+
FlashVars="text=#{text}"
|
58
|
+
bgcolor="#{bgcolor}"
|
59
|
+
/>
|
60
|
+
</object>
|
61
|
+
EOF
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Ghoul
|
2
|
+
module Repository
|
3
|
+
def repos_path
|
4
|
+
home = ENV['HOME']
|
5
|
+
repos_path = File.join(home, "repos")
|
6
|
+
return repos_path
|
7
|
+
end
|
8
|
+
|
9
|
+
def repos_path_exists?
|
10
|
+
File.directory? repos_path
|
11
|
+
end
|
12
|
+
|
13
|
+
def repository(name)
|
14
|
+
path = File.join(repos_path, name)
|
15
|
+
return Grit::Repo.new(path, :is_bare => true)
|
16
|
+
end
|
17
|
+
|
18
|
+
def repositories
|
19
|
+
return Dir.entries(repos_path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def commit_from_repository(repository, commit_id)
|
23
|
+
if commit_id == "trunk"
|
24
|
+
commit = repository(repository).commits.first or raise NoCommits
|
25
|
+
else
|
26
|
+
commit = repository(repository).commit(params[:commit])
|
27
|
+
end
|
28
|
+
return commit
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_repository(name)
|
32
|
+
path = File.join(repos_path, name)
|
33
|
+
if File.exist?(path)
|
34
|
+
return false
|
35
|
+
end
|
36
|
+
Grit::Repo.init_bare(path)
|
37
|
+
end
|
38
|
+
|
39
|
+
class NoCommits < NameError; end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Ghoul
|
2
|
+
module UrlHelpers
|
3
|
+
def guides_path
|
4
|
+
return "/guides"
|
5
|
+
end
|
6
|
+
|
7
|
+
def guide_path(guide)
|
8
|
+
return "/guides/#{guide}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def repositories_path
|
12
|
+
url "/repositories"
|
13
|
+
end
|
14
|
+
|
15
|
+
def repository_path(repository)
|
16
|
+
url "/repository/#{repository}/trunk/tree"
|
17
|
+
end
|
18
|
+
|
19
|
+
def repository_git_url(repository)
|
20
|
+
return "http://#{@request.host_with_port}/repo/#{repository}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def repository_settings_path(repository)
|
24
|
+
url "/repository/#{repository}/settings"
|
25
|
+
end
|
26
|
+
|
27
|
+
def clone_url(repository)
|
28
|
+
return "http://#{@request.host_with_port}/repo/#{repository}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def commits_path(repository)
|
32
|
+
url "/repository/#{repository}/commits"
|
33
|
+
end
|
34
|
+
|
35
|
+
def commit_path(repository, commit)
|
36
|
+
url "/repository/#{repository}/commits/#{commit}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def blob_for_commit_path(repository, commit, splat="", name="")
|
40
|
+
parts = [repository, commit, "tree", splat, name].find_all { |i| i != ""}
|
41
|
+
url "/repository/#{parts.join("/")}"
|
42
|
+
end
|
43
|
+
alias_method :tree_for_commit_path, :blob_for_commit_path
|
44
|
+
|
45
|
+
def raw_blob_for_commit_path(repository, commit, splat)
|
46
|
+
url "/repository/#{repository}/#{commit}/raw/#{splat}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def diff_for_commit_path(repository, commit)
|
50
|
+
url "/repository/#{repository}/#{commit}/diff"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
.thoughtbot_button {
|
2
|
+
background-color: #ee432e;
|
3
|
+
background-image: -webkit-gradient(linear, left top, left bottom, from(#ee432e 0%), to(#c63929 50%));
|
4
|
+
/* Saf4+, Chrome */
|
5
|
+
background-image: -webkit-linear-gradient(top, #ee432e 0%, #c63929 50%, #b51700 50%, #891100 100%);
|
6
|
+
background-image: -moz-linear-gradient(top, #ee432e 0%, #c63929 50%, #b51700 50%, #891100 100%);
|
7
|
+
background-image: -ms-linear-gradient(top, #ee432e 0%, #c63929 50%, #b51700 50%, #891100 100%);
|
8
|
+
background-image: -o-linear-gradient(top, #ee432e 0%, #c63929 50%, #b51700 50%, #891100 100%);
|
9
|
+
background-image: linear-gradient(top, #ee432e 0%, #c63929 50%, #b51700 50%, #891100 100%);
|
10
|
+
border: 1px solid #951100;
|
11
|
+
-webkit-border-radius: 5px;
|
12
|
+
-moz-border-radius: 5px;
|
13
|
+
-ms-border-radius: 5px;
|
14
|
+
-o-border-radius: 5px;
|
15
|
+
border-radius: 5px;
|
16
|
+
-webkit-box-shadow: inset 0px 0px 0px 1px rgba(255, 115, 100, 0.4), 0 1px 3px #333333;
|
17
|
+
-moz-box-shadow: inset 0px 0px 0px 1px rgba(255, 115, 100, 0.4), 0 1px 3px #333333;
|
18
|
+
-ms-box-shadow: inset 0px 0px 0px 1px rgba(255, 115, 100, 0.4), 0 1px 3px #333333;
|
19
|
+
-o-box-shadow: inset 0px 0px 0px 1px rgba(255, 115, 100, 0.4), 0 1px 3px #333333;
|
20
|
+
box-shadow: inset 0px 0px 0px 1px rgba(255, 115, 100, 0.4), 0 1px 3px #333333;
|
21
|
+
color: #fff;
|
22
|
+
font: bold 20px "helvetica neue", helvetica, arial, sans-serif;
|
23
|
+
line-height: 1;
|
24
|
+
padding: 8px 10px 8px 10px;
|
25
|
+
text-align: center;
|
26
|
+
text-decoration:none;
|
27
|
+
text-shadow: 0px -1px 1px rgba(0, 0, 0, 0.8);
|
28
|
+
width: auto !important ;}
|
29
|
+
.thoughtbot_button:hover {
|
30
|
+
background-color: #f37873;
|
31
|
+
background-image: -webkit-gradient(linear, left top, left bottom, from(#f37873 0%), to(#db504d 50%));
|
32
|
+
/* Saf4+, Chrome */
|
33
|
+
background-image: -webkit-linear-gradient(top, #f37873 0%, #db504d 50%, #cb0500 50%, #a20601 100%);
|
34
|
+
background-image: -moz-linear-gradient(top, #f37873 0%, #db504d 50%, #cb0500 50%, #a20601 100%);
|
35
|
+
background-image: -ms-linear-gradient(top, #f37873 0%, #db504d 50%, #cb0500 50%, #a20601 100%);
|
36
|
+
background-image: -o-linear-gradient(top, #f37873 0%, #db504d 50%, #cb0500 50%, #a20601 100%);
|
37
|
+
background-image: linear-gradient(top, #f37873 0%, #db504d 50%, #cb0500 50%, #a20601 100%);
|
38
|
+
cursor: pointer; }
|
@@ -0,0 +1,136 @@
|
|
1
|
+
.CodeRay {
|
2
|
+
background-color: hsl(0,0%,95%);
|
3
|
+
border: 1px solid silver;
|
4
|
+
color: black;
|
5
|
+
}
|
6
|
+
.CodeRay pre {
|
7
|
+
margin: 0px;
|
8
|
+
}
|
9
|
+
|
10
|
+
span.CodeRay { white-space: pre; border: 0px; padding: 2px; }
|
11
|
+
|
12
|
+
table.CodeRay { border-collapse: collapse; width: 100%; padding: 2px; }
|
13
|
+
table.CodeRay td { padding: 2px 4px; vertical-align: top; }
|
14
|
+
|
15
|
+
.CodeRay .line-numbers {
|
16
|
+
background-color: #ccc;
|
17
|
+
color: gray;
|
18
|
+
text-align: right;
|
19
|
+
-webkit-user-select: none;
|
20
|
+
-moz-user-select: none;
|
21
|
+
user-select: none;
|
22
|
+
}
|
23
|
+
.CodeRay .line-numbers a {
|
24
|
+
background-color: #ccc !important;
|
25
|
+
color: gray !important;
|
26
|
+
text-decoration: none !important;
|
27
|
+
}
|
28
|
+
.CodeRay .line-numbers a:target { color: maroon !important; font-weight:bold; }
|
29
|
+
.CodeRay .line-numbers .highlighted { color: red !important; }
|
30
|
+
.CodeRay .line-numbers .highlighted a { color: red !important; }
|
31
|
+
.CodeRay span.line-numbers { padding: 0px 4px; }
|
32
|
+
.CodeRay .line { display: block; float: left; width: 100%; }
|
33
|
+
.CodeRay .code { width: 100%; }
|
34
|
+
.CodeRay .code pre { overflow: auto; }
|
35
|
+
|
36
|
+
.CodeRay .debug { color: white !important; background: blue !important; }
|
37
|
+
|
38
|
+
.CodeRay .annotation { color:#007 }
|
39
|
+
.CodeRay .attribute-name { color:#b48 }
|
40
|
+
.CodeRay .attribute-value { color:#700 }
|
41
|
+
.CodeRay .binary { color:#509 }
|
42
|
+
.CodeRay .char .content { color:#D20 }
|
43
|
+
.CodeRay .char .delimiter { color:#710 }
|
44
|
+
.CodeRay .char { color:#D20 }
|
45
|
+
.CodeRay .class { color:#B06; font-weight:bold }
|
46
|
+
.CodeRay .class-variable { color:#369 }
|
47
|
+
.CodeRay .color { color:#0A0 }
|
48
|
+
.CodeRay .comment { color:#777 }
|
49
|
+
.CodeRay .comment .char { color:#444 }
|
50
|
+
.CodeRay .comment .delimiter { color:#444 }
|
51
|
+
.CodeRay .complex { color:#A08 }
|
52
|
+
.CodeRay .constant { color:#036; font-weight:bold }
|
53
|
+
.CodeRay .decorator { color:#B0B }
|
54
|
+
.CodeRay .definition { color:#099; font-weight:bold }
|
55
|
+
.CodeRay .delimiter { color:black }
|
56
|
+
.CodeRay .directive { color:#088; font-weight:bold }
|
57
|
+
.CodeRay .doc { color:#970 }
|
58
|
+
.CodeRay .doc-string { color:#D42; font-weight:bold }
|
59
|
+
.CodeRay .doctype { color:#34b }
|
60
|
+
.CodeRay .entity { color:#800; font-weight:bold }
|
61
|
+
.CodeRay .error { color:#F00; background-color:#FAA }
|
62
|
+
.CodeRay .escape { color:#666 }
|
63
|
+
.CodeRay .exception { color:#C00; font-weight:bold }
|
64
|
+
.CodeRay .float { color:#60E }
|
65
|
+
.CodeRay .function { color:#06B; font-weight:bold }
|
66
|
+
.CodeRay .global-variable { color:#d70 }
|
67
|
+
.CodeRay .hex { color:#02b }
|
68
|
+
.CodeRay .imaginary { color:#f00 }
|
69
|
+
.CodeRay .include { color:#B44; font-weight:bold }
|
70
|
+
.CodeRay .inline { background-color: hsla(0,0%,0%,0.07); color: black }
|
71
|
+
.CodeRay .inline-delimiter { font-weight: bold; color: #666 }
|
72
|
+
.CodeRay .instance-variable { color:#33B }
|
73
|
+
.CodeRay .integer { color:#00D }
|
74
|
+
.CodeRay .key .char { color: #60f }
|
75
|
+
.CodeRay .key .delimiter { color: #404 }
|
76
|
+
.CodeRay .key { color: #606 }
|
77
|
+
.CodeRay .keyword { color:#080; font-weight:bold }
|
78
|
+
.CodeRay .label { color:#970; font-weight:bold }
|
79
|
+
.CodeRay .local-variable { color:#963 }
|
80
|
+
.CodeRay .namespace { color:#707; font-weight:bold }
|
81
|
+
.CodeRay .octal { color:#40E }
|
82
|
+
.CodeRay .operator { }
|
83
|
+
.CodeRay .predefined { color:#369; font-weight:bold }
|
84
|
+
.CodeRay .predefined-constant { color:#069 }
|
85
|
+
.CodeRay .predefined-type { color:#0a5; font-weight:bold }
|
86
|
+
.CodeRay .preprocessor { color:#579 }
|
87
|
+
.CodeRay .pseudo-class { color:#00C; font-weight:bold }
|
88
|
+
.CodeRay .regexp .content { color:#808 }
|
89
|
+
.CodeRay .regexp .delimiter { color:#404 }
|
90
|
+
.CodeRay .regexp .modifier { color:#C2C }
|
91
|
+
.CodeRay .regexp { background-color:hsla(300,100%,50%,0.06); }
|
92
|
+
.CodeRay .reserved { color:#080; font-weight:bold }
|
93
|
+
.CodeRay .shell .content { color:#2B2 }
|
94
|
+
.CodeRay .shell .delimiter { color:#161 }
|
95
|
+
.CodeRay .shell { background-color:hsla(120,100%,50%,0.06); }
|
96
|
+
.CodeRay .string .char { color: #b0b }
|
97
|
+
.CodeRay .string .content { color: #D20 }
|
98
|
+
.CodeRay .string .delimiter { color: #710 }
|
99
|
+
.CodeRay .string .modifier { color: #E40 }
|
100
|
+
.CodeRay .string { background-color:hsla(0,100%,50%,0.05); }
|
101
|
+
.CodeRay .symbol .content { color:#A60 }
|
102
|
+
.CodeRay .symbol .delimiter { color:#630 }
|
103
|
+
.CodeRay .symbol { color:#A60 }
|
104
|
+
.CodeRay .tag { color:#070 }
|
105
|
+
.CodeRay .type { color:#339; font-weight:bold }
|
106
|
+
.CodeRay .value { color: #088; }
|
107
|
+
.CodeRay .variable { color:#037 }
|
108
|
+
|
109
|
+
.CodeRay .insert { background: hsla(120,100%,50%,0.12) }
|
110
|
+
.CodeRay .delete { background: hsla(0,100%,50%,0.12) }
|
111
|
+
.CodeRay .change { color: #bbf; background: #007; }
|
112
|
+
.CodeRay .head { color: #f8f; background: #505 }
|
113
|
+
.CodeRay .head .filename { color: white; }
|
114
|
+
|
115
|
+
.CodeRay .delete .eyecatcher { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; }
|
116
|
+
.CodeRay .insert .eyecatcher { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
|
117
|
+
|
118
|
+
.CodeRay .insert .insert { color: #0c0; background:transparent; font-weight:bold }
|
119
|
+
.CodeRay .delete .delete { color: #c00; background:transparent; font-weight:bold }
|
120
|
+
.CodeRay .change .change { color: #88f }
|
121
|
+
.CodeRay .head .head { color: #f4f }
|
122
|
+
|
123
|
+
|
124
|
+
table.CodeRay {
|
125
|
+
width: auto;
|
126
|
+
}
|
127
|
+
|
128
|
+
#main .example {
|
129
|
+
width: 960px;
|
130
|
+
overflow: auto;
|
131
|
+
}
|
132
|
+
|
133
|
+
#main .CodeRay pre {
|
134
|
+
font-size: 13px ! important;
|
135
|
+
line-height: 15px;
|
136
|
+
}
|