overcommit-jeygeethanmedia 0.53.1.2 → 0.58.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/bin/overcommit +6 -5
  3. data/config/default.yml +37 -5
  4. data/lib/overcommit/cli.rb +14 -13
  5. data/lib/overcommit/command_splitter.rb +2 -0
  6. data/lib/overcommit/configuration.rb +1 -1
  7. data/lib/overcommit/configuration_loader.rb +11 -8
  8. data/lib/overcommit/exceptions.rb +19 -16
  9. data/lib/overcommit/git_config.rb +1 -0
  10. data/lib/overcommit/git_repo.rb +14 -13
  11. data/lib/overcommit/hook/commit_msg/base.rb +1 -1
  12. data/lib/overcommit/hook/commit_msg/spell_check.rb +1 -1
  13. data/lib/overcommit/hook/commit_msg/text_width.rb +1 -1
  14. data/lib/overcommit/hook/post_checkout/base.rb +1 -0
  15. data/lib/overcommit/hook/post_commit/git_guilt.rb +2 -1
  16. data/lib/overcommit/hook/pre_commit/author_name.rb +2 -2
  17. data/lib/overcommit/hook/pre_commit/bundle_audit.rb +1 -1
  18. data/lib/overcommit/hook/pre_commit/chamber_compare.rb +5 -5
  19. data/lib/overcommit/hook/pre_commit/chamber_security.rb +1 -0
  20. data/lib/overcommit/hook/pre_commit/coffee_lint.rb +1 -1
  21. data/lib/overcommit/hook/pre_commit/css_lint.rb +1 -1
  22. data/lib/overcommit/hook/pre_commit/dart_analyzer.rb +22 -0
  23. data/lib/overcommit/hook/pre_commit/erb_lint.rb +20 -0
  24. data/lib/overcommit/hook/pre_commit/es_lint.rb +3 -6
  25. data/lib/overcommit/hook/pre_commit/fasterer.rb +1 -1
  26. data/lib/overcommit/hook/pre_commit/foodcritic.rb +3 -1
  27. data/lib/overcommit/hook/pre_commit/hlint.rb +1 -1
  28. data/lib/overcommit/hook/pre_commit/html_tidy.rb +1 -1
  29. data/lib/overcommit/hook/pre_commit/java_checkstyle.rb +1 -1
  30. data/lib/overcommit/hook/pre_commit/js_lint.rb +1 -1
  31. data/lib/overcommit/hook/pre_commit/jsl.rb +1 -1
  32. data/lib/overcommit/hook/pre_commit/kt_lint.rb +1 -1
  33. data/lib/overcommit/hook/pre_commit/license_finder.rb +1 -0
  34. data/lib/overcommit/hook/pre_commit/line_endings.rb +3 -2
  35. data/lib/overcommit/hook/pre_commit/nginx_test.rb +1 -1
  36. data/lib/overcommit/hook/pre_commit/php_cs.rb +1 -1
  37. data/lib/overcommit/hook/pre_commit/php_cs_fixer.rb +1 -1
  38. data/lib/overcommit/hook/pre_commit/php_lint.rb +3 -3
  39. data/lib/overcommit/hook/pre_commit/php_stan.rb +1 -1
  40. data/lib/overcommit/hook/pre_commit/puppet_lint.rb +1 -1
  41. data/lib/overcommit/hook/pre_commit/puppet_metadata_json_lint.rb +1 -1
  42. data/lib/overcommit/hook/pre_commit/pyflakes.rb +1 -1
  43. data/lib/overcommit/hook/pre_commit/pylint.rb +1 -1
  44. data/lib/overcommit/hook/pre_commit/python_flake8.rb +1 -1
  45. data/lib/overcommit/hook/pre_commit/rails_best_practices.rb +1 -1
  46. data/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb +2 -2
  47. data/lib/overcommit/hook/pre_commit/rst_lint.rb +1 -1
  48. data/lib/overcommit/hook/pre_commit/scalariform.rb +1 -1
  49. data/lib/overcommit/hook/pre_commit/scalastyle.rb +1 -1
  50. data/lib/overcommit/hook/pre_commit/scss_lint.rb +3 -3
  51. data/lib/overcommit/hook/pre_commit/semi_standard.rb +1 -1
  52. data/lib/overcommit/hook/pre_commit/sqlint.rb +1 -1
  53. data/lib/overcommit/hook/pre_commit/standard.rb +1 -1
  54. data/lib/overcommit/hook/pre_commit/stylelint.rb +2 -1
  55. data/lib/overcommit/hook/pre_commit/swift_lint.rb +1 -1
  56. data/lib/overcommit/hook/pre_commit/ts_lint.rb +4 -4
  57. data/lib/overcommit/hook/pre_commit/w3c_css.rb +4 -4
  58. data/lib/overcommit/hook/pre_commit/w3c_html.rb +4 -4
  59. data/lib/overcommit/hook/pre_commit/xml_lint.rb +1 -1
  60. data/lib/overcommit/hook/pre_commit/yaml_lint.rb +25 -4
  61. data/lib/overcommit/hook/pre_commit/yaml_syntax.rb +7 -3
  62. data/lib/overcommit/hook/pre_commit/yard_coverage.rb +0 -1
  63. data/lib/overcommit/hook/pre_push/cargo_test.rb +1 -0
  64. data/lib/overcommit/hook/pre_push/flutter_test.rb +16 -0
  65. data/lib/overcommit/hook/pre_push/pub_test.rb +16 -0
  66. data/lib/overcommit/hook/prepare_commit_msg/base.rb +1 -0
  67. data/lib/overcommit/hook/prepare_commit_msg/replace_branch.rb +38 -4
  68. data/lib/overcommit/hook/shared/bower_install.rb +1 -0
  69. data/lib/overcommit/hook/shared/bundle_install.rb +1 -0
  70. data/lib/overcommit/hook/shared/composer_install.rb +1 -0
  71. data/lib/overcommit/hook/shared/npm_install.rb +1 -0
  72. data/lib/overcommit/hook/shared/pronto.rb +7 -3
  73. data/lib/overcommit/hook/shared/yarn_install.rb +1 -0
  74. data/lib/overcommit/hook_context/commit_msg.rb +7 -0
  75. data/lib/overcommit/hook_context/helpers/file_modifications.rb +79 -0
  76. data/lib/overcommit/hook_context/helpers/stash_unstaged_changes.rb +144 -0
  77. data/lib/overcommit/hook_context/post_commit.rb +1 -0
  78. data/lib/overcommit/hook_context/pre_commit.rb +5 -199
  79. data/lib/overcommit/hook_context/pre_push.rb +1 -0
  80. data/lib/overcommit/hook_context/run_all.rb +1 -0
  81. data/lib/overcommit/hook_context.rb +3 -3
  82. data/lib/overcommit/hook_loader/base.rb +3 -3
  83. data/lib/overcommit/hook_loader/plugin_hook_loader.rb +3 -3
  84. data/lib/overcommit/hook_runner.rb +8 -7
  85. data/lib/overcommit/hook_signer.rb +1 -0
  86. data/lib/overcommit/installer.rb +2 -1
  87. data/lib/overcommit/subprocess.rb +24 -2
  88. data/lib/overcommit/utils/messages_utils.rb +1 -0
  89. data/lib/overcommit/version.rb +1 -1
  90. data/libexec/index-tags +6 -4
  91. data/template-dir/hooks/commit-msg +27 -20
  92. data/template-dir/hooks/overcommit-hook +27 -20
  93. data/template-dir/hooks/post-checkout +27 -20
  94. data/template-dir/hooks/post-commit +27 -20
  95. data/template-dir/hooks/post-merge +27 -20
  96. data/template-dir/hooks/post-rewrite +27 -20
  97. data/template-dir/hooks/pre-commit +27 -20
  98. data/template-dir/hooks/pre-push +27 -20
  99. data/template-dir/hooks/pre-rebase +27 -20
  100. data/template-dir/hooks/prepare-commit-msg +27 -20
  101. metadata +27 -7
