dolt 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/Gemfile.lock +25 -5
  2. data/Readme.md +90 -16
  3. data/bin/dolt +22 -4
  4. data/dolt.gemspec +10 -2
  5. data/lib/dolt/disk_repo_resolver.rb +3 -5
  6. data/lib/dolt/git/blame.rb +112 -0
  7. data/lib/dolt/git/commit.rb +73 -0
  8. data/lib/dolt/git/repository.rb +26 -24
  9. data/lib/dolt/repo_actions.rb +32 -19
  10. data/lib/dolt/sinatra/actions.rb +51 -18
  11. data/lib/dolt/sinatra/multi_repo_browser.rb +30 -3
  12. data/lib/dolt/sinatra/single_repo_browser.rb +36 -2
  13. data/lib/dolt/template_renderer.rb +7 -8
  14. data/lib/dolt/version.rb +1 -1
  15. data/lib/dolt/view.rb +3 -61
  16. data/lib/dolt/view/blame.rb +57 -0
  17. data/lib/dolt/view/blob.rb +60 -0
  18. data/lib/dolt/view/breadcrumb.rb +10 -17
  19. data/lib/dolt/{git/blob.rb → view/commit.rb} +5 -11
  20. data/lib/dolt/view/gravatar.rb +29 -0
  21. data/lib/dolt/{git/shell.rb → view/markup.rb} +10 -16
  22. data/lib/dolt/view/multi_repository.rb +27 -0
  23. data/lib/dolt/{async/deferrable_child_process.rb → view/object.rb} +11 -24
  24. data/lib/dolt/view/single_repository.rb +27 -0
  25. data/lib/dolt/view/smart_blob_renderer.rb +33 -0
  26. data/lib/dolt/view/syntax_highlight.rb +86 -0
  27. data/lib/dolt/view/tree.rb +69 -0
  28. data/test/dolt/git/blame_test.rb +128 -0
  29. data/test/dolt/git/commit_test.rb +89 -0
  30. data/test/dolt/git/repository_test.rb +24 -73
  31. data/test/dolt/repo_actions_test.rb +77 -15
  32. data/test/dolt/sinatra/actions_test.rb +168 -8
  33. data/test/dolt/template_renderer_test.rb +44 -10
  34. data/test/dolt/templates/blame_test.rb +56 -0
  35. data/test/dolt/{views → templates}/blob_test.rb +44 -34
  36. data/test/dolt/templates/commits_test.rb +61 -0
  37. data/test/dolt/templates/raw_test.rb +41 -0
  38. data/test/dolt/templates/tree_test.rb +51 -0
  39. data/test/dolt/view/blame_test.rb +122 -0
  40. data/test/dolt/view/blob_test.rb +90 -0
  41. data/test/dolt/view/breadcrumb_test.rb +46 -0
  42. data/test/dolt/view/commit_test.rb +31 -0
  43. data/test/dolt/view/gravatar_test.rb +30 -0
  44. data/test/dolt/view/markup_test.rb +30 -0
  45. data/test/dolt/{git/blob_test.rb → view/multi_repository_test.rb} +10 -24
  46. data/test/dolt/view/object_test.rb +71 -0
  47. data/test/dolt/view/single_repository_test.rb +30 -0
  48. data/test/dolt/{view_test.rb → view/syntax_highlight_test.rb} +40 -27
  49. data/test/dolt/view/tree_test.rb +115 -0
  50. data/test/test_helper.rb +18 -13
  51. data/vendor/ui/css/gitorious.css +20 -8
  52. data/views/blame.erb +41 -0
  53. data/views/blob.erb +6 -9
  54. data/views/commits.erb +23 -0
  55. data/views/index.erb +25 -0
  56. data/views/raw.erb +19 -0
  57. data/views/tree.erb +28 -26
  58. metadata +156 -26
  59. data/lib/dolt/git/tree.rb +0 -65
  60. data/lib/dolt/view/highlighter.rb +0 -52
  61. data/test/dolt/git/shell_test.rb +0 -112
  62. data/test/dolt/git/tree_test.rb +0 -120
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+ #--
3
+ # Copyright (C) 2012 Gitorious AS
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #++
18
+
19
+ module Dolt
20
+ module View
21
+ module Blame
22
+ def blame_annotations(blame)
23
+ blame.chunks.inject([]) do |blames, chunk|
24
+ blames << chunk
25
+ (chunk[:lines].length - 1).times { blames << nil }
26
+ blames
27
+ end
28
+ end
29
+
30
+ def blame_lines(path, blame)
31
+ lines = blame.chunks.inject([]) do |lines, chunk|
32
+ lines.concat(chunk[:lines])
33
+ end
34
+
35
+ return lines unless respond_to?(:highlight)
36
+ highlight(path, lines.join("\n")).split("\n")
37
+ end
38
+
39
+ def blame_annotation_cell(annotation)
40
+ class_name = "gts-blame-annotation" + (annotation.nil? ? "" : " gts-annotated")
41
+ return "<td class=\"#{class_name}\"></td>" if annotation.nil?
42
+
43
+ <<-HTML
44
+ <td class="#{class_name}">
45
+ <span class="gts-sha">#{annotation[:oid][0..7]}</span>
46
+ #{annotation[:committer][:time].strftime("%Y-%m-%d")}
47
+ #{annotation[:committer][:name]}
48
+ </td>
49
+ HTML
50
+ end
51
+
52
+ def blame_code_cell(line)
53
+ "<td class=\"gts-code\"><code>#{line}</code></td>"
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+ #--
3
+ # Copyright (C) 2012 Gitorious AS
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #++
18
+ require "htmlentities"
19
+
20
+ module Dolt
21
+ module View
22
+ module Blob
23
+ def format_blob(path, content)
24
+ @coder ||= HTMLEntities.new
25
+ multiline(@coder.encode(content))
26
+ end
27
+
28
+ def blob_url(repository, ref, path)
29
+ repo_url(repository, "/blob/#{ref}:#{path}")
30
+ end
31
+
32
+ def blame_url(repository, ref, path)
33
+ repo_url(repository, "/blame/#{ref}:#{path}")
34
+ end
35
+
36
+ def history_url(repository, ref, path)
37
+ repo_url(repository, "/history/#{ref}:#{path}")
38
+ end
39
+
40
+ def raw_url(repository, ref, path)
41
+ repo_url(repository, "/raw/#{ref}:#{path}")
42
+ end
43
+
44
+ def multiline(blob, options = {})
45
+ class_names = options[:class_names] || []
46
+ class_names << "prettyprint" << "linenums"
47
+
48
+ num = 0
49
+ lines = blob.split("\n").inject("") do |html, line|
50
+ num += 1
51
+ line = line.gsub(/\t/, " ")
52
+ "#{html}<li class=\"L#{num}\"><span class=\"line\">#{line}</span></li>"
53
+ end
54
+
55
+ "<pre class=\"#{class_names.join(' ')}\">" +
56
+ "<ol class=\"linenums\">#{lines}</ol></pre>"
57
+ end
58
+ end
59
+ end
60
+ end
@@ -15,40 +15,33 @@
15
15
  # You should have received a copy of the GNU Affero General Public License
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  #++
18
+
18
19
  module Dolt
