From 8812c5f0560da43e1fa2c613684ea9b628945628 Mon Sep 17 00:00:00 2001 From: Carlos Palhares Date: Sun, 11 Sep 2022 07:21:16 -0300 Subject: [PATCH 01/43] Allow overriding Gemfile.lock (#796) * Allow overriding Gemfile.lock * Fix lint rule violation --- lib/overcommit/hook/pre_commit/bundle_check.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/overcommit/hook/pre_commit/bundle_check.rb b/lib/overcommit/hook/pre_commit/bundle_check.rb index 10d30d2c..70f5fa2e 100644 --- a/lib/overcommit/hook/pre_commit/bundle_check.rb +++ b/lib/overcommit/hook/pre_commit/bundle_check.rb @@ -6,7 +6,7 @@ module Overcommit::Hook::PreCommit # # @see http://bundler.io/ class BundleCheck < Base - LOCK_FILE = 'Gemfile.lock' + LOCK_FILE = File.basename(ENV['BUNDLE_GEMFILE'] || 'Gemfile') + '.lock' def run # Ignore if Gemfile.lock is not tracked by git From 1e62370e8b29a96961c3f9c4e17d936dbcb05e19 Mon Sep 17 00:00:00 2001 From: Mark Delk Date: Sun, 18 Dec 2022 17:00:33 -0600 Subject: [PATCH 02/43] support trailing space in replace_branch's 'replacement_text' config (#804) --- lib/overcommit/hook/prepare_commit_msg/replace_branch.rb | 8 ++++---- .../hook/prepare_commit_msg/replace_branch_spec.rb | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/overcommit/hook/prepare_commit_msg/replace_branch.rb b/lib/overcommit/hook/prepare_commit_msg/replace_branch.rb index 7a40ed69..e8c09887 100644 --- a/lib/overcommit/hook/prepare_commit_msg/replace_branch.rb +++ b/lib/overcommit/hook/prepare_commit_msg/replace_branch.rb @@ -11,9 +11,9 @@ module Overcommit::Hook::PrepareCommitMsg # For instance, if your current branch is `123-topic` then this config # # branch_pattern: '(\d+)-(\w+)' - # replacement_text: '[#\1]' + # replacement_text: '[#\1] ' # - # would make this hook prepend commit messages with `[#123]`. + # would make this hook prepend commit messages with `[#123] `. # # Similarly, a replacement text of `[\1][\2]` would result in `[123][topic]`. # @@ -53,7 +53,7 @@ def new_template @new_template ||= begin curr_branch = Overcommit::GitRepo.current_branch - curr_branch.gsub(branch_pattern, replacement_text).strip + curr_branch.gsub(branch_pattern, replacement_text) end end @@ -69,7 +69,7 @@ def replacement_text @replacement_text ||= begin if File.exist?(replacement_text_config) - File.read(replacement_text_config) + File.read(replacement_text_config).chomp else replacement_text_config end diff --git a/spec/overcommit/hook/prepare_commit_msg/replace_branch_spec.rb b/spec/overcommit/hook/prepare_commit_msg/replace_branch_spec.rb index 3844f77a..6af27921 100644 --- a/spec/overcommit/hook/prepare_commit_msg/replace_branch_spec.rb +++ b/spec/overcommit/hook/prepare_commit_msg/replace_branch_spec.rb @@ -62,6 +62,14 @@ def remove_file(name) it 'prepends the replacement text' do expect(File.read('COMMIT_EDITMSG')).to eq("[#123]\n") end + + context 'when the replacement text contains a space' do + let(:config) { new_config('replacement_text' => '[\1] ') } + + it 'prepends the replacement text, including the space' do + expect(File.read('COMMIT_EDITMSG')).to eq("[123] \n") + end + end end context "when the checked out branch doesn't matches the pattern" do From 9aa62593f56c2f5f09d411214f482252c9a300a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dino=20Kova=C4=8D?= Date: Mon, 19 Dec 2022 00:01:18 +0100 Subject: [PATCH 03/43] Add MixFormat hook (#801) --- config/default.yml | 10 ++++ lib/overcommit/hook/pre_commit/mix_format.rb | 30 ++++++++++++ .../hook/pre_commit/mix_format_spec.rb | 47 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 lib/overcommit/hook/pre_commit/mix_format.rb create mode 100644 spec/overcommit/hook/pre_commit/mix_format_spec.rb diff --git a/config/default.yml b/config/default.yml index bfd91e08..42ea17a8 100644 --- a/config/default.yml +++ b/config/default.yml @@ -536,6 +536,16 @@ PreCommit: required_executable: 'grep' flags: ['-IHn', "^<<<<<<<[ \t]"] + MixFormat: + enabled: false + description: 'Check formatting with mix format' + required_executable: 'mix' + flags: ['format', '--check-formatted'] + include: + - '**/*.ex' + - '**/*.heex' + - '**/*.exs' + PuppetMetadataJsonLint: enabled: false description: 'Checking module metadata' diff --git a/lib/overcommit/hook/pre_commit/mix_format.rb b/lib/overcommit/hook/pre_commit/mix_format.rb new file mode 100644 index 00000000..2fa07551 --- /dev/null +++ b/lib/overcommit/hook/pre_commit/mix_format.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Overcommit::Hook::PreCommit + # Runs `mix format --check-formatted` against any modified ex/heex/exs files. + # + # @see https://hexdocs.pm/mix/main/Mix.Tasks.Format.html + class MixFormat < Base + # example message: + # ** (Mix) mix format failed due to --check-formatted. + # The following files are not formatted: + # + # * lib/file1.ex + # * lib/file2.ex + FILES_REGEX = /^\s+\*\s+(?.+)$/.freeze + + def run + result = execute(command, args: applicable_files) + return :pass if result.success? + + result.stderr.scan(FILES_REGEX).flatten. + map { |file| message(file) } + end + + private + + def message(file) + Overcommit::Hook::Message.new(:error, file, nil, file) + end + end +end diff --git a/spec/overcommit/hook/pre_commit/mix_format_spec.rb b/spec/overcommit/hook/pre_commit/mix_format_spec.rb new file mode 100644 index 00000000..9acc50ed --- /dev/null +++ b/spec/overcommit/hook/pre_commit/mix_format_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Overcommit::Hook::PreCommit::MixFormat do + let(:config) { Overcommit::ConfigurationLoader.default_configuration } + let(:context) { double('context') } + subject { described_class.new(config, context) } + + before do + subject.stub(:applicable_files).and_return(%w[file1.ex file2.exs]) + end + + context 'when mix format exits successfully' do + before do + result = double('result') + result.stub(:success?).and_return(true) + subject.stub(:execute).and_return(result) + end + + it { should pass } + end + + context 'when mix format exits unsucessfully' do + let(:result) { double('result') } + + before do + result.stub(:success?).and_return(false) + subject.stub(:execute).and_return(result) + end + + context 'and it reports an error' do + before do + result.stub(:stdout).and_return('') + result.stub(:stderr).and_return([ + '** (Mix) mix format failed due to --check-formatted.', + 'The following files are not formatted:', + '', + ' * lib/file1.ex', + ' * lib/file2.ex' + ].join("\n")) + end + + it { should fail_hook } + end + end +end From 774019a0b60c138ea229facf6e0fcaabf0336d5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dino=20Kova=C4=8D?= Date: Mon, 19 Dec 2022 00:01:34 +0100 Subject: [PATCH 04/43] Add MixTest hook (#802) --- config/default.yml | 6 ++++ lib/overcommit/hook/pre_push/mix_test.rb | 16 ++++++++++ .../overcommit/hook/pre_push/mix_test_spec.rb | 31 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 lib/overcommit/hook/pre_push/mix_test.rb create mode 100644 spec/overcommit/hook/pre_push/mix_test_spec.rb diff --git a/config/default.yml b/config/default.yml index 42ea17a8..181187af 100644 --- a/config/default.yml +++ b/config/default.yml @@ -1326,6 +1326,12 @@ PrePush: command: ['ruby', '-Ilib:test', '-rminitest', "-e 'exit! Minitest.run'"] include: 'test/**/*_test.rb' + MixTest: + enabled: false + description: 'Run mix test suite' + required_executable: 'mix' + flags: ['test'] + PhpUnit: enabled: false description: 'Run PhpUnit test suite' diff --git a/lib/overcommit/hook/pre_push/mix_test.rb b/lib/overcommit/hook/pre_push/mix_test.rb new file mode 100644 index 00000000..3ce005e9 --- /dev/null +++ b/lib/overcommit/hook/pre_push/mix_test.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Overcommit::Hook::PrePush + # Runs `mix test` test suite before push + # + # @see https://hexdocs.pm/mix/Mix.Tasks.Test.html + class MixTest < Base + def run + result = execute(command) + return :pass if result.success? + + output = result.stdout + result.stderr + [:fail, output] + end + end +end diff --git a/spec/overcommit/hook/pre_push/mix_test_spec.rb b/spec/overcommit/hook/pre_push/mix_test_spec.rb new file mode 100644 index 00000000..798da7f7 --- /dev/null +++ b/spec/overcommit/hook/pre_push/mix_test_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Overcommit::Hook::PrePush::MixTest do + let(:config) { Overcommit::ConfigurationLoader.default_configuration } + let(:context) { double('context') } + subject { described_class.new(config, context) } + + context 'when mix test exits successfully' do + before do + result = double('result') + result.stub(:success?).and_return(true) + subject.stub(:execute).and_return(result) + end + + it { should pass } + end + + context 'when mix test exits unsucessfully' do + before do + result = double('result') + result.stub(:success?).and_return(false) + result.stub(:stdout).and_return('Some error message') + result.stub(:stderr).and_return('') + subject.stub(:execute).and_return(result) + end + + it { should fail_hook 'Some error message' } + end +end From 807de37897834c1083f19616860382d2c989a69c Mon Sep 17 00:00:00 2001 From: Julianna Date: Fri, 20 Jan 2023 00:40:46 -0600 Subject: [PATCH 05/43] Add optional additional local configuration (#799) Adds support for an additional configuration file, .local-overcommit.yml, in order to allow local configuration on a local box. That way the main config .overcommit.yml can be commited to a repo and a local developer can also add configurations to this new file. --- README.md | 4 ++ lib/overcommit/configuration_loader.rb | 16 ++++++-- lib/overcommit/constants.rb | 1 + spec/overcommit/configuration_loader_spec.rb | 42 ++++++++++++++++++++ 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0464e604..afcbcbbf 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,10 @@ PreCommit: command: ['bundle', 'exec', 'rubocop'] # Invoke within Bundler context ``` +Additionally, you may wish to have repo-specific configurations that are local to your computer that are not part of the shared repo config. +Adding a `.local-overcommit.yml` file in the top-level directory of the repository adds another configuration file. This file works the same as `.overcommit.yml`. +Adding this to ignored files in a git repo will allow you to have a local configuration per repo. + ### Hook Options Individual hooks expose both built-in configuration options as well as their diff --git a/lib/overcommit/configuration_loader.rb b/lib/overcommit/configuration_loader.rb index 77a08549..e4063d7e 100644 --- a/lib/overcommit/configuration_loader.rb +++ b/lib/overcommit/configuration_loader.rb @@ -53,10 +53,14 @@ def initialize(logger, options = {}) # # @return [Overcommit::Configuration] def load_repo_config + overcommit_local_yml = File.join(Overcommit::Utils.repo_root, + Overcommit::LOCAL_CONFIG_FILE_NAME) overcommit_yml = File.join(Overcommit::Utils.repo_root, Overcommit::CONFIG_FILE_NAME) - if File.exist?(overcommit_yml) + if File.exist?(overcommit_local_yml) && File.exist?(overcommit_yml) + load_file(overcommit_yml, overcommit_local_yml) + elsif File.exist?(overcommit_yml) load_file(overcommit_yml) else self.class.default_configuration @@ -64,9 +68,13 @@ def load_repo_config end # Loads a configuration, ensuring it extends the default configuration. - def load_file(file) - config = self.class.load_from_file(file, default: false, logger: @log) - config = self.class.default_configuration.merge(config) + def load_file(file, local_file = nil) + overcommit_config = self.class.load_from_file(file, default: false, logger: @log) + if local_file + local_config = self.class.load_from_file(local_file, default: false, logger: @log) + end + config = self.class.default_configuration.merge(overcommit_config) + config = self.class.default_configuration.merge(local_config) if local_config if @options.fetch(:verify) { config.verify_signatures? } verify_signatures(config) diff --git a/lib/overcommit/constants.rb b/lib/overcommit/constants.rb index dd027932..e7c19728 100644 --- a/lib/overcommit/constants.rb +++ b/lib/overcommit/constants.rb @@ -4,6 +4,7 @@ module Overcommit HOME = File.expand_path(File.join(File.dirname(__FILE__), '..', '..')).freeze CONFIG_FILE_NAME = '.overcommit.yml' + LOCAL_CONFIG_FILE_NAME = '.local-overcommit.yml' HOOK_DIRECTORY = File.join(HOME, 'lib', 'overcommit', 'hook').freeze diff --git a/spec/overcommit/configuration_loader_spec.rb b/spec/overcommit/configuration_loader_spec.rb index a99608d4..2ddbe4e6 100644 --- a/spec/overcommit/configuration_loader_spec.rb +++ b/spec/overcommit/configuration_loader_spec.rb @@ -57,5 +57,47 @@ end end end + + context 'when repo contains a local configuration file' do + let(:config_contents) { <<-CFG } + plugin_directory: 'some-directory' + CFG + + let(:local_config_contents) { <<-CFG } + plugin_directory: 'some-different-directory' + CFG + + around do |example| + repo do + File.open('.overcommit.yml', 'w') { |f| f.write(config_contents) } + File.open('.local-overcommit.yml', 'w') { |f| f.write(local_config_contents) } + example.run + end + end + + it 'loads the file' do + Overcommit::ConfigurationLoader.any_instance. + should_receive(:load_file). + with(File.expand_path('.overcommit.yml'), File.expand_path('.local-overcommit.yml')) + subject + end + + it 'merges each loaded file with the default configuration' do + subject.plugin_directory.should == File.expand_path('some-different-directory') + end + + context 'and the configuration file contains a hook with no `enabled` option' do + let(:config_contents) { <<-CFG } + PreCommit: + ScssLint: + command: ['bundle', 'exec', 'scss-lint'] + CFG + + it 'displays a warning' do + subject + output.string.should =~ /PreCommit::ScssLint.*not.*enabled/i + end + end + end end end From 4d204bdb6ed8ef001ecd0175fb9de8b658cf04cc Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Fri, 20 Jan 2023 01:41:27 -0500 Subject: [PATCH 06/43] Rescue Psych::DisallowedClass in YamlSyntax (#805) * Rescue Psych::DisallowedClass in YamlSyntax This improves the output for errors safe loading disallowed classes with psych 5.0 * Remove extra whitespace --- lib/overcommit/hook/pre_commit/yaml_syntax.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/overcommit/hook/pre_commit/yaml_syntax.rb b/lib/overcommit/hook/pre_commit/yaml_syntax.rb index 493e9c5a..dd685450 100644 --- a/lib/overcommit/hook/pre_commit/yaml_syntax.rb +++ b/lib/overcommit/hook/pre_commit/yaml_syntax.rb @@ -15,10 +15,19 @@ def run rescue ArgumentError, Psych::SyntaxError => e messages << Overcommit::Hook::Message.new(:error, file, nil, e.message) end + rescue Psych::DisallowedClass => e + messages << error_message(file, e) end end messages end + + private + + def error_message(file, error) + text = "#{file}: #{error.message}" + Overcommit::Hook::Message.new(:error, file, nil, text) + end end end From 8bc2eec0375bf2f75b7f39453713e8dec49ae679 Mon Sep 17 00:00:00 2001 From: Thomas Millward Wright Date: Fri, 20 Jan 2023 06:45:26 +0000 Subject: [PATCH 07/43] Add non ASCII encoding schema support to RailsSchemaUpToDate hook (#786) * Add non ASCII encoding schema support to RailsSchemaUpToDate hook * Add guard to check presence of @config['encoding'] Co-authored-by: Paul Wilson --- .../pre_commit/rails_schema_up_to_date.rb | 8 +++++- .../rails_schema_up_to_date_spec.rb | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb b/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb index 13d7932f..dafd31a1 100644 --- a/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb +++ b/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb @@ -34,6 +34,12 @@ def run # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplex private + def encoding + return unless @config.key?('encoding') + + { encoding: @config['encoding'] }.compact + end + def migration_files @migration_files ||= applicable_files.select do |file| file.match %r{db/migrate/.*\.rb} @@ -47,7 +53,7 @@ def schema_files end def schema - @schema ||= schema_files.map { |file| File.read(file) }.join + @schema ||= schema_files.map { |file| File.read(file, encoding) }.join @schema.tr('_', '') end diff --git a/spec/overcommit/hook/pre_commit/rails_schema_up_to_date_spec.rb b/spec/overcommit/hook/pre_commit/rails_schema_up_to_date_spec.rb index ad53485e..9ee704b7 100644 --- a/spec/overcommit/hook/pre_commit/rails_schema_up_to_date_spec.rb +++ b/spec/overcommit/hook/pre_commit/rails_schema_up_to_date_spec.rb @@ -70,6 +70,33 @@ end it { should fail_hook } + + context 'when non ASCII encoding is required' do + let!(:config) do + super().merge(Overcommit::Configuration.new( + 'PreCommit' => { + 'RailsSchemaUpToDate' => { + 'encoding' => 'utf-8' + } + } + )) + end + + before do + subject.stub(:applicable_files).and_return([sql_schema_file]) + end + + around do |example| + repo do + FileUtils.mkdir_p('db/migrate') + File.open(sql_schema_file, 'w') { |f| f.write("version: 12345678901234\nVALUES ('字')") } + `git add #{sql_schema_file}` + example.run + end + end + + it { should fail_hook } + end end context 'when a Ruby schema file with the latest version and migrations are added' do From 2214dd12f5dd6cd944a5c7a6c5a4ea25e2668349 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Thu, 19 Jan 2023 22:57:23 -0800 Subject: [PATCH 08/43] Cut version 0.60.0 (#807) --- CHANGELOG.md | 10 ++++++++++ lib/overcommit/version.rb | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa326ff2..ca3a52eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Overcommit Changelog +## 0.60.0 + +* Allow overriding `Gemfile.lock` location for `BundleCheck` pre-commit hook +* Fix `ReplaceBranch` prepare-commit-msg hook to allow trailing spaces +* Add `MixFormat` pre-commit hook +* Add `MixTest` pre-push hook +* Allow loading custom local configuration from `.local-overcommit.yml` +* Handle `Psych::DisallowedClass` when running `YamlSyntax` pre-commit hook +* Add support for specifying custom `encoding` in `RailsSchemaUpToDate` pre-commit hook + ## 0.59.1 * Remove `--disable-pending-cops` as default flag to `RuboCop` pre-commit hook. diff --git a/lib/overcommit/version.rb b/lib/overcommit/version.rb index e8f6bb39..0c03dd7f 100644 --- a/lib/overcommit/version.rb +++ b/lib/overcommit/version.rb @@ -2,5 +2,5 @@ # Defines the gem version. module Overcommit - VERSION = '0.59.1' + VERSION = '0.60.0' end From 90e367940b87e3a22a4654ed536d20db2e380256 Mon Sep 17 00:00:00 2001 From: Linus Oleander Date: Mon, 27 Mar 2023 19:28:19 +0200 Subject: [PATCH 09/43] Allow ReplaceBranch to use skip_if (#809) * Allow ReplaceBranch to use skip_if * Fix linting error * Clearify specs * Use bash instead of sh in spec --- .../hook/prepare_commit_msg/replace_branch.rb | 2 +- .../prepare_commit_msg/replace_branch_spec.rb | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/overcommit/hook/prepare_commit_msg/replace_branch.rb b/lib/overcommit/hook/prepare_commit_msg/replace_branch.rb index e8c09887..8852b0b5 100644 --- a/lib/overcommit/hook/prepare_commit_msg/replace_branch.rb +++ b/lib/overcommit/hook/prepare_commit_msg/replace_branch.rb @@ -85,7 +85,7 @@ def skipped_commit_types end def skip? - skipped_commit_types.include?(commit_message_source) + super || skipped_commit_types.include?(commit_message_source) end end end diff --git a/spec/overcommit/hook/prepare_commit_msg/replace_branch_spec.rb b/spec/overcommit/hook/prepare_commit_msg/replace_branch_spec.rb index 6af27921..e355517f 100644 --- a/spec/overcommit/hook/prepare_commit_msg/replace_branch_spec.rb +++ b/spec/overcommit/hook/prepare_commit_msg/replace_branch_spec.rb @@ -70,6 +70,26 @@ def remove_file(name) expect(File.read('COMMIT_EDITMSG')).to eq("[123] \n") end end + + context 'when skip_if exits with a zero status' do + let(:config) { new_config('skip_if' => ['bash', '-c', 'exit 0']) } + + it { is_expected.to pass } + + it 'does not change the commit message' do + expect(File.read('COMMIT_EDITMSG')).to eq("\n") + end + end + + context 'when skip_if exits with a non-zero status' do + let(:config) { new_config('skip_if' => ['bash', '-c', 'exit 1']) } + + it { is_expected.to pass } + + it 'does change the commit message' do + expect(File.read('COMMIT_EDITMSG')).to eq("[#123]\n") + end + end end context "when the checked out branch doesn't matches the pattern" do From 02f7b3ef2d455fff46cb6d5a0877a5193bc769c9 Mon Sep 17 00:00:00 2001 From: Julianna Date: Wed, 13 Dec 2023 01:05:04 -0600 Subject: [PATCH 10/43] fix: local overcommit file merges with existing .overcommit.yml file (#815) --- lib/overcommit/configuration_loader.rb | 6 +- spec/overcommit/configuration_loader_spec.rb | 62 ++++++++++++++------ 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/lib/overcommit/configuration_loader.rb b/lib/overcommit/configuration_loader.rb index e4063d7e..8fd68a01 100644 --- a/lib/overcommit/configuration_loader.rb +++ b/lib/overcommit/configuration_loader.rb @@ -70,11 +70,9 @@ def load_repo_config # Loads a configuration, ensuring it extends the default configuration. def load_file(file, local_file = nil) overcommit_config = self.class.load_from_file(file, default: false, logger: @log) - if local_file - local_config = self.class.load_from_file(local_file, default: false, logger: @log) - end + l_config = self.class.load_from_file(local_file, default: false, logger: @log) if local_file config = self.class.default_configuration.merge(overcommit_config) - config = self.class.default_configuration.merge(local_config) if local_config + config = config.merge(l_config) if l_config if @options.fetch(:verify) { config.verify_signatures? } verify_signatures(config) diff --git a/spec/overcommit/configuration_loader_spec.rb b/spec/overcommit/configuration_loader_spec.rb index 2ddbe4e6..90497201 100644 --- a/spec/overcommit/configuration_loader_spec.rb +++ b/spec/overcommit/configuration_loader_spec.rb @@ -58,11 +58,32 @@ end end - context 'when repo contains a local configuration file' do + context 'when repo only contains a repo level configuration file' do let(:config_contents) { <<-CFG } - plugin_directory: 'some-directory' + PreCommit: + Rubocop: + enabled: true CFG + around do |example| + repo do + File.open('.overcommit.yml', 'w') { |f| f.write(config_contents) } + example.run + end + end + + it 'includes default settings' do + subject + subject.for_hook('CapitalizedSubject', 'CommitMsg').should include('enabled' => true) + end + + it 'includes .overwrite.yml configs' do + subject + subject.for_hook('Rubocop', 'PreCommit').should include('enabled' => true) + end + end + + context 'when repo also contains a local configuration file' do let(:local_config_contents) { <<-CFG } plugin_directory: 'some-different-directory' CFG @@ -75,28 +96,31 @@ end end - it 'loads the file' do - Overcommit::ConfigurationLoader.any_instance. - should_receive(:load_file). - with(File.expand_path('.overcommit.yml'), File.expand_path('.local-overcommit.yml')) + let(:config_contents) { <<-CFG } + PreCommit: + ScssLint: + enabled: true + CFG + + let(:local_config_contents) { <<-CFG } + PreCommit: + Rubocop: + enabled: true + CFG + + it 'includes default settings' do subject + subject.for_hook('CapitalizedSubject', 'CommitMsg').should include('enabled' => true) end - it 'merges each loaded file with the default configuration' do - subject.plugin_directory.should == File.expand_path('some-different-directory') + it 'includes .overwrite.yml configs' do + subject + subject.for_hook('ScssLint', 'PreCommit').should include('enabled' => true) end - context 'and the configuration file contains a hook with no `enabled` option' do - let(:config_contents) { <<-CFG } - PreCommit: - ScssLint: - command: ['bundle', 'exec', 'scss-lint'] - CFG - - it 'displays a warning' do - subject - output.string.should =~ /PreCommit::ScssLint.*not.*enabled/i - end + it 'includes .local-overwrite.yml configs' do + subject + subject.for_hook('Rubocop', 'PreCommit').should include('enabled' => true) end end end From 38febfc1d798a5220d97c58307a8621e8d427258 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Tue, 12 Dec 2023 23:09:05 -0800 Subject: [PATCH 11/43] Cut version 0.61.0 (#817) --- CHANGELOG.md | 5 +++++ lib/overcommit/version.rb | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca3a52eb..cc14f3f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Overcommit Changelog +## 0.61.0 + +* Allow `ReplaceBranch` to use `skip_if` +* Fix local Overcommit file merges with existing `.overcommit.yml` + ## 0.60.0 * Allow overriding `Gemfile.lock` location for `BundleCheck` pre-commit hook diff --git a/lib/overcommit/version.rb b/lib/overcommit/version.rb index 0c03dd7f..0646ce48 100644 --- a/lib/overcommit/version.rb +++ b/lib/overcommit/version.rb @@ -2,5 +2,5 @@ # Defines the gem version. module Overcommit - VERSION = '0.60.0' + VERSION = '0.61.0' end From 4f11048e99134ea0e4128d7ad6694f3b230d88f1 Mon Sep 17 00:00:00 2001 From: Denis Zaratan Pasin Date: Wed, 13 Dec 2023 08:11:36 +0100 Subject: [PATCH 12/43] Adding Ruby 3.2 to test matrix (#816) --- .github/workflows/tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 848db60c..416afe34 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -18,6 +18,7 @@ jobs: - '2.7' - '3.0' - '3.1' + - '3.2' os: - ubuntu - windows @@ -27,6 +28,8 @@ jobs: exclude: - ruby-version: '3.1' os: windows + - ruby-version: '3.2' + os: windows steps: - uses: actions/checkout@v2 From faf76fc7aa01c2b3264020ed301b569a9ed53360 Mon Sep 17 00:00:00 2001 From: Andy Waite <13400+andyw8@users.noreply.github.com> Date: Sun, 14 Jan 2024 21:06:39 -0500 Subject: [PATCH 13/43] Update RuboCop (#818) The current version of Ruby is from April 2020. Since there are quite a lot of new issues identified, I've committed them to the `.rubocop_todo.yml` so that they can be addressed incrementally or disabled. Co-authored-by: Andy Waite --- .rubocop.yml | 2 + .rubocop_todo.yml | 137 ++++++++++++++++++ Gemfile | 4 +- .../hook/pre_commit/phpcs_fixer_spec.rb | 12 +- 4 files changed, 147 insertions(+), 8 deletions(-) create mode 100644 .rubocop_todo.yml diff --git a/.rubocop.yml b/.rubocop.yml index 35002594..8c779097 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,3 +1,5 @@ +inherit_from: .rubocop_todo.yml + AllCops: TargetRubyVersion: 2.4 diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 00000000..53df9159 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,137 @@ +# This configuration was generated by +# `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit` +# on 2024-01-10 14:09:00 UTC using RuboCop version 1.59.0. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowAliasSyntax, AllowedMethods. +# AllowedMethods: alias_method, public, protected, private +Layout/EmptyLinesAroundAttributeAccessor: + Exclude: + - 'lib/overcommit/hook_context/post_merge.rb' + +# Offense count: 6 +# Configuration parameters: AllowedMethods. +# AllowedMethods: enums +Lint/ConstantDefinitionInBlock: + Exclude: + - 'spec/overcommit/message_processor_spec.rb' + +# Offense count: 4 +Lint/MixedRegexpCaptureTypes: + Exclude: + - 'lib/overcommit/hook/pre_commit/dart_analyzer.rb' + - 'lib/overcommit/hook/pre_commit/java_checkstyle.rb' + - 'lib/overcommit/hook/pre_commit/kt_lint.rb' + - 'lib/overcommit/hook/pre_commit/scalastyle.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +Lint/RedundantCopDisableDirective: + Exclude: + - 'lib/overcommit/hook_runner.rb' + - 'lib/overcommit/printer.rb' + +# Offense count: 1 +# Configuration parameters: CountComments, Max, CountAsOne. +Metrics/ClassLength: + Exclude: + - 'lib/overcommit/utils.rb' + +# Offense count: 2 +# Configuration parameters: AllowedMethods, AllowedPatterns, Max. +Metrics/CyclomaticComplexity: + Exclude: + - 'lib/overcommit/configuration.rb' + - 'lib/overcommit/hook_runner.rb' + +# Offense count: 3 +# Configuration parameters: AllowedMethods, AllowedPatterns, Max. +Metrics/PerceivedComplexity: + Exclude: + - 'lib/overcommit/configuration.rb' + - 'lib/overcommit/configuration_validator.rb' + - 'lib/overcommit/hook_runner.rb' + +# Offense count: 23 +# This cop supports unsafe autocorrection (--autocorrect-all). +Style/GlobalStdStream: + Exclude: + - 'bin/overcommit' + - 'lib/overcommit/hook/post_commit/git_guilt.rb' + - 'template-dir/hooks/commit-msg' + - 'template-dir/hooks/overcommit-hook' + - 'template-dir/hooks/post-checkout' + - 'template-dir/hooks/post-commit' + - 'template-dir/hooks/post-merge' + - 'template-dir/hooks/post-rewrite' + - 'template-dir/hooks/pre-commit' + - 'template-dir/hooks/pre-push' + - 'template-dir/hooks/pre-rebase' + - 'template-dir/hooks/prepare-commit-msg' + +# Offense count: 2 +# This cop supports unsafe autocorrection (--autocorrect-all). +Style/HashTransformValues: + Exclude: + - 'lib/overcommit/configuration.rb' + - 'lib/overcommit/configuration_validator.rb' + +# Offense count: 1 +# Configuration parameters: AllowedMethods. +# AllowedMethods: respond_to_missing? +Style/OptionalBooleanParameter: + Exclude: + - 'lib/overcommit/logger.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +Style/RedundantBegin: + Exclude: + - 'lib/overcommit/hook/prepare_commit_msg/replace_branch.rb' + - 'lib/overcommit/utils.rb' + +# Offense count: 10 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: SafeForConstants. +Style/RedundantFetchBlock: + Exclude: + - 'lib/overcommit/configuration.rb' + - 'lib/overcommit/configuration_validator.rb' + - 'lib/overcommit/hook/base.rb' + - 'lib/overcommit/hook/pre_commit/chamber_verification.rb' + - 'lib/overcommit/logger.rb' + - 'spec/support/shell_helpers.rb' + +# Offense count: 8 +# This cop supports safe autocorrection (--autocorrect). +Style/RedundantRegexpEscape: + Exclude: + - 'lib/overcommit/configuration.rb' + - 'lib/overcommit/hook/pre_commit/php_cs.rb' + - 'lib/overcommit/hook/pre_commit/php_lint.rb' + - 'lib/overcommit/hook/pre_commit/php_stan.rb' + +# Offense count: 15 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: Mode. +Style/StringConcatenation: + Exclude: + - 'lib/overcommit/hook/pre_commit/bundle_check.rb' + - 'lib/overcommit/hook_runner.rb' + - 'lib/overcommit/message_processor.rb' + - 'spec/integration/gemfile_option_spec.rb' + - 'spec/overcommit/hook/commit_msg/text_width_spec.rb' + - 'spec/overcommit/hook/prepare_commit_msg/base_spec.rb' + - 'spec/overcommit/message_processor_spec.rb' + - 'spec/spec_helper.rb' + +# Offense count: 1 +# This cop supports unsafe autocorrection (--autocorrect-all). +Style/ZeroLengthPredicate: + Exclude: + - 'lib/overcommit/hook/pre_commit/ruby_syntax.rb' diff --git a/Gemfile b/Gemfile index ff22be0c..53b13c7f 100644 --- a/Gemfile +++ b/Gemfile @@ -11,7 +11,7 @@ gem 'rspec', '~> 3.0' gem 'simplecov', '~> 0.21.0' gem 'simplecov-lcov', '~> 0.8.0' -# Pin RuboCop for Travis builds. -gem 'rubocop', '0.82.0' +# Pin RuboCop for CI builds +gem 'rubocop', '1.59.0' gem 'ffi' if Gem.win_platform? diff --git a/spec/overcommit/hook/pre_commit/phpcs_fixer_spec.rb b/spec/overcommit/hook/pre_commit/phpcs_fixer_spec.rb index 33b0d7c1..a4b1e187 100644 --- a/spec/overcommit/hook/pre_commit/phpcs_fixer_spec.rb +++ b/spec/overcommit/hook/pre_commit/phpcs_fixer_spec.rb @@ -13,7 +13,7 @@ context 'when phpcs fixer exits successfully with fixed file' do before do - # rubocop:disable Metrics/LineLength + # rubocop:disable Layout/LineLength sample_output = [ 'Loaded config default.', 'Using cache file ".php_cs.cache".', @@ -24,7 +24,7 @@ 'Fixed all files in 0.001 seconds, 10.000 MB memory used', '', ].join("\n") - # rubocop:enable Metrics/LineLength + # rubocop:enable Layout/LineLength result = double('result') result.stub(:status).and_return(0) @@ -38,7 +38,7 @@ context 'when phpcs fixer exits successfully with no file to fix' do before do - # rubocop:disable Metrics/LineLength + # rubocop:disable Layout/LineLength sample_output = [ 'Loaded config default.', 'Using cache file ".php_cs.cache".', @@ -46,7 +46,7 @@ 'Legend: ?-unknown, I-invalid file syntax, file ignored, S-Skipped, .-no changes, F-fixed, E-error', '', ].join("\n") - # rubocop:enable Metrics/LineLength + # rubocop:enable Layout/LineLength result = double('result') result.stub(:status).and_return(0) @@ -60,7 +60,7 @@ context 'when phpcs exits unsuccessfully' do before do - # rubocop:disable Metrics/LineLength + # rubocop:disable Layout/LineLength sample_output = [ 'Loaded config default.', 'Using cache file ".php_cs.cache".', @@ -72,7 +72,7 @@ ' 1) /home/damien/Code/Rezdy/php/foo/broken.php', '', ].join("\n") - # rubocop:enable Metrics/LineLength + # rubocop:enable Layout/LineLength result = double('result') result.stub(:status).and_return(1) From bc1fec660e5c7c0cd83e2c8b3de8f02b55c0b367 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Sun, 14 Jan 2024 18:17:08 -0800 Subject: [PATCH 14/43] Update branch for CI from `master` to `main` (#819) This was missed when we switched to using `main`. --- .github/workflows/lint.yml | 6 +++--- .github/workflows/tests.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b1879f09..8b23cbab 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,9 +1,9 @@ name: Lint on: push: - branches: [master] + branches: [main] pull_request: - branches: [master] + branches: [main] jobs: overcommit: @@ -16,7 +16,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: 2.7 + ruby-version: 3.3 bundler-cache: true - name: Prepare environment diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 416afe34..26c20dd1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,9 +1,9 @@ name: Tests on: push: - branches: [master] + branches: [main] pull_request: - branches: [master] + branches: [main] jobs: rspec: From 2dd1eb9e3fbaaf3693b9a32414fb8cf7706c9db9 Mon Sep 17 00:00:00 2001 From: Patrik Ragnarsson Date: Wed, 17 Jan 2024 00:02:11 +0100 Subject: [PATCH 15/43] Allow childprocess 5 (#820) I think it only brings improvements: https://github.com/enkessler/childprocess/releases/tag/v5.0.0 --- overcommit.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overcommit.gemspec b/overcommit.gemspec index ef9f24fc..8bc70845 100644 --- a/overcommit.gemspec +++ b/overcommit.gemspec @@ -27,7 +27,7 @@ Gem::Specification.new do |s| s.required_ruby_version = '>= 2.4' - s.add_dependency 'childprocess', '>= 0.6.3', '< 5' + s.add_dependency 'childprocess', '>= 0.6.3', '< 6' s.add_dependency 'iniparse', '~> 1.4' s.add_dependency 'rexml', '~> 3.2' end From f190f24b748ba04ed5199c9ac8ca12557237800c Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Tue, 16 Jan 2024 15:05:50 -0800 Subject: [PATCH 16/43] Cut version 0.62.0 (#821) --- CHANGELOG.md | 4 ++++ lib/overcommit/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc14f3f1..5953a7c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Overcommit Changelog +## 0.62.0 + +* Allow version 5 of `childprocess` gem dependency + ## 0.61.0 * Allow `ReplaceBranch` to use `skip_if` diff --git a/lib/overcommit/version.rb b/lib/overcommit/version.rb index 0646ce48..f6805668 100644 --- a/lib/overcommit/version.rb +++ b/lib/overcommit/version.rb @@ -2,5 +2,5 @@ # Defines the gem version. module Overcommit - VERSION = '0.61.0' + VERSION = '0.62.0' end From 607ce057b760b697dc63623e7b7dc06a79316eab Mon Sep 17 00:00:00 2001 From: benmelz Date: Sat, 24 Feb 2024 18:50:30 -0500 Subject: [PATCH 17/43] Get suite running smoothly again (#824) Am planning on proposing/implementing a new feature, but first I noticed that there are a number of failing specs on main, so I figured I would start with that. As written, this includes four main adjustments, two of which might actually be bugfixes: - one spec was hanging indefinitely for me locally on a `Thread.join` call - explicitly capturing the child threads and joining them directly fixed it (might be machine dependent?) - when an encoding is specified, the rails schema up to date hook was passing arguments incorrectly (kwarg containing `encoding` was being interpreted as the `length` positional arg) (possible bug) - many specs were attempting to create file submodules without the `protocol.file.allow=always` config option causing failure - alias detection for amendment appeared to be broken, due to regexp incompatibilities between ruby/git (git wasn't properly parsing `\s` in the value matcher for `git config --regexp [key] [value]` command), so moved that matching into ruby (possible bug, also maybe machine/git build opt dependent) - dropped ruby 2.6 from the test matrix - it appears that it's far enough EOL that github has trouble even setting it up. I can attempt to add it back/get it working, but I figured it might be time to ditch it *I don't have a windows machine, so I'm not gonna be much help with those CI builds (should note fails appear unrelated to anything I've done here). --- .github/workflows/tests.yml | 1 - .../pre_commit/rails_schema_up_to_date.rb | 4 +-- .../helpers/file_modifications.rb | 31 ++++++++++++------- spec/overcommit/git_repo_spec.rb | 22 +++++++------ .../hook/prepare_commit_msg/base_spec.rb | 4 +-- .../hook_context/commit_msg_spec.rb | 10 +++--- .../hook_context/post_checkout_spec.rb | 2 +- .../hook_context/post_commit_spec.rb | 2 +- .../hook_context/post_merge_spec.rb | 2 +- .../hook_context/post_rewrite_spec.rb | 3 +- .../hook_context/pre_commit_spec.rb | 10 +++--- spec/overcommit/hook_context/run_all_spec.rb | 3 +- spec/overcommit/installer_spec.rb | 2 +- 13 files changed, 54 insertions(+), 42 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 26c20dd1..71a83ba6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,6 @@ jobs: fail-fast: false matrix: ruby-version: - - '2.6' - '2.7' - '3.0' - '3.1' diff --git a/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb b/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb index dafd31a1..1f2de970 100644 --- a/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb +++ b/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb @@ -35,7 +35,7 @@ def run # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplex private def encoding - return unless @config.key?('encoding') + return {} unless @config.key?('encoding') { encoding: @config['encoding'] }.compact end @@ -53,7 +53,7 @@ def schema_files end def schema - @schema ||= schema_files.map { |file| File.read(file, encoding) }.join + @schema ||= schema_files.map { |file| File.read(file, **encoding) }.join @schema.tr('_', '') end diff --git a/lib/overcommit/hook_context/helpers/file_modifications.rb b/lib/overcommit/hook_context/helpers/file_modifications.rb index 00aaccc8..8d221ddc 100644 --- a/lib/overcommit/hook_context/helpers/file_modifications.rb +++ b/lib/overcommit/hook_context/helpers/file_modifications.rb @@ -12,7 +12,7 @@ def amendment? cmd = Overcommit::Utils.parent_command return unless cmd - amend_pattern = 'commit(\s.*)?\s--amend(\s|$)' + amend_pattern = /commit(\s.*)?\s--amend/ # Since the ps command can return invalid byte sequences for commands # containing unicode characters, we replace the offending characters, @@ -24,18 +24,11 @@ def amendment? encode('UTF-8') end - return @amendment if - # True if the command is a commit with the --amend flag - @amendment = !(/\s#{amend_pattern}/ =~ cmd).nil? + # True if the command is a commit with the --amend flag + return @amendment if @amendment = cmd.match?(amend_pattern) # Check for git aliases that call `commit --amend` - `git config --get-regexp "^alias\\." "#{amend_pattern}"`. - scan(/alias\.([-\w]+)/). # Extract the alias - each do |match| - return @amendment if - # True if the command uses a git alias for `commit --amend` - @amendment = !(/git(\.exe)?\s+#{match[0]}/ =~ cmd).nil? - end + return @amendment if @amendment = command_is_amend_alias?(cmd, amend_pattern) @amendment end @@ -74,6 +67,22 @@ def modified_lines_in_file(file) end @modified_lines[file] end + + private + + def command_is_amend_alias?(cmd, amend_pattern) + `git config --get-regexp "^alias"`.split("\n").each do |alias_def| + alias_map = alias_def.match /alias\.(?[-\w]+)\s+(?.+)/ + next unless alias_map + + alias_from_match = alias_map[:from].match? amend_pattern + alias_to_match = cmd.match? /git(\.exe)?\s+#{alias_map[:to]}/ + + # True if the command uses a git alias for `commit --amend` + return true if @amendment = alias_from_match && alias_to_match + end + false + end end end end diff --git a/spec/overcommit/git_repo_spec.rb b/spec/overcommit/git_repo_spec.rb index 128737c3..08f3b585 100644 --- a/spec/overcommit/git_repo_spec.rb +++ b/spec/overcommit/git_repo_spec.rb @@ -24,12 +24,13 @@ end submodule = repo do - `git submodule add #{nested_submodule} nested-sub 2>&1 > #{File::NULL}` + git_config = '-c protocol.file.allow=always' + `git #{git_config} submodule add #{nested_submodule} nested-sub 2>&1 > #{File::NULL}` `git commit -m "Add nested submodule"` end repo do - `git submodule add #{submodule} sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} sub 2>&1 > #{File::NULL}` example.run end end @@ -150,7 +151,7 @@ end before do - `git submodule add #{submodule} sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} sub 2>&1 > #{File::NULL}` end it { should_not include File.expand_path('sub') } @@ -178,7 +179,8 @@ `git commit --allow-empty -m "Submodule commit"` end - `git submodule add #{submodule} #{submodule_dir} 2>&1 > #{File::NULL}` + git_config = '-c protocol.file.allow=always' + `git #{git_config} submodule add #{submodule} #{submodule_dir} 2>&1 > #{File::NULL}` `git commit -m "Add submodule"` end @@ -282,7 +284,7 @@ touch 'tracked' `git add tracked` `git commit -m "Initial commit"` - `git submodule add #{submodule} sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} sub 2>&1 > #{File::NULL}` touch 'staged' `git add staged` example.run @@ -327,7 +329,7 @@ end repo do - `git submodule add #{submodule} sub-repo 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} sub-repo 2>&1 > #{File::NULL}` `git commit -m "Initial commit"` example.run end @@ -343,7 +345,8 @@ `git commit --allow-empty -m "Another submodule"` end - `git submodule add #{another_submodule} another-sub-repo 2>&1 > #{File::NULL}` + git_config = '-c protocol.file.allow=always' + `git #{git_config} submodule add #{another_submodule} another-sub-repo 2>&1 > #{File::NULL}` end it { should be_empty } @@ -365,11 +368,12 @@ context 'when there are multiple submodule removals staged' do before do - another_submodule = repo do + another_submod = repo do `git commit --allow-empty -m "Another submodule"` end - `git submodule add #{another_submodule} yet-another-sub-repo 2>&1 > #{File::NULL}` + git_conf = '-c protocol.file.allow=always' + `git #{git_conf} submodule add #{another_submod} yet-another-sub-repo 2>&1 > #{File::NULL}` `git commit -m "Add yet another submodule"` `git rm sub-repo` `git rm yet-another-sub-repo` diff --git a/spec/overcommit/hook/prepare_commit_msg/base_spec.rb b/spec/overcommit/hook/prepare_commit_msg/base_spec.rb index 616d6b8e..ef635a48 100644 --- a/spec/overcommit/hook/prepare_commit_msg/base_spec.rb +++ b/spec/overcommit/hook/prepare_commit_msg/base_spec.rb @@ -38,9 +38,7 @@ contents + "bravo\n" end end - Thread.new { hook_1.run } - Thread.new { hook_2.run } - Thread.list.each { |t| t.join unless t == Thread.current } + [Thread.new { hook_1.run }, Thread.new { hook_2.run }].each(&:join) expect(File.read(tempfile)).to match(/alpha\n#{initial_content}bravo\n/m) end end diff --git a/spec/overcommit/hook_context/commit_msg_spec.rb b/spec/overcommit/hook_context/commit_msg_spec.rb index 2aa68516..058f1508 100644 --- a/spec/overcommit/hook_context/commit_msg_spec.rb +++ b/spec/overcommit/hook_context/commit_msg_spec.rb @@ -298,7 +298,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -474,7 +474,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -500,7 +500,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -532,7 +532,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` `git rm sub` example.run @@ -561,7 +561,7 @@ end repo do - `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` expect(subject).to_not include File.expand_path('test-sub') end end diff --git a/spec/overcommit/hook_context/post_checkout_spec.rb b/spec/overcommit/hook_context/post_checkout_spec.rb index 50657c37..df1dccd2 100644 --- a/spec/overcommit/hook_context/post_checkout_spec.rb +++ b/spec/overcommit/hook_context/post_checkout_spec.rb @@ -67,7 +67,7 @@ repo do `git commit --allow-empty -m "Initial commit"` - `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` `git commit -m "Add submodule"` expect(subject).to_not include File.expand_path('test-sub') end diff --git a/spec/overcommit/hook_context/post_commit_spec.rb b/spec/overcommit/hook_context/post_commit_spec.rb index 81758256..5322a1f2 100644 --- a/spec/overcommit/hook_context/post_commit_spec.rb +++ b/spec/overcommit/hook_context/post_commit_spec.rb @@ -20,7 +20,7 @@ end repo do - `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` `git commit -m "Initial commit"` expect(subject).to_not include File.expand_path('test-sub') end diff --git a/spec/overcommit/hook_context/post_merge_spec.rb b/spec/overcommit/hook_context/post_merge_spec.rb index aa89fa82..0621b695 100644 --- a/spec/overcommit/hook_context/post_merge_spec.rb +++ b/spec/overcommit/hook_context/post_merge_spec.rb @@ -94,7 +94,7 @@ repo do `git commit --allow-empty -m "Initial commit"` `git checkout -b child > #{File::NULL} 2>&1` - `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` `git commit -m "Add submodule"` `git checkout master > #{File::NULL} 2>&1` `git merge --no-ff --no-edit child` diff --git a/spec/overcommit/hook_context/post_rewrite_spec.rb b/spec/overcommit/hook_context/post_rewrite_spec.rb index d2f18f6e..0d510c4a 100644 --- a/spec/overcommit/hook_context/post_rewrite_spec.rb +++ b/spec/overcommit/hook_context/post_rewrite_spec.rb @@ -101,8 +101,9 @@ end repo do + git_config = '-c protocol.file.allow=always' `git commit --allow-empty -m "Initial commit"` - `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git #{git_config} submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` `git commit --amend -m "Add submodule"` expect(subject).to_not include File.expand_path('test-sub') end diff --git a/spec/overcommit/hook_context/pre_commit_spec.rb b/spec/overcommit/hook_context/pre_commit_spec.rb index dae42e66..719982a1 100644 --- a/spec/overcommit/hook_context/pre_commit_spec.rb +++ b/spec/overcommit/hook_context/pre_commit_spec.rb @@ -207,7 +207,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -383,7 +383,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -409,7 +409,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -441,7 +441,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` `git rm sub` example.run @@ -470,7 +470,7 @@ end repo do - `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` expect(subject).to_not include File.expand_path('test-sub') end end diff --git a/spec/overcommit/hook_context/run_all_spec.rb b/spec/overcommit/hook_context/run_all_spec.rb index 516fb70b..c6696edc 100644 --- a/spec/overcommit/hook_context/run_all_spec.rb +++ b/spec/overcommit/hook_context/run_all_spec.rb @@ -46,7 +46,8 @@ end repo do - `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + git_config = '-c protocol.file.allow=always' + `git #{git_config} submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` example.run end end diff --git a/spec/overcommit/installer_spec.rb b/spec/overcommit/installer_spec.rb index c7cfb05e..8739a70e 100644 --- a/spec/overcommit/installer_spec.rb +++ b/spec/overcommit/installer_spec.rb @@ -231,7 +231,7 @@ def hook_files_installed?(hooks_dir) context 'which has an external git dir' do let(:submodule) { File.join(target, 'submodule') } before do - system 'git', 'submodule', 'add', target, 'submodule', + system 'git', '-c', 'protocol.file.allow=always', 'submodule', 'add', target, 'submodule', chdir: target, out: :close, err: :close end let(:submodule_git_file) { File.join(submodule, '.git') } From 65e211451816710afe3b530d2e319db08f2c2f1b Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Sat, 24 Feb 2024 15:57:56 -0800 Subject: [PATCH 18/43] Revert "Get suite running smoothly again (#824)" (#840) This reverts commit 607ce057b760b697dc63623e7b7dc06a79316eab. Going to try to merge a different branch. --- .github/workflows/tests.yml | 1 + .../pre_commit/rails_schema_up_to_date.rb | 4 +-- .../helpers/file_modifications.rb | 31 +++++++------------ spec/overcommit/git_repo_spec.rb | 22 ++++++------- .../hook/prepare_commit_msg/base_spec.rb | 4 ++- .../hook_context/commit_msg_spec.rb | 10 +++--- .../hook_context/post_checkout_spec.rb | 2 +- .../hook_context/post_commit_spec.rb | 2 +- .../hook_context/post_merge_spec.rb | 2 +- .../hook_context/post_rewrite_spec.rb | 3 +- .../hook_context/pre_commit_spec.rb | 10 +++--- spec/overcommit/hook_context/run_all_spec.rb | 3 +- spec/overcommit/installer_spec.rb | 2 +- 13 files changed, 42 insertions(+), 54 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 71a83ba6..26c20dd1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,6 +14,7 @@ jobs: fail-fast: false matrix: ruby-version: + - '2.6' - '2.7' - '3.0' - '3.1' diff --git a/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb b/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb index 1f2de970..dafd31a1 100644 --- a/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb +++ b/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb @@ -35,7 +35,7 @@ def run # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplex private def encoding - return {} unless @config.key?('encoding') + return unless @config.key?('encoding') { encoding: @config['encoding'] }.compact end @@ -53,7 +53,7 @@ def schema_files end def schema - @schema ||= schema_files.map { |file| File.read(file, **encoding) }.join + @schema ||= schema_files.map { |file| File.read(file, encoding) }.join @schema.tr('_', '') end diff --git a/lib/overcommit/hook_context/helpers/file_modifications.rb b/lib/overcommit/hook_context/helpers/file_modifications.rb index 8d221ddc..00aaccc8 100644 --- a/lib/overcommit/hook_context/helpers/file_modifications.rb +++ b/lib/overcommit/hook_context/helpers/file_modifications.rb @@ -12,7 +12,7 @@ def amendment? cmd = Overcommit::Utils.parent_command return unless cmd - amend_pattern = /commit(\s.*)?\s--amend/ + amend_pattern = 'commit(\s.*)?\s--amend(\s|$)' # Since the ps command can return invalid byte sequences for commands # containing unicode characters, we replace the offending characters, @@ -24,11 +24,18 @@ def amendment? encode('UTF-8') end - # True if the command is a commit with the --amend flag - return @amendment if @amendment = cmd.match?(amend_pattern) + return @amendment if + # True if the command is a commit with the --amend flag + @amendment = !(/\s#{amend_pattern}/ =~ cmd).nil? # Check for git aliases that call `commit --amend` - return @amendment if @amendment = command_is_amend_alias?(cmd, amend_pattern) + `git config --get-regexp "^alias\\." "#{amend_pattern}"`. + scan(/alias\.([-\w]+)/). # Extract the alias + each do |match| + return @amendment if + # True if the command uses a git alias for `commit --amend` + @amendment = !(/git(\.exe)?\s+#{match[0]}/ =~ cmd).nil? + end @amendment end @@ -67,22 +74,6 @@ def modified_lines_in_file(file) end @modified_lines[file] end - - private - - def command_is_amend_alias?(cmd, amend_pattern) - `git config --get-regexp "^alias"`.split("\n").each do |alias_def| - alias_map = alias_def.match /alias\.(?[-\w]+)\s+(?.+)/ - next unless alias_map - - alias_from_match = alias_map[:from].match? amend_pattern - alias_to_match = cmd.match? /git(\.exe)?\s+#{alias_map[:to]}/ - - # True if the command uses a git alias for `commit --amend` - return true if @amendment = alias_from_match && alias_to_match - end - false - end end end end diff --git a/spec/overcommit/git_repo_spec.rb b/spec/overcommit/git_repo_spec.rb index 08f3b585..128737c3 100644 --- a/spec/overcommit/git_repo_spec.rb +++ b/spec/overcommit/git_repo_spec.rb @@ -24,13 +24,12 @@ end submodule = repo do - git_config = '-c protocol.file.allow=always' - `git #{git_config} submodule add #{nested_submodule} nested-sub 2>&1 > #{File::NULL}` + `git submodule add #{nested_submodule} nested-sub 2>&1 > #{File::NULL}` `git commit -m "Add nested submodule"` end repo do - `git -c protocol.file.allow=always submodule add #{submodule} sub 2>&1 > #{File::NULL}` + `git submodule add #{submodule} sub 2>&1 > #{File::NULL}` example.run end end @@ -151,7 +150,7 @@ end before do - `git -c protocol.file.allow=always submodule add #{submodule} sub 2>&1 > #{File::NULL}` + `git submodule add #{submodule} sub 2>&1 > #{File::NULL}` end it { should_not include File.expand_path('sub') } @@ -179,8 +178,7 @@ `git commit --allow-empty -m "Submodule commit"` end - git_config = '-c protocol.file.allow=always' - `git #{git_config} submodule add #{submodule} #{submodule_dir} 2>&1 > #{File::NULL}` + `git submodule add #{submodule} #{submodule_dir} 2>&1 > #{File::NULL}` `git commit -m "Add submodule"` end @@ -284,7 +282,7 @@ touch 'tracked' `git add tracked` `git commit -m "Initial commit"` - `git -c protocol.file.allow=always submodule add #{submodule} sub 2>&1 > #{File::NULL}` + `git submodule add #{submodule} sub 2>&1 > #{File::NULL}` touch 'staged' `git add staged` example.run @@ -329,7 +327,7 @@ end repo do - `git -c protocol.file.allow=always submodule add #{submodule} sub-repo 2>&1 > #{File::NULL}` + `git submodule add #{submodule} sub-repo 2>&1 > #{File::NULL}` `git commit -m "Initial commit"` example.run end @@ -345,8 +343,7 @@ `git commit --allow-empty -m "Another submodule"` end - git_config = '-c protocol.file.allow=always' - `git #{git_config} submodule add #{another_submodule} another-sub-repo 2>&1 > #{File::NULL}` + `git submodule add #{another_submodule} another-sub-repo 2>&1 > #{File::NULL}` end it { should be_empty } @@ -368,12 +365,11 @@ context 'when there are multiple submodule removals staged' do before do - another_submod = repo do + another_submodule = repo do `git commit --allow-empty -m "Another submodule"` end - git_conf = '-c protocol.file.allow=always' - `git #{git_conf} submodule add #{another_submod} yet-another-sub-repo 2>&1 > #{File::NULL}` + `git submodule add #{another_submodule} yet-another-sub-repo 2>&1 > #{File::NULL}` `git commit -m "Add yet another submodule"` `git rm sub-repo` `git rm yet-another-sub-repo` diff --git a/spec/overcommit/hook/prepare_commit_msg/base_spec.rb b/spec/overcommit/hook/prepare_commit_msg/base_spec.rb index ef635a48..616d6b8e 100644 --- a/spec/overcommit/hook/prepare_commit_msg/base_spec.rb +++ b/spec/overcommit/hook/prepare_commit_msg/base_spec.rb @@ -38,7 +38,9 @@ contents + "bravo\n" end end - [Thread.new { hook_1.run }, Thread.new { hook_2.run }].each(&:join) + Thread.new { hook_1.run } + Thread.new { hook_2.run } + Thread.list.each { |t| t.join unless t == Thread.current } expect(File.read(tempfile)).to match(/alpha\n#{initial_content}bravo\n/m) end end diff --git a/spec/overcommit/hook_context/commit_msg_spec.rb b/spec/overcommit/hook_context/commit_msg_spec.rb index 058f1508..2aa68516 100644 --- a/spec/overcommit/hook_context/commit_msg_spec.rb +++ b/spec/overcommit/hook_context/commit_msg_spec.rb @@ -298,7 +298,7 @@ end repo do - `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -474,7 +474,7 @@ end repo do - `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -500,7 +500,7 @@ end repo do - `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -532,7 +532,7 @@ end repo do - `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` `git rm sub` example.run @@ -561,7 +561,7 @@ end repo do - `git -c protocol.file.allow=always submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` expect(subject).to_not include File.expand_path('test-sub') end end diff --git a/spec/overcommit/hook_context/post_checkout_spec.rb b/spec/overcommit/hook_context/post_checkout_spec.rb index df1dccd2..50657c37 100644 --- a/spec/overcommit/hook_context/post_checkout_spec.rb +++ b/spec/overcommit/hook_context/post_checkout_spec.rb @@ -67,7 +67,7 @@ repo do `git commit --allow-empty -m "Initial commit"` - `git -c protocol.file.allow=always submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` `git commit -m "Add submodule"` expect(subject).to_not include File.expand_path('test-sub') end diff --git a/spec/overcommit/hook_context/post_commit_spec.rb b/spec/overcommit/hook_context/post_commit_spec.rb index 5322a1f2..81758256 100644 --- a/spec/overcommit/hook_context/post_commit_spec.rb +++ b/spec/overcommit/hook_context/post_commit_spec.rb @@ -20,7 +20,7 @@ end repo do - `git -c protocol.file.allow=always submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` `git commit -m "Initial commit"` expect(subject).to_not include File.expand_path('test-sub') end diff --git a/spec/overcommit/hook_context/post_merge_spec.rb b/spec/overcommit/hook_context/post_merge_spec.rb index 0621b695..aa89fa82 100644 --- a/spec/overcommit/hook_context/post_merge_spec.rb +++ b/spec/overcommit/hook_context/post_merge_spec.rb @@ -94,7 +94,7 @@ repo do `git commit --allow-empty -m "Initial commit"` `git checkout -b child > #{File::NULL} 2>&1` - `git -c protocol.file.allow=always submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` `git commit -m "Add submodule"` `git checkout master > #{File::NULL} 2>&1` `git merge --no-ff --no-edit child` diff --git a/spec/overcommit/hook_context/post_rewrite_spec.rb b/spec/overcommit/hook_context/post_rewrite_spec.rb index 0d510c4a..d2f18f6e 100644 --- a/spec/overcommit/hook_context/post_rewrite_spec.rb +++ b/spec/overcommit/hook_context/post_rewrite_spec.rb @@ -101,9 +101,8 @@ end repo do - git_config = '-c protocol.file.allow=always' `git commit --allow-empty -m "Initial commit"` - `git #{git_config} submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` `git commit --amend -m "Add submodule"` expect(subject).to_not include File.expand_path('test-sub') end diff --git a/spec/overcommit/hook_context/pre_commit_spec.rb b/spec/overcommit/hook_context/pre_commit_spec.rb index 719982a1..dae42e66 100644 --- a/spec/overcommit/hook_context/pre_commit_spec.rb +++ b/spec/overcommit/hook_context/pre_commit_spec.rb @@ -207,7 +207,7 @@ end repo do - `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -383,7 +383,7 @@ end repo do - `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -409,7 +409,7 @@ end repo do - `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -441,7 +441,7 @@ end repo do - `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` `git rm sub` example.run @@ -470,7 +470,7 @@ end repo do - `git -c protocol.file.allow=always submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` expect(subject).to_not include File.expand_path('test-sub') end end diff --git a/spec/overcommit/hook_context/run_all_spec.rb b/spec/overcommit/hook_context/run_all_spec.rb index c6696edc..516fb70b 100644 --- a/spec/overcommit/hook_context/run_all_spec.rb +++ b/spec/overcommit/hook_context/run_all_spec.rb @@ -46,8 +46,7 @@ end repo do - git_config = '-c protocol.file.allow=always' - `git #{git_config} submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` example.run end end diff --git a/spec/overcommit/installer_spec.rb b/spec/overcommit/installer_spec.rb index 8739a70e..c7cfb05e 100644 --- a/spec/overcommit/installer_spec.rb +++ b/spec/overcommit/installer_spec.rb @@ -231,7 +231,7 @@ def hook_files_installed?(hooks_dir) context 'which has an external git dir' do let(:submodule) { File.join(target, 'submodule') } before do - system 'git', '-c', 'protocol.file.allow=always', 'submodule', 'add', target, 'submodule', + system 'git', 'submodule', 'add', target, 'submodule', chdir: target, out: :close, err: :close end let(:submodule_git_file) { File.join(submodule, '.git') } From 9c3d118b8f21ef8bf77d9a9dfc62a8051f8078d3 Mon Sep 17 00:00:00 2001 From: Sorin Guga Date: Sun, 25 Feb 2024 01:58:04 +0200 Subject: [PATCH 19/43] Green CI PoC (#833) Cherry-picked commits from #830, #831, #832, #835, #837 and #839. --- .github/workflows/lint.yml | 2 +- .github/workflows/tests.yml | 29 ++++++++----------- Gemfile | 6 +++- .../pre_commit/rails_schema_up_to_date.rb | 2 +- spec/overcommit/git_repo_spec.rb | 20 ++++++++----- .../hook/prepare_commit_msg/base_spec.rb | 6 ++-- .../hook_context/commit_msg_spec.rb | 10 +++---- .../hook_context/pre_commit_spec.rb | 10 +++---- spec/overcommit/installer_spec.rb | 4 +-- 9 files changed, 46 insertions(+), 43 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 8b23cbab..8cf8b4a0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Ruby uses: ruby/setup-ruby@v1 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 26c20dd1..e9987e06 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,25 +14,20 @@ jobs: fail-fast: false matrix: ruby-version: - - '2.6' - - '2.7' - - '3.0' - - '3.1' - - '3.2' + - "2.6" + - "2.7" + - "3.0" + - "3.1" + - "3.2" os: - ubuntu - - windows - - # Tempfile behavior has changed on Ruby 3.1 such that tests - # fail with permission denied. Would welcome a PR with a fix. - exclude: - - ruby-version: '3.1' - os: windows - - ruby-version: '3.2' - os: windows + # At the moment of this commit various specs fail on Windows. + # Any contributor is welcome to fix them and enable the Windows build. + # Please see Issue #836 for more details. + # - windows steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Ruby ${{ matrix.ruby-version }} uses: ruby/setup-ruby@v1 @@ -47,7 +42,7 @@ jobs: bundle exec rspec - name: Code coverage reporting - uses: coverallsapp/github-action@master + uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.github_token }} flag-name: ruby${{ matrix.ruby-version }}-${{ matrix.os }} @@ -59,7 +54,7 @@ jobs: steps: - name: Finalize code coverage report - uses: coverallsapp/github-action@master + uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.github_token }} parallel-finished: true diff --git a/Gemfile b/Gemfile index 53b13c7f..49dc7923 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,10 @@ gem 'simplecov', '~> 0.21.0' gem 'simplecov-lcov', '~> 0.8.0' # Pin RuboCop for CI builds -gem 'rubocop', '1.59.0' +if RUBY_VERSION < '2.7.0' + gem 'rubocop', '1.50.0' +else + gem 'rubocop', '1.59.0' +end gem 'ffi' if Gem.win_platform? diff --git a/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb b/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb index dafd31a1..61725074 100644 --- a/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb +++ b/lib/overcommit/hook/pre_commit/rails_schema_up_to_date.rb @@ -53,7 +53,7 @@ def schema_files end def schema - @schema ||= schema_files.map { |file| File.read(file, encoding) }.join + @schema ||= schema_files.map { |file| File.read(file, **(encoding || {})) }.join @schema.tr('_', '') end diff --git a/spec/overcommit/git_repo_spec.rb b/spec/overcommit/git_repo_spec.rb index 128737c3..b887415b 100644 --- a/spec/overcommit/git_repo_spec.rb +++ b/spec/overcommit/git_repo_spec.rb @@ -24,12 +24,13 @@ end submodule = repo do - `git submodule add #{nested_submodule} nested-sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add \ + #{nested_submodule} nested-sub 2>&1 > #{File::NULL}` `git commit -m "Add nested submodule"` end repo do - `git submodule add #{submodule} sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} sub 2>&1 > #{File::NULL}` example.run end end @@ -150,7 +151,7 @@ end before do - `git submodule add #{submodule} sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} sub 2>&1 > #{File::NULL}` end it { should_not include File.expand_path('sub') } @@ -178,7 +179,8 @@ `git commit --allow-empty -m "Submodule commit"` end - `git submodule add #{submodule} #{submodule_dir} 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add \ + #{submodule} #{submodule_dir} 2>&1 > #{File::NULL}` `git commit -m "Add submodule"` end @@ -282,7 +284,7 @@ touch 'tracked' `git add tracked` `git commit -m "Initial commit"` - `git submodule add #{submodule} sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} sub 2>&1 > #{File::NULL}` touch 'staged' `git add staged` example.run @@ -327,7 +329,7 @@ end repo do - `git submodule add #{submodule} sub-repo 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} sub-repo 2>&1 > #{File::NULL}` `git commit -m "Initial commit"` example.run end @@ -343,7 +345,8 @@ `git commit --allow-empty -m "Another submodule"` end - `git submodule add #{another_submodule} another-sub-repo 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add \ + #{another_submodule} another-sub-repo 2>&1 > #{File::NULL}` end it { should be_empty } @@ -369,7 +372,8 @@ `git commit --allow-empty -m "Another submodule"` end - `git submodule add #{another_submodule} yet-another-sub-repo 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add \ + #{another_submodule} yet-another-sub-repo 2>&1 > #{File::NULL}` `git commit -m "Add yet another submodule"` `git rm sub-repo` `git rm yet-another-sub-repo` diff --git a/spec/overcommit/hook/prepare_commit_msg/base_spec.rb b/spec/overcommit/hook/prepare_commit_msg/base_spec.rb index 616d6b8e..873ed637 100644 --- a/spec/overcommit/hook/prepare_commit_msg/base_spec.rb +++ b/spec/overcommit/hook/prepare_commit_msg/base_spec.rb @@ -38,9 +38,9 @@ contents + "bravo\n" end end - Thread.new { hook_1.run } - Thread.new { hook_2.run } - Thread.list.each { |t| t.join unless t == Thread.current } + t1 = Thread.new { hook_1.run } + t2 = Thread.new { hook_2.run } + [t1, t2].each(&:join) expect(File.read(tempfile)).to match(/alpha\n#{initial_content}bravo\n/m) end end diff --git a/spec/overcommit/hook_context/commit_msg_spec.rb b/spec/overcommit/hook_context/commit_msg_spec.rb index 2aa68516..058f1508 100644 --- a/spec/overcommit/hook_context/commit_msg_spec.rb +++ b/spec/overcommit/hook_context/commit_msg_spec.rb @@ -298,7 +298,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -474,7 +474,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -500,7 +500,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -532,7 +532,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` `git rm sub` example.run @@ -561,7 +561,7 @@ end repo do - `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` expect(subject).to_not include File.expand_path('test-sub') end end diff --git a/spec/overcommit/hook_context/pre_commit_spec.rb b/spec/overcommit/hook_context/pre_commit_spec.rb index dae42e66..719982a1 100644 --- a/spec/overcommit/hook_context/pre_commit_spec.rb +++ b/spec/overcommit/hook_context/pre_commit_spec.rb @@ -207,7 +207,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -383,7 +383,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -409,7 +409,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` echo('Hello World', 'sub/submodule-file') `git submodule foreach "git add submodule-file" < #{File::NULL}` @@ -441,7 +441,7 @@ end repo do - `git submodule add #{submodule} sub > #{File::NULL} 2>&1` + `git -c protocol.file.allow=always submodule add #{submodule} sub > #{File::NULL} 2>&1` `git commit -m "Add submodule"` `git rm sub` example.run @@ -470,7 +470,7 @@ end repo do - `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git -c protocol.file.allow=always submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` expect(subject).to_not include File.expand_path('test-sub') end end diff --git a/spec/overcommit/installer_spec.rb b/spec/overcommit/installer_spec.rb index c7cfb05e..5283b2b6 100644 --- a/spec/overcommit/installer_spec.rb +++ b/spec/overcommit/installer_spec.rb @@ -231,8 +231,8 @@ def hook_files_installed?(hooks_dir) context 'which has an external git dir' do let(:submodule) { File.join(target, 'submodule') } before do - system 'git', 'submodule', 'add', target, 'submodule', - chdir: target, out: :close, err: :close + system 'git', '-c', 'protocol.file.allow=always', 'submodule', 'add', target, + 'submodule', chdir: target, out: :close, err: :close end let(:submodule_git_file) { File.join(submodule, '.git') } let(:submodule_git_dir) do From a2fb742f28407c9a762d60ae723a796b6472667c Mon Sep 17 00:00:00 2001 From: Sorin Guga Date: Sun, 25 Feb 2024 02:05:52 +0200 Subject: [PATCH 20/43] [FEATURE] New pre-commit hook: Sorbet (Issue #825) (#826) ## Introduction This pre-commit hook runs the Sorbet type-checker. [More information about Sorbet here](https://sorbet.org/docs/overview) Fixes #825 ## Requirements [Sorbet](https://github.com/sorbet/sorbet) Notes: not sure if this should be a pre-commit hook or pre-push hook to be honest. Co-authored-by: Shane da Silva --- README.md | 66 +++++++++++-------- config/default.yml | 8 +++ lib/overcommit/hook/pre_commit/sorbet.rb | 24 +++++++ .../overcommit/hook/pre_commit/sorbet_spec.rb | 54 +++++++++++++++ 4 files changed, 124 insertions(+), 28 deletions(-) create mode 100644 lib/overcommit/hook/pre_commit/sorbet.rb create mode 100644 spec/overcommit/hook/pre_commit/sorbet_spec.rb diff --git a/README.md b/README.md index afcbcbbf..769c1cf1 100644 --- a/README.md +++ b/README.md @@ -17,34 +17,43 @@ are stored in source control. You can also easily [add your existing hook scripts](#adding-existing-git-hooks) without writing any Ruby code. -* [Requirements](#requirements) - * [Dependencies](#dependencies) -* [Installation](#installation) - * [Automatically Install Overcommit Hooks](#automatically-install-overcommit-hooks) -* [Usage](#usage) -* [Continuous Integration](#continuous-integration) -* [Configuration](#configuration) - * [Hook Options](#hook-options) - * [Hook Categories](#hook-categories) - * [Gemfile](#gemfile) - * [Plugin Directory](#plugin-directory) - * [Signature Verification](#signature-verification) -* [Built-In Hooks](#built-in-hooks) - * [CommitMsg](#commitmsg) - * [PostCheckout](#postcheckout) - * [PostCommit](#postcommit) - * [PostMerge](#postmerge) - * [PostRewrite](#postrewrite) - * [PreCommit](#precommit) - * [PrePush](#prepush) - * [PreRebase](#prerebase) -* [Repo-Specific Hooks](#repo-specific-hooks) - * [Adding Existing Git Hooks](#adding-existing-git-hooks) -* [Security](#security) -* [Contributing](#contributing) -* [Community](#community) -* [Changelog](#changelog) -* [License](#license) +- [Requirements](#requirements) + - [Windows](#windows) + - [Dependencies](#dependencies) +- [Installation](#installation) + - [Automatically Install Overcommit Hooks](#automatically-install-overcommit-hooks) +- [Usage](#usage) + - [Skipping Hooks](#skipping-hooks) + - [Disabling Overcommit](#disabling-overcommit) + - [Disabling Colorized Output](#disabling-colorized-output) +- [Continuous Integration](#continuous-integration) +- [Configuration](#configuration) + - [Hook Options](#hook-options) + - [Hook Categories](#hook-categories) + - [The `ALL` Hook](#the-all-hook) + - [Gemfile](#gemfile) + - [Plugin Directory](#plugin-directory) + - [Quiet Hook Runs](#quiet-hook-runs) + - [Concurrency](#concurrency) + - [Signature Verification](#signature-verification) +- [Built-In Hooks](#built-in-hooks) + - [CommitMsg](#commitmsg) + - [PostCheckout](#postcheckout) + - [PostCommit](#postcommit) + - [PostMerge](#postmerge) + - [PostRewrite](#postrewrite) + - [PreCommit](#precommit) + - [WARNING: pre-commit hooks cannot have side effects](#warning-pre-commit-hooks-cannot-have-side-effects) + - [PrePush](#prepush) + - [PreRebase](#prerebase) +- [Repo-Specific hooks](#repo-specific-hooks) + - [Adding Existing Git Hooks](#adding-existing-git-hooks) +- [Security](#security) + - [Disabling Signature Checking](#disabling-signature-checking) +- [Contributing](#contributing) +- [Community](#community) +- [Changelog](#changelog) +- [License](#license) ## Requirements @@ -561,6 +570,7 @@ issue](https://github.com/sds/overcommit/issues/238) for more details. * [SemiStandard](lib/overcommit/hook/pre_commit/semi_standard.rb) * [ShellCheck](lib/overcommit/hook/pre_commit/shell_check.rb) * [SlimLint](lib/overcommit/hook/pre_commit/slim_lint.rb) +* [Sorbet](lib/overcommit/hook/pre_commit/sorbet.rb) * [Sqlint](lib/overcommit/hook/pre_commit/sqlint.rb) * [Standard](lib/overcommit/hook/pre_commit/standard.rb) * [Stylelint](lib/overcommit/hook/pre_commit/stylelint.rb) diff --git a/config/default.yml b/config/default.yml index 181187af..e0fc3910 100644 --- a/config/default.yml +++ b/config/default.yml @@ -790,6 +790,14 @@ PreCommit: install_command: 'gem install slim_lint' include: '**/*.slim' + Sorbet: + enabled: false + description: 'Analyze with Sorbet' + required_executable: 'srb' + install_command: 'gem install sorbet' + command: ['srb', 'tc'] + include: '**/*.rb' + Sqlint: enabled: false description: 'Analyze with sqlint' diff --git a/lib/overcommit/hook/pre_commit/sorbet.rb b/lib/overcommit/hook/pre_commit/sorbet.rb new file mode 100644 index 00000000..57988a6e --- /dev/null +++ b/lib/overcommit/hook/pre_commit/sorbet.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Overcommit::Hook::PreCommit + # Runs 'srb tc' against any modified files. + # + # @see https://github.com/sorbet/sorbet + class Sorbet < Base + # example of output: + # sorbet.rb:1: Method `foo` does not exist on `T.class_of(Bar)` https://srb.help/7003 + MESSAGE_REGEX = /^(?[^:]+):(?\d+): (?.*)$/.freeze + + def run + result = execute(command, args: applicable_files) + return :pass if result.success? + + output = result.stderr.split("\n").grep(MESSAGE_REGEX) + + extract_messages( + output, + MESSAGE_REGEX + ) + end + end +end diff --git a/spec/overcommit/hook/pre_commit/sorbet_spec.rb b/spec/overcommit/hook/pre_commit/sorbet_spec.rb new file mode 100644 index 00000000..60f811cb --- /dev/null +++ b/spec/overcommit/hook/pre_commit/sorbet_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Overcommit::Hook::PreCommit::Sorbet do + let(:config) { Overcommit::ConfigurationLoader.default_configuration } + let(:context) { double('context') } + subject { described_class.new(config, context) } + + before do + subject.stub(:applicable_files).and_return(%w[file1.rb file2.rb]) + end + + context 'when Sorbet exits successfully' do + let(:result) { double('result') } + + before do + result.stub(:success?).and_return(true) + subject.stub(:execute).and_return(result) + end + + it { should pass } + + context 'and it printed a message to stderr' do + before do + result.stub(:stderr).and_return("No errors! Great job.\n") + end + + it { should pass } + end + end + + context 'when Sorbet exits unsucessfully' do + let(:result) { double('result') } + + before do + result.stub(:success?).and_return(false) + subject.stub(:execute).and_return(result) + end + + context 'and it reports an error' do + before do + result.stub(:stderr).and_return(normalize_indent(<<-MSG)) + sorbet.rb:1: Method `foo` does not exist on `T.class_of(Bar)` https://srb.help/7003 + 5 | foo 'bar' + ^^^ + Errors: 1 + MSG + end + + it { should fail_hook } + end + end +end From c4aa796d09ac5a432501a37cf270f8edc6aa4cb2 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Sat, 24 Feb 2024 16:12:12 -0800 Subject: [PATCH 21/43] Fix RuboCop warnings (#841) --- .rubocop.yml | 4 +++- lib/overcommit/cli.rb | 16 +++++++--------- lib/overcommit/hook/base.rb | 14 ++++++-------- lib/overcommit/hook/commit_msg/text_width.rb | 2 +- lib/overcommit/hook/pre_commit/erb_lint.rb | 2 +- lib/overcommit/hook/pre_commit/html_hint.rb | 2 +- lib/overcommit/hook/pre_commit/json_syntax.rb | 10 ++++------ lib/overcommit/hook/pre_commit/xml_syntax.rb | 10 ++++------ lib/overcommit/hook/pre_commit/yaml_syntax.rb | 16 +++++++--------- lib/overcommit/utils/messages_utils.rb | 2 +- overcommit.gemspec | 2 +- 11 files changed, 36 insertions(+), 44 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 8c779097..1b4e7ad7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,7 +1,9 @@ inherit_from: .rubocop_todo.yml AllCops: - TargetRubyVersion: 2.4 + TargetRubyVersion: 2.6 + NewCops: disable + SuggestExtensions: false Layout/ClosingParenthesisIndentation: Enabled: false diff --git a/lib/overcommit/cli.rb b/lib/overcommit/cli.rb index bc2ec994..f8127125 100644 --- a/lib/overcommit/cli.rb +++ b/lib/overcommit/cli.rb @@ -124,15 +124,13 @@ def install_or_uninstall end @options[:targets].each do |target| - begin - Installer.new(log).run(target, @options) - rescue Overcommit::Exceptions::InvalidGitRepo => e - log.warning "Invalid repo #{target}: #{e}" - halt 69 # EX_UNAVAILABLE - rescue Overcommit::Exceptions::PreExistingHooks => e - log.warning "Unable to install into #{target}: #{e}" - halt 73 # EX_CANTCREAT - end + Installer.new(log).run(target, @options) + rescue Overcommit::Exceptions::InvalidGitRepo => e + log.warning "Invalid repo #{target}: #{e}" + halt 69 # EX_UNAVAILABLE + rescue Overcommit::Exceptions::PreExistingHooks => e + log.warning "Unable to install into #{target}: #{e}" + halt 73 # EX_CANTCREAT end end diff --git a/lib/overcommit/hook/base.rb b/lib/overcommit/hook/base.rb index 37696d08..3c2eaeb3 100644 --- a/lib/overcommit/hook/base.rb +++ b/lib/overcommit/hook/base.rb @@ -228,14 +228,12 @@ def check_for_libraries output = [] required_libraries.each do |library| - begin - require library - rescue LoadError - install_command = @config['install_command'] - install_command = " -- install via #{install_command}" if install_command - - output << "Unable to load '#{library}'#{install_command}" - end + require library + rescue LoadError + install_command = @config['install_command'] + install_command = " -- install via #{install_command}" if install_command + + output << "Unable to load '#{library}'#{install_command}" end return if output.empty? diff --git a/lib/overcommit/hook/commit_msg/text_width.rb b/lib/overcommit/hook/commit_msg/text_width.rb index 63addbcf..52de3bd7 100644 --- a/lib/overcommit/hook/commit_msg/text_width.rb +++ b/lib/overcommit/hook/commit_msg/text_width.rb @@ -41,7 +41,7 @@ def find_errors_in_body(lines) max_body_width = config['max_body_width'] - lines[2..-1].each_with_index do |line, index| + lines[2..].each_with_index do |line, index| if line.chomp.size > max_body_width @errors << "Line #{index + 3} of commit message has > " \ "#{max_body_width} characters" diff --git a/lib/overcommit/hook/pre_commit/erb_lint.rb b/lib/overcommit/hook/pre_commit/erb_lint.rb index a903b10b..ae5af164 100644 --- a/lib/overcommit/hook/pre_commit/erb_lint.rb +++ b/lib/overcommit/hook/pre_commit/erb_lint.rb @@ -12,7 +12,7 @@ def run return :pass if result.success? extract_messages( - result.stdout.split("\n\n")[1..-1], + result.stdout.split("\n\n")[1..], MESSAGE_REGEX ) end diff --git a/lib/overcommit/hook/pre_commit/html_hint.rb b/lib/overcommit/hook/pre_commit/html_hint.rb index e8cb4a68..ddbe37d1 100644 --- a/lib/overcommit/hook/pre_commit/html_hint.rb +++ b/lib/overcommit/hook/pre_commit/html_hint.rb @@ -14,7 +14,7 @@ def run lines = group.split("\n").map(&:strip) file = lines[0][/(.+):/, 1] extract_messages( - lines[1..-1].map { |msg| "#{file}: #{msg}" }, + lines[1..].map { |msg| "#{file}: #{msg}" }, /^(?(?:\w:)?[^:]+): line (?\d+)/ ) end.flatten diff --git a/lib/overcommit/hook/pre_commit/json_syntax.rb b/lib/overcommit/hook/pre_commit/json_syntax.rb index 04972b91..bd162f7d 100644 --- a/lib/overcommit/hook/pre_commit/json_syntax.rb +++ b/lib/overcommit/hook/pre_commit/json_syntax.rb @@ -7,12 +7,10 @@ def run messages = [] applicable_files.each do |file| - begin - JSON.parse(IO.read(file)) - rescue JSON::ParserError => e - error = "#{e.message} parsing #{file}" - messages << Overcommit::Hook::Message.new(:error, file, nil, error) - end + JSON.parse(IO.read(file)) + rescue JSON::ParserError => e + error = "#{e.message} parsing #{file}" + messages << Overcommit::Hook::Message.new(:error, file, nil, error) end messages diff --git a/lib/overcommit/hook/pre_commit/xml_syntax.rb b/lib/overcommit/hook/pre_commit/xml_syntax.rb index 7ac05360..99465182 100644 --- a/lib/overcommit/hook/pre_commit/xml_syntax.rb +++ b/lib/overcommit/hook/pre_commit/xml_syntax.rb @@ -7,12 +7,10 @@ def run messages = [] applicable_files.each do |file| - begin - REXML::Document.new(IO.read(file)) - rescue REXML::ParseException => e - error = "Error parsing #{file}: #{e.message}" - messages << Overcommit::Hook::Message.new(:error, file, nil, error) - end + REXML::Document.new(IO.read(file)) + rescue REXML::ParseException => e + error = "Error parsing #{file}: #{e.message}" + messages << Overcommit::Hook::Message.new(:error, file, nil, error) end messages diff --git a/lib/overcommit/hook/pre_commit/yaml_syntax.rb b/lib/overcommit/hook/pre_commit/yaml_syntax.rb index dd685450..83ff6789 100644 --- a/lib/overcommit/hook/pre_commit/yaml_syntax.rb +++ b/lib/overcommit/hook/pre_commit/yaml_syntax.rb @@ -7,17 +7,15 @@ def run messages = [] applicable_files.each do |file| + YAML.load_file(file, aliases: true) + rescue ArgumentError begin - YAML.load_file(file, aliases: true) - rescue ArgumentError - begin - YAML.load_file(file) - rescue ArgumentError, Psych::SyntaxError => e - messages << Overcommit::Hook::Message.new(:error, file, nil, e.message) - end - rescue Psych::DisallowedClass => e - messages << error_message(file, e) + YAML.load_file(file) + rescue ArgumentError, Psych::SyntaxError => e + messages << Overcommit::Hook::Message.new(:error, file, nil, e.message) end + rescue Psych::DisallowedClass => e + messages << error_message(file, e) end messages diff --git a/lib/overcommit/utils/messages_utils.rb b/lib/overcommit/utils/messages_utils.rb index c92a6010..31c0f8db 100644 --- a/lib/overcommit/utils/messages_utils.rb +++ b/lib/overcommit/utils/messages_utils.rb @@ -26,7 +26,7 @@ def extract_messages(output_messages, regex, type_categorizer = nil) raise Overcommit::Exceptions::MessageProcessingError, 'Unexpected output: unable to determine line number or type ' \ "of error/warning for output:\n" \ - "#{output_messages[index..-1].join("\n")}" + "#{output_messages[index..].join("\n")}" end file = extract_file(match, message) diff --git a/overcommit.gemspec b/overcommit.gemspec index 8bc70845..268a9fc1 100644 --- a/overcommit.gemspec +++ b/overcommit.gemspec @@ -25,7 +25,7 @@ Gem::Specification.new do |s| Dir['libexec/**/*'] + Dir['template-dir/**/*'] - s.required_ruby_version = '>= 2.4' + s.required_ruby_version = '>= 2.6' s.add_dependency 'childprocess', '>= 0.6.3', '< 6' s.add_dependency 'iniparse', '~> 1.4' From b58b6358e7e8d8a278d4ebba83a5b4a68d2f0058 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Sat, 24 Feb 2024 16:18:43 -0800 Subject: [PATCH 22/43] Add RSpec Hook to PreCommit, Add Applicable files if set (#842) - **Add RSpec to pre_commit hooks** - **Add applicable files to RSpec command if include configuration set** - **Fix RuboCop errors** --------- Co-authored-by: Max Prettyjohns --- config/default.yml | 5 + lib/overcommit/hook/pre_commit/r_spec.rb | 12 ++ lib/overcommit/hook/pre_push/r_spec.rb | 12 +- lib/overcommit/hook/shared/r_spec.rb | 21 ++++ .../overcommit/hook/pre_commit/r_spec_spec.rb | 116 ++++++++++++++++++ spec/overcommit/hook/pre_push/r_spec_spec.rb | 36 ++++++ 6 files changed, 194 insertions(+), 8 deletions(-) create mode 100644 lib/overcommit/hook/pre_commit/r_spec.rb create mode 100644 lib/overcommit/hook/shared/r_spec.rb create mode 100644 spec/overcommit/hook/pre_commit/r_spec_spec.rb diff --git a/config/default.yml b/config/default.yml index e0fc3910..70ae0b2d 100644 --- a/config/default.yml +++ b/config/default.yml @@ -709,6 +709,11 @@ PreCommit: install_command: 'pip install restructuredtext_lint' include: '**/*.rst' + RSpec: + enabled: false + description: 'Run tests with Rspec' + required_executable: 'rspec' + RuboCop: enabled: false description: 'Analyze with RuboCop' diff --git a/lib/overcommit/hook/pre_commit/r_spec.rb b/lib/overcommit/hook/pre_commit/r_spec.rb new file mode 100644 index 00000000..26bbc0a8 --- /dev/null +++ b/lib/overcommit/hook/pre_commit/r_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'overcommit/hook/shared/r_spec' + +module Overcommit::Hook::PreCommit + # Runs `rspec` test suite + # + # @see http://rspec.info/ + class RSpec < Base + include Overcommit::Hook::Shared::RSpec + end +end diff --git a/lib/overcommit/hook/pre_push/r_spec.rb b/lib/overcommit/hook/pre_push/r_spec.rb index a3b4474c..7ce3df29 100644 --- a/lib/overcommit/hook/pre_push/r_spec.rb +++ b/lib/overcommit/hook/pre_push/r_spec.rb @@ -1,16 +1,12 @@ # frozen_string_literal: true +require 'overcommit/hook/shared/r_spec' + module Overcommit::Hook::PrePush - # Runs `rspec` test suite before push + # Runs `rspec` test suite # # @see http://rspec.info/ class RSpec < Base - def run - result = execute(command) - return :pass if result.success? - - output = result.stdout + result.stderr - [:fail, output] - end + include Overcommit::Hook::Shared::RSpec end end diff --git a/lib/overcommit/hook/shared/r_spec.rb b/lib/overcommit/hook/shared/r_spec.rb new file mode 100644 index 00000000..9b41e8e1 --- /dev/null +++ b/lib/overcommit/hook/shared/r_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Overcommit::Hook::Shared + # Runs `rspec` test suite before push + # + # @see http://rspec.info/ + module RSpec + def run + result = if @config['include'] + execute(command, args: applicable_files) + else + execute(command) + end + + return :pass if result.success? + + output = result.stdout + result.stderr + [:fail, output] + end + end +end diff --git a/spec/overcommit/hook/pre_commit/r_spec_spec.rb b/spec/overcommit/hook/pre_commit/r_spec_spec.rb new file mode 100644 index 00000000..7fdff3b3 --- /dev/null +++ b/spec/overcommit/hook/pre_commit/r_spec_spec.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Overcommit::Hook::PreCommit::RSpec do + let(:config) { Overcommit::ConfigurationLoader.default_configuration } + let(:context) { double('context') } + subject { described_class.new(config, context) } + + context 'when rspec exits successfully' do + let(:result) { double('result') } + + before do + result.stub(:success?).and_return(true) + subject.stub(:execute).and_return(result) + end + + it { should pass } + + it { + expect(subject).to receive(:execute).with(['rspec']).and_return(result) + + subject.run + } + end + + context 'with included files set' do + let(:result) { double('result') } + let(:config) do + super().merge(Overcommit::Configuration.new( + 'PreCommit' => { + 'RSpec' => { + 'include' => ['**/*_spec.rb'], + } + } + )) + end + + let(:context) { double('context') } + + before do + result.stub(:success?).and_return(true) + subject.stub(:execute).and_return(result) + subject.stub(:applicable_files).and_return('spec/test_spec.rb') + end + + it { should pass } + + it { + expect(subject).to receive(:execute).with(['rspec'], + args: 'spec/test_spec.rb').and_return(result) + + subject.run + } + end + + context 'when rspec exits unsuccessfully' do + let(:result) { double('result') } + + before do + result.stub(:success?).and_return(false) + subject.stub(:execute).and_return(result) + end + + context 'with a runtime error' do + before do + result.stub(stdout: '', stderr: <<-MSG) + /home/user/.rbenv/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/configuration.rb:1226:in `load': /home/user/dev/github/overcommit/spec/overcommit/hook/pre_push/rspec_spec.rb:49: can't find string "EOS" anywhere before EOF (SyntaxError) + /home/user/dev/overcommit/spec/overcommit/hook/pre_push/rspec_spec.rb:29: syntax error, unexpected end-of-input + from /home/user/.rbenv/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/configuration.rb:1226:in `block in load_spec_files' + from /home/user/.rbenv/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/configuration.rb:1224:in `each' + from /home/user/.rbenv/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/configuration.rb:1224:in `load_spec_files' + from /home/user/.rbenv/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/runner.rb:97:in `setup' + from /home/user/.rbenv/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/runner.rb:85:in `run' + from /home/user/.rbenv/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/runner.rb:70:in `run' + from /home/user/.rbenv/gems/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/runner.rb:38:in `invoke' + from /home/user/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rspec-core-3.2.2/exe/rspec:4:in `' + from /home/user/.rbenv/versions/2.2.1/bin/rspec:23:in `load' + from /home/user/.rbenv/versions/2.2.1/bin/rspec:23:in `
' + MSG + end + + it { should fail_hook } + end + + context 'with a test failure' do + before do + result.stub(stderr: '', stdout: <<-MSG) + .FF + + Failures: + + 1) Overcommit::Hook::PrePush::RSpec when rspec exits unsuccessfully with a runtime error should fail + Failure/Error: it { should fail_hook } + expected that the hook would fail + # ./spec/overcommit/hook/pre_push/rspec_spec.rb:45:in `block (4 levels) in ' + + 2) Overcommit::Hook::PrePush::RSpec when rspec exits unsuccessfully with a test failure should fail + Failure/Error: it { should fail_hook } + expected that the hook would fail + # ./spec/overcommit/hook/pre_push/rspec_spec.rb:57:in `block (4 levels) in ' + + Finished in 0.00505 seconds (files took 0.27437 seconds to load) + 3 examples, 2 failures + + Failed examples: + + rspec ./spec/overcommit/hook/pre_push/rspec_spec.rb:45 # Overcommit::Hook::PrePush::RSpec when rspec exits unsuccessfully with a runtime error should fail + rspec ./spec/overcommit/hook/pre_push/rspec_spec.rb:57 # Overcommit::Hook::PrePush::RSpec when rspec exits unsuccessfully with a test failure should fail + MSG + end + + it { should fail_hook } + end + end +end diff --git a/spec/overcommit/hook/pre_push/r_spec_spec.rb b/spec/overcommit/hook/pre_push/r_spec_spec.rb index 26f6ea0f..1efc56d7 100644 --- a/spec/overcommit/hook/pre_push/r_spec_spec.rb +++ b/spec/overcommit/hook/pre_push/r_spec_spec.rb @@ -16,6 +16,42 @@ end it { should pass } + + it { + expect(subject).to receive(:execute).with(['rspec']).and_return(result) + + subject.run + } + end + + context 'with included files set' do + let(:result) { double('result') } + let(:config) do + super().merge(Overcommit::Configuration.new( + 'PrePush' => { + 'RSpec' => { + 'include' => ['**/*_spec.rb'], + } + } + )) + end + + let(:context) { double('context') } + + before do + result.stub(:success?).and_return(true) + subject.stub(:execute).and_return(result) + subject.stub(:applicable_files).and_return('spec/test_spec.rb') + end + + it { should pass } + + it { + expect(subject).to receive(:execute).with(['rspec'], + args: 'spec/test_spec.rb').and_return(result) + + subject.run + } end context 'when rspec exits unsuccessfully' do From b700bd25723fe0a731c2102d33b42d5e5d760d80 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Sat, 24 Feb 2024 16:24:07 -0800 Subject: [PATCH 23/43] Cut version 0.63.0 (#843) --- CHANGELOG.md | 5 +++++ lib/overcommit/version.rb | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5953a7c1..f61b7d5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Overcommit Changelog +## 0.63.0 + +* Add `Sorbet` pre-commit hook +* Add `RSpec` pre-commit hook + ## 0.62.0 * Allow version 5 of `childprocess` gem dependency diff --git a/lib/overcommit/version.rb b/lib/overcommit/version.rb index f6805668..e640bf38 100644 --- a/lib/overcommit/version.rb +++ b/lib/overcommit/version.rb @@ -2,5 +2,5 @@ # Defines the gem version. module Overcommit - VERSION = '0.62.0' + VERSION = '0.63.0' end From 7974b3b08ee8e78ace35ee0472698c830ac08104 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Sat, 24 Feb 2024 16:28:42 -0800 Subject: [PATCH 24/43] Fix README badges (#844) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 769c1cf1..4ad91913 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ [![Gem Version](https://badge.fury.io/rb/overcommit.svg)](https://badge.fury.io/rb/overcommit) -[![Build Status](https://github.com/sds/overcommit/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/sds/overcommit/actions/workflows/tests.yml/badge.svg?branch=master) -[![Coverage Status](https://coveralls.io/repos/github/sds/overcommit/badge.svg?branch=master)](https://coveralls.io/github/sds/overcommit?branch=master) +[![Build Status](https://github.com/sds/overcommit/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/sds/overcommit/actions/workflows/tests.yml/badge.svg?branch=main) +[![Coverage Status](https://coveralls.io/repos/github/sds/overcommit/badge.svg?branch=main)](https://coveralls.io/github/sds/overcommit?branch=main) [![Maintainability](https://api.codeclimate.com/v1/badges/5da42f7f365e5fef6b4c/maintainability)](https://codeclimate.com/github/sds/overcommit/maintainability) -[![Inline docs](http://inch-ci.org/github/sds/overcommit.svg?branch=master)](http://inch-ci.org/github/sds/overcommit) +[![Inline docs](http://inch-ci.org/github/sds/overcommit.svg?branch=main)](http://inch-ci.org/github/sds/overcommit)

