1
1
# frozen_string_literal: true
2
2
3
3
module Overcommit ::Hook ::PrePush
4
- # Prevents destructive updates to specified branches.
4
+ # Prevents updates to specified branches.
5
+ # Accepts a 'destructive_only' option globally or per branch
6
+ # to only prevent destructive updates.
5
7
class ProtectedBranches < Base
6
8
def run
7
9
return :pass unless illegal_pushes . any?
@@ -17,32 +19,55 @@ def run
17
19
18
20
def illegal_pushes
19
21
@illegal_pushes ||= pushed_refs . select do |pushed_ref |
20
- protected? ( pushed_ref . remote_ref ) && allow_non_destructive? ( pushed_ref )
22
+ protected? ( pushed_ref )
21
23
end
22
24
end
23
25
24
- def protected? ( remote_ref )
26
+ def protected? ( ref )
27
+ find_pattern ( ref . remote_ref ) &.destructive? ( ref )
28
+ end
29
+
30
+ def find_pattern ( remote_ref )
25
31
ref_name = remote_ref [ %r{refs/heads/(.*)} , 1 ]
26
- return false if ref_name . nil?
27
- protected_branch_patterns . any? do |pattern |
28
- File . fnmatch ( pattern , ref_name )
32
+ return if ref_name . nil?
33
+
34
+ patterns . find do |pattern |
35
+ File . fnmatch ( pattern . to_s , ref_name )
29
36
end
30
37
end
31
38
32
- def protected_branch_patterns
33
- @protected_branch_patterns ||= Array ( config [ 'branches' ] ) .
34
- concat ( Array ( config [ 'branch_patterns' ] ) )
39
+ def patterns
40
+ @patterns ||= fetch_patterns
35
41
end
36
42
37
- def destructive_only?
43
+ def fetch_patterns
44
+ branch_configurations . map do |pattern |
45
+ if pattern . is_a? ( Hash )
46
+ Pattern . new ( pattern . keys . first , pattern [ 'destructive_only' ] )
47
+ else
48
+ Pattern . new ( pattern , global_destructive_only? )
49
+ end
50
+ end
51
+ end
52
+
53
+ def branch_configurations
54
+ config [ 'branches' ] . to_a + config [ 'branch_patterns' ] . to_a
55
+ end
56
+
57
+ def global_destructive_only?
38
58
config [ 'destructive_only' ] . nil? || config [ 'destructive_only' ]
39
59
end
40
60
41
- def allow_non_destructive? ( ref )
42
- if destructive_only?
43
- ref . destructive?
44
- else
45
- true
61
+ Pattern = Struct . new ( 'Pattern' , :name , :destructive_only ) do
62
+ alias_method :to_s , :name
63
+ alias_method :destructive_only? , :destructive_only
64
+
65
+ def destructive? ( ref )
66
+ if destructive_only?
67
+ ref . destructive?
68
+ else
69
+ true
70
+ end
46
71
end
47
72
end
48
73
end
0 commit comments