19
20
  module View
20
- class Breadcrumb
21
- attr_reader :multi_repo_mode
22
-
23
- def initialize(options = {})
24
- @multi_repo_mode = options[:multi_repo_mode]
25
- end
26
-
27
- def render(repository, ref, path)
21
+ module Breadcrumb
22
+ def breadcrumb(repository, ref, path)
28
23
  dirs = path.split("/")
29
24
  filename = dirs.pop
30
- dir_html = accumulate_dirs(dirs, repository.name, ref)
25
+ dir_html = accumulate_dirs(dirs, repository, ref)
26
+ url = repo_url(repository, "/tree/#{ref}")
31
27
  <<-HTML
32
28
  <ul class="breadcrumb">
33
- <li><a href="#{prefix(repository)}/tree/#{ref}:"><i class="icon icon-file"></i></a></li>
29
+ <li><a href="#{url}:"><i class="icon icon-file"></i></a></li>
34
30
  #{dir_html}<li class="active">#{filename}</li>
35
31
  </ul>
36
32
  HTML
37
33
  end
38
34
 
39
35
  private
40
- def accumulate_dirs(dirs, repo, ref)
36
+ def accumulate_dirs(dirs, repository, ref)
41
37
  accumulated = []
38
+ divider = "<span class=\"divider\">/</span>"
42
39
  dir_html = dirs.inject("") do |html, dir|
