gitgo 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/History +44 -0
  2. data/License.txt +22 -0
  3. data/README +45 -0
  4. data/bin/gitgo +4 -0
  5. data/lib/gitgo.rb +1 -0
  6. data/lib/gitgo/app.rb +63 -0
  7. data/lib/gitgo/controller.rb +89 -0
  8. data/lib/gitgo/controllers/code.rb +198 -0
  9. data/lib/gitgo/controllers/issue.rb +76 -0
  10. data/lib/gitgo/controllers/repo.rb +186 -0
  11. data/lib/gitgo/controllers/wiki.rb +19 -0
  12. data/lib/gitgo/document.rb +680 -0
  13. data/lib/gitgo/document/invalid_document_error.rb +34 -0
  14. data/lib/gitgo/documents/comment.rb +20 -0
  15. data/lib/gitgo/documents/issue.rb +56 -0
  16. data/lib/gitgo/git.rb +941 -0
  17. data/lib/gitgo/git/tree.rb +315 -0
  18. data/lib/gitgo/git/utils.rb +59 -0
  19. data/lib/gitgo/helper.rb +3 -0
  20. data/lib/gitgo/helper/doc.rb +28 -0
  21. data/lib/gitgo/helper/form.rb +88 -0
  22. data/lib/gitgo/helper/format.rb +200 -0
  23. data/lib/gitgo/helper/html.rb +19 -0
  24. data/lib/gitgo/helper/utils.rb +85 -0
  25. data/lib/gitgo/index.rb +421 -0
  26. data/lib/gitgo/index/idx_file.rb +119 -0
  27. data/lib/gitgo/index/sha_file.rb +135 -0
  28. data/lib/gitgo/patches/grit.rb +47 -0
  29. data/lib/gitgo/repo.rb +626 -0
  30. data/lib/gitgo/repo/graph.rb +333 -0
  31. data/lib/gitgo/repo/node.rb +122 -0
  32. data/lib/gitgo/rest.rb +87 -0
  33. data/lib/gitgo/server.rb +114 -0
  34. data/lib/gitgo/version.rb +8 -0
  35. data/public/css/gitgo.css +24 -0
  36. data/public/javascript/gitgo.js +148 -0
  37. data/public/javascript/jquery-1.4.2.min.js +154 -0
  38. data/views/app/index.erb +4 -0
  39. data/views/app/timeline.erb +27 -0
  40. data/views/app/welcome.erb +13 -0
  41. data/views/code/_comment.erb +10 -0
  42. data/views/code/_comment_form.erb +14 -0
  43. data/views/code/_comments.erb +5 -0
  44. data/views/code/_commit.erb +25 -0
  45. data/views/code/_grepnav.erb +5 -0
  46. data/views/code/_treenav.erb +3 -0
  47. data/views/code/blob.erb +6 -0
  48. data/views/code/commit_grep.erb +35 -0
  49. data/views/code/commits.erb +11 -0
  50. data/views/code/diff.erb +10 -0
  51. data/views/code/grep.erb +32 -0
  52. data/views/code/index.erb +17 -0
  53. data/views/code/obj/blob.erb +4 -0
  54. data/views/code/obj/commit.erb +25 -0
  55. data/views/code/obj/tag.erb +25 -0
  56. data/views/code/obj/tree.erb +9 -0
  57. data/views/code/tree.erb +9 -0
  58. data/views/error.erb +19 -0
  59. data/views/issue/_issue.erb +15 -0
  60. data/views/issue/_issue_form.erb +39 -0
  61. data/views/issue/edit.erb +11 -0
  62. data/views/issue/index.erb +28 -0
  63. data/views/issue/new.erb +5 -0
  64. data/views/issue/show.erb +27 -0
  65. data/views/layout.erb +34 -0
  66. data/views/not_found.erb +1 -0
  67. data/views/repo/fsck.erb +29 -0
  68. data/views/repo/help.textile +5 -0
  69. data/views/repo/help/faq.textile +19 -0
  70. data/views/repo/help/howto.textile +31 -0
  71. data/views/repo/help/trouble.textile +28 -0
  72. data/views/repo/idx.erb +29 -0
  73. data/views/repo/index.erb +72 -0
  74. data/views/repo/status.erb +16 -0
  75. data/views/wiki/index.erb +3 -0
  76. metadata +253 -0
