Don't show timeout message for empty diffs (ie. blank file added)
[gitorious.git] / lib / push_spec_parser.rb
blob3ee3491ee73d8b76de19375a1c36f2af32a86af1
1 # encoding: utf-8
2 #--
3 #   Copyright (C) 2011, 2013 Gitorious AS
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.
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.
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 #++
19 # Parses the line input to git's pre-receive and post-receive hooks:
20 # <old-value> SP <new-value> SP <ref-name> LF
22 # The parser basically knows what action this line represents (create, update,
23 # delete) and whether its target is tag, a head or (custom for Gitorious) a
24 # merge request. The parser also knows the ref-name of the target.
26 # Example:
28 #     spec = PushSpecParser.new("9b0c1c59c682f9cb908a7aaf28a30b60846237fb",
29 #                               "8edf464ae27b6ff8d39600df05ebfbf6c1f1b0d3",
30 #                               "refs/heads/master")
31 #     spec.head? #=> true
32 #     spec.action_update? #=> true
33 #     spec.action_create? #=> false
34 #     spec.ref_name #=> "master"
36 # Refer to unit tests for further examples.
38 class PushSpecParser
39   attr_reader :from_sha, :to_sha, :ref
41   def initialize(from_sha, to_sha, ref)
42     @from_sha = Sha.new(from_sha)
43     @to_sha = Sha.new(to_sha)
44     @ref = Ref.new(ref)
45   end
47   def to_s
48     "<Spec from: #{@from_sha.sha} to: #{@to_sha.sha} for: #{ref.name}>"
49   end
51   def tag?
52     ref.tag?
53   end
55   def head?
56     ref.head?
57   end
59   def merge_request?
60     ref.merge_request?
61   end
63   def action_create?
64     from_sha.null_sha?
65   end
67   def action_update?
68     !from_sha.null_sha? && !to_sha.null_sha?
69   end
71   def action_delete?
72     to_sha.null_sha?
73   end
75   def ref_name
76     ref.name
77   end
79   # Internal representation of a single sha.
80   class Sha
81     def initialize(sha)
82       @sha = sha
83     end
85     def null_sha?
86       (@sha =~ /^0+$/) == 0
87     end
89     def sha
90       @sha
91     end
92   end
94   # Internal representation of a Git ref, e.g. res/tags/topic-branch
95   class Ref
96     attr_reader :name
98     def initialize(ref)
99       r, @type, @name = ref.split("/", 3)
100     end
102     def tag?
103       @type == "tags"
104     end
106     def head?
107       @type == "heads"
108     end
110     def merge_request?
111       @type == "merge-requests"
112     end
113   end