Overcommit Logo From a14ec6330c778bae3df46fce8b6a640ee74e8d37 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Sat, 24 Feb 2024 16:35:08 -0800 Subject: [PATCH 25/43] Update README with latest requirements (#845) Clarify Windows support is now best effort, given we don't have tests. --- README.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4ad91913..877e9396 100644 --- a/README.md +++ b/README.md @@ -57,15 +57,9 @@ any Ruby code. ## Requirements -This project aims to support the following Ruby runtimes on both \*nix and Windows: +This project aims to support the following Ruby runtimes on \*nix (and best effort on Windows): -* Ruby 2.4+ - -### Windows - -If you are using Overcommit on **Windows**, make sure you include the `ffi` gem in your -list of dependencies. Overcommit does not include the `ffi` gem by default since it -significantly increases the install time for non-Windows platforms. +* Ruby 2.6+ ### Dependencies From 841954c64954818be1d246ec01b72f922ca28faa Mon Sep 17 00:00:00 2001 From: Matt Brictson Date: Sat, 11 May 2024 23:36:11 -0700 Subject: [PATCH 26/43] Add Ruby 3.3 to CI matrix (#849) It might be a good idea to also update the `main` branch protection rules to require that the 3.2 and 3.3 jobs succeed. Right now only 2.7, 3.0, and 3.1 are required. A repository admin will need to make this change. --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e9987e06..0e2aac20 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -19,6 +19,7 @@ jobs: - "3.0" - "3.1" - "3.2" + - "3.3" os: - ubuntu # At the moment of this commit various specs fail on Windows. From 0e717f97a60e88ddd0b8a408b84f4420d7bda1a8 Mon Sep 17 00:00:00 2001 From: Matt Brictson Date: Sat, 11 May 2024 23:36:50 -0700 Subject: [PATCH 27/43] Support stylelint 16+, which emits messages on stderr (#848) Before Stylelint 16, Stylelint emitted its messages on stdout. Hence Overcommit's Stylelint hook was built to read output from stdout. Starting with Stylelint 16, Stylelint now emits its messages to stderr, which means the existing Overcommit implementation no longer works. This PR updates Overcommit's Stylelint plugin to check for messages on _both_ stdout and stderr. That way <16 and >=16 versions of Stylelint are supported. Fixes #823 --- lib/overcommit/hook/pre_commit/stylelint.rb | 2 +- .../hook/pre_commit/stylelint_spec.rb | 29 ++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/overcommit/hook/pre_commit/stylelint.rb b/lib/overcommit/hook/pre_commit/stylelint.rb index b129cbd2..aae26f08 100644 --- a/lib/overcommit/hook/pre_commit/stylelint.rb +++ b/lib/overcommit/hook/pre_commit/stylelint.rb @@ -12,7 +12,7 @@ class Stylelint < Base def run result = execute(command, args: applicable_files) - output = result.stdout.chomp + output = result.stdout + result.stderr.chomp return :pass if result.success? && output.empty? extract_messages( diff --git a/spec/overcommit/hook/pre_commit/stylelint_spec.rb b/spec/overcommit/hook/pre_commit/stylelint_spec.rb index d31ba948..68e83f65 100644 --- a/spec/overcommit/hook/pre_commit/stylelint_spec.rb +++ b/spec/overcommit/hook/pre_commit/stylelint_spec.rb @@ -15,6 +15,7 @@ before do result = double('result') result.stub(:success?).and_return(true) + result.stub(:stderr).and_return('') result.stub(:stdout).and_return('') subject.stub(:execute).and_return(result) end @@ -22,7 +23,7 @@ it { should pass } end - context 'when stylelint exits unsucessfully' do + context 'when stylelint exits unsucessfully with messages on stdout (stylelint < 16)' do let(:result) { double('result') } before do @@ -32,6 +33,7 @@ context 'and it reports an error' do before do result.stub(:success?).and_return(false) + result.stub(:stderr).and_return('') result.stub(:stdout).and_return([ 'index.css: line 4, col 4, error - Expected indentation of 2 spaces (indentation)', 'form.css: line 10, col 6, error - Expected indentation of 4 spaces (indentation)', @@ -45,4 +47,29 @@ end end end + + context 'when stylelint exits unsucessfully with messages on stderr (stylelint >= 16)' do + let(:result) { double('result') } + + before do + subject.stub(:execute).and_return(result) + end + + context 'and it reports an error' do + before do + result.stub(:success?).and_return(false) + result.stub(:stdout).and_return('') + result.stub(:stderr).and_return([ + 'index.css: line 4, col 4, error - Expected indentation of 2 spaces (indentation)', + 'form.css: line 10, col 6, error - Expected indentation of 4 spaces (indentation)', + ].join("\n")) + end + + it { should fail_hook } + + it 'extracts lines numbers correctly from output' do + expect(subject.run.map(&:line)).to eq([4, 10]) + end + end + end end From 26e78aa9e5e907ed41ebdac8098483af4d54865c Mon Sep 17 00:00:00 2001 From: fynsta <63241108+fynsta@users.noreply.github.com> Date: Mon, 24 Jun 2024 20:54:52 +0200 Subject: [PATCH 28/43] Add changelog_uri to gemspec (#851) Supported here: https://guides.rubygems.org/specification-reference/#metadata Useful for running https://github.com/MaximeD/gem_updater --- overcommit.gemspec | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/overcommit.gemspec b/overcommit.gemspec index 268a9fc1..0b3a590d 100644 --- a/overcommit.gemspec +++ b/overcommit.gemspec @@ -15,6 +15,10 @@ Gem::Specification.new do |s| s.post_install_message = 'Install hooks by running `overcommit --install` in your Git repository' + s.metadata = { + 'changelog_uri' => 'https://github.com/sds/overcommit/blob/main/CHANGELOG.md' + } + s.require_paths = %w[lib] s.executables = ['overcommit'] From 939d9e6be210fb59b453e3ce18abf4409d105503 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Mon, 22 Jul 2024 13:48:43 -0700 Subject: [PATCH 29/43] Cut version 0.64.0 (#852) --- lib/overcommit/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/overcommit/version.rb b/lib/overcommit/version.rb index e640bf38..9df380b0 100644 --- a/lib/overcommit/version.rb +++ b/lib/overcommit/version.rb @@ -2,5 +2,5 @@ # Defines the gem version. module Overcommit - VERSION = '0.63.0' + VERSION = '0.64.0' end From 5ff9d5e78906813fc9421f2ce9388aee9363b8bf Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Mon, 22 Jul 2024 13:52:53 -0700 Subject: [PATCH 30/43] Update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f61b7d5c..d8d2133f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Overcommit Changelog +## 0.64.0 + +* Add support for `stylelint` 16+ +* Add `changelog_uri` to gemspec + ## 0.63.0 * Add `Sorbet` pre-commit hook From 5a3d68eaa70573bb600bb9deedda0e5d622eafea Mon Sep 17 00:00:00 2001 From: Joakim Antman Date: Sun, 11 Aug 2024 09:31:18 +0300 Subject: [PATCH 31/43] Fix spec compatibility with recent git versions (#854) The original array was defining the shellwords like this: `["git", "commit", "-m", "\"Resolve", "conflicts\"", "-i", "some-file"]` This combined with the most recent git version failed with: ``` error: pathspec 'conflicts"' did not match any file(s) known to git ``` This PR just simplifies the commit message to work with the %w array literal. --- spec/integration/resolving_cherry_pick_conflict_spec.rb | 2 +- spec/integration/resolving_merge_conflict_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/integration/resolving_cherry_pick_conflict_spec.rb b/spec/integration/resolving_cherry_pick_conflict_spec.rb index 58e22e65..2a7f053c 100644 --- a/spec/integration/resolving_cherry_pick_conflict_spec.rb +++ b/spec/integration/resolving_cherry_pick_conflict_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe 'resolving cherry-pick conflicts' do - subject { shell(%w[git commit -m "Resolve conflicts" -i some-file]) } + subject { shell(%w[git commit -m Test -i some-file]) } let(:config) { <<-YML } PreCommit: diff --git a/spec/integration/resolving_merge_conflict_spec.rb b/spec/integration/resolving_merge_conflict_spec.rb index 679ba136..997dcb09 100644 --- a/spec/integration/resolving_merge_conflict_spec.rb +++ b/spec/integration/resolving_merge_conflict_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe 'resolving merge conflicts' do - subject { shell(%w[git commit -m "Resolve conflicts" -i some-file]) } + subject { shell(%w[git commit -m Test -i some-file]) } around do |example| repo do From 31c83ce603008de3ac04ff9b7d1ea9fca6e529c8 Mon Sep 17 00:00:00 2001 From: Joakim Antman Date: Sun, 11 Aug 2024 09:37:24 +0300 Subject: [PATCH 32/43] Expand tildes(~) for hooksPath (#853) While installing overcommit git hooks i noticed that tildes are not expanded to home folders for the `hooksPath` config, the result was a tilde folder in the current directory. This PR addresses that by switching `File.absolute_path` to `File.expand_path`. The [underlaying implementation](https://github.com/ruby/ruby/blob/v3_3_4/file.c#L3753) in Ruby is exactly the same just with this difference in how `~` is handled. --------- Co-authored-by: Shane da Silva --- lib/overcommit/git_config.rb | 2 +- spec/overcommit/git_config_spec.rb | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/overcommit/git_config.rb b/lib/overcommit/git_config.rb index 392dd9da..c1243861 100644 --- a/lib/overcommit/git_config.rb +++ b/lib/overcommit/git_config.rb @@ -17,7 +17,7 @@ def hooks_path path = `git config --get core.hooksPath`.chomp return File.join(Overcommit::Utils.git_dir, 'hooks') if path.empty? - File.absolute_path(path, Dir.pwd) + File.expand_path(path, Dir.pwd) end end end diff --git a/spec/overcommit/git_config_spec.rb b/spec/overcommit/git_config_spec.rb index 22ad7c02..9cc51862 100644 --- a/spec/overcommit/git_config_spec.rb +++ b/spec/overcommit/git_config_spec.rb @@ -78,5 +78,19 @@ expect(subject).to eq File.expand_path('my-hooks') end end + + context 'when explicitly set to a path starting with a tilde' do + around do |example| + repo do + `git config --local core.hooksPath ~/my-hooks` + example.run + end + end + + it 'returns the absolute path to the folder in the users home path' do + expect(subject).to eq File.expand_path('~/my-hooks') + expect(subject).not_to include('~') + end + end end end From 9825868ba2b2194a2329d24c08d47a054bf265cc Mon Sep 17 00:00:00 2001 From: Edward Woodcock <768254+RemoteCTO@users.noreply.github.com> Date: Thu, 31 Oct 2024 05:47:17 +0100 Subject: [PATCH 33/43] Bump rexml to >= 3.3.9 to resolve GHSA-2rxp-v6pw-ch6m (#857) A `ReDoS vulnerability in REXML` has been identified in versions <3.3.9 Details in GitHub: - https://github.com/ruby/rexml/security/advisories/GHSA-2rxp-v6pw-ch6m This is a small bump to the latest patched version. This should resolve anybody getting the following `bundle audit` error when using overcommit: ``` Name: rexml Version: 3.3.8 CVE: CVE-2024-49761 GHSA: GHSA-2rxp-v6pw-ch6m Criticality: High URL: https://github.com/ruby/rexml/security/advisories/GHSA-2rxp-v6pw-ch6m Title: REXML ReDoS vulnerability Solution: update to '>= 3.3.9' ``` --- lib/overcommit/version.rb | 2 +- overcommit.gemspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/overcommit/version.rb b/lib/overcommit/version.rb index 9df380b0..afd18470 100644 --- a/lib/overcommit/version.rb +++ b/lib/overcommit/version.rb @@ -2,5 +2,5 @@ # Defines the gem version. module Overcommit - VERSION = '0.64.0' + VERSION = '0.64.1' end diff --git a/overcommit.gemspec b/overcommit.gemspec index 0b3a590d..caaa8499 100644 --- a/overcommit.gemspec +++ b/overcommit.gemspec @@ -33,5 +33,5 @@ Gem::Specification.new do |s| s.add_dependency 'childprocess', '>= 0.6.3', '< 6' s.add_dependency 'iniparse', '~> 1.4' - s.add_dependency 'rexml', '~> 3.2' + s.add_dependency 'rexml', '>= 3.3.9' end From eff94a7f058d9eeca3f30e069fadba5a82f43da2 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Wed, 30 Oct 2024 21:49:26 -0700 Subject: [PATCH 34/43] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8d2133f..1ba199d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Overcommit Changelog +## 0.64.1 + +* Update minimum version of rexml to address [CVE-2024-49761](https://www.ruby-lang.org/en/news/2024/10/28/redos-rexml-cve-2024-49761/) + ## 0.64.0 * Add support for `stylelint` 16+ From 7d3e8fa5ed9feb07a57e7fec685a46ccd58769ee Mon Sep 17 00:00:00 2001 From: Carlos Palhares Date: Mon, 27 Jan 2025 16:26:12 -0300 Subject: [PATCH 35/43] Load bundled gems on expected version (#859) Fixes https://github.com/sds/overcommit/issues/789 `psych` is no longer a default gem, but current and old ruby still ships with it. When we `require 'yaml'`, we activate that gem in whatever version that is bundled with ruby. Later on, we load bundler, and we `Bundler.setup`, which will then activate whatever version specified in the lock file. More often than not, they might not match. The approach in this PR is to strip the `yaml` dependency completely from the hook scripts, while retaining the ability to configure the Gemfile using it. --- template-dir/hooks/commit-msg | 10 ++-------- template-dir/hooks/overcommit-hook | 10 ++-------- template-dir/hooks/post-checkout | 10 ++-------- template-dir/hooks/post-commit | 10 ++-------- template-dir/hooks/post-merge | 10 ++-------- template-dir/hooks/post-rewrite | 10 ++-------- template-dir/hooks/pre-commit | 10 ++-------- template-dir/hooks/pre-push | 10 ++-------- template-dir/hooks/pre-rebase | 10 ++-------- template-dir/hooks/prepare-commit-msg | 10 ++-------- 10 files changed, 20 insertions(+), 80 deletions(-) diff --git a/template-dir/hooks/commit-msg b/template-dir/hooks/commit-msg index 7f8023de..377c892b 100755 --- a/template-dir/hooks/commit-msg +++ b/template-dir/hooks/commit-msg @@ -27,14 +27,8 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -require 'yaml' -# rubocop:disable Style/RescueModifier -gemfile = - begin - YAML.load_file('.overcommit.yml', aliases: true)['gemfile'] - rescue ArgumentError - YAML.load_file('.overcommit.yml')['gemfile'] - end rescue nil +config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +gemfile = Regexp.last_match(1) if gemfile ENV['BUNDLE_GEMFILE'] = gemfile diff --git a/template-dir/hooks/overcommit-hook b/template-dir/hooks/overcommit-hook index 7f8023de..377c892b 100755 --- a/template-dir/hooks/overcommit-hook +++ b/template-dir/hooks/overcommit-hook @@ -27,14 +27,8 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -require 'yaml' -# rubocop:disable Style/RescueModifier -gemfile = - begin - YAML.load_file('.overcommit.yml', aliases: true)['gemfile'] - rescue ArgumentError - YAML.load_file('.overcommit.yml')['gemfile'] - end rescue nil +config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +gemfile = Regexp.last_match(1) if gemfile ENV['BUNDLE_GEMFILE'] = gemfile diff --git a/template-dir/hooks/post-checkout b/template-dir/hooks/post-checkout index 7f8023de..377c892b 100755 --- a/template-dir/hooks/post-checkout +++ b/template-dir/hooks/post-checkout @@ -27,14 +27,8 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -require 'yaml' -# rubocop:disable Style/RescueModifier -gemfile = - begin - YAML.load_file('.overcommit.yml', aliases: true)['gemfile'] - rescue ArgumentError - YAML.load_file('.overcommit.yml')['gemfile'] - end rescue nil +config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +gemfile = Regexp.last_match(1) if gemfile ENV['BUNDLE_GEMFILE'] = gemfile diff --git a/template-dir/hooks/post-commit b/template-dir/hooks/post-commit index 7f8023de..377c892b 100755 --- a/template-dir/hooks/post-commit +++ b/template-dir/hooks/post-commit @@ -27,14 +27,8 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -require 'yaml' -# rubocop:disable Style/RescueModifier -gemfile = - begin - YAML.load_file('.overcommit.yml', aliases: true)['gemfile'] - rescue ArgumentError - YAML.load_file('.overcommit.yml')['gemfile'] - end rescue nil +config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +gemfile = Regexp.last_match(1) if gemfile ENV['BUNDLE_GEMFILE'] = gemfile diff --git a/template-dir/hooks/post-merge b/template-dir/hooks/post-merge index 7f8023de..377c892b 100755 --- a/template-dir/hooks/post-merge +++ b/template-dir/hooks/post-merge @@ -27,14 +27,8 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -require 'yaml' -# rubocop:disable Style/RescueModifier -gemfile = - begin - YAML.load_file('.overcommit.yml', aliases: true)['gemfile'] - rescue ArgumentError - YAML.load_file('.overcommit.yml')['gemfile'] - end rescue nil +config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +gemfile = Regexp.last_match(1) if gemfile ENV['BUNDLE_GEMFILE'] = gemfile diff --git a/template-dir/hooks/post-rewrite b/template-dir/hooks/post-rewrite index 7f8023de..377c892b 100755 --- a/template-dir/hooks/post-rewrite +++ b/template-dir/hooks/post-rewrite @@ -27,14 +27,8 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -require 'yaml' -# rubocop:disable Style/RescueModifier -gemfile = - begin - YAML.load_file('.overcommit.yml', aliases: true)['gemfile'] - rescue ArgumentError - YAML.load_file('.overcommit.yml')['gemfile'] - end rescue nil +config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +gemfile = Regexp.last_match(1) if gemfile ENV['BUNDLE_GEMFILE'] = gemfile diff --git a/template-dir/hooks/pre-commit b/template-dir/hooks/pre-commit index 7f8023de..377c892b 100755 --- a/template-dir/hooks/pre-commit +++ b/template-dir/hooks/pre-commit @@ -27,14 +27,8 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -require 'yaml' -# rubocop:disable Style/RescueModifier -gemfile = - begin - YAML.load_file('.overcommit.yml', aliases: true)['gemfile'] - rescue ArgumentError - YAML.load_file('.overcommit.yml')['gemfile'] - end rescue nil +config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +gemfile = Regexp.last_match(1) if gemfile ENV['BUNDLE_GEMFILE'] = gemfile diff --git a/template-dir/hooks/pre-push b/template-dir/hooks/pre-push index 7f8023de..377c892b 100755 --- a/template-dir/hooks/pre-push +++ b/template-dir/hooks/pre-push @@ -27,14 +27,8 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -require 'yaml' -# rubocop:disable Style/RescueModifier -gemfile = - begin - YAML.load_file('.overcommit.yml', aliases: true)['gemfile'] - rescue ArgumentError - YAML.load_file('.overcommit.yml')['gemfile'] - end rescue nil +config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +gemfile = Regexp.last_match(1) if gemfile ENV['BUNDLE_GEMFILE'] = gemfile diff --git a/template-dir/hooks/pre-rebase b/template-dir/hooks/pre-rebase index 7f8023de..377c892b 100755 --- a/template-dir/hooks/pre-rebase +++ b/template-dir/hooks/pre-rebase @@ -27,14 +27,8 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -require 'yaml' -# rubocop:disable Style/RescueModifier -gemfile = - begin - YAML.load_file('.overcommit.yml', aliases: true)['gemfile'] - rescue ArgumentError - YAML.load_file('.overcommit.yml')['gemfile'] - end rescue nil +config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +gemfile = Regexp.last_match(1) if gemfile ENV['BUNDLE_GEMFILE'] = gemfile diff --git a/template-dir/hooks/prepare-commit-msg b/template-dir/hooks/prepare-commit-msg index 7f8023de..377c892b 100755 --- a/template-dir/hooks/prepare-commit-msg +++ b/template-dir/hooks/prepare-commit-msg @@ -27,14 +27,8 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -require 'yaml' -# rubocop:disable Style/RescueModifier -gemfile = - begin - YAML.load_file('.overcommit.yml', aliases: true)['gemfile'] - rescue ArgumentError - YAML.load_file('.overcommit.yml')['gemfile'] - end rescue nil +config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +gemfile = Regexp.last_match(1) if gemfile ENV['BUNDLE_GEMFILE'] = gemfile From 9ce54927dda3fdc7de00fbfcf68a9ebaf9e008c3 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Mon, 27 Jan 2025 11:27:56 -0800 Subject: [PATCH 36/43] Cut version 0.65.0 --- CHANGELOG.md | 4 ++++ lib/overcommit/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ba199d2..bbe08fb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Overcommit Changelog +## 0.65.0 + +* Load bundled gems on expected version + ## 0.64.1 * Update minimum version of rexml to address [CVE-2024-49761](https://www.ruby-lang.org/en/news/2024/10/28/redos-rexml-cve-2024-49761/) diff --git a/lib/overcommit/version.rb b/lib/overcommit/version.rb index afd18470..0b718a39 100644 --- a/lib/overcommit/version.rb +++ b/lib/overcommit/version.rb @@ -2,5 +2,5 @@ # Defines the gem version. module Overcommit - VERSION = '0.64.1' + VERSION = '0.65.0' end From b4d4ce0e819dad926dfd0073540dd73a5217e2e9 Mon Sep 17 00:00:00 2001 From: benmelz Date: Wed, 29 Jan 2025 19:26:01 -0500 Subject: [PATCH 37/43] Add `-diff` cli option for running precommit hooks against diffs (#860) For example, running `overcommit --diff main` from a feature branch will run pre-commit hooks against the diff between the two branches. I was able to very easily leverage existing code for the bulk of the feature - this is mainly just adding the cli option, a hook context to do the execution and some tests based on the existing `--run-all` test. --- For background, my team is responsible for a couple of really old, really large rails apps. Getting them completely in compliance with our various linters is a huge task that isn't getting done anytime soon (things are funky to the point that we've even observed breakages with "safe" auto-correct functions). I introduced/started heavily encouraging overcommit so that we at least don't add _new_ linting offenses and things will naturally improve over time. It's been great, but offenses still slip through though here and there, especially with juniors who might be getting away with not having a local install (and/or abusing `OVERCOMMIT_DISABLE=1`). An option like this would allow me to leverage the very useful "only apply to changed lines" logic within a ci environment and help enforce my desired "no new linting offenses" policy. --- lib/overcommit/cli.rb | 23 +++- lib/overcommit/hook_context.rb | 4 +- lib/overcommit/hook_context/base.rb | 4 +- lib/overcommit/hook_context/diff.rb | 37 ++++++ spec/integration/diff_flag_spec.rb | 39 ++++++ spec/overcommit/cli_spec.rb | 26 ++++ spec/overcommit/hook_context/diff_spec.rb | 143 ++++++++++++++++++++++ 7 files changed, 272 insertions(+), 4 deletions(-) create mode 100644 lib/overcommit/hook_context/diff.rb create mode 100644 spec/integration/diff_flag_spec.rb create mode 100644 spec/overcommit/hook_context/diff_spec.rb diff --git a/lib/overcommit/cli.rb b/lib/overcommit/cli.rb index f8127125..dafc545a 100644 --- a/lib/overcommit/cli.rb +++ b/lib/overcommit/cli.rb @@ -9,6 +9,7 @@ module Overcommit class CLI # rubocop:disable Metrics/ClassLength def initialize(arguments, input, logger) @arguments = arguments + @cli_options = {} @input = input @log = logger @options = {} @@ -28,6 +29,8 @@ def run sign when :run_all run_all + when :diff + diff end rescue Overcommit::Exceptions::ConfigurationSignatureChanged => e puts e @@ -45,7 +48,7 @@ def parse_arguments @parser = create_option_parser begin - @parser.parse!(@arguments) + @parser.parse!(@arguments, into: @cli_options) # Default action is to install @options[:action] ||= :install @@ -98,6 +101,11 @@ def add_installation_options(opts) @options[:action] = :run_all @options[:hook_to_run] = arg ? arg.to_s : 'run-all' end + + opts.on('--diff [ref]', 'Run pre_commit hooks against the diff between a given ref. Defaults to `main`.') do |arg| # rubocop:disable Layout/LineLength + @options[:action] = :diff + arg + end end def add_other_options(opts) @@ -209,6 +217,19 @@ def run_all halt(status ? 0 : 65) end + def diff + empty_stdin = File.open(File::NULL) # pre-commit hooks don't take input + context = Overcommit::HookContext.create('diff', config, @arguments, empty_stdin, **@cli_options) # rubocop:disable Layout/LineLength + config.apply_environment!(context, ENV) + + printer = Overcommit::Printer.new(config, log, context) + runner = Overcommit::HookRunner.new(config, log, context, printer) + + status = runner.run + + halt(status ? 0 : 65) + end + # Used for ease of stubbing in tests def halt(status = 0) exit status diff --git a/lib/overcommit/hook_context.rb b/lib/overcommit/hook_context.rb index acdff1bb..5863ed94 100644 --- a/lib/overcommit/hook_context.rb +++ b/lib/overcommit/hook_context.rb @@ -2,13 +2,13 @@ # Utility module which manages the creation of {HookContext}s. module Overcommit::HookContext - def self.create(hook_type, config, args, input) + def self.create(hook_type, config, args, input, **cli_options) hook_type_class = Overcommit::Utils.camel_case(hook_type) underscored_hook_type = Overcommit::Utils.snake_case(hook_type) require "overcommit/hook_context/#{underscored_hook_type}" - Overcommit::HookContext.const_get(hook_type_class).new(config, args, input) + Overcommit::HookContext.const_get(hook_type_class).new(config, args, input, **cli_options) rescue LoadError, NameError => e # Could happen when a symlink was created for a hook type Overcommit does # not yet support. diff --git a/lib/overcommit/hook_context/base.rb b/lib/overcommit/hook_context/base.rb index 077394fb..b50698c9 100644 --- a/lib/overcommit/hook_context/base.rb +++ b/lib/overcommit/hook_context/base.rb @@ -18,10 +18,12 @@ class Base # @param config [Overcommit::Configuration] # @param args [Array] # @param input [IO] standard input stream - def initialize(config, args, input) + # @param options [Hash] cli options + def initialize(config, args, input, **options) @config = config @args = args @input = input + @options = options end # Executes a command as if it were a regular git hook, passing all diff --git a/lib/overcommit/hook_context/diff.rb b/lib/overcommit/hook_context/diff.rb new file mode 100644 index 00000000..0c4b97e0 --- /dev/null +++ b/lib/overcommit/hook_context/diff.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'overcommit/git_repo' + +module Overcommit::HookContext + # Simulates a pre-commit context based on the diff with another git ref. + # + # This results in pre-commit hooks running against the changes between the current + # and another ref, which is useful for automated CI scripts. + class Diff < Base + def modified_files + @modified_files ||= Overcommit::GitRepo.modified_files(refs: @options[:diff]) + end + + def modified_lines_in_file(file) + @modified_lines ||= {} + @modified_lines[file] ||= Overcommit::GitRepo.extract_modified_lines(file, + refs: @options[:diff]) + end + + def hook_class_name + 'PreCommit' + end + + def hook_type_name + 'pre_commit' + end + + def hook_script_name + 'pre-commit' + end + + def initial_commit? + @initial_commit ||= Overcommit::GitRepo.initial_commit? + end + end +end diff --git a/spec/integration/diff_flag_spec.rb b/spec/integration/diff_flag_spec.rb new file mode 100644 index 00000000..dcaa1bd3 --- /dev/null +++ b/spec/integration/diff_flag_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'overcommit --diff' do + subject { shell(%w[overcommit --diff main]) } + + context 'when using an existing pre-commit hook script' do + let(:script_name) { 'test-script' } + let(:script_contents) { "#!/bin/bash\nexit 0" } + let(:script_path) { ".#{Overcommit::OS::SEPARATOR}#{script_name}" } + + let(:config) do + { + 'PreCommit' => { + 'MyHook' => { + 'enabled' => true, + 'required_executable' => script_path, + } + } + } + end + + around do |example| + repo do + File.open('.overcommit.yml', 'w') { |f| f.puts(config.to_yaml) } + echo(script_contents, script_path) + `git add #{script_path}` + FileUtils.chmod(0o755, script_path) + example.run + end + end + + it 'completes successfully without blocking' do + wait_until(timeout: 10) { subject } # Need to wait long time for JRuby startup + subject.status.should == 0 + end + end +end diff --git a/spec/overcommit/cli_spec.rb b/spec/overcommit/cli_spec.rb index 40923ad3..3d95b09d 100644 --- a/spec/overcommit/cli_spec.rb +++ b/spec/overcommit/cli_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' require 'overcommit/cli' +require 'overcommit/hook_context/diff' require 'overcommit/hook_context/run_all' describe Overcommit::CLI do @@ -125,5 +126,30 @@ subject end end + + context 'with the diff switch specified' do + let(:arguments) { ['--diff=some-ref'] } + let(:config) { Overcommit::ConfigurationLoader.default_configuration } + + before do + cli.stub(:halt) + Overcommit::HookRunner.any_instance.stub(:run) + end + + it 'creates a HookRunner with the diff context' do + Overcommit::HookRunner.should_receive(:new). + with(config, + logger, + instance_of(Overcommit::HookContext::Diff), + instance_of(Overcommit::Printer)). + and_call_original + subject + end + + it 'runs the HookRunner' do + Overcommit::HookRunner.any_instance.should_receive(:run) + subject + end + end end end diff --git a/spec/overcommit/hook_context/diff_spec.rb b/spec/overcommit/hook_context/diff_spec.rb new file mode 100644 index 00000000..0c712fbc --- /dev/null +++ b/spec/overcommit/hook_context/diff_spec.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'overcommit/hook_context/diff' + +describe Overcommit::HookContext::Diff do + let(:config) { double('config') } + let(:args) { [] } + let(:input) { double('input') } + let(:context) { described_class.new(config, args, input, diff: 'master') } + + describe '#modified_files' do + subject { context.modified_files } + + context 'when repo contains no files' do + around do |example| + repo do + `git commit --allow-empty -m "Initial commit"` + `git checkout -b other-branch 2>&1` + example.run + end + end + + it { should be_empty } + end + + context 'when the repo contains files that are unchanged from the ref' do + around do |example| + repo do + touch('some-file') + `git add some-file` + touch('some-other-file') + `git add some-other-file` + `git commit -m "Add files"` + `git checkout -b other-branch 2>&1` + example.run + end + end + + it { should be_empty } + end + + context 'when repo contains files that have been changed from the ref' do + around do |example| + repo do + touch('some-file') + `git add some-file` + touch('some-other-file') + `git add some-other-file` + `git commit -m "Add files"` + `git checkout -b other-branch 2>&1` + File.open('some-file', 'w') { |f| f.write("hello\n") } + `git add some-file` + `git commit -m "Edit file"` + example.run + end + end + + it { should == %w[some-file].map { |file| File.expand_path(file) } } + end + + context 'when repo contains submodules' do + around do |example| + submodule = repo do + touch 'foo' + `git add foo` + `git commit -m "Initial commit"` + end + + repo do + `git submodule add #{submodule} test-sub 2>&1 > #{File::NULL}` + `git commit --allow-empty -m "Initial commit"` + `git checkout -b other-branch 2>&1` + example.run + end + end + + it { should_not include File.expand_path('test-sub') } + end + end + + describe '#modified_lines_in_file' do + let(:modified_file) { 'some-file' } + subject { context.modified_lines_in_file(modified_file) } + + context 'when file contains a trailing newline' do + around do |example| + repo do + touch(modified_file) + `git add #{modified_file}` + `git commit -m "Add file"` + `git checkout -b other-branch 2>&1` + File.open(modified_file, 'w') { |f| (1..3).each { |i| f.write("#{i}\n") } } + `git add #{modified_file}` + `git commit -m "Edit file"` + example.run + end + end + + it { should == Set.new(1..3) } + end + + context 'when file does not contain a trailing newline' do + around do |example| + repo do + touch(modified_file) + `git add #{modified_file}` + `git commit -m "Add file"` + `git checkout -b other-branch 2>&1` + File.open(modified_file, 'w') do |f| + (1..2).each { |i| f.write("#{i}\n") } + f.write(3) + end + `git add #{modified_file}` + `git commit -m "Edit file"` + example.run + end + end + + it { should == Set.new(1..3) } + end + end + + describe '#hook_type_name' do + subject { context.hook_type_name } + + it { should == 'pre_commit' } + end + + describe '#hook_script_name' do + subject { context.hook_script_name } + + it { should == 'pre-commit' } + end + + describe '#initial_commit?' do + subject { context.initial_commit? } + + before { Overcommit::GitRepo.stub(:initial_commit?).and_return(true) } + + it { should == true } + end +end From 43e17fb384e51101cd45449e03d39188f18959f9 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Wed, 29 Jan 2025 16:32:23 -0800 Subject: [PATCH 38/43] Cut version 0.66.0 (#861) --- CHANGELOG.md | 4 ++++ README.md | 1 + lib/overcommit/version.rb | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbe08fb9..d82b5b50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Overcommit Changelog +## 0.66.0 + +* Add `--diff` CLI option for running pre-commit hooks against only changed files + ## 0.65.0 * Load bundled gems on expected version diff --git a/README.md b/README.md index 877e9396..a0d46726 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ Command Line Flag | Description `-f`/`--force` | Don't bail on install if other hooks already exist--overwrite them `-l`/`--list-hooks` | Display all available hooks in the current repository `-r`/`--run` | Run pre-commit hook against all tracked files in repository +`--diff ` | Run pre-commit hook against all changed files relative to `` `-t`/`--template-dir` | Print location of template directory `-h`/`--help` | Show command-line flag documentation `-v`/`--version` | Show version diff --git a/lib/overcommit/version.rb b/lib/overcommit/version.rb index 0b718a39..c1091e52 100644 --- a/lib/overcommit/version.rb +++ b/lib/overcommit/version.rb @@ -2,5 +2,5 @@ # Defines the gem version. module Overcommit - VERSION = '0.65.0' + VERSION = '0.66.0' end From 3db733e5b7dd479baee1c8e587aa86ed73e5011f Mon Sep 17 00:00:00 2001 From: Matt Brictson Date: Sun, 16 Feb 2025 13:04:54 -0800 Subject: [PATCH 39/43] Restore ability to specify "gemfile: false" in config (#863) Setting `gemfile: false` in `.overcommit.yml` is supposed to disable Bundler. However, a recently-introduced bug causes `false` to be interpreted as the name of the gemfile. Bundler looks for a gemfile named "false", which fails, leading overcommit's hooks to crash. This PR fixes the bug by adjusting the regex used to parse the `gemfile:` line in the config. Now, `false` is no longer interpreted as a gemfile name. I added an integration test to verify the fix. Fixes #862 --- spec/integration/gemfile_option_spec.rb | 211 +++++++++++++++--------- template-dir/hooks/commit-msg | 2 +- template-dir/hooks/overcommit-hook | 2 +- template-dir/hooks/post-checkout | 2 +- template-dir/hooks/post-commit | 2 +- template-dir/hooks/post-merge | 2 +- template-dir/hooks/post-rewrite | 2 +- template-dir/hooks/pre-commit | 2 +- template-dir/hooks/pre-push | 2 +- template-dir/hooks/pre-rebase | 2 +- template-dir/hooks/prepare-commit-msg | 2 +- 11 files changed, 144 insertions(+), 87 deletions(-) diff --git a/spec/integration/gemfile_option_spec.rb b/spec/integration/gemfile_option_spec.rb index 7a0175da..a6a6a4ba 100644 --- a/spec/integration/gemfile_option_spec.rb +++ b/spec/integration/gemfile_option_spec.rb @@ -3,99 +3,156 @@ require 'spec_helper' describe 'specifying `gemfile` option in Overcommit configuration' do - let(:repo_root) { File.expand_path(File.join('..', '..'), File.dirname(__FILE__)) } - let(:fake_gem_path) { File.join('lib', 'my_fake_gem') } - - # We point the overcommit gem back to this repo since we can't assume the gem - # has already been installed in a test environment - let(:gemfile) { normalize_indent(<<-RUBY) } - source 'https://rubygems.org' - - gem 'overcommit', path: '#{repo_root}' - gem 'my_fake_gem', path: '#{fake_gem_path}' - gem 'ffi' if Gem.win_platform? # Necessary for test to pass on Windows - RUBY - - let(:gemspec) { normalize_indent(<<-RUBY) } - Gem::Specification.new do |s| - s.name = 'my_fake_gem' - s.version = '1.0.0' - s.author = 'John Doe' - s.license = 'MIT' - s.homepage = 'https://example.com' - s.email = 'john.doe@example.com' - s.summary = 'A fake gem' - s.files = [File.join('lib', 'my_fake_gem.rb')] - end - RUBY - - # Specify a hook that depends on an external gem to test Gemfile loading - let(:hook) { normalize_indent(<<-RUBY) } - module Overcommit::Hook::PreCommit - class FakeHook < Base - def run - require 'my_fake_gem' - :pass + context 'given a project that uses a Gemfile' do + let(:repo_root) { File.expand_path(File.join('..', '..'), File.dirname(__FILE__)) } + let(:fake_gem_path) { File.join('lib', 'my_fake_gem') } + + # We point the overcommit gem back to this repo since we can't assume the gem + # has already been installed in a test environment + let(:gemfile) { normalize_indent(<<-RUBY) } + source 'https://rubygems.org' + + gem 'overcommit', path: '#{repo_root}' + gem 'my_fake_gem', path: '#{fake_gem_path}' + gem 'ffi' if Gem.win_platform? # Necessary for test to pass on Windows + RUBY + + let(:gemspec) { normalize_indent(<<-RUBY) } + Gem::Specification.new do |s| + s.name = 'my_fake_gem' + s.version = '1.0.0' + s.author = 'John Doe' + s.license = 'MIT' + s.homepage = 'https://example.com' + s.email = 'john.doe@example.com' + s.summary = 'A fake gem' + s.files = [File.join('lib', 'my_fake_gem.rb')] + end + RUBY + + # Specify a hook that depends on an external gem to test Gemfile loading + let(:hook) { normalize_indent(<<-RUBY) } + module Overcommit::Hook::PreCommit + class FakeHook < Base + def run + require 'my_fake_gem' + :pass + end + end + end + RUBY + + let(:config) { normalize_indent(<<-YAML) } + verify_signatures: false + + CommitMsg: + ALL: + enabled: false + + PreCommit: + ALL: + enabled: false + FakeHook: + enabled: true + requires_files: false + YAML + + around do |example| + repo do + # Since RSpec is being run within a Bundler context we need to clear it + # in order to not taint the test + Bundler.with_unbundled_env do + FileUtils.mkdir_p(File.join(fake_gem_path, 'lib')) + echo(gemspec, File.join(fake_gem_path, 'my_fake_gem.gemspec')) + touch(File.join(fake_gem_path, 'lib', 'my_fake_gem.rb')) + + echo(gemfile, '.overcommit_gems.rb') + `bundle install --gemfile=.overcommit_gems.rb` + + echo(config, '.overcommit.yml') + + # Set BUNDLE_GEMFILE so we load Overcommit from the current repo + ENV['BUNDLE_GEMFILE'] = '.overcommit_gems.rb' + `bundle exec overcommit --install > #{File::NULL}` + FileUtils.mkdir_p(File.join('.git-hooks', 'pre_commit')) + echo(hook, File.join('.git-hooks', 'pre_commit', 'fake_hook.rb')) + + Overcommit::Utils.with_environment 'OVERCOMMIT_NO_VERIFY' => '1' do + example.run + end end end end - RUBY - - let(:config) { normalize_indent(<<-YAML) } - verify_signatures: false - - CommitMsg: - ALL: - enabled: false - - PreCommit: - ALL: - enabled: false - FakeHook: - enabled: true - requires_files: false - YAML - - around do |example| - repo do - # Since RSpec is being run within a Bundler context we need to clear it - # in order to not taint the test - Bundler.with_unbundled_env do - FileUtils.mkdir_p(File.join(fake_gem_path, 'lib')) - echo(gemspec, File.join(fake_gem_path, 'my_fake_gem.gemspec')) - touch(File.join(fake_gem_path, 'lib', 'my_fake_gem.rb')) - - echo(gemfile, '.overcommit_gems.rb') - `bundle install --gemfile=.overcommit_gems.rb` + subject { shell(%w[git commit --allow-empty -m Test]) } + + context 'when configuration specifies the gemfile' do + let(:config) { "gemfile: .overcommit_gems.rb\n" + super() } + + it 'runs the hook successfully' do + subject.status.should == 0 + end + end + + context 'when configuration does not specify the gemfile' do + it 'fails to run the hook' do + subject.status.should_not == 0 + end + end + end + + context 'given a project that does not use a Gemfile' do + let(:hook) { normalize_indent(<<-RUBY) } + module Overcommit::Hook::PreCommit + class NoInvalidGemfileHook < Base + def run + if (gemfile = ENV["BUNDLE_GEMFILE"]) + raise unless File.exist?(gemfile) + end + + :pass + end + end + end + RUBY + + let(:config) { normalize_indent(<<-YAML) } + verify_signatures: false + + CommitMsg: + ALL: + enabled: false + + PreCommit: + ALL: + enabled: false + NoInvalidGemfileHook: + enabled: true + requires_files: false + YAML + + around do |example| + repo do echo(config, '.overcommit.yml') - # Set BUNDLE_GEMFILE so we load Overcommit from the current repo - ENV['BUNDLE_GEMFILE'] = '.overcommit_gems.rb' - `bundle exec overcommit --install > #{File::NULL}` + `overcommit --install > #{File::NULL}` FileUtils.mkdir_p(File.join('.git-hooks', 'pre_commit')) - echo(hook, File.join('.git-hooks', 'pre_commit', 'fake_hook.rb')) + echo(hook, File.join('.git-hooks', 'pre_commit', 'no_invalid_gemfile_hook.rb')) Overcommit::Utils.with_environment 'OVERCOMMIT_NO_VERIFY' => '1' do example.run end end end - end - - subject { shell(%w[git commit --allow-empty -m Test]) } - context 'when configuration specifies the gemfile' do - let(:config) { "gemfile: .overcommit_gems.rb\n" + super() } + subject { shell(%w[git commit --allow-empty -m Test]) } - it 'runs the hook successfully' do - subject.status.should == 0 - end - end + context 'when configuration explicitly sets the gemfile to false' do + let(:config) { "gemfile: false\n" + super() } - context 'when configuration does not specify the gemfile' do - it 'fails to run the hook' do - subject.status.should_not == 0 + it 'runs the hook successfully' do + subject.status.should == 0 + end end end end diff --git a/template-dir/hooks/commit-msg b/template-dir/hooks/commit-msg index 377c892b..87ffeb58 100755 --- a/template-dir/hooks/commit-msg +++ b/template-dir/hooks/commit-msg @@ -27,7 +27,7 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +File.read('.overcommit.yml') =~ /gemfile: (?:false|['"]?(.*)['"]?)/ gemfile = Regexp.last_match(1) if gemfile diff --git a/template-dir/hooks/overcommit-hook b/template-dir/hooks/overcommit-hook index 377c892b..87ffeb58 100755 --- a/template-dir/hooks/overcommit-hook +++ b/template-dir/hooks/overcommit-hook @@ -27,7 +27,7 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +File.read('.overcommit.yml') =~ /gemfile: (?:false|['"]?(.*)['"]?)/ gemfile = Regexp.last_match(1) if gemfile diff --git a/template-dir/hooks/post-checkout b/template-dir/hooks/post-checkout index 377c892b..87ffeb58 100755 --- a/template-dir/hooks/post-checkout +++ b/template-dir/hooks/post-checkout @@ -27,7 +27,7 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +File.read('.overcommit.yml') =~ /gemfile: (?:false|['"]?(.*)['"]?)/ gemfile = Regexp.last_match(1) if gemfile diff --git a/template-dir/hooks/post-commit b/template-dir/hooks/post-commit index 377c892b..87ffeb58 100755 --- a/template-dir/hooks/post-commit +++ b/template-dir/hooks/post-commit @@ -27,7 +27,7 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +File.read('.overcommit.yml') =~ /gemfile: (?:false|['"]?(.*)['"]?)/ gemfile = Regexp.last_match(1) if gemfile diff --git a/template-dir/hooks/post-merge b/template-dir/hooks/post-merge index 377c892b..87ffeb58 100755 --- a/template-dir/hooks/post-merge +++ b/template-dir/hooks/post-merge @@ -27,7 +27,7 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +File.read('.overcommit.yml') =~ /gemfile: (?:false|['"]?(.*)['"]?)/ gemfile = Regexp.last_match(1) if gemfile diff --git a/template-dir/hooks/post-rewrite b/template-dir/hooks/post-rewrite index 377c892b..87ffeb58 100755 --- a/template-dir/hooks/post-rewrite +++ b/template-dir/hooks/post-rewrite @@ -27,7 +27,7 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +File.read('.overcommit.yml') =~ /gemfile: (?:false|['"]?(.*)['"]?)/ gemfile = Regexp.last_match(1) if gemfile diff --git a/template-dir/hooks/pre-commit b/template-dir/hooks/pre-commit index 377c892b..87ffeb58 100755 --- a/template-dir/hooks/pre-commit +++ b/template-dir/hooks/pre-commit @@ -27,7 +27,7 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +File.read('.overcommit.yml') =~ /gemfile: (?:false|['"]?(.*)['"]?)/ gemfile = Regexp.last_match(1) if gemfile diff --git a/template-dir/hooks/pre-push b/template-dir/hooks/pre-push index 377c892b..87ffeb58 100755 --- a/template-dir/hooks/pre-push +++ b/template-dir/hooks/pre-push @@ -27,7 +27,7 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +File.read('.overcommit.yml') =~ /gemfile: (?:false|['"]?(.*)['"]?)/ gemfile = Regexp.last_match(1) if gemfile diff --git a/template-dir/hooks/pre-rebase b/template-dir/hooks/pre-rebase index 377c892b..87ffeb58 100755 --- a/template-dir/hooks/pre-rebase +++ b/template-dir/hooks/pre-rebase @@ -27,7 +27,7 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +File.read('.overcommit.yml') =~ /gemfile: (?:false|['"]?(.*)['"]?)/ gemfile = Regexp.last_match(1) if gemfile diff --git a/template-dir/hooks/prepare-commit-msg b/template-dir/hooks/prepare-commit-msg index 377c892b..87ffeb58 100755 --- a/template-dir/hooks/prepare-commit-msg +++ b/template-dir/hooks/prepare-commit-msg @@ -27,7 +27,7 @@ if hook_type == 'overcommit-hook' end # Check if Overcommit should invoke a Bundler context for loading gems -config = File.read('.overcommit.yml') =~ /gemfile: ['"]?(.*)['"]?/ +File.read('.overcommit.yml') =~ /gemfile: (?:false|['"]?(.*)['"]?)/ gemfile = Regexp.last_match(1) if gemfile From 88bee0845bff4142642253f89aabaa9fd318465b Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Sun, 16 Feb 2025 13:08:25 -0800 Subject: [PATCH 40/43] Cut version 0.67.0 (#864) --- CHANGELOG.md | 4 ++++ lib/overcommit/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d82b5b50..8b99417a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Overcommit Changelog +## 0.67.0 + +* Fix bug introduced in 0.65.0 that prevented `gemfile: false` from working correctly + ## 0.66.0 * Add `--diff` CLI option for running pre-commit hooks against only changed files diff --git a/lib/overcommit/version.rb b/lib/overcommit/version.rb index c1091e52..803dbbfc 100644 --- a/lib/overcommit/version.rb +++ b/lib/overcommit/version.rb @@ -2,5 +2,5 @@ # Defines the gem version. module Overcommit - VERSION = '0.66.0' + VERSION = '0.67.0' end From 9f142c2a4f66a63e27ae2e5c64f507fc36f3807b Mon Sep 17 00:00:00 2001 From: Pedro Fayolle Date: Thu, 20 Feb 2025 03:17:00 +0900 Subject: [PATCH 41/43] Add note about unsupported YAML features in `gemfile:` line in default.yml (#865) Related to #863 and [this comment](https://github.com/sds/overcommit/issues/862#issuecomment-2641924147): > Having a similar problem since we had this line in our `.overcommit.yml`: > > ```yaml > gemfile: Gemfile # enforce bundled version of overcommit > ``` > > And now overcommit doesn't strip out the inline comment, resulting in this weird looking error message: > > ``` > Problem loading 'Gemfile # enforce bundled version of overcommit': /path/to/project/Gemfile # enforce bundled version of overcommit not found > ``` I think adding support for comments in the `gemfile:` regexp is likely overkill and may still not be enough when the next person tries to use yet another YAML feature in that line, but perhaps this little warning would help someone else avoid tripping. --- config/default.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/default.yml b/config/default.yml index 70ae0b2d..ba8af533 100644 --- a/config/default.yml +++ b/config/default.yml @@ -32,6 +32,10 @@ # your repository, and then set the `gemfile` option below to the name you gave # the file. # (Generate lock file by running `bundle install --gemfile=.overcommit_gems.rb`) +# +# NOTE: the following line will be parsed by a regexp rather than a proper YAML +# parser, so avoid any values other than false or a string, and don't use inline +# comments gemfile: false # Where to store hook plugins specific to a repository. These are loaded in From 11ef06b6eb3398e5891e8d9d2698c4edf2318f1f Mon Sep 17 00:00:00 2001 From: raul Date: Mon, 3 Mar 2025 07:22:25 +0100 Subject: [PATCH 42/43] adds 'set' requirements to diff hook context. (#866) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Running `overcommit` with the `--diff` flag results in errors for version `0.67.0`. ```sh bundle exec overcommit --diff HEAD ``` It results on the following: ```ruby Running pre-commit hooks Check for case-insensitivity conflicts................[CaseConflicts] FAILED Hook raised unexpected error uninitialized constant Overcommit::Hook::PreCommit::CaseConflicts::Set repo_files = Set.new(applicable_files) ^^^ .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook/pre_commit/case_conflicts.rb:8:in `run' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook/base.rb:47:in `block in run_and_transform' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/utils.rb:260:in `with_environment' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook/base.rb:47:in `run_and_transform' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook_runner.rb:162:in `run_hook' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook_runner.rb:98:in `block in consume' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook_runner.rb:94:in `loop' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook_runner.rb:94:in `consume' Analyze with RuboCop........................................[RuboCop] FAILED Hook raised unexpected error uninitialized constant Overcommit::GitRepo::Set lines = Set.new ^^^ .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/git_repo.rb:69:in `extract_modified_lines' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook_context/diff.rb:17:in `modified_lines_in_file' /nix/store/0sj7d3r1kf95f27028j93j0sx3v6p1kw-ruby-3.1.6/lib/ruby/3.1.0/forwardable.rb:238:in `modified_lines_in_file' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/message_processor.rb:145:in `message_on_modified_line?' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/message_processor.rb:138:in `block in remove_ignored_messages' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/message_processor.rb:138:in `select' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/message_processor.rb:138:in `remove_ignored_messages' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/message_processor.rb:45:in `handle_modified_lines' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/message_processor.rb:39:in `hook_result' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook/base.rb:263:in `process_hook_return_value' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook/base.rb:48:in `run_and_transform' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook_runner.rb:162:in `run_hook' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook_runner.rb:98:in `block in consume' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook_runner.rb:94:in `loop' .bundle/ruby/3.1.0/gems/overcommit-0.67.0/lib/overcommit/hook_runner.rb:94:in `consume' ✗ One or more pre-commit hooks failed ``` The problems are fixed once `set` is required in the context that the sub command is run. `run_all.rb` also requires `set` where the module is [defined](https://github.com/sds/overcommit/blob/main/lib/overcommit/hook_context/run_all.rb#L3). --- lib/overcommit/hook_context/diff.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/overcommit/hook_context/diff.rb b/lib/overcommit/hook_context/diff.rb index 0c4b97e0..3e9aa568 100644 --- a/lib/overcommit/hook_context/diff.rb +++ b/lib/overcommit/hook_context/diff.rb @@ -2,6 +2,8 @@ require 'overcommit/git_repo' +require 'set' + module Overcommit::HookContext # Simulates a pre-commit context based on the diff with another git ref. # From 46c303377c495b1455531218f195c61243a61655 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Sun, 2 Mar 2025 22:23:44 -0800 Subject: [PATCH 43/43] Cut version 0.67.1 --- CHANGELOG.md | 4 ++++ lib/overcommit/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b99417a..ad1cb477 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Overcommit Changelog +## 0.67.1 + +* Fix `set` gem dependency error when running with `--diff` flag + ## 0.67.0 * Fix bug introduced in 0.65.0 that prevented `gemfile: false` from working correctly diff --git a/lib/overcommit/version.rb b/lib/overcommit/version.rb index 803dbbfc..872c5327 100644 --- a/lib/overcommit/version.rb +++ b/lib/overcommit/version.rb @@ -2,5 +2,5 @@ # Defines the gem version. module Overcommit - VERSION = '0.67.0' + VERSION = '0.67.1' end