43
40
  accumulated << dir
44
- "#{html}<li><a href=\"#{prefix(repo)}/tree/#{ref}:#{accumulated.join('/')}\">" +
45
- "#{dir}<span class=\"divider\">/</span></a></li>"
41
+ url = repo_url(repository, "/tree/#{ref}:#{accumulated.join('/')}")
42
+ "#{html}<li><a href=\"#{url}\">#{dir}#{divider}</a></li>"
46
43
  end
47
44
  end
48
-
49
- def prefix(repo)
50
- multi_repo_mode ? "/#{repo}" : ""
51
- end
52
45
  end
53
46
  end
54
47
  end
@@ -15,18 +15,12 @@
15
15
  # You should have received a copy of the GNU Affero General Public License
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  #++
18
- module Dolt
19
- module Git
20
- class Blob
21
- attr_reader :path, :raw, :repo
22
-
23
- def initialize(path, raw)
24
- @path = path
25
- @raw = raw
26
- end
27
18
 
28
- def lines
29
- raw.split("\n")
19
+ module Dolt
20
+ module View
21
+ module Commit
22
+ def commit_oid(oid)
23
+ oid[0...7]
30
24
  end
31
25
  end
32
26
  end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ #--
3
+ # Copyright (C) 2012 Gitorious AS
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #++
18
+ require 'digest/md5'
19
+
20
+ module Dolt
21
+ module View
22
+ module Gravatar
23
+ def gravatar(email)
24
+ hashed = Digest::MD5.hexdigest(email.downcase)
25
+ "http://www.gravatar.com/avatar/#{hashed}"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -15,28 +15,22 @@
15
15
  # You should have received a copy of the GNU Affero General Public License
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  #++
18
- require "dolt/async/deferrable_child_process"
18
+ require "github/markup"
19
19
 
20
20
  module Dolt
21
- module Git
22
- class Shell
23
- def initialize(work_tree, git_dir = nil)
24
- @work_tree = work_tree
25
- @git_dir = git_dir || File.join(work_tree, ".git")
21
+ module View
22
+ module Markup
23
+ def render_markup(path, content)
24
+ markup = GitHub::Markup.render(path, content)
25
+ "<div class=\"gts-markup\">#{markup}</div>"
26
26
  end
27
27
 
28
- def show(path, ref)
29
- git("show", "#{ref}:#{path}")
28
+ def supported_markup_format?(path)
29
+ GitHub::Markup.can_render?(path)
30
30
  end
31
31
 
32
- def ls_tree(path, ref)
33
- git("ls-tree", ref, path.sub(/(^\.?\/)?/, "./").sub(/\/?$/, "/"))
34
- end
35
-
36
- def git(command, *args)
37
- base = "git --git-dir #{@git_dir} --work-tree #{@work_tree}"
38
- cmd = "#{base} #{command} #{args.join(' ')}".strip
39
- Dolt::DeferrableChildProcess.open(cmd)
32
+ def format_blob(path, code, options = {})
33
+ render_markup(path, code)
40
34
  end
41
35
  end
42
36
  end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ #--
3
+ # Copyright (C) 2012 Gitorious AS
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #++
18
+
19
+ module Dolt
20
+ module View
21
+ module MultiRepository
22
+ def repo_url(repository, url)
23
+ "/#{repository}#{url}"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -15,34 +15,21 @@
15
15
  # You should have received a copy of the GNU Affero General Public License
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  #++
18
- require "eventmachine"
19
18
 
20
19
  module Dolt
21
- # A deferrable child process implementation that actually considers
22
- # the not uncommon situation where the command fails.
23
- #
24
- class DeferrableChildProcess < EventMachine::Connection
25
- include EventMachine::Deferrable
26
-
27
- def initialize
28
- super
29
- @data = []
30
- end
31
-
32
- def self.open cmd
33
- EventMachine.popen(cmd, DeferrableChildProcess)
34
- end
20
+ module View
21
+ module Object
22
+ def object_url(repository, ref, path, object)
23
+ url = "/#{object[:type]}/#{ref}:#{object_path(path, object)}"
24
+ repo_url(repository, url)
25
+ end
35
26
 
