dolt 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/Gemfile.lock +21 -18
  2. data/Readme.md +3 -5
  3. data/bin/dolt +3 -6
  4. data/dolt.gemspec +5 -16
  5. data/lib/dolt/sinatra/multi_repo_browser.rb +3 -3
  6. data/lib/dolt/sinatra/single_repo_browser.rb +3 -3
  7. data/test/test_helper.rb +5 -3
  8. data/vendor/ui/css/gitorious.css +5 -0
  9. metadata +23 -239
  10. data/lib/dolt/async/when.rb +0 -128
  11. data/lib/dolt/disk_repo_resolver.rb +0 -39
  12. data/lib/dolt/git/blame.rb +0 -112
  13. data/lib/dolt/git/commit.rb +0 -73
  14. data/lib/dolt/git/repository.rb +0 -139
  15. data/lib/dolt/git/submodule.rb +0 -35
  16. data/lib/dolt/git/tree.rb +0 -42
  17. data/lib/dolt/repo_actions.rb +0 -91
  18. data/lib/dolt/template_renderer.rb +0 -67
  19. data/lib/dolt/version.rb +0 -21
  20. data/lib/dolt/view.rb +0 -23
  21. data/lib/dolt/view/binary_blob_embedder.rb +0 -41
  22. data/lib/dolt/view/blame.rb +0 -57
  23. data/lib/dolt/view/blob.rb +0 -97
  24. data/lib/dolt/view/breadcrumb.rb +0 -47
  25. data/lib/dolt/view/commit.rb +0 -27
  26. data/lib/dolt/view/gravatar.rb +0 -29
  27. data/lib/dolt/view/markup.rb +0 -107
  28. data/lib/dolt/view/multi_repository.rb +0 -27
  29. data/lib/dolt/view/object.rb +0 -44
  30. data/lib/dolt/view/single_repository.rb +0 -27
  31. data/lib/dolt/view/smart_blob_renderer.rb +0 -33
  32. data/lib/dolt/view/syntax_highlight.rb +0 -90
  33. data/lib/dolt/view/tab_width.rb +0 -30
  34. data/lib/dolt/view/tree.rb +0 -100
  35. data/test/dolt/async/when_test.rb +0 -112
  36. data/test/dolt/git/blame_test.rb +0 -128
  37. data/test/dolt/git/commit_test.rb +0 -89
  38. data/test/dolt/git/repository_test.rb +0 -186
  39. data/test/dolt/repo_actions_test.rb +0 -236
  40. data/test/dolt/template_renderer_test.rb +0 -122
  41. data/test/dolt/templates/blame_test.rb +0 -56
  42. data/test/dolt/templates/blob_test.rb +0 -118
  43. data/test/dolt/templates/commits_test.rb +0 -61
  44. data/test/dolt/templates/raw_test.rb +0 -41
  45. data/test/dolt/templates/refs_test.rb +0 -38
  46. data/test/dolt/templates/tree_history_test.rb +0 -93
  47. data/test/dolt/templates/tree_test.rb +0 -65
  48. data/test/dolt/view/binary_blob_embedder_test.rb +0 -49
  49. data/test/dolt/view/blame_test.rb +0 -122
  50. data/test/dolt/view/blob_test.rb +0 -116
  51. data/test/dolt/view/breadcrumb_test.rb +0 -46
  52. data/test/dolt/view/commit_test.rb +0 -31
  53. data/test/dolt/view/gravatar_test.rb +0 -30
  54. data/test/dolt/view/markup_test.rb +0 -94
  55. data/test/dolt/view/multi_repository_test.rb +0 -35
  56. data/test/dolt/view/object_test.rb +0 -83
  57. data/test/dolt/view/single_repository_test.rb +0 -30
  58. data/test/dolt/view/smart_blob_renderer_test.rb +0 -38
  59. data/test/dolt/view/syntax_highlight_test.rb +0 -108
  60. data/test/dolt/view/tab_width_test.rb +0 -40
  61. data/test/dolt/view/tree_test.rb +0 -199
  62. data/views/500.erb +0 -22
  63. data/views/blame.erb +0 -42
  64. data/views/blob.erb +0 -31
  65. data/views/commits.erb +0 -26
  66. data/views/index.erb +0 -25
  67. data/views/layout.erb +0 -45
  68. data/views/raw.erb +0 -19
  69. data/views/refs.erb +0 -22
  70. data/views/tree.erb +0 -50
  71. data/views/tree_history.erb +0 -19
