Handle wiki updates and web hooks from the PushProcessor.
[gitorious:mainline.git] / lib / gitorious / wiki / commit_parser.rb
1 # encoding: utf-8
2 #--
3 #   Copyright (C) 2011 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 Gitorious
20   module Wiki
21     class CommitParser
22       # Expects the output of git log --pretty=short --name-status
23       def parse(git_output)
24         current_commit_output = []
25         lines = git_output.split("\n")
26
27         commits = []
28
29         while line = lines.shift
30           if line =~ /^commit.*/ && !current_commit_output.blank?
31             commits << parse_commit(current_commit_output)
32             current_commit_output.clear
33           end
34
35           current_commit_output << line
36         end
37         commits << parse_commit(current_commit_output)
38         commits
39       end
40
41       def parse_commit(lines)
42         sha_line = lines.first
43         author_line = lines[1]
44         message_line = lines[3]
45
46         result = Commit.new
47
48         result.commit_sha = extract_sha_from_line(sha_line)
49
50         result.email = extract_email_from_line(author_line)
51         result.commit_message = extract_commit_message_from_line(message_line)
52
53         file_listing = lines.drop(4).join("\n")
54         
55         result.added_file_names = extract_added_files_from_git_output(file_listing)
56         result.modified_file_names = extract_modified_files_from_git_output(file_listing)
57         result
58       end
59
60       def fetch_from_git(repository, spec)
61         from = spec.from_sha.sha
62         to = spec.to_sha.sha
63         output = repository.git.git.log({:pretty => "short", :"name-status" => true}, [from, to].join(".."))
64         parse(output)
65       end
66
67       def extract_email_from_line(author_line)
68         author_line.scan(/Author:.*<(.*)>$/).flatten.first
69       end
70
71       def extract_sha_from_line(sha_line)
72         sha_line.scan(/^commit\s([a-f0-9]*)$/).flatten.first
73       end
74
75       def extract_commit_message_from_line(message_line)
76         message_line.strip
77       end
78
79       def extract_added_files_from_git_output(git_output)
80         extract_filename_from_file_list("A", git_output)
81       end
82
83       def extract_modified_files_from_git_output(git_output)
84         extract_filename_from_file_list("M", git_output)
85       end
86
87       private
88       def extract_filename_from_file_list(flag, git_output)
89         git_output.scan(/^#{flag}\s*([A-Z][a-z\.A-Z]+)$/).flatten
90       end
91     end
92   end
93 end