data/History ADDED
@@ -0,0 +1,44 @@
1
+ == 0.3.3 2010-04-28
2
+
3
+ Fixed (hopefully) usage in repos with no user name/email set.
4
+
5
+ == 0.3.2 2010-04-27
6
+
7
+ Fixed (hopefully) the cause of zero-padded file modes warning.
8
+
9
+ == 0.3.1 2010-04-26
10
+
11
+ Improvements to repo lifecycle.
12
+
13
+ == 0.3.0 2010-04-26
14
+
15
+ Updated internal data store to (more or less) halve the overhead of each new
16
+ document by storing document information inline with associations. Index now
17
+ assigns shas an integer index for faster comparisons and smaller index files.
18
+ Continued overhaul of internals. General updates to the interface.
19
+
20
+ == 0.2.0 2010-03-29
21
+
22
+ This release significantly changes the internals of Gitgo. Old gitgo branches
23
+ will not be compatible. To migrate a gitgo-0.1.* branch to the new storage
24
+ format:
25
+
26
+ % git clone git://github.com/bahuvrihi/gitgo.git
27
+ % cd gitgo
28
+ % git checkout migrate-0.2.0
29
+ % ruby script/migrate-0.2.0.rb PATH_TO_REPO SOURCE_BRANCH TARGET_BRANCH
30
+
31
+ Then rename the target branch as necessary. You will also have to remove the
32
+ old gitgo files:
33
+
34
+ % cd <path_to_repo>
35
+ % rm -rf .git/gitgo
36
+
37
+ Major changes:
38
+
39
+ * changed document serialization format to JSON
40
+ * complete overhaul of internal classes
41
+ * implemented a more robust system for calculating
42
+ (and drawing) a document graph
43
+ * temporary removal of comments
44
+ * improvements to indexing system
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2010 Pinnacol Assurance
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software. Except as contained in this
12
+ notice, the name(s) of the above copyright holders shall not be used in
13
+ advertising or otherwise to promote the sale, use or other dealings in this
14
+ Software without prior written authorization.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
data/README ADDED
@@ -0,0 +1,45 @@
1
+ = Gitgo
2
+
3
+ Gitgo -- git-driven issues, comments, and a wiki... to go.
4
+
5
+ == Description
6
+
7
+ Gitgo is an issue tracker that stores issue information in a git repository.
8
+
9
+ At present gitgo is in a developmental state. While the backend and data model
10
+ both work and appear to be robust, the front-end is highly lacking. Usage will
11
+ be difficult without insider knowledge.
12
+
13
+ == Usage
14
+
15
+ In the working directory for a git repository:
16
+
17
+ % gitgo
18
+
19
+ Then visit http://localhost:8080 in a web browser.
20
+
21
+ == Installation
22
+
23
+ Gitgo is not available as a gem yet. To clone the project and build your own:
24
+
25
+ % git clone git://github.com/pinnacol/gitgo.git
26
+ % cd gitgo
27
+ % rake gem
28
+ % gem install pkg/gitgo-...
29
+
30
+ == Development
31
+
32
+ Gitgo is open-source and welcomes help from the community! To get started:
33
+
34
+ % git clone git://github.com/pinnacol/gitgo.git
35
+ % cd gitgo
36
+ % rake test
37
+
38
+ To see bugs tracked in the gitgo repo:
39
+
40
+ % bin/gitgo
41
+
42
+ == Info
43
+
44
+ Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com]
45
+ License:: {MIT-Style}[link:files/License_txt.html]
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'gitgo'
4
+ Gitgo::Server.start
@@ -0,0 +1 @@
1
+ require 'gitgo/server'
@@ -0,0 +1,63 @@
1
+ require 'gitgo/controller'
2
+ require 'gitgo/controllers/code'
3
+ require 'gitgo/controllers/issue'
4
+ require 'gitgo/controllers/repo'
5
+ require 'gitgo/controllers/wiki'
6
+
7
+ module Gitgo
8
+ class App < Controller
9
+ set :views, File.expand_path("views/app", ROOT)
10
+ set :static, true
11
+
12
+ get('/') { repo.head ? index : welcome }
13
+ get('/timeline') { timeline }
14
+
15
+ use Controllers::Code
16
+ use Controllers::Issue
17
+ use Controllers::Wiki
18
+ use Controllers::Repo
19
+
20
+ def index
21
+ erb :index
22
+ end
23
+
24
+ def welcome
25
+ erb :welcome, :locals => {
26
+ :branch => repo.branch,
27
+ :remotes => repo.refs
28
+ }
29
+ end
30
+
31
+ def timeline
32
+ Document.update_index
33
+
34
+ page = (request[:page] || 0).to_i
35
+ per_page = (request[:per_page] || 5).to_i
36
+
37
+ author = request[:author]
38
+ author = '' if author == 'unknown'
39
+
40
+ docs = repo.timeline(:n => per_page, :offset => page * per_page) do |sha|
41
+ author.nil? || repo[sha]['author'].include?("<#{author}>")
42
+ end.collect do |sha|
43
+ Document.cast(repo[sha], sha)
44
+ end.sort_by do |doc|
45
+ doc.date
46
+ end
47
+
48
+ erb :timeline, :locals => {
49
+ :page => page,
50
+ :per_page => per_page,
51
+ :docs => docs,
52
+ :author => author,
53
+ :authors => repo.index.values('email'),
54
+ :active_sha => session_head
55
+ }
56
+ end
57
+
58
+ def build_query(params)
59
+ params.delete_if {|key, value| value.nil? }
60
+ super(params)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,89 @@
1
+ require 'erb'
2
+ require 'sinatra/base'
3
+ require 'gitgo/helper'
4
+ require 'gitgo/document'
5
+ require 'gitgo/rest'
6
+
7
+ module Gitgo
8
+ class Controller < Sinatra::Base
9
+ ROOT = File.expand_path(File.dirname(__FILE__) + "/../..")
10
+ HEAD = 'gitgo.head'
11
+ MOUNT = 'gitgo.mount'
12
+
13
+ set :root, ROOT
14
+ set :raise_errors, Proc.new { test? }
15
+ set :dump_errors, true
16
+
17
+ template(:layout) do
18
+ File.read(File.join(ROOT, "views/layout.erb"))
19
+ end
20
+
21
+ not_found do
22
+ erb :not_found, :views => path("views")
23
+ end
24
+
25
+ error Exception do
26
+ err = env['sinatra.error']
27
+ resetable = err.kind_of?(Errno::ENOENT) && err.message =~ /No such file or directory - .*idx/
28
+
29
+ erb :error, :views => path("views"), :locals => {:err => err, :resetable => resetable}
30
+ end
31
+
32
+ def initialize(app=nil, repo=nil)
33
+ super(app)
34
+ @repo = repo
35
+ end
36
+
37
+ # Returns the path expanded relative to the Gitgo::ROOT directory. Paths
38
+ # often need to be expanded like this so that they will be correct when
39
+ # Gitgo is running as a gem.
40
+ def path(path)
41
+ File.expand_path(path, ROOT)
42
+ end
43
+
44
+ def repo
45
+ @repo ||= Repo.current
46
+ end
47
+
48
+ def call(env)
49
+ env[Repo::REPO] ||= @repo
50
+ Repo.with_env(env) { super(env) }
51
+ end
52
+
53
+ def session_head
54
+ # grit.head will be nil if not on a local branch
55
+ @session_head ||= begin
56
+ if session.has_key?(HEAD)
57
+ session[HEAD]
58
+ else
59
+ grit = repo.git.grit
60
+ session[HEAD] = grit.head ? grit.head.name : nil
61
+ end
62
+ end
63
+ end
64
+
65
+ def session_head=(input)
66
+ @session_head = session[HEAD] = input
67
+ end
68
+
69
+ def mount_point
70
+ @mount_point ||= (env[MOUNT] || '/')
71
+ end
72
+
73
+ def url(paths)
74
+ File.join(mount_point, *paths)
75
+ end
76
+
77
+ def format
78
+ @format ||= Helper::Format.new(self)
79
+ end
80
+
81
+ def form
82
+ @form ||= Helper::Form.new(self)
83
+ end
84
+
85
+ def html
86
+ Helper::Html
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,198 @@
1
+ require 'gitgo/controller'
2
+ require 'gitgo/documents/comment'
3
+
4
+ module Gitgo
5
+ module Controllers
6
+ class Code < Controller
7
+ include Rest
8
+
9
+ set :views, File.expand_path("views/code", ROOT)
10
+
11
+ get('/code') { index }
12
+ get('/blob') { blob_grep }
13
+ get('/tree') { tree_grep }
14
+ get('/commit') { commit_grep }
15
+
16
+ get('/blob/:treeish/*') {|treeish, path| show_blob(treeish, path) }
17
+ get('/tree/:treeish') {|treeish| show_tree(treeish, '') }
18
+ get('/tree/:treeish/*') {|treeish, path| show_tree(treeish, path) }
19
+ get('/commit/:treeish') {|treeish| show_commit(treeish) }
20
+ get('/commits/:treeish') {|treeish| show_commits(treeish) }
21
+ get('/obj/:sha') {|sha| show_object(sha) }
22
+
23
+ get('/comment/:sha') {|sha| read(sha) }
24
+ post('/comment') { create }
25
+ post('/comment/:sha') do |sha|
26
+ _method = request[:_method]
27
+ case _method
28
+ when /\Aupdate\z/i then update(obj)
29
+ when /\Adelete\z/i then destroy(obj)
30
+ else raise("unknown post method: #{_method}")
31
+ end
32
+ end
33
+ put('/comment/:sha') {|sha| update(sha) }
34
+ delete('/comment/:sha') {|sha| destroy(sha) }
35
+
36
+ Comment = Documents::Comment
37
+
38
+ def git
39
+ @git ||= repo.git
40
+ end
41
+
42
+ def grit
43
+ @grit ||= git.grit
44
+ end
45
+
46
+ def model
47
+ Comment
48
+ end
49
+
50
+ #
51
+ # actions
52
+ #
53
+
54
+ def index
55
+ erb :index, :locals => {
56
+ :branches => grit.branches,
57
+ :tags => grit.tags
58
+ }
59
+ end
60
+
61
+ def treeish
62
+ request['at'] || grit.head.commit
63
+ end
64
+
65
+ def grep_opts(overrides={})
66
+ {
67
+ :ignore_case => request['ignore_case'] == 'true',
68
+ :invert_match => request['invert_match'] == 'true',
69
+ :fixed_strings => request['fixed_strings'] == 'true',
70
+ }.merge!(overrides)
71
+ end
72
+
73
+ def blob_grep
74
+ options = grep_opts(:e => request['pattern'])
75
+
76
+ selected = []
77
+ git.grep(options, treeish) do |path, blob|
78
+ selected << [path, blob.id]
79
+ end
80
+
81
+ erb :grep, :locals => options.merge!(
82
+ :type => 'blob',
83
+ :at => treeish,
84
+ :selected => selected,
85
+ :refs => grit.refs
86
+ )
87
+ end
88
+
89
+ def tree_grep
90
+ options = grep_opts(:e => request['pattern'])
91
+
92
+ selected = []
93
+ git.tree_grep(options, treeish) do |path, blob|
94
+ selected << [path, blob.id]
95
+ end
96
+
97
+ erb :grep, :locals => options.merge!(
98
+ :type => 'tree',
99
+ :at => treeish,
100
+ :selected => selected,
101
+ :refs => grit.refs
102
+ )
103
+ end
104
+
105
+ def commit_grep
106
+ options = grep_opts(
107
+ :author => request['author'],
108
+ :committer => request['committer'],
109
+ :grep => request['grep'],
110
+ :regexp_ignore_case => request['regexp_ignore_case'] == 'true',
111
+ :fixed_strings => request['fixed_strings'] == 'true',
112
+ :all_match => request['all_match'] == 'true',
113
+ :max_count => request['max_count'] || '10'
114
+ )
115
+
116
+ selected = []
117
+ git.commit_grep(options, treeish) {|sha| selected << sha }
118
+
119
+ erb :commit_grep, :locals => options.merge!(
120
+ :selected => selected
121
+ )
122
+ end
123
+
124
+ def show_blob(treeish, path)
125
+ commit = grit.commit(treeish) || not_found
126
+ blob = commit.tree / path || not_found
127
+
128
+ erb :blob, :locals => {
129
+ :commit => commit,
130
+ :treeish => treeish,
131
+ :blob => blob,
132
+ :path => path
133
+ }
134
+ end
135
+
136
+ def show_tree(treeish, path)
137
+ commit = grit.commit(treeish) || not_found
138
+ tree = path.split("/").inject(commit.tree) do |obj, name|
139
+ not_found if obj.nil?
140
+ obj.trees.find {|obj| obj.name == name }
141
+ end
142
+
143
+ erb :tree, :locals => {
144
+ :commit => commit,
145
+ :treeish => treeish,
146
+ :tree => tree,
147
+ :path => path
148
+ }
149
+ end
150
+
151
+ def show_commit(treeish)
152
+ commit = grit.commit(treeish) || not_found
153
+ erb :diff, :locals => {
154
+ :commit => commit,
155
+ :treeish => treeish
156
+ }
157
+ end
158
+
159
+ def show_commits(treeish)
160
+ commit = grit.commit(treeish)
161
+ page = (request[:page] || 0).to_i
162
+ per_page = (request[:per_page] || 10).to_i
163
+
164
+ erb :commits, :locals => {
165
+ :treeish => treeish,
166
+ :page => page,
167
+ :per_page => per_page,
168
+ :commits => grit.commits(commit.sha, per_page, page * per_page)
169
+ }
170
+ end
171
+
172
+ def show_object(sha)
173
+ sha = git.resolve(sha)
174
+
175
+ case
176
+ when request['content'] == 'true'
177
+ response['Content-Type'] = 'text/plain'
178
+ grit.git.cat_file({:p => true}, sha)
179
+
180
+ when request['download'] == 'true'
181
+ response['Content-Type'] = 'text/plain'
182
+ response['Content-Disposition'] = "attachment; filename=#{sha};"
183
+ raw_object = grit.git.ruby_git.get_raw_object_by_sha1(sha)
184
+ "%s %d\0" % [raw_object.type, raw_object.content.length] + raw_object.content
185
+
186
+ else
187
+ type = git.type(sha).to_sym
188
+ obj = git.get(type, sha) or not_found
189
+
190
+ erb type, :locals => {
191
+ :sha => sha,
192
+ :obj => obj
193
+ }, :views => path('views/code/obj')
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end