lib/overcommit/hook/pre_push/protected_branches.rb in overcommit-0.51.0 vs lib/overcommit/hook/pre_push/protected_branches.rb in overcommit-0.52.0

- old
+ new

@@ -1,9 +1,11 @@ # frozen_string_literal: true module Overcommit::Hook::PrePush - # Prevents destructive updates to specified branches. + # Prevents updates to specified branches. + # Accepts a 'destructive_only' option globally or per branch + # to only prevent destructive updates. class ProtectedBranches < Base def run return :pass unless illegal_pushes.any? messages = illegal_pushes.map do |pushed_ref| @@ -15,35 +17,58 @@ private def illegal_pushes @illegal_pushes ||= pushed_refs.select do |pushed_ref| - protected?(pushed_ref.remote_ref) && allow_non_destructive?(pushed_ref) + protected?(pushed_ref) end end - def protected?(remote_ref) + def protected?(ref) + find_pattern(ref.remote_ref)&.destructive?(ref) + end + + def find_pattern(remote_ref) ref_name = remote_ref[%r{refs/heads/(.*)}, 1] - return false if ref_name.nil? - protected_branch_patterns.any? do |pattern| - File.fnmatch(pattern, ref_name) + return if ref_name.nil? + + patterns.find do |pattern| + File.fnmatch(pattern.to_s, ref_name) end end - def protected_branch_patterns - @protected_branch_patterns ||= Array(config['branches']). - concat(Array(config['branch_patterns'])) + def patterns + @patterns ||= fetch_patterns end - def destructive_only? + def fetch_patterns + branch_configurations.map do |pattern| + if pattern.is_a?(Hash) + Pattern.new(pattern.keys.first, pattern['destructive_only']) + else + Pattern.new(pattern, global_destructive_only?) + end + end + end + + def branch_configurations + config['branches'].to_a + config['branch_patterns'].to_a + end + + def global_destructive_only? config['destructive_only'].nil? || config['destructive_only'] end - def allow_non_destructive?(ref) - if destructive_only? - ref.destructive? - else - true + Pattern = Struct.new('Pattern', :name, :destructive_only) do + alias_method :to_s, :name + alias_method :destructive_only?, :destructive_only + + def destructive?(ref) + if destructive_only? + ref.destructive? + else + true + end end end end end