dolt 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +25 -5
- data/Readme.md +90 -16
- data/bin/dolt +22 -4
- data/dolt.gemspec +10 -2
- data/lib/dolt/disk_repo_resolver.rb +3 -5
- data/lib/dolt/git/blame.rb +112 -0
- data/lib/dolt/git/commit.rb +73 -0
- data/lib/dolt/git/repository.rb +26 -24
- data/lib/dolt/repo_actions.rb +32 -19
- data/lib/dolt/sinatra/actions.rb +51 -18
- data/lib/dolt/sinatra/multi_repo_browser.rb +30 -3
- data/lib/dolt/sinatra/single_repo_browser.rb +36 -2
- data/lib/dolt/template_renderer.rb +7 -8
- data/lib/dolt/version.rb +1 -1
- data/lib/dolt/view.rb +3 -61
- data/lib/dolt/view/blame.rb +57 -0
- data/lib/dolt/view/blob.rb +60 -0
- data/lib/dolt/view/breadcrumb.rb +10 -17
- data/lib/dolt/{git/blob.rb → view/commit.rb} +5 -11
- data/lib/dolt/view/gravatar.rb +29 -0
- data/lib/dolt/{git/shell.rb → view/markup.rb} +10 -16
- data/lib/dolt/view/multi_repository.rb +27 -0
- data/lib/dolt/{async/deferrable_child_process.rb → view/object.rb} +11 -24
- data/lib/dolt/view/single_repository.rb +27 -0
- data/lib/dolt/view/smart_blob_renderer.rb +33 -0
- data/lib/dolt/view/syntax_highlight.rb +86 -0
- data/lib/dolt/view/tree.rb +69 -0
- data/test/dolt/git/blame_test.rb +128 -0
- data/test/dolt/git/commit_test.rb +89 -0
- data/test/dolt/git/repository_test.rb +24 -73
- data/test/dolt/repo_actions_test.rb +77 -15
- data/test/dolt/sinatra/actions_test.rb +168 -8
- data/test/dolt/template_renderer_test.rb +44 -10
- data/test/dolt/templates/blame_test.rb +56 -0
- data/test/dolt/{views → templates}/blob_test.rb +44 -34
- data/test/dolt/templates/commits_test.rb +61 -0
- data/test/dolt/templates/raw_test.rb +41 -0
- data/test/dolt/templates/tree_test.rb +51 -0
- data/test/dolt/view/blame_test.rb +122 -0
- data/test/dolt/view/blob_test.rb +90 -0
- data/test/dolt/view/breadcrumb_test.rb +46 -0
- data/test/dolt/view/commit_test.rb +31 -0
- data/test/dolt/view/gravatar_test.rb +30 -0
- data/test/dolt/view/markup_test.rb +30 -0
- data/test/dolt/{git/blob_test.rb → view/multi_repository_test.rb} +10 -24
- data/test/dolt/view/object_test.rb +71 -0
- data/test/dolt/view/single_repository_test.rb +30 -0
- data/test/dolt/{view_test.rb → view/syntax_highlight_test.rb} +40 -27
- data/test/dolt/view/tree_test.rb +115 -0
- data/test/test_helper.rb +18 -13
- data/vendor/ui/css/gitorious.css +20 -8
- data/views/blame.erb +41 -0
- data/views/blob.erb +6 -9
- data/views/commits.erb +23 -0
- data/views/index.erb +25 -0
- data/views/raw.erb +19 -0
- data/views/tree.erb +28 -26
- metadata +156 -26
- data/lib/dolt/git/tree.rb +0 -65
- data/lib/dolt/view/highlighter.rb +0 -52
- data/test/dolt/git/shell_test.rb +0 -112
- 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
|
-
|
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 (
|
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
|
-
|
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
|
-
|
25
|
-
|
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
|
4
|
-
browser
|
5
|
-
|
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
|
8
|
-
|
9
|
-
(
|
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
|
-
|
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
|
-
|
14
|
-
Dolt allows you to surf repos locally on your disk:
|
18
|
+
## Installing Dolt
|
15
19
|
|
16
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
30
|
+
### Systems using apt (Debian/Ubuntu, others)
|
23
31
|
|
24
|
-
|
25
|
-
|
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
|
-
|
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
|
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
|
-
|
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).
|
34
|
-
|
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
|