36
- def receive_data data
37
- @data << data
38
- end
27
+ def object_path(root, object)
28
+ File.join(root, object[:name]).sub(/^\//, "")
29
+ end
39
30
 
40
- def unbind
41
- status = get_status
42
- if status.exitstatus != 0
43
- fail(status)
44
- else
45
- succeed(@data.join, status)
31
+ def object_icon_class(entry)
32
+ entry[:type] == :blob ? "icon-file" : "icon-folder-close"
46
33
  end
47
34
  end
48
35
  end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ #--
3
+ # Copyright (C) 2012 Gitorious AS
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #++
18
+
19
+ module Dolt
20
+ module View
21
+ module SingleRepository
22
+ def repo_url(repository, url)
23
+ url
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ #--
3
+ # Copyright (C) 2012 Gitorious AS
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #++
18
+ require "dolt/view/syntax_highlight"
19
+ require "dolt/view/markup"
20
+
21
+ module Dolt
22
+ module View
23
+ module SmartBlobRenderer
24
+ include Dolt::View::Markup
25
+ include Dolt::View::SyntaxHighlight
26
+
27
+ def format_blob(path, content, options = {})
28
+ return render_markup(path, content) if supported_markup_format?(path)
29
+ highlight_multiline(path, content, options)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: utf-8
2
+ #--
3
+ # Copyright (C) 2012 Gitorious AS
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #++
18
+ require "pygments"
19
+
20
+ module Dolt
21
+ module View
22
+ module SyntaxHighlight
23
+ def highlight(path, code, opt = {})
24
+ options = { :lexer => lexer(path, code) }.merge(opt)
25
+ Pygments.highlight(code, highlight_options(options))
26
+ rescue RubyPython::PythonError
27
+ code
28
+ end
29
+
30
+ def highlight_multiline(path, code, options = {})
31
+ return highlight(path, code, options) unless respond_to?(:multiline)
32
+ lexer = lexer(path, code)
33
+ multiline(highlight(path, code, options), :class_names => [lexer])
34
+ end
35
+
36
+ def format_blob(path, code, options = {})
37
+ highlight_multiline(path, code, options)
38
+ end
39
+
40
+ def lexer(path, code = nil)
41
+ Dolt::View::SyntaxHighlight.lexer(path.split(".").pop, code)
42
+ end
43
+
44
+ def self.lexer(suffix, code = nil)
45
+ return @@lexer_aliases[suffix] if @@lexer_aliases[suffix]
46
+ shebang_language(shebang(code)) || suffix
47
+ end
48
+
49
+ def self.shebang(code)
50
+ first_line = (code || "").split("\n")[0]
51
+ first_line =~ /^#!/ ? first_line : nil
52
+ end
53
+
54
+ def self.shebang_language(shebang)
55
+ shebang = @@lexer_shebangs.find { |s| (shebang || "") =~ s[:pattern] }
56
+ shebang && shebang[:lexer]
57
+ end
58
+
59
+ def self.add_lexer_alias(extension, lexer)
60
+ @@lexer_aliases ||= {}
61
+ @@lexer_aliases[extension] = lexer
62
+ end
63
+
64
+ def self.add_lexer_shebang(pattern, lexer)
65
+ @@lexer_shebangs ||= []
66
+ @@lexer_shebangs << { :pattern => pattern, :lexer => lexer }
67
+ end
68
+
69
+ private
70
+ def highlight_options(options = {})
71
+ options[:options] ||= {}
72
+ options[:options][:nowrap] = true
73
+ options[:options][:encoding] ||= "utf-8"
74
+ options
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ Dolt::View::SyntaxHighlight.add_lexer_alias("yml", "yaml")
81
+ Dolt::View::SyntaxHighlight.add_lexer_alias("Rakefile", "rb")
82
+ Dolt::View::SyntaxHighlight.add_lexer_alias("Gemfile", "rb")
83
+ Dolt::View::SyntaxHighlight.add_lexer_alias("Gemfile.lock", "yaml")
84
+ Dolt::View::SyntaxHighlight.add_lexer_alias("gemspec", "rb")
85
+
86
+ Dolt::View::SyntaxHighlight.add_lexer_shebang(/\bruby\b/, "rb")