@@ -1,8 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'pre_commit'
4
+ require_relative 'helpers/stash_unstaged_changes'
5
+ require_relative 'helpers/file_modifications'
6
+
3
7
  module Overcommit::HookContext
4
8
  # Contains helpers related to contextual information used by commit-msg hooks.
5
9
  class CommitMsg < Base
10
+ include Overcommit::HookContext::Helpers::StashUnstagedChanges
11
+ include Overcommit::HookContext::Helpers::FileModifications
12
+
6
13
  def empty_message?
7
14
  commit_message.strip.empty?
8
15
  end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Overcommit::HookContext
4
+ module Helpers
5
+ # This module contains methods for determining what files were changed and on what unique line
6
+ # numbers did the change occur.
7
+ module FileModifications
8
+ # Returns whether this hook run was triggered by `git commit --amend`
9
+ def amendment?
10
+ return @amendment unless @amendment.nil?
11
+
12
+ cmd = Overcommit::Utils.parent_command
13
+ return unless cmd
14
+
15
+ amend_pattern = 'commit(\s.*)?\s--amend(\s|$)'
16
+
17
+ # Since the ps command can return invalid byte sequences for commands
18
+ # containing unicode characters, we replace the offending characters,
19
+ # since the pattern we're looking for will consist of ASCII characters
20
+ unless cmd.valid_encoding?
21
+ cmd = Overcommit::Utils.
22
+ parent_command.
23
+ encode('UTF-16be', invalid: :replace, replace: '?').
24
+ encode('UTF-8')
25
+ end
26
+
27
+ return @amendment if
28
+ # True if the command is a commit with the --amend flag
29
+ @amendment = !(/\s#{amend_pattern}/ =~ cmd).nil?
30
+
31
+ # Check for git aliases that call `commit --amend`
32
+ `git config --get-regexp "^alias\\." "#{amend_pattern}"`.
33
+ scan(/alias\.([-\w]+)/). # Extract the alias
34
+ each do |match|
35
+ return @amendment if
36
+ # True if the command uses a git alias for `commit --amend`
37
+ @amendment = !(/git(\.exe)?\s+#{match[0]}/ =~ cmd).nil?
38
+ end
39
+
40
+ @amendment
41
+ end
42
+
43
+ # Get a list of added, copied, or modified files that have been staged.
44
+ # Renames and deletions are ignored, since there should be nothing to check.
45
+ def modified_files
46
+ unless @modified_files
47
+ currently_staged = Overcommit::GitRepo.modified_files(staged: true)
48
+ @modified_files = currently_staged
49
+
50
+ # Include files modified in last commit if amending
51
+ if amendment?
52
+ subcmd = 'show --format=%n'
53
+ previously_modified = Overcommit::GitRepo.modified_files(subcmd: subcmd)
54
+ @modified_files |= filter_modified_files(previously_modified)
55
+ end
56
+ end
57
+ @modified_files
58
+ end
59
+
60
+ # Returns the set of line numbers corresponding to the lines that were
61
+ # changed in a specified file.
62
+ def modified_lines_in_file(file)
63
+ @modified_lines ||= {}
64
+ unless @modified_lines[file]
65
+ @modified_lines[file] =
66
+ Overcommit::GitRepo.extract_modified_lines(file, staged: true)
67
+
68
+ # Include lines modified in last commit if amending
69
+ if amendment?
70
+ subcmd = 'show --format=%n'
71
+ @modified_lines[file] +=
72
+ Overcommit::GitRepo.extract_modified_lines(file, subcmd: subcmd)
73
+ end
74
+ end
75
+ @modified_lines[file]
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Overcommit::HookContext
4
+ module Helpers
5
+ # This module contains behavior for stashing unstaged changes before hooks are ran and restoring
6
+ # them afterwards
7
+ module StashUnstagedChanges
8
+ # Stash unstaged contents of files so hooks don't see changes that aren't
9
+ # about to be committed.
10
+ def setup_environment
11
+ store_modified_times
12
+ Overcommit::GitRepo.store_merge_state
13
+ Overcommit::GitRepo.store_cherry_pick_state
14
+
15
+ # Don't attempt to stash changes if all changes are staged, as this
16
+ # prevents us from modifying files at all, which plays better with
17
+ # editors/tools which watch for file changes.
18
+ if !initial_commit? && unstaged_changes?
19
+ stash_changes
20
+
21
+ # While running hooks make it appear as if nothing changed
22
+ restore_modified_times
23
+ end
24
+ end
25
+
26
+ # Returns whether the current git branch is empty (has no commits).
27
+ def initial_commit?
28
+ return @initial_commit unless @initial_commit.nil?
29
+
30
+ @initial_commit = Overcommit::GitRepo.initial_commit?
31
+ end
32
+
33
+ # Restore unstaged changes and reset file modification times so it appears
34
+ # as if nothing ever changed.
35
+ #
36
+ # We want to restore the modification times for each of the files after
37
+ # every step to ensure as little time as possible has passed while the
38
+ # modification time on the file was newer. This helps us play more nicely
39
+ # with file watchers.
40
+ def cleanup_environment
41
+ if @changes_stashed
42
+ clear_working_tree
43
+ restore_working_tree
44
+ restore_modified_times
45
+ end
46
+
47
+ Overcommit::GitRepo.restore_merge_state
48
+ Overcommit::GitRepo.restore_cherry_pick_state
49
+ end
50
+
51
+ private
52
+
53
+ # Stores the modification times for all modified files to make it appear like
54
+ # they never changed.
55
+ #
56
+ # This prevents (some) editors from complaining about files changing when we
57
+ # stash changes before running the hooks.
58
+ def store_modified_times
59
+ @modified_times = {}
60
+
61
+ staged_files = modified_files
62
+ unstaged_files = Overcommit::GitRepo.modified_files(staged: false)
63
+
64
+ (staged_files + unstaged_files).each do |file|
65
+ next if Overcommit::Utils.broken_symlink?(file)
66
+ next unless File.exist?(file) # Ignore renamed files (old file no longer exists)
67
+
68
+ @modified_times[file] = File.mtime(file)
69
+ end
70
+ end
71
+
72
+ # Returns whether there are any changes to tracked files which have not yet
73
+ # been staged.
74
+ def unstaged_changes?
75
+ result = Overcommit::Utils.execute(%w[git --no-pager diff --quiet])
76
+ !result.success?
77
+ end
78
+
79
+ def stash_changes
80
+ @stash_attempted = true
81
+
82
+ stash_message = "Overcommit: Stash of repo state before hook run at #{Time.now}"
83
+ result = Overcommit::Utils.with_environment('GIT_LITERAL_PATHSPECS' => '0') do
84
+ Overcommit::Utils.execute(
85
+ %w[git -c commit.gpgsign=false stash save --keep-index --quiet] + [stash_message]
86
+ )
87
+ end
88
+
89
+ unless result.success?
90
+ # Failure to stash in this case is likely due to a configuration
91
+ # issue (e.g. author/email not set or GPG signing key incorrect)
92
+ raise Overcommit::Exceptions::HookSetupFailed,
93
+ "Unable to setup environment for #{hook_script_name} hook run:" \
94
+ "\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}"
95
+ end
96
+
97
+ @changes_stashed = `git stash list -1`.include?(stash_message)
98
+ end
99
+
100
+ # Restores the file modification times for all modified files to make it
101
+ # appear like they never changed.
102
+ def restore_modified_times
103
+ @modified_times.each do |file, time|
104
+ next if Overcommit::Utils.broken_symlink?(file)
105
+ next unless File.exist?(file)
106
+
107
+ File.utime(time, time, file)
108
+ end
109
+ end
110
+
111
+ # Clears the working tree so that the stash can be applied.
112
+ def clear_working_tree
113
+ removed_submodules = Overcommit::GitRepo.staged_submodule_removals
114
+
115
+ result = Overcommit::Utils.execute(%w[git reset --hard])
116
+ unless result.success?
117
+ raise Overcommit::Exceptions::HookCleanupFailed,
118
+ "Unable to cleanup working tree after #{hook_script_name} hooks run:" \
119
+ "\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}"
120
+ end
121
+
122
+ # Hard-resetting a staged submodule removal results in the index being
123
+ # reset but the submodule being restored as an empty directory. This empty
124
+ # directory prevents us from stashing on a subsequent run if a hook fails.
125
+ #
126
+ # Work around this by removing these empty submodule directories as there
127
+ # doesn't appear any reason to keep them around.
128
+ removed_submodules.each do |submodule|
129
+ FileUtils.rmdir(submodule.path)
130
+ end
131
+ end
132
+
133
+ # Applies the stash to the working tree to restore the user's state.
134
+ def restore_working_tree
135
+ result = Overcommit::Utils.execute(%w[git stash pop --index])
136
+ unless result.success?
137
+ raise Overcommit::Exceptions::HookCleanupFailed,
138
+ "Unable to restore working tree after #{hook_script_name} hooks run:" \
139
+ "\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}"
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -27,6 +27,7 @@ module Overcommit::HookContext
27
27
  # @return [true,false]
28
28
  def initial_commit?
29
29
  return @initial_commit unless @initial_commit.nil?
30
+
30
31
  @initial_commit = !Overcommit::Utils.execute(%w[git rev-parse HEAD~]).success?
31
32
  end
32
33
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'fileutils'
4
4
  require 'set'
5
+ require_relative 'helpers/stash_unstaged_changes'
6
+ require_relative 'helpers/file_modifications'
5
7
 
6
8
  module Overcommit::HookContext
7
9
  # Contains helpers related to contextual information used by pre-commit hooks.
@@ -9,204 +11,8 @@ module Overcommit::HookContext
9
11
  # This includes staged files, which lines of those files have been modified,
10
12
  # etc. It is also responsible for saving/restoring the state of the repo so
11
13
  # hooks only inspect staged changes.
12
- class PreCommit < Base # rubocop:disable ClassLength
13
- # Returns whether this hook run was triggered by `git commit --amend`
14
- def amendment?
15
- return @amendment unless @amendment.nil?
16
-
17
- cmd = Overcommit::Utils.parent_command
18
- return unless cmd
19
- amend_pattern = 'commit(\s.*)?\s--amend(\s|$)'
20
-
21
- # Since the ps command can return invalid byte sequences for commands
22
- # containing unicode characters, we replace the offending characters,
23
- # since the pattern we're looking for will consist of ASCII characters
24
- unless cmd.valid_encoding?
25
- cmd = Overcommit::Utils.parent_command.encode('UTF-16be', invalid: :replace, replace: '?').
26
- encode('UTF-8')
27
- end
28
-
29
- return @amendment if
30
- # True if the command is a commit with the --amend flag
31
- @amendment = !(/\s#{amend_pattern}/ =~ cmd).nil?
32
-
33
- # Check for git aliases that call `commit --amend`
34
- `git config --get-regexp "^alias\\." "#{amend_pattern}"`.
35
- scan(/alias\.([-\w]+)/). # Extract the alias
36
- each do |match|
37
- return @amendment if
38
- # True if the command uses a git alias for `commit --amend`
39
- @amendment = !(/git(\.exe)?\s+#{match[0]}/ =~ cmd).nil?
40
- end
41
-
42
- @amendment
43
- end
44
-
45
- # Stash unstaged contents of files so hooks don't see changes that aren't
46
- # about to be committed.
47
- def setup_environment
48
- store_modified_times
49
- Overcommit::GitRepo.store_merge_state
50
- Overcommit::GitRepo.store_cherry_pick_state
51
-
52
- # Don't attempt to stash changes if all changes are staged, as this
53
- # prevents us from modifying files at all, which plays better with
54
- # editors/tools which watch for file changes.
55
- if !initial_commit? && unstaged_changes?
56
- stash_changes
57
-
58
- # While running hooks make it appear as if nothing changed
59
- restore_modified_times
60
- end
61
- end
62
-
63
- # Restore unstaged changes and reset file modification times so it appears
64
- # as if nothing ever changed.
65
- #
66
- # We want to restore the modification times for each of the files after
67
- # every step to ensure as little time as possible has passed while the
68
- # modification time on the file was newer. This helps us play more nicely
69
- # with file watchers.
70
- def cleanup_environment
71
- if @changes_stashed
72
- clear_working_tree
73
- restore_working_tree
74
- restore_modified_times
75
- end
76
-
77
- Overcommit::GitRepo.restore_merge_state
78
- Overcommit::GitRepo.restore_cherry_pick_state
79
- end
80
-
81
- # Get a list of added, copied, or modified files that have been staged.
82
- # Renames and deletions are ignored, since there should be nothing to check.
83
- def modified_files
84
- unless @modified_files
85
- currently_staged = Overcommit::GitRepo.modified_files(staged: true)
86
- @modified_files = currently_staged
87
-
88
- # Include files modified in last commit if amending
89
- if amendment?
90
- subcmd = 'show --format=%n'
91
- previously_modified = Overcommit::GitRepo.modified_files(subcmd: subcmd)
92
- @modified_files |= filter_modified_files(previously_modified)
93
- end
94
- end
95
- @modified_files
96
- end
97
-
98
- # Returns the set of line numbers corresponding to the lines that were
99
- # changed in a specified file.
100
- def modified_lines_in_file(file)
101
- @modified_lines ||= {}
102
- unless @modified_lines[file]
103
- @modified_lines[file] =
104
- Overcommit::GitRepo.extract_modified_lines(file, staged: true)
105
-
106
- # Include lines modified in last commit if amending
107
- if amendment?
108
- subcmd = 'show --format=%n'
109
- @modified_lines[file] +=
110
- Overcommit::GitRepo.extract_modified_lines(file, subcmd: subcmd)
111
- end
112
- end
113
- @modified_lines[file]
114
- end
115
-
116
- # Returns whether the current git branch is empty (has no commits).
117
- def initial_commit?
118
- return @initial_commit unless @initial_commit.nil?
119
- @initial_commit = Overcommit::GitRepo.initial_commit?
120
- end
121
-
122
- private
123
-
124
- def stash_changes
125
- @stash_attempted = true
126
-
127
- stash_message = "Overcommit: Stash of repo state before hook run at #{Time.now}"
128
- result = Overcommit::Utils.with_environment('GIT_LITERAL_PATHSPECS' => '0') do
129
- Overcommit::Utils.execute(
130
- %w[git -c commit.gpgsign=false stash save --keep-index --quiet] + [stash_message]
131
- )
132
- end
133
-
134
- unless result.success?
135
- # Failure to stash in this case is likely due to a configuration
136
- # issue (e.g. author/email not set or GPG signing key incorrect)
137
- raise Overcommit::Exceptions::HookSetupFailed,
138
- "Unable to setup environment for #{hook_script_name} hook run:" \
139
- "\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}"
140
- end
141
-
142
- @changes_stashed = `git stash list -1`.include?(stash_message)
143
- end
144
-
145
- # Clears the working tree so that the stash can be applied.
146
- def clear_working_tree
147
- removed_submodules = Overcommit::GitRepo.staged_submodule_removals
148
-
149
- result = Overcommit::Utils.execute(%w[git reset --hard])
150
- unless result.success?
151
- raise Overcommit::Exceptions::HookCleanupFailed,
152
- "Unable to cleanup working tree after #{hook_script_name} hooks run:" \
153
- "\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}"
154
- end
155
-
156
- # Hard-resetting a staged submodule removal results in the index being
157
- # reset but the submodule being restored as an empty directory. This empty
158
- # directory prevents us from stashing on a subsequent run if a hook fails.
159
- #
160
- # Work around this by removing these empty submodule directories as there
161
- # doesn't appear any reason to keep them around.
162
- removed_submodules.each do |submodule|
163
- FileUtils.rmdir(submodule.path)
164
- end
165
- end
166
-
167
- # Applies the stash to the working tree to restore the user's state.
168
- def restore_working_tree
169
- result = Overcommit::Utils.execute(%w[git stash pop --index --quiet])
170
- unless result.success?
171
- raise Overcommit::Exceptions::HookCleanupFailed,
172
- "Unable to restore working tree after #{hook_script_name} hooks run:" \
173
- "\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}"
174
- end
175
- end
176
-
177
- # Returns whether there are any changes to tracked files which have not yet
178
- # been staged.
179
- def unstaged_changes?
180
- result = Overcommit::Utils.execute(%w[git --no-pager diff --quiet])
181
- !result.success?
182
- end
183
-
184
- # Stores the modification times for all modified files to make it appear like
185
- # they never changed.
186
- #
187
- # This prevents (some) editors from complaining about files changing when we
188
- # stash changes before running the hooks.
189
- def store_modified_times
190
- @modified_times = {}
191
-
192
- staged_files = modified_files
193
- unstaged_files = Overcommit::GitRepo.modified_files(staged: false)
194
-
195
- (staged_files + unstaged_files).each do |file|
196
- next if Overcommit::Utils.broken_symlink?(file)
197
- next unless File.exist?(file) # Ignore renamed files (old file no longer exists)
198
- @modified_times[file] = File.mtime(file)
199
- end
200
- end
201
-
202
- # Restores the file modification times for all modified files to make it
203
- # appear like they never changed.
204
- def restore_modified_times
205
- @modified_times.each do |file, time|
206
- next if Overcommit::Utils.broken_symlink?(file)
207
- next unless File.exist?(file)
208
- File.utime(time, time, file)
209
- end
210
- end
14
+ class PreCommit < Base
15
+ include Overcommit::HookContext::Helpers::StashUnstagedChanges
16
+ include Overcommit::HookContext::Helpers::FileModifications
211
17
  end
212
18
  end
@@ -76,6 +76,7 @@ module Overcommit::HookContext
76
76
 
77
77
  def overwritten_commits
78
78
  return @overwritten_commits if defined? @overwritten_commits
79
+
79
80
  result = Overcommit::Subprocess.spawn(%W[git rev-list #{remote_sha1} ^#{local_sha1}])
80
81
  if result.success?
81
82
  result.stdout.split("\n")
@@ -36,6 +36,7 @@ module Overcommit::HookContext
36
36
 
37
37
  def initial_commit?
38
38
  return @initial_commit unless @initial_commit.nil?
39
+
39
40
  @initial_commit = Overcommit::GitRepo.initial_commit?
40
41
  end
41
42
 
@@ -9,11 +9,11 @@ module Overcommit::HookContext
9
9
  require "overcommit/hook_context/#{underscored_hook_type}"
10
10
 
11
11
  Overcommit::HookContext.const_get(hook_type_class).new(config, args, input)
12
- rescue LoadError, NameError => error
12
+ rescue LoadError, NameError => e
13
13
  # Could happen when a symlink was created for a hook type Overcommit does
14
14
  # not yet support.
15
15
  raise Overcommit::Exceptions::HookContextLoadError,
16
- "Unable to load '#{hook_type}' hook context: '#{error}'",
17
- error.backtrace
16
+ "Unable to load '#{hook_type}' hook context: '#{e}'",
17
+ e.backtrace
18
18
  end
19
19
  end
@@ -38,10 +38,10 @@ module Overcommit::HookLoader
38
38
  Overcommit::Hook.const_get(@context.hook_class_name).
39
39
  const_get(hook_name).
40
40
  new(@config, @context)
41
- rescue LoadError, NameError => error
41
+ rescue LoadError, NameError => e
42
42
  raise Overcommit::Exceptions::HookLoadError,
43
- "Unable to load hook '#{hook_name}': #{error}",
44
- error.backtrace
43
+ "Unable to load hook '#{hook_name}': #{e}",
44
+ e.backtrace
45
45
  end
46
46
  end
47
47
  end
@@ -93,10 +93,10 @@ module Overcommit::HookLoader
93
93
  end
94
94
 
95
95
  hook_module.const_set(hook_name, hook_class).new(@config, @context)
96
- rescue LoadError, NameError => error
96
+ rescue LoadError, NameError => e
97
97
  raise Overcommit::Exceptions::HookLoadError,
98
- "Unable to load hook '#{hook_name}': #{error}",
99
- error.backtrace
98
+ "Unable to load hook '#{hook_name}': #{e}",
99
+ e.backtrace
100
100
  end
101
101
  end
102
102
  end
@@ -94,6 +94,7 @@ module Overcommit
94
94
  loop do
95
95
  hook = @lock.synchronize { @hooks_left.pop }
96
96
  break unless hook
97
+
97
98
  run_hook(hook)
98
99
  end
99
100
  end
@@ -159,12 +160,12 @@ module Overcommit
159
160
  return if should_skip?(hook)
160
161
 
161
162
  status, output = hook.run_and_transform
162
- rescue Overcommit::Exceptions::MessageProcessingError => ex
163
+ rescue Overcommit::Exceptions::MessageProcessingError => e
163
164
  status = :fail
164
- output = ex.message
165
- rescue StandardError => ex
165
+ output = e.message
166
+ rescue StandardError => e
166
167
  status = :fail
167
- output = "Hook raised unexpected error\n#{ex.message}\n#{ex.backtrace.join("\n")}"
168
+ output = "Hook raised unexpected error\n#{e.message}\n#{e.backtrace.join("\n")}"
168
169
  end
169
170
 
170
171
  @failed = true if status == :fail
@@ -202,7 +203,7 @@ module Overcommit
202
203
 
203
204
  # Load plugin hooks after so they can subclass existing hooks
204
205
  @hooks += HookLoader::PluginHookLoader.new(@config, @context, @log).load_hooks
205
- rescue LoadError => ex
206
+ rescue LoadError => e
206
207
  # Include a more helpful message that will probably save some confusion
207
208
  message = 'A load error occurred. ' +
208
209
  if @config['gemfile']
@@ -212,8 +213,8 @@ module Overcommit
212
213
  end
213
214
 
214
215
  raise Overcommit::Exceptions::HookLoadError,
215
- "#{message}\n#{ex.message}",
216
- ex.backtrace
216
+ "#{message}\n#{e.message}",
217
+ e.backtrace
217
218
  end
218
219
  end
219
220
  end
@@ -52,6 +52,7 @@ module Overcommit
52
52
 
53
53
  def signable_file?(file)
54
54
  return unless file
55
+
55
56
  sep = Overcommit::OS.windows? ? '\\' : File::SEPARATOR
56
57
  file.start_with?(".#{sep}") ||
57
58
  file.start_with?(Overcommit::Utils.repo_root)
@@ -4,7 +4,7 @@ require 'fileutils'
4
4
 
5
5
  module Overcommit
6
6
  # Manages the installation of Overcommit hooks in a git repository.
7
- class Installer # rubocop:disable ClassLength
7
+ class Installer # rubocop:disable Metrics/ClassLength
8
8
  TEMPLATE_DIRECTORY = File.join(Overcommit::HOME, 'template-dir')
9
9
  MASTER_HOOK = File.join(TEMPLATE_DIRECTORY, 'hooks', 'overcommit-hook')
10
10
 
@@ -174,6 +174,7 @@ module Overcommit
174
174
  repo_config_file = File.join(@target, Overcommit::CONFIG_FILE_NAME)
175
175
 
176
176
  return if File.exist?(repo_config_file)
177
+
177
178
  FileUtils.cp(File.join(Overcommit::HOME, 'config', 'starter.yml'), repo_config_file)
178
179
  end
179
180
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'childprocess'
4
4
  require 'tempfile'
5
+ require 'overcommit/os'
5
6
 
6
7
  module Overcommit
7
8
  # Manages execution of a child process, collecting the exit status and
@@ -38,7 +39,7 @@ module Overcommit
38
39
  if options[:input]
39
40
  begin
40
41
  process.io.stdin.puts(options[:input])
41
- rescue StandardError # rubocop:disable Lint/HandleExceptions
42
+ rescue StandardError
42
43
  # Silently ignore if the standard input stream of the spawned
43
44
  # process is closed before we get a chance to write to it. This
44
45
  # happens on JRuby a lot.
@@ -51,7 +52,7 @@ module Overcommit
51
52
  err.rewind
52
53
  out.rewind
53
54
 
54
- Result.new(process.exit_code, out.read, err.read)
55
+ Result.new(process.exit_code, to_utf8(out.read), to_utf8(err.read))
55
56
  end
56
57
 
57
58
  # Spawns a new process in the background using the given array of
@@ -83,6 +84,27 @@ module Overcommit
83
84
  %w[cmd.exe /c] + [args.join(' ')]
84
85
  end
85
86
 
87
+ # Convert string from current locale to utf-8
88
+ #
89
+ # When running commands under windows the command output is using
90
+ # current system locale (depends on system lanuage) not UTF-8
91
+ #
92
+ # @param process [String]
93
+ # @return [String]
94
+ def to_utf8(string)
95
+ # Our encoding code doesn't work on the GitHub Actions Windows
96
+ # environment for unknown reasons, so just skip it in CI.
97
+ return string if OS.windows? && ENV['GITHUB_ACTIONS']
98
+
99
+ if Encoding.locale_charmap == 'UTF-8'
100
+ return string
101
+ end
102
+
103
+ ec = Encoding::Converter.new(Encoding.locale_charmap, 'UTF-8')
104
+ # Convert encoding, alternatively simple: string.scrub will suffice
105
+ ec.convert(string)
106
+ end
107
+
86
108
  # @param process [ChildProcess]
87
109
  # @return [Array<IO>]
88
110
  def assign_output_streams(process)
@@ -52,6 +52,7 @@ module Overcommit::Utils
52
52
 
53
53
  def extract_line(match, message)
54
54
  return unless match.names.include?('line')
55
+
55
56
  Integer(match[:line])
56
57
  rescue ArgumentError, TypeError
57
58
  raise Overcommit::Exceptions::MessageProcessingError,
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Defines the gem version.
4
4
  module Overcommit
5
- VERSION = '0.53.1.2'
5
+ VERSION = '0.58.0'
6
6
  end