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
data/Gemfile.lock CHANGED
@@ -3,11 +3,17 @@ PATH
3
3
  specs:
4
4
  dolt (0.1.1)
5
5
  async_sinatra (~> 1.0)
6
- eventmachine (~> 0.12)
6
+ builder (~> 3.1)
7
+ em_pessimistic (~> 0.1)
8
+ em_rugged (~> 0.1.0)
9
+ eventmachine (~> 1.0)
10
+ github-markup (~> 0.7)
11
+ htmlentities (~> 4.3)
7
12
  pygments.rb (~> 0.2)
8
13
  sinatra (~> 1.3)
9
14
  thin (~> 1.4)
10
15
  tilt (~> 1.3)
16
+ tzinfo (~> 0.3)
11
17
 
12
18
  GEM
13
19
  remote: http://rubygems.org/
@@ -15,23 +21,35 @@ GEM
15
21
  async_sinatra (1.0.0)
16
22
  rack (>= 1.4.1)
17
23
  sinatra (>= 1.3.2)
18
- blankslate (2.1.2.4)
24
+ blankslate (3.1.2)
25
+ builder (3.1.3)
19
26
  daemons (1.1.9)
20
27
  em-minitest-spec (1.1.1)
21
28
  eventmachine
22
- eventmachine (0.12.10)
29
+ em_pessimistic (0.1.2)
30
+ eventmachine (~> 1.0)
31
+ em_rugged (0.1.1)
32
+ eventmachine (~> 1.0)
33
+ rugged (~> 0.17)
34
+ eventmachine (1.0.0)
23
35
  ffi (1.0.11)
24
- minitest (2.1.0)
25
- mocha (0.9.12)
36
+ github-markup (0.7.4)
37
+ htmlentities (4.3.1)
38
+ metaclass (0.0.1)
39
+ minitest (2.12.1)
40
+ mocha (0.12.4)
41
+ metaclass (~> 0.0.1)
26
42
  pygments.rb (0.2.13)
27
43
  rubypython (~> 0.5.3)
28
44
  rack (1.4.1)
29
45
  rack-protection (1.2.0)
30
46
  rack
31
47
  rake (0.9.2.2)
48
+ redcarpet (2.1.1)
32
49
  rubypython (0.5.3)
33
50
  blankslate (>= 2.1.2.3)
34
51
  ffi (~> 1.0.7)
52
+ rugged (0.17.0)
35
53
  sinatra (1.3.3)
36
54
  rack (~> 1.3, >= 1.3.6)
37
55
  rack-protection (~> 1.2)
@@ -41,6 +59,7 @@ GEM
41
59
  eventmachine (>= 0.12.6)
42
60
  rack (>= 1.0.0)
43
61
  tilt (1.3.3)
62
+ tzinfo (0.3.33)
44
63
 
45
64
  PLATFORMS
46
65
  ruby
@@ -51,3 +70,4 @@ DEPENDENCIES
51
70
  minitest (~> 2.0)
52
71
  mocha
53
72
  rake (~> 0.9)
73
+ redcarpet
data/Readme.md CHANGED
@@ -1,25 +1,99 @@
1
1
  # Dolt - The Git project browser
2
2
 
