dolt 0.1.1 → 0.2.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.
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")