gitgo 0.3.3

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.
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