3
- Dolt is a stand-alone server that allows you to browse git repositories in your
4
- browser. It uses Pygments to syntax highlight code, and displays blame as well
5
- as git history for individual files.
3
+ Dolt is a stand-alone Git repository browser. It can be used to explore repos in
4
+ your browser of choice and features syntax highlighting with
5
+ [Pygments](http://pygments.org/),
6
+ [Markdown](http://daringfireball.net/projects/markdown/)/[org-mode](http://orgmode.org/)/[+++](https://github.com/github/markup/)
7
+ rendering, commit log and blame.
6
8
 
7
- Dolt can also be used as a library to serve git trees from e.g. a Rails app. It
8
- is the blob viewer implementation that will be used in the Gitorious application
9
- (gitorious.org) when it is ready.
9
+ Dolt is also a library, designed to render Git trees, blobs, commit log and
10
+ blame. It can render said views with or without a layout, or you can provide
11
+ your own templates (through [Tilt](https://github.com/rtomayko/tilt/)). You can
12
+ also provide your own rendering implementation to render other formats than
13
+ templates outputting HTML.
10
14
 
11
- ## Blobs
15
+ Dolt is the implementation of the next generation repo browser to be used in the
16
+ [Gitorious](http://gitorious.org) software.
12
17
 
13
- Dolt currenly only serves blobs. The sample Rack application that comes with
14
- Dolt allows you to surf repos locally on your disk:
18
+ ## Installing Dolt
15
19
 
16
- env REPO_ROOT=/where/git/repos/reside rackup -Ilib
20
+ To install `dolt` you need Ruby, RubyGems and Python development files. The
21
+ Python development files are required to support Pygments syntax highlighting.
17
22
 
18
- That command will start the server, and allow you to view blobs in repos
19
- available in the `/where/git/repos/reside` directory. For example, on my machine,
20
- when I issue:
23
+ Note: Dolt uses [libgit2](http://libgit2.github.com) and its Ruby bindings,
24
+ [Rugged](http://github.com/libgit2/rugged) through
25
+ [em-rugged](http://gitorious.org/gitorious/em-rugged) for Git access where
26
+ feasible. Currently, ``EMRugged`` relies on a version of `Rugged` that is not
27
+ yet released, so you have to build it yourself.
28
+ [See em-rugged instructions](http://github.com/cjohansen/em-rugged).
21
29
 
22
- env REPO_ROOT=/home/christian/projects rackup -Ilib
30
+ ### Systems using apt (Debian/Ubuntu, others)
23
31
 
24
- I can go to [http://localhost:9292/gitorious/blob/master:app/models/repository.rb](http://localhost:9292/gitorious/blob/master:app/models/repository.rb)
25
- to view Gitorious blobs.
32
+ # 1) Install Ruby (skip if you already have Ruby installed)
33
+ sudo apt-get install ruby
34
+
35
+ # 2) Install Python development files
36
+ sudo apt-get install python-dev
37
+
38
+ # 3) Install dolt. This may or may not require the use of sudo, depending on
39
+ # how you installed Ruby. This step assumes that you already built and
40
+ # installed em-rugged as explained above.
41
+ sudo gem install dolt
42
+
43
+ ### Systems using yum (Fedora/CentOS/RedHat, others)
44
+
45
+ # 1) Install Ruby (skip if you already have Ruby installed)
46
+ sudo yum install ruby
47
+
48
+ # 2) Install Python development files
49
+ sudo yum install python-devel
50
+
51
+ # 3) Install dolt. This may or may not require the use of sudo, depending on
52
+ # how you installed Ruby. This step assumes that you already built and
53
+ # installed em-rugged as explained above.
54
+ sudo gem install dolt
55
+
56
+ # The Dolt CLI
57
+
58
+ The `dolt` library installs a CLI that can be used to quickly browse either a
59
+ single (typically the current) repository, or multiple repositories.
60
+
61
+ ## Browsing a single repository
62
+
63
+ In a git repository, issue the following command:
64
+
65
+ $ dolt .
66
+
67
+ Then open a browser at [http://localhost:3000](http://localhost:3000). You will
68
+ be redirected to the root tree, and can browse the repository. To view trees and
69
+ blobs at specific refs, use the URL. A branch/tag selector will be added later.
70
+
71
+ ## Browsing multiple repositories
72
+
73
+ The idea is that eventually, `dolt` should be able to serve up all Git
74
+ repositories managed by your Gitorious server. It does not yet do that, because
75
+ there currently is no "repository resolver" that understands the hashed paths
76
+ Gitorious uses.
77
+
78
+ Meanwhile, if you have a directory that contains multiple git repositories, you
79
+ can browse all of them through the same process by doing:
80
+
81
+ $ dolt /path/to/repos
82
+
83
+ Now [http://localhost:3000/repo](http://localhost:3000/repo) will allow you to
84
+ browse the `/path/repos/repo` repository. As `dolt` matures, there will be a
85
+ listing of all repositories and more.
86
+
87
+ ## Markup rendering
88
+
89
+ Dolt uses the [``GitHub::Markup``](https://github.com/github/markup/) library to
90
+ render certain markup formats as HTML. Dolt does not have a hard dependency on
91
+ any of the required gems to actually render markups, so see the
92
+ [``GitHub::Markup`` docs](https://github.com/github/markup/) for information on
93
+ what and how to install support for various languages.
94
+
95
+ # License
96
+
97
+ Dolt is free software licensed under the
98
+ [GNU Affero General Public License (AGPL)](http://www.gnu.org/licenses/agpl-3.0.html).
99
+ Dolt is developed as part of the Gitorious project.
data/bin/dolt CHANGED
@@ -21,14 +21,16 @@ end
21
21
 
22
22
  def create_app(dir, view)
23
23
  if is_git_repo?(dir)
24
- require "dolt/sinatra/single_repo_browser"
25
24
  dir = File.expand_path(dir)
26
25
  resolver = Dolt::DiskRepoResolver.new(File.dirname(dir))
27
26
  actions = Dolt::RepoActions.new(resolver)
27
+ view.helper(Dolt::View::SingleRepository)
28
+ require "dolt/sinatra/single_repo_browser"
28
29
  Dolt::Sinatra::SingleRepoBrowser.new(File.basename(dir), actions, view)
29
30
  else
30
31
  resolver = Dolt::DiskRepoResolver.new(dir)
31
32
  actions = Dolt::RepoActions.new(resolver)
33
+ view.helper(Dolt::View::MultiRepository)
32
34
  require "dolt/sinatra/multi_repo_browser"
33
35
  Dolt::Sinatra::MultiRepoBrowser.new(actions, view)
34
36
  end
@@ -39,11 +41,27 @@ base = File.join(File.dirname(__FILE__), "..")
39
41
  template_root = File.join(base, "views")
40
42
  view = Dolt::TemplateRenderer.new(template_root, {
41
43
  :cache => false,
42
- :layout => "layout",
43
- :attributes => { :multi_repo_mode => !is_git_repo?(ARGV[0]) }
44
+ :layout => "layout"
44
45
  })
45
46
 
46
- view.helper(Dolt::View)
47
+ view.helper(Dolt::View::Object)
48
+ view.helper(Dolt::View::Blob)
49
+ view.helper(Dolt::View::Blame)
50
+ view.helper(Dolt::View::Breadcrumb)
51
+ view.helper(Dolt::View::Tree)
52
+ view.helper(Dolt::View::Commit)
53
+ view.helper(Dolt::View::Gravatar)
54
+
55
+ # Configure blob rendering module
56
+
57
+ # Attempt to syntax highlight every blob
58
+ # view.helper(Dolt::View::SyntaxHighlight)
59
+
60
+ # Attempt to render every blob as markup
61
+ # view.helper(Dolt::View::Markup)
62
+
63
+ # Render supported formats as markup, syntax highlight the rest
64
+ view.helper(Dolt::View::SmartBlobRenderer)
47
65
 
48
66
  Sinatra::Base.set(:public_folder, File.join(base, "vendor/ui"))
49
67
  server = create_app(ARGV[0], view)
data/dolt.gemspec CHANGED
@@ -1,5 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.join("lib/dolt/version")
2
+ dir = File.expand_path(File.dirname(__FILE__))
3
+ require File.join(dir, "lib/dolt/version")
3
4
 
4
5
  module GemSpecHelper
5
6
  def self.files(path)
@@ -20,17 +21,24 @@ Gem::Specification.new do |s|
20
21
 
21
22
  s.rubyforge_project = "dolt"
22
23
 
23
- s.add_dependency "eventmachine", "~>0.12"
24
+ s.add_dependency "eventmachine", "~>1.0"
24
25
  s.add_dependency "thin", "~>1.4"
25
26
  s.add_dependency "sinatra", "~>1.3"
26
27
  s.add_dependency "async_sinatra", "~>1.0"
27
28
  s.add_dependency "tilt", "~>1.3"
28
29
  s.add_dependency "pygments.rb", "~>0.2"
30
+ s.add_dependency "em_pessimistic", "~>0.1"
31
+ s.add_dependency "builder", "~> 3.1"
32
+ s.add_dependency "em_rugged", "~> 0.1.2"
33
+ s.add_dependency "tzinfo", "~> 0.3"
34
+ s.add_dependency "github-markup", "~> 0.7"
35
+ s.add_dependency "htmlentities", "~> 4.3"
29
36
 
30
37
  s.add_development_dependency "minitest", "~> 2.0"
31
38
  s.add_development_dependency "em-minitest-spec", "~> 1.1"
32
39
  s.add_development_dependency "rake", "~> 0.9"
33
40
  s.add_development_dependency "mocha"
41
+ s.add_development_dependency "redcarpet"
34
42
 
35
43
  s.files = GemSpecHelper.files(".") + GemSpecHelper.files("vendor/ui")
36
44
  s.test_files = `git ls-files -- {test}/*`.split("\n")
@@ -15,7 +15,6 @@
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/git/shell"
19
18
  require "dolt/git/repository"
20
19
 
21
20
  module Dolt
@@ -25,13 +24,12 @@ module Dolt
25
24
  end
26
25
 
27
26
  def resolve(repo)
28
- git = Dolt::Git::Shell.new(File.join(root, repo))
29
- Dolt::Git::Repository.new(repo, git)
27
+ Dolt::Git::Repository.new(File.join(root, repo))
30
28
  end
31
29
 
32
30
  def all
33
- Dir.entries(root).reject do |e|
34
- e =~ /^\.+$/ || File.file?(File.join(root, e))
31
+ Dir.entries(root).select do |e|
32
+ File.exists?(File.join(root, e, ".git"))
35
33
  end
36
34
  end
37
35
 
@@ -0,0 +1,112 @@
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 "tzinfo"
19
+
20
+ module Dolt
21
+ module Git
22
+ class Blame
23
+ attr_reader :chunks
24
+
25
+ def initialize(chunks)
26
+ @chunks = chunks
27
+ end
28
+
29
+ def self.parse_porcelain(output)
30
+ self.new(Dolt::Git::Blame::PorcelainParser.new(output).parse)
31
+ end
32
+
33
+ class PorcelainParser
34
+ def initialize(output)
35
+ @output = output
36
+ @commits = {}
37
+ end
38
+
39
+ def parse
40
+ lines = @output.split("\n")
41
+ chunks = []
42
+
43
+ while lines.length > 0
44
+ chunk = extract_header(lines)
45
+ affected_lines = extract_lines(lines, chunk[:num_lines])
46
+
47
+ if chunks.last && chunk[:oid] == chunks.last[:oid]
48
+ chunks.last[:lines].concat(affected_lines)
49
+ else
50
+ chunk[:lines] = affected_lines
51
+ chunks << chunk
52
+ end
53
+ end
54
+
55
+ chunks
56
+ end
57
+
58
+ def is_header?(line)
59
+ line =~ /^[0-9a-f]{40} \d+ \d+ \d+$/
60
+ end
61
+
62
+ def extract_header(lines)
63
+ header = lines.shift
64
+ pieces = header.scan(/^([0-9a-f]{40}) (\d+) (\d+) (\d+)$/).first
65
+ header = { :oid => pieces.first, :num_lines => pieces[3].to_i }
66
+
67
+ if lines.first =~ /^author/
68
+ header[:author] = extract_hash(lines, :author)
69
+ header[:committer] = extract_hash(lines, :committer)
70
+ header[:summary] = extract(lines, "summary")
71
+ throwaway = lines.shift until throwaway =~ /^filename/
72
+ @commits[header[:oid]] = header
73
+ else
74
+ header[:author] = @commits[header[:oid]][:author]
75
+ header[:committer] = @commits[header[:oid]][:committer]
76
+ header[:summary] = @commits[header[:oid]][:summary]
77
+ end
78
+
79
+ header
80
+ end
81
+
82
+ def extract_lines(lines, num)
83
+ extracted = []
84
+
85
+ num.times do
86
+ if extracted.length > 0
87
+ line = lines.shift # Header for next line
88
+ end
89
+
90
+ content = lines.shift # Actual content
91
+ extracted.push(content[1..content.length]) # 8 spaces padding
92
+ end
93
+
94
+ extracted
95
+ end
96
+
97
+ def extract_hash(lines, type)
98
+ {
99
+ :name => extract(lines, "#{type}"),
100
+ :mail => extract(lines, "#{type}-mail").gsub(/[<>]/, ""),
101
+ :time => (Time.at(extract(lines, "#{type}-time").to_i) +
102
+ Time.zone_offset(extract(lines, "#{type}-tz")))
103
+ }
104
+ end
105
+
106
+ def extract(lines, thing)
107
+ lines.shift.split("#{thing} ")[1]
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,73 @@
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 "parsedate"
19
+
20
+ module Dolt
21
+ module Git
22
+ class Commit
23
+ def self.parse_log(log)
24
+ commits = []
25
+ lines = log.split("\n")
26
+ commits << extract_commit(lines) while lines.length > 0
27
+ commits
28
+ end
29
+
30
+ def self.extract_commit(lines)
31
+ commit = { :oid => lines.shift.split(" ")[1] }
32
+ while (line = lines.shift) != ""
33
+ pieces = line.split(": ")
34
+ extract_property(commit, pieces[0], pieces[1])
35
+ end
36
+
37
+ commit[:summary] = extract_commit_summary(lines)
38
+ commit[:message] = extract_commit_message(lines)
39
+ commit
40
+ end
41
+
42
+ def self.extract_property(hash, name, value)
43
+ key = name.downcase.to_sym
44
+
45
+ case key
46
+ when :author
47
+ pieces = value.match(/(.*)\s<(.*)>/)
48
+ value = { :name => pieces[1], :email => pieces[2] }
49
+ when :date
50
+ value = Time.mktime(*ParseDate.parsedate(value))
51
+ end
52
+
53
+ hash[key] = value
54
+ end
55
+
56
+ def self.extract_commit_summary(lines)
57
+ summary = lines.shift
58
+ lines.shift if lines.first == ""
59
+ summary
60
+ end
61
+
62
+ def self.extract_commit_message(lines)
63
+ message = ""
64
+
65
+ while !lines.first.nil? && lines.first !~ /^commit [a-z0-9]{40}$/
66
+ message << lines.shift
67
+ end
68
+
69
+ message
70
+ end
71
+ end
72
+ end
73
+ end