ginatra 3.0.1 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -15
- data/.travis.yml +7 -6
- data/CONTRIBUTING.md +30 -0
- data/Gemfile +1 -9
- data/LICENSE.txt +30 -0
- data/README.md +63 -114
- data/Rakefile +10 -12
- data/bin/ginatra +79 -63
- data/config.ru +35 -3
- data/ginatra.gemspec +29 -18
- data/lib/ginatra.rb +161 -148
- data/lib/ginatra/config.rb +18 -121
- data/lib/ginatra/errors.rb +10 -0
- data/lib/ginatra/helpers.rb +154 -139
- data/lib/ginatra/repo.rb +67 -82
- data/lib/ginatra/repo_list.rb +25 -18
- data/lib/ginatra/repo_stats.rb +93 -0
- data/lib/ginatra/version.rb +4 -0
- data/lib/git/webby.rb +292 -0
- data/lib/git/webby/extensions.rb +10 -0
- data/lib/git/webby/http_backend.rb +177 -0
- data/lib/sinatra/partials.rb +1 -1
- data/public/css/application.css +6 -0
- data/public/css/custom.css +57 -0
- data/public/css/lib/bootstrap-responsive.min.css +9 -0
- data/public/css/lib/bootstrap.min.css +9 -0
- data/public/css/lib/highlight.css +209 -0
- data/public/img/glyphicons-halflings-white.png +0 -0
- data/public/img/glyphicons-halflings.png +0 -0
- data/public/img/spin.gif +0 -0
- data/public/js/application.js +5 -0
- data/public/js/custom.js +51 -0
- data/public/js/lib/bootstrap.min.js +6 -0
- data/public/js/lib/jquery.lazyload.min.js +2 -0
- data/public/js/lib/jquery.min.js +2 -0
- data/public/js/lib/jquery.pjax.js +739 -0
- data/repos/README.md +21 -8
- data/spec/ginatra/helpers_spec.rb +95 -0
- data/spec/ginatra/repo_list_spec.rb +66 -0
- data/spec/ginatra/repo_spec.rb +78 -0
- data/spec/ginatra/repo_stats_spec.rb +27 -0
- data/spec/ginatra_spec.rb +121 -0
- data/spec/spec_helper.rb +8 -17
- data/views/404.erb +18 -0
- data/views/500.erb +18 -0
- data/views/_footer.erb +7 -0
- data/views/_header.erb +12 -6
- data/views/_tree_nav.erb +53 -0
- data/views/atom.erb +32 -0
- data/views/blob.erb +27 -8
- data/views/commit.erb +95 -17
- data/views/empty_repo.erb +10 -0
- data/views/index.erb +27 -11
- data/views/layout.erb +16 -20
- data/views/log.erb +74 -54
- data/views/stats.erb +89 -0
- data/views/tree.erb +32 -20
- metadata +168 -94
- data/bin/ginatra-daemon +0 -87
- data/bin/ginatra-directory +0 -55
- data/bin/ginatra-server +0 -27
- data/bin/ginatra-setup +0 -28
- data/lib/ginatra/graph_commit.rb +0 -77
- 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/branch-graph.js +0 -170
- data/public/src/colour.css +0 -86
- data/public/src/commit.css +0 -211
- data/public/src/ginatra.js +0 -7
- data/public/src/github.css +0 -129
- data/public/src/graph.css +0 -9
- data/public/src/highlight.pack.js +0 -1
- data/public/src/index.css +0 -92
- data/public/src/lists.css +0 -25
- data/public/src/raphael.js +0 -7
- data/public/src/reset.css +0 -49
- data/public/src/table.css +0 -33
- data/public/src/type.css +0 -30
- data/rackup.ru +0 -5
- data/spec/graph_commit_spec.rb +0 -54
- data/spec/repo_list_spec.rb +0 -84
- data/spec/repo_spec.rb +0 -61
- data/views/_actor_box.erb +0 -13
- data/views/_commit_info_box.erb +0 -27
- data/views/_tree_part.erb +0 -11
- data/views/atom.builder +0 -32
- data/views/graph.erb +0 -15
data/repos/README.md
CHANGED
@@ -1,8 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
To make Ginatra see repositories, put them into this directory. You can do this
|
2
|
+
by several ways:
|
3
|
+
|
4
|
+
1. Clone repository here
|
5
|
+
|
6
|
+
git clone git://github.com/NARKOZ/ginatra.git
|
7
|
+
|
8
|
+
2. Symlink repository into there
|
9
|
+
|
10
|
+
ln -s /path/to/repo repos/
|
11
|
+
|
12
|
+
3. Copy repository here
|
13
|
+
|
14
|
+
cp -R /path/to/repo repos/
|
15
|
+
|
16
|
+
4. Move repository here
|
17
|
+
|
18
|
+
mv -R /path/to/repo repos/
|
19
|
+
|
20
|
+
Run `ginatra --help` for additional command line help and see `config.yml` file
|
21
|
+
for available settings.
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ginatra::Helpers do
|
4
|
+
before { allow(Time).to receive(:now).and_return(Time.new(2012, 12, 25, 0, 0, 0, '+00:00')) }
|
5
|
+
|
6
|
+
let(:repo) { Ginatra::RepoList.find('test') }
|
7
|
+
let(:commit) { repo.commit('095955b') }
|
8
|
+
|
9
|
+
describe "#secure_mail" do
|
10
|
+
it "returns masked email" do
|
11
|
+
expect(secure_mail('eggscellent@example.com')).to eq('eggs...@example.com')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#gravatar_image_tag" do
|
16
|
+
context "when options passed" do
|
17
|
+
it "returns a gravatar image tag with custom options" do
|
18
|
+
expect(
|
19
|
+
gravatar_image_tag('john@example.com', size: 100, alt: 'John', class: 'avatar')
|
20
|
+
).to eq("<img src='https://secure.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=100' alt='John' height='100' width='100' class='avatar'>")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when options not passed" do
|
25
|
+
it "returns a gravatar image tag with default options" do
|
26
|
+
expect(
|
27
|
+
gravatar_image_tag('john@example.com')
|
28
|
+
).to eq("<img src='https://secure.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=40' alt='john' height='40' width='40'>")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#file_icon" do
|
34
|
+
context "symbolic link" do
|
35
|
+
it "returns icon share-alt" do
|
36
|
+
expect(file_icon(40960)).to eq("<span class='icon-share-alt'></span>")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "executable file" do
|
41
|
+
it "returns icon asterisk" do
|
42
|
+
expect(file_icon(33261)).to eq("<span class='icon-asterisk'></span>")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "non-executable file" do
|
47
|
+
it "returns icon file" do
|
48
|
+
expect(file_icon(33188)).to eq("<span class='icon-file'></span>")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#nicetime" do
|
54
|
+
it "returns a time in nice format" do
|
55
|
+
expect(nicetime(Time.now)).to eq('Dec 25, 2012 – 00:00')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#time_tag" do
|
60
|
+
it "returns a time in nice format" do
|
61
|
+
expect(
|
62
|
+
time_tag(Time.now)
|
63
|
+
).to eq("<time datetime='2012-12-25T00:00:00+0000' title='2012-12-25 00:00:00'>December 25, 2012 00:00</time>")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#patch_link" do
|
68
|
+
it "returns a link for a commit patch" do
|
69
|
+
expect(
|
70
|
+
patch_link(commit, 'test')
|
71
|
+
).to eq("<a href='/test/commit/095955b6402c30ef24520bafdb8a8687df0a98d3.patch'>Download Patch</a>")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#empty_description_hint_for" do
|
76
|
+
it "returns a hint for a repo with empty description" do
|
77
|
+
hint_text = "Edit `#{repo.path}description` file to set the repository description."
|
78
|
+
expect(empty_description_hint_for(repo)).to eq("<span class='icon-exclamation-sign' title='#{hint_text}'></span>")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#atom_feed_url" do
|
83
|
+
context "when ref name passed" do
|
84
|
+
it "returns a link to repo reference atom feed" do
|
85
|
+
expect(atom_feed_url('test', 'master')).to eq("/test/master.atom")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when ref name not passed" do
|
90
|
+
it "returns a link to repo atom feed" do
|
91
|
+
expect(atom_feed_url('test')).to eq("/test.atom")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ginatra::RepoList do
|
4
|
+
let(:repo) { Ginatra::RepoList.find('test') }
|
5
|
+
let(:repo_list) { Ginatra::RepoList.list }
|
6
|
+
|
7
|
+
it "is an array of 'Ginatra::Repo'" do
|
8
|
+
repo_list.each do |repo|
|
9
|
+
expect(repo).to be_an_instance_of(Ginatra::Repo)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it "contains the test repo" do
|
14
|
+
expect(repo_list).to include(repo)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "has_repo? works for existing repo" do
|
18
|
+
expect(Ginatra::RepoList.instance.has_repo?('test')).to be true
|
19
|
+
end
|
20
|
+
|
21
|
+
it "has_repo? works for non-existant repo" do
|
22
|
+
expect(Ginatra::RepoList.instance.has_repo?('bad-test')).to be false
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "New repos added to repo directory" do
|
26
|
+
before(:each) do
|
27
|
+
@new_repo_name = 'temp-new-repo'
|
28
|
+
@repo_dir = File.join(current_path, '..', 'repos')
|
29
|
+
|
30
|
+
FileUtils.cd(@repo_dir) do |repo_dir|
|
31
|
+
FileUtils.mkdir_p(@new_repo_name)
|
32
|
+
FileUtils.cd(@new_repo_name) do |new_repo_dir|
|
33
|
+
`git init`
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should detect new repo after refresh" do
|
39
|
+
repo_list = Ginatra::RepoList.list # calling this should refresh the list
|
40
|
+
expect(Ginatra::RepoList.instance.has_repo?(@new_repo_name)).to be true
|
41
|
+
|
42
|
+
new_repo = Ginatra::RepoList.find(@new_repo_name)
|
43
|
+
expect(repo_list).to include(new_repo)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should detect when a repo has been removed after refresh" do
|
47
|
+
repo_list = Ginatra::RepoList.list # calling this should refresh the list
|
48
|
+
expect(Ginatra::RepoList.instance.has_repo?(@new_repo_name)).to be true
|
49
|
+
|
50
|
+
new_repo = Ginatra::RepoList.find(@new_repo_name)
|
51
|
+
expect(repo_list).to include(new_repo)
|
52
|
+
|
53
|
+
# remove the new repository from the file system
|
54
|
+
FileUtils.rm_rf File.join(@repo_dir, @new_repo_name), secure: true
|
55
|
+
|
56
|
+
repo_list = Ginatra::RepoList.list # refresh the repo list
|
57
|
+
|
58
|
+
expect(Ginatra::RepoList.instance.has_repo?(@new_repo_name)).to be false
|
59
|
+
expect(repo_list).to_not include(new_repo)
|
60
|
+
end
|
61
|
+
|
62
|
+
after(:each) do
|
63
|
+
FileUtils.rm_rf File.join(@repo_dir, @new_repo_name), secure: true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ginatra::Repo do
|
4
|
+
let(:repo) { Ginatra::RepoList.find('test') }
|
5
|
+
|
6
|
+
describe "repo" do
|
7
|
+
it "returns name" do
|
8
|
+
expect(repo.name).to eq("test")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns param" do
|
12
|
+
expect(repo.param).to eq("test")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns description" do
|
16
|
+
expect(repo.description).to eq("")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#commit" do
|
21
|
+
it "returns commit by sha" do
|
22
|
+
commit = repo.commit '095955b'
|
23
|
+
expect(commit).to be_a_kind_of(Rugged::Commit)
|
24
|
+
expect(commit.oid).to eq('095955b6402c30ef24520bafdb8a8687df0a98d3')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#commit_by_tag" do
|
29
|
+
it "returns commit by tag" do
|
30
|
+
commit = repo.commit_by_tag 'v0.0.3'
|
31
|
+
expect(commit).to be_a_kind_of(Rugged::Commit)
|
32
|
+
expect(commit.oid).to eq('0c386b293878fb5f69031a998d564ecb8c2fee4d')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#commits" do
|
37
|
+
context "when branch exist" do
|
38
|
+
it "returns an array of commits" do
|
39
|
+
commits = repo.commits('master', 2)
|
40
|
+
expect(commits).to be_a_kind_of(Array)
|
41
|
+
expect(commits.size).to eq(2)
|
42
|
+
expect(commits.first.oid).to eq('095955b6402c30ef24520bafdb8a8687df0a98d3')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when branch not exist" do
|
47
|
+
it "raises Ginatra::InvalidRef" do
|
48
|
+
expect { repo.commits('404-branch') }.to raise_error(Ginatra::InvalidRef)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#branches" do
|
54
|
+
it "returns an array of branches" do
|
55
|
+
branches = repo.branches
|
56
|
+
expect(branches).to be_a_kind_of(Array)
|
57
|
+
expect(branches.size).to eq(1)
|
58
|
+
expect(branches.first.name).to eq('master')
|
59
|
+
expect(branches.first.target.oid).to eq('095955b6402c30ef24520bafdb8a8687df0a98d3')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#branches_with" do
|
64
|
+
it "returns an array of branches including commit" do
|
65
|
+
branches = repo.branches_with('095955b6402c30ef24520bafdb8a8687df0a98d3')
|
66
|
+
expect(branches).to be_a_kind_of(Array)
|
67
|
+
expect(branches.size).to eq(1)
|
68
|
+
expect(branches.first.name).to eq('master')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#branch_exists?" do
|
73
|
+
it "checks existence of branch" do
|
74
|
+
expect(repo.branch_exists?('master')).to be true
|
75
|
+
expect(repo.branch_exists?('master-404')).to be false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ginatra::RepoStats do
|
4
|
+
let(:repo) { Ginatra::RepoList.find('test') }
|
5
|
+
let(:repo_stats) { Ginatra::RepoStats.new(repo, 'master') }
|
6
|
+
|
7
|
+
it "#license" do
|
8
|
+
expect(repo_stats.license).to eq('MIT')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "#commits_count" do
|
12
|
+
expect(repo_stats.commits_count).to eq(57)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "#contributors" do
|
16
|
+
contributors = repo_stats.contributors
|
17
|
+
expect(contributors).to be_a_kind_of(Array)
|
18
|
+
expect(contributors.size).to eq(2)
|
19
|
+
expect(contributors.first).to eq(['atmos@atmos.org', { author: 'Corey Donohoe', commits_count: 55 }])
|
20
|
+
end
|
21
|
+
|
22
|
+
it "#created_at" do
|
23
|
+
created_at = repo_stats.created_at
|
24
|
+
expect(created_at).to be_a_kind_of(Time)
|
25
|
+
expect(created_at.to_s).to include('2009-03-04')
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ginatra::App do
|
4
|
+
describe "main page" do
|
5
|
+
it "returns http success" do
|
6
|
+
get '/'
|
7
|
+
expect(last_response.status).to eq(200)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "repo commits atom feed" do
|
12
|
+
it "returns http success" do
|
13
|
+
get '/test.atom'
|
14
|
+
expect(last_response.status).to eq(200)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns application/xml" do
|
18
|
+
get '/test.atom'
|
19
|
+
expect(last_response.headers['Content-Type']).to match("application/xml.*")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "repo page" do
|
24
|
+
it "returns http success" do
|
25
|
+
get '/test'
|
26
|
+
expect(last_response.status).to eq(200)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "repo stats page" do
|
31
|
+
it "returns http success" do
|
32
|
+
get '/test/stats/master'
|
33
|
+
expect(last_response.status).to eq(200)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "branch commits atom feed" do
|
38
|
+
it "returns http success" do
|
39
|
+
get '/test/master.atom'
|
40
|
+
expect(last_response.status).to eq(200)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns application/xml" do
|
44
|
+
get '/test/master.atom'
|
45
|
+
expect(last_response.headers['Content-Type']).to match("application/xml.*")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "repo branch page" do
|
50
|
+
it "returns http success" do
|
51
|
+
get '/test/master'
|
52
|
+
expect(last_response.status).to eq(200)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "repo commit patch" do
|
57
|
+
it "returns http success" do
|
58
|
+
get "/test/commit/095955b.patch"
|
59
|
+
expect(last_response.status).to eq(200)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns text/plain" do
|
63
|
+
get "/test/commit/095955b.patch"
|
64
|
+
expect(last_response.headers['Content-Type']).to match("text/plain.*")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "repo commit page" do
|
69
|
+
it "returns http success" do
|
70
|
+
get "/test/commit/095955b"
|
71
|
+
expect(last_response.status).to eq(200)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "repo tag page" do
|
76
|
+
it "returns http success" do
|
77
|
+
get "/test/tag/v0.0.3"
|
78
|
+
expect(last_response.status).to eq(200)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "repo tree page" do
|
83
|
+
it "returns http success" do
|
84
|
+
get "/test/tree/master"
|
85
|
+
expect(last_response.status).to eq(200)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "repo tree page with path" do
|
90
|
+
it "returns http success" do
|
91
|
+
get "/test/tree/master/examples"
|
92
|
+
expect(last_response.status).to eq(200)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "repo blob page with path" do
|
97
|
+
it "returns http success" do
|
98
|
+
get '/test/blob/master/Gemfile'
|
99
|
+
expect(last_response.status).to eq(200)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "repo blob raw page" do
|
104
|
+
it "returns http success" do
|
105
|
+
get '/test/raw/master/Gemfile'
|
106
|
+
expect(last_response.status).to eq(200)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "returns text/plain" do
|
110
|
+
get '/test/raw/master/Gemfile'
|
111
|
+
expect(last_response.headers['Content-Type']).to match("text/plain.*")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "repo log page" do
|
116
|
+
it "returns http success" do
|
117
|
+
get '/test/master/page/1'
|
118
|
+
expect(last_response.status).to eq(200)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,27 +1,18 @@
|
|
1
|
+
ENV['RACK_ENV'] = 'test'
|
1
2
|
|
2
|
-
require 'bundler'
|
3
|
-
Bundler.setup(:default, :test)
|
4
3
|
require 'rspec'
|
5
4
|
require 'ginatra'
|
6
|
-
require 'webrat'
|
7
5
|
require 'rack/test'
|
8
6
|
|
9
|
-
|
10
|
-
|
7
|
+
def app
|
8
|
+
Ginatra::App
|
11
9
|
end
|
12
10
|
|
13
|
-
current_path
|
14
|
-
|
15
|
-
|
16
|
-
Ginatra::Config[:git_dirs] = ["#{current_path}/../repos/*"]
|
11
|
+
def current_path
|
12
|
+
File.expand_path File.dirname(__FILE__)
|
13
|
+
end
|
17
14
|
|
18
15
|
RSpec.configure do |config|
|
19
|
-
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
config.include(Rack::Test::Methods)
|
24
|
-
config.include(Webrat::Methods)
|
25
|
-
config.include(Webrat::Matchers)
|
16
|
+
config.include Rack::Test::Methods
|
17
|
+
config.include Ginatra::Helpers
|
26
18
|
end
|
27
|
-
|