ginatra 3.0.1 → 4.0.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.
- 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
|
-
|