@@ -1,128 +0,0 @@
1
- require "eventmachine"
2
-
3
- module When
4
- class Promise
5
- def initialize(deferred = EM::DefaultDeferrable.new)
6
- @deferred = deferred
7
- end
8
-
9
- def callback(&block)
10
- @deferred.callback(&block)
11
- self
12
- end
13
-
14
- def errback(&block)
15
- @deferred.errback(&block)
16
- self
17
- end
18
- end
19
-
20
- class Resolver
21
- def initialize(deferred = EM::DefaultDeferrable.new)
22
- @deferred = deferred
23
- @resolved = false
24
- end
25
-
26
- def resolve(*args)
27
- mark_resolved
28
- @deferred.succeed(*args)
29
- end
30
-
31
- def reject(*args)
32
- mark_resolved
33
- @deferred.fail(*args)
34
- end
35
-
36
- def resolved?
37
- @resolved
38
- end
39
-
40
- private
41
- def mark_resolved
42
- raise StandardError.new("Already resolved") if @resolved
43
- @resolved = true
44
- end
45
- end
46
-
47
- class Deferred
48
- attr_reader :resolver, :promise
49
-
50
- def initialize
51
- deferred = EM::DefaultDeferrable.new
52
- @resolver = Resolver.new(deferred)
53
- @promise = Promise.new(deferred)
54
- end
55
-
56
- def resolve(*args)
57
- @resolver.resolve(*args)
58
- end
59
-
60
- def reject(*args)
61
- @resolver.reject(*args)
62
- end
63
-
64
- def callback(&block)
65
- @promise.callback(&block)
66
- end
67
-
68
- def errback(&block)
69
- @promise.errback(&block)
70
- end
71
-
72
- def resolved?
73
- @resolver.resolved?
74
- end
75
-
76
- def self.resolved(value)
77
- d = self.new
78
- d.resolve(value)
79
- d
80
- end
81
-
82
- def self.rejected(value)
83
- d = self.new
84
- d.reject(value)
85
- d
86
- end
87
- end
88
-
89
- def self.deferred(val)
90
- return val if val.respond_to?(:callback) && val.respond_to?(:errback)
91
- Deferred.resolved(val).promise
92
- end
93
-
94
- def self.all(promises)
95
- raise(ArgumentError, "expected enumerable promises") if !promises.is_a?(Enumerable)
96
- resolved = 0
97
- results = []
98
- d = Deferred.new
99
-
100
- attempt_resolution = lambda do |err, res|
101
- break if d.resolved?
102
- if err.nil?
103
- d.resolve(res) if promises.length == resolved
104
- else
105
- d.reject(err)
106
- end
107
- end
108
-
109
- wait_for_all(promises) do |err, result, index|
110
- resolved += 1
111
- results[index] = result
112
- attempt_resolution.call(err, results)
113
- end
114
-
115
- attempt_resolution.call(nil, results) if promises.length == 0
116
- d.promise
117
- end
118
-
119
- private
120
- def self.wait_for_all(promises, &block)
121
- promises.each_with_index do |p, i|
122
- p.callback do |result|
123
- block.call(nil, result, i)
124
- end
125
- p.errback { |e| block.call(e, nil, i) }
126
- end
127
- end
128
- end
@@ -1,39 +0,0 @@
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/git/repository"
19
-
20
- module Dolt
21
- class DiskRepoResolver
22
- def initialize(root)
23
- @root = root
24
- end
25
-
26
- def resolve(repo)
27
- Dolt::Git::Repository.new(File.join(root, repo))
28
- end
29
-
30
- def all
31
- (Dir.entries(root).select do |e|
32
- File.exists?(File.join(root, e, ".git"))
33
- end).sort
34
- end
35
-
36
- private
37
- def root; @root; end
38
- end
39
- end
@@ -1,112 +0,0 @@
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
@@ -1,73 +0,0 @@
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 "time"
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.parse(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.sub(/^ /, "")
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
@@ -1,139 +0,0 @@
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 "em_rugged/repository"
19
- require "em_pessimistic/deferrable_child_process"
20
- require "em/deferrable"
21
- require "dolt/git/blame"
22
- require "dolt/git/commit"
23
- require "dolt/git/submodule"
24
- require "dolt/git/tree"
25
- require "dolt/async/when"
26
-
27
- module Dolt
28
- module Git
29
- class Repository < EMRugged::Repository
30
- def submodules(ref)
31
- d = EventMachine::DefaultDeferrable.new
32
- gm = rev_parse("#{ref}:.gitmodules")
33
- gm.callback do |config|
34
- d.succeed(Dolt::Git::Submodule.parse_config(config.content))
35
- end
36
- # Fails if .gitmodules cannot be found, which means no submodules
37
- gm.errback { |err| d.succeed([]) }
38
- d
39
- end
40
-
41
- def tree(ref, path)
42
- d = EventMachine::DefaultDeferrable.new
43
- rp = rev_parse("#{ref}:#{path}")
44
- rp.callback do |tree|
45
- break d.fail(StandardError.new("Not a tree")) unless tree.is_a?(Rugged::Tree)
46
- break d.succeed(tree) if !tree.find { |e| e[:type].nil? }
47
- annotate_submodules(ref, path, d, tree)
48
- end
49
- rp.errback { |err| d.fail(err) }
50
- d
51
- end
52
-
53
- def blame(ref, path)
54
- deferred_method("blame -l -t -p #{ref} #{path}") do |output, s|
55
- Dolt::Git::Blame.parse_porcelain(output)
56
- end
57
- end
58
-
59
- def log(ref, path, limit)
60
- entry_history(ref, path, limit)
61
- end
62
-
63
- def tree_history(ref, path, limit = 1)
64
- d = EventMachine::DefaultDeferrable.new
65
- rp = rev_parse("#{ref}:#{path}")
66
- rp.errback { |err| d.fail(err) }
67
- rp.callback do |tree|
68
- if tree.class != Rugged::Tree
69
- message = "#{ref}:#{path} is not a tree (#{tree.class.to_s})"
70
- break d.fail(Exception.new(message))
71
- end
72
-
73
- building = build_history(path || "./", ref, tree, limit)
74
- building.callback { |history| d.succeed(history) }
75
- building.errback { |err| d.fail(err) }
76
- end
77
- d
78
- end
79
-
80
- private
81
- def entry_history(ref, entry, limit)
82
- deferred_method("log -n #{limit} #{ref} -- #{entry}") do |out, s|
83
- Dolt::Git::Commit.parse_log(out)
84
- end
85
- end
86
-
87
- def build_history(path, ref, entries, limit)
88
- d = EventMachine::DefaultDeferrable.new
89
- resolve = lambda { |p| path == "" ? p : File.join(path, p) }
90
- progress = When.all(entries.map do |e|
91
- entry_history(ref, resolve.call(e[:name]), limit)
92
- end)
93
- progress.errback { |e| d.fail(e) }
94
- progress.callback do |history|
95
- d.succeed(entries.map { |e| e.merge({ :history => history.shift }) })
96
- end
97
- d
98
- end
99
-
100
- def annotate_submodules(ref, path, deferrable, tree)
101
- submodules(ref).callback do |submodules|
102
- entries = tree.entries.map do |entry|
103
- if entry[:type].nil?
104
- mod = path == "" ? entry[:name] : File.join(path, entry[:name])
105
- meta = submodules.find { |s| s[:path] == mod }
106
- if meta
107
- entry[:type] = :submodule
108
- entry[:url] = meta[:url]
109
- end
110
- end
111
- entry
112
- end
113
-
114
- deferrable.succeed(Dolt::Git::Tree.new(tree.oid, entries))
115
- end
116
- end
117
-
118
- def deferred_method(cmd, &block)
119
- d = EventMachine::DefaultDeferrable.new
120
- cmd = git(cmd)
121
- p = EMPessimistic::DeferrableChildProcess.open(cmd)
122
-
123
- p.callback do |output, status|
124
- d.succeed(block.call(output, status))
125
- end
126
-
127
- p.errback do |stderr, status|
128
- d.fail(stderr)
129
- end
130
-
131
- d
132
- end
133
-
134
- def git(cmd)
135
- "git --git-dir #{subject.path} #{cmd}"
136
- end
137
- end
138
- end
139
- end