ginatra 3.0.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -15
  3. data/.travis.yml +7 -6
  4. data/CONTRIBUTING.md +30 -0
  5. data/Gemfile +1 -9
  6. data/LICENSE.txt +30 -0
  7. data/README.md +63 -114
  8. data/Rakefile +10 -12
  9. data/bin/ginatra +79 -63
  10. data/config.ru +35 -3
  11. data/ginatra.gemspec +29 -18
  12. data/lib/ginatra.rb +161 -148
  13. data/lib/ginatra/config.rb +18 -121
  14. data/lib/ginatra/errors.rb +10 -0
  15. data/lib/ginatra/helpers.rb +154 -139
  16. data/lib/ginatra/repo.rb +67 -82
  17. data/lib/ginatra/repo_list.rb +25 -18
  18. data/lib/ginatra/repo_stats.rb +93 -0
  19. data/lib/ginatra/version.rb +4 -0
  20. data/lib/git/webby.rb +292 -0
  21. data/lib/git/webby/extensions.rb +10 -0
  22. data/lib/git/webby/http_backend.rb +177 -0
  23. data/lib/sinatra/partials.rb +1 -1
  24. data/public/css/application.css +6 -0
  25. data/public/css/custom.css +57 -0
  26. data/public/css/lib/bootstrap-responsive.min.css +9 -0
  27. data/public/css/lib/bootstrap.min.css +9 -0
  28. data/public/css/lib/highlight.css +209 -0
  29. data/public/img/glyphicons-halflings-white.png +0 -0
  30. data/public/img/glyphicons-halflings.png +0 -0
  31. data/public/img/spin.gif +0 -0
  32. data/public/js/application.js +5 -0
  33. data/public/js/custom.js +51 -0
  34. data/public/js/lib/bootstrap.min.js +6 -0
  35. data/public/js/lib/jquery.lazyload.min.js +2 -0
  36. data/public/js/lib/jquery.min.js +2 -0
  37. data/public/js/lib/jquery.pjax.js +739 -0
  38. data/repos/README.md +21 -8
  39. data/spec/ginatra/helpers_spec.rb +95 -0
  40. data/spec/ginatra/repo_list_spec.rb +66 -0
  41. data/spec/ginatra/repo_spec.rb +78 -0
  42. data/spec/ginatra/repo_stats_spec.rb +27 -0
  43. data/spec/ginatra_spec.rb +121 -0
  44. data/spec/spec_helper.rb +8 -17
  45. data/views/404.erb +18 -0
  46. data/views/500.erb +18 -0
  47. data/views/_footer.erb +7 -0
  48. data/views/_header.erb +12 -6
  49. data/views/_tree_nav.erb +53 -0
  50. data/views/atom.erb +32 -0
  51. data/views/blob.erb +27 -8
  52. data/views/commit.erb +95 -17
  53. data/views/empty_repo.erb +10 -0
  54. data/views/index.erb +27 -11
  55. data/views/layout.erb +16 -20
  56. data/views/log.erb +74 -54
  57. data/views/stats.erb +89 -0
  58. data/views/tree.erb +32 -20
  59. metadata +168 -94
  60. data/bin/ginatra-daemon +0 -87
  61. data/bin/ginatra-directory +0 -55
  62. data/bin/ginatra-server +0 -27
  63. data/bin/ginatra-setup +0 -28
  64. data/lib/ginatra/graph_commit.rb +0 -77
  65. data/public/img/add.png +0 -0
  66. data/public/img/diff.png +0 -0
  67. data/public/img/doc.png +0 -0
  68. data/public/img/rm.png +0 -0
  69. data/public/img/tree.png +0 -0
  70. data/public/src/branch-graph.js +0 -170
  71. data/public/src/colour.css +0 -86
  72. data/public/src/commit.css +0 -211
  73. data/public/src/ginatra.js +0 -7
  74. data/public/src/github.css +0 -129
  75. data/public/src/graph.css +0 -9
  76. data/public/src/highlight.pack.js +0 -1
  77. data/public/src/index.css +0 -92
  78. data/public/src/lists.css +0 -25
  79. data/public/src/raphael.js +0 -7
  80. data/public/src/reset.css +0 -49
  81. data/public/src/table.css +0 -33
  82. data/public/src/type.css +0 -30
  83. data/rackup.ru +0 -5
  84. data/spec/graph_commit_spec.rb +0 -54
  85. data/spec/repo_list_spec.rb +0 -84
  86. data/spec/repo_spec.rb +0 -61
  87. data/views/_actor_box.erb +0 -13
  88. data/views/_commit_info_box.erb +0 -27
  89. data/views/_tree_part.erb +0 -11
  90. data/views/atom.builder +0 -32
  91. data/views/graph.erb +0 -15
data/repos/README.md CHANGED
@@ -1,8 +1,21 @@
1
- From the top README:
2
-
3
- > To clone repositories so that Ginatra can see them, clone the repositories into `./repos/` - they will be served automatically. Use the `--bare` switch to both save space and make sure Ginatra can read them. If you rename them, make sure the directory ends in `.git'. For Example:
4
- >
5
- > cd repos
6
- > git clone --bare git://github.com/lenary/ginatra.git
7
- > git clone --bare git://github.com/mojombo/grit.git fun.git
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 &ndash; 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
- Webrat.configure do |config|
10
- config.mode = :rack
7
+ def app
8
+ Ginatra::App
11
9
  end
12
10
 
13
- current_path = File.expand_path(File.dirname(__FILE__))
14
-
15
- Ginatra::App.set :environment, :test
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
- def app
20
- Ginatra::App
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
-