git-hooks 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cdc0af42b64037b04523c40d8d46608f9c290165
4
- data.tar.gz: 6f61b8bc2caa7870e2313c69b8f0e5871e2b97d2
3
+ metadata.gz: 75855100ba5dd50b3b7f661a2ac7d812bd192fae
4
+ data.tar.gz: 1fd3d8ffd9087ddbb106fc807164c08008a25818
5
5
  SHA512:
6
- metadata.gz: 9df358874679ddeeda3a1543cc07e5061ed6b7fdbba18f56784bd96d7aa2457bb5390a77c9ff3522c352f5e6a40c9b477ff87b3d7fdbf38b3236fcba3e7bd91d
7
- data.tar.gz: a934f38495f94adb396a399f91d4f4c557663a62d2f7e650f9857f22f0cb48a45c27f570226b04751dda1a66340545fea0a7daa56b1b9576abb39bccccbceb86
6
+ metadata.gz: 6d6dbb403c9cdd29e97ebe8882fcb45e312adcaa2cc1f917b209b23aa7fd7aabeeaa6893799cc7df723dc84927ee9b8153af34280ab02dcedd29846231e5baad
7
+ data.tar.gz: 2bd1ab2bce9efbfe3a84302fea4d73fc657e95195ed20a03dfad7b8b9f5f4026a567e49afe999031c23a2d43598af8737fe1d76cf04a307fedd94929e94e11db
data/.gitignore CHANGED
@@ -20,3 +20,4 @@ tmp
20
20
  *.o
21
21
  *.a
22
22
  mkmf.log
23
+ coverage
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - '2.0.0'
4
+ - '2.1.0'
5
+ script: bundle exec rspec
data/CHANGELOG ADDED
@@ -0,0 +1,24 @@
1
+ 0.2.0
2
+
3
+ * Add whitespace validation (by @rranelli)
4
+ * Handle Errno::EEXIST on hook installation
5
+ * Add whitespace validation (by @rranelli)
6
+ * Add all the bagdes
7
+ * Add PreCommit::PreventDebugger
8
+
9
+ 0.1.0
10
+
11
+ * Add configuration command on cli
12
+
13
+ 0.1.0.pre
14
+
15
+ * Add tests for each pre-commit
16
+ * Include configurations
17
+ * Fix rubocop offences
18
+ * Rewrite pre-commits to extract RspecExecutor and Git
19
+ * Add pre-commit hook existence validator
20
+ * Add .git_hooks.yml to configure hooks
21
+
22
+ 0.0.2
23
+
24
+ * Rubocop, Prevent master and Rspec pre-commits
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
+ [![Version](http://allthebadges.io/stupied4ever/git-hooks/badge_fury.png)](http://allthebadges.io/stupied4ever/git-hooks/badge_fury)
2
+ [![Dependencies](http://allthebadges.io/stupied4ever/git-hooks/gemnasium.png)](http://allthebadges.io/stupied4ever/git-hooks/gemnasium)
3
+ [![Build Status](http://allthebadges.io/stupied4ever/git-hooks/travis.png)](http://allthebadges.io/stupied4ever/git-hooks/travis)
4
+ [![Coverage](http://allthebadges.io/stupied4ever/git-hooks/coveralls.png)](http://allthebadges.io/stupied4ever/git-hooks/coveralls)
5
+ [![Code Climate](http://allthebadges.io/stupied4ever/git-hooks/code_climate.png)](http://allthebadges.io/stupied4ever/git-hooks/code_climate)
6
+
1
7
  # GitHooks
2
8
 
3
- Some usefull ruby git hooks.
9
+ Some usefull git hooks, it's written on ruby but can be used for other languages.
4
10
 
5
11
  ## Installation
6
12
 
@@ -19,36 +25,36 @@ Or install it yourself as:
19
25
  ## Usage
20
26
  ### Install git_hooks on project.
21
27
 
22
- ```
23
- $ git_hooks install pre-commit
28
+ ```bash
29
+ $ git_hooks install pre-commit [--force]
24
30
  ```
25
31
 
26
32
  ### Create configuration file
27
33
 
28
- Create a ```.git_hooks.yml``` on project root.
34
+ Create a `.git_hooks.yml` on project root.
29
35
 
30
36
  ```bash
31
- $ git_hooks configure
37
+ $ git_hooks init
32
38
  ```
33
39
 
34
-
35
40
  By now you will find only some simple hooks to:
36
41
 
37
42
  - Prevent commit on master.
38
43
  - Prevent commit with rubocop offences.
39
44
  - prevent commit with broken rspec tests.
45
+ - prevent commit with debugger
40
46
 
41
47
  ### Ensure hooks existence
42
48
 
43
- To ensure that hooks exists on ```.git/hooks```, include on your application
44
- start up (probably ```config/environments/development.rb``` or
45
- ```config/environments/test.rb```)
49
+ To ensure that hooks exists on `.git/hooks`, include on your application
50
+ start up (probably `config/environments/development.rb` or
51
+ `config/environments/test.rb`)
46
52
 
47
53
  ```ruby
48
54
  GitHooks.validate_hooks!
49
55
  ```
50
56
 
51
- This will force ```git_hooks``` installation before your application start.
57
+ This will force `git_hooks` installation before your application start.
52
58
 
53
59
  ## Contributing
54
60
 
data/git-hooks.gemspec CHANGED
@@ -24,5 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'equalizer', '~> 0.0.9'
25
25
 
26
26
  spec.add_development_dependency 'bundler', '~> 1.6'
27
+ spec.add_development_dependency 'coveralls', '>= 0.7.0'
27
28
  spec.add_development_dependency 'rspec', '~> 3.0'
29
+ spec.add_development_dependency 'pry'
28
30
  end
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  pre_commits:
3
+ - GitHooks::PreCommit::PreventDebugger
3
4
  - GitHooks::PreCommit::PreventMaster
4
5
  - GitHooks::PreCommit::Rubocop
5
6
  - GitHooks::PreCommit::Rspec
data/lib/git-hooks.rb CHANGED
@@ -6,8 +6,10 @@ require 'git'
6
6
  require_relative 'git_hooks/configurations'
7
7
  require_relative 'git_hooks/git'
8
8
  require_relative 'git_hooks/config_file'
9
+ require_relative 'git_hooks/installer'
9
10
  require_relative 'git_hooks/rspec_executor'
10
11
  require_relative 'git_hooks/rubocop_validator'
12
+ require_relative 'git_hooks/trailing_whitespace_validator'
11
13
 
12
14
  require_relative 'git_hooks/exceptions'
13
15
  require_relative 'git_hooks/pre_commit'
@@ -30,19 +32,7 @@ module GitHooks
30
32
  end
31
33
 
32
34
  def base_path
33
- File.absolute_path(File.join(File.expand_path(__FILE__), '..', '..'))
34
- end
35
-
36
- def hook_installed?(hook)
37
- hook_file = File.join(Dir.pwd, '.git', 'hooks', hook)
38
- real_hook_file = File.join(base_path, HOOK_SAMPLE_FILE)
39
-
40
- return false unless File.symlink?(hook_file)
41
- File.realpath(hook_file) == real_hook_file
42
- end
43
-
44
- def install_hook(hook)
45
- File.symlink(real_hook_template_path, ".git/hooks/#{hook}")
35
+ File.expand_path('../..', __FILE__)
46
36
  end
47
37
 
48
38
  def validate_hooks!
@@ -52,8 +42,8 @@ module GitHooks
52
42
  private
53
43
 
54
44
  def valid_pre_commit_hook?
55
- return true if configurations.pre_commits.empty?
56
- hook_installed?(PRE_COMMIT)
45
+ configurations.pre_commits.empty? ||
46
+ Installer.new(PRE_COMMIT).installed?
57
47
  end
58
48
 
59
49
  def real_hook_template_path
data/lib/git_hooks/cli.rb CHANGED
@@ -5,22 +5,23 @@ require_relative '../git-hooks'
5
5
  module GitHooks
6
6
  class CLI < Thor
7
7
  desc 'install HOOK', 'Install some hook'
8
+ option :force, type: :boolean
8
9
  long_desc <<-LONGDESC
9
10
  Install some hook:
10
11
 
11
- > $ git_hooks install pre-commit
12
+ $ git_hooks install pre-commit
12
13
  LONGDESC
13
14
  def install(hook)
14
- GitHooks.install_hook(hook)
15
+ GitHooks::Installer.new(hook).install(options[:force])
15
16
  end
16
17
 
17
- desc 'Create configuration file', 'Create a configuration file'
18
+ desc 'Init GitHooks on current folder', 'Create a configuration file'
18
19
  long_desc <<-LONGDESC
19
20
  Create a configuration file base on git_hooks.yml.examle
20
21
 
21
- > $ git_hooks configure
22
+ $ git_hooks init
22
23
  LONGDESC
23
- def configure
24
+ def init
24
25
  example_file = File.expand_path(
25
26
  '../../../git_hooks.yml.example', __FILE__
26
27
  )
@@ -7,7 +7,7 @@ module GitHooks
7
7
  end
8
8
 
9
9
  def pre_commits
10
- content['pre_commits'] || []
10
+ content.fetch('pre_commits') { [] }
11
11
  end
12
12
 
13
13
  def content
@@ -1,20 +1,29 @@
1
1
  require 'forwardable'
2
2
 
3
3
  module GitHooks
4
- class Configurations
4
+ class Configurations < SimpleDelegator
5
5
  include Equalizer.new(:config_file, :git_repository)
6
- extend Forwardable
7
6
 
8
7
  attr_reader :config_file, :git_repository
9
8
 
10
- def_delegator :config_file, :pre_commits
11
-
12
9
  def initialize(
13
- config_file: ConfigFile.new('.git_hooks.yml'),
14
- git_repository: Git.new('.')
10
+ config_file: default_config_file,
11
+ git_repository: default_git_repository
15
12
  )
16
13
  @config_file = config_file
17
14
  @git_repository = git_repository
15
+
16
+ super(config_file)
17
+ end
18
+
19
+ private
20
+
21
+ def default_config_file
22
+ ConfigFile.new('.git_hooks.yml')
23
+ end
24
+
25
+ def default_git_repository
26
+ Git.new('.')
18
27
  end
19
28
  end
20
29
  end
@@ -1 +1,2 @@
1
1
  require_relative 'exceptions/missing_hooks'
2
+ require_relative 'exceptions/unknown_hook_present'
@@ -0,0 +1,9 @@
1
+ module GitHooks
2
+ module Exceptions
3
+ class UnknowHookPresent < RuntimeError
4
+ def initialize(hook)
5
+ super "There is a unknown #{hook} hook. If you are sure, use --force."
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,33 @@
1
+ module GitHooks
2
+ class Installer
3
+ attr_accessor :hook
4
+
5
+ HOOK_SAMPLE_FILE = 'hook.sample'
6
+
7
+ def initialize(hook)
8
+ @hook = hook
9
+ end
10
+
11
+ def install(force = false)
12
+ return true if installed?
13
+
14
+ FileUtils.symlink(
15
+ hook_template_path, File.join('.git', 'hooks', hook), force: force
16
+ )
17
+ rescue Errno::EEXIST
18
+ raise GitHooks::Exceptions::UnknowHookPresent, hook
19
+ end
20
+
21
+ def installed?
22
+ hook_file = File.join(Dir.pwd, '.git', 'hooks', hook)
23
+
24
+ File.symlink?(hook_file) && File.realpath(hook_file) == hook_template_path
25
+ end
26
+
27
+ private
28
+
29
+ def hook_template_path
30
+ File.join(GitHooks.base_path, HOOK_SAMPLE_FILE)
31
+ end
32
+ end
33
+ end
@@ -1,6 +1,8 @@
1
+ require_relative 'pre_commit/prevent_debugger'
1
2
  require_relative 'pre_commit/prevent_master'
2
3
  require_relative 'pre_commit/rspec'
3
4
  require_relative 'pre_commit/rubocop'
5
+ require_relative 'pre_commit/trailing_whitespace'
4
6
 
5
7
  module GitHooks
6
8
  module PreCommit
@@ -0,0 +1,36 @@
1
+ module GitHooks
2
+ module PreCommit
3
+ class PreventDebugger
4
+ attr_reader :git_repository
5
+
6
+ def self.validate
7
+ new(GitHooks.configurations.git_repository).validate
8
+ end
9
+
10
+ def initialize(git_repository)
11
+ @git_repository = git_repository
12
+ end
13
+
14
+ def validate
15
+ abort 'Prevented to commit with debugger' if any_debugger?
16
+ end
17
+
18
+ private
19
+
20
+ def any_debugger?
21
+ git_repository.added_or_modified.any? do |file_name|
22
+ File.read(file_name) =~ debugger_regex
23
+ end
24
+ end
25
+
26
+ def debugger_regex
27
+ Regexp.union(
28
+ %w(
29
+ binding.pry binding.remote_pry
30
+ save_and_open_page debugger
31
+ )
32
+ )
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,32 @@
1
+ module GitHooks
2
+ module PreCommit
3
+ class TrailingWhitespace
4
+ attr_reader :git_repository, :trailing_whitespace_validator
5
+
6
+ def self.validate
7
+ new(GitHooks.git_repository, TrailingWhitespaceValidator.new).validate
8
+ end
9
+
10
+ def initialize(git_repository, trailing_whitespace_validator)
11
+ @git_repository = git_repository
12
+ @trailing_whitespace_validator = trailing_whitespace_validator
13
+ end
14
+
15
+ def validate
16
+ abort 'Check presence of trailling space' if offences?
17
+ end
18
+
19
+ private
20
+
21
+ def changed_files
22
+ git_repository
23
+ .added_or_modified
24
+ .select { |file| File.extname(file) == '.rb' }
25
+ end
26
+
27
+ def offences?
28
+ trailing_whitespace_validator.errors?(changed_files)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,12 @@
1
+ module GitHooks
2
+ class TrailingWhitespaceValidator
3
+ def errors?(files)
4
+ files
5
+ .map { |file| File.open(file) }
6
+ .map(&:read)
7
+ .grep(/ +$/)
8
+ .compact
9
+ .any?
10
+ end
11
+ end
12
+ end
@@ -1,3 +1,3 @@
1
1
  module GitHooks
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -0,0 +1,4 @@
1
+ ---
2
+ pre_commits:
3
+ - foo
4
+ - bar
@@ -2,28 +2,24 @@ module GitHooks
2
2
  describe ConfigFile do
3
3
  subject(:config) { described_class.new(path) }
4
4
 
5
- let(:path) { '' }
5
+ let(:path) { 'some-not-existent-file' }
6
6
  let(:content) { { 'pre_commits' => pre_commits } }
7
7
  let(:pre_commits) { %w(foo bar) }
8
8
 
9
- context 'when the given file does not exists' do
10
- subject(:config) { -> { described_class.new(path) } }
11
-
12
- let(:path) { 'some-not-existent-file' }
13
-
14
- it { is_expected.to_not raise_error }
15
- end
16
-
17
9
  describe '#pre_commits' do
18
10
  subject { config.pre_commits }
19
11
 
20
- before do
21
- allow(YAML).to receive(:load_file).and_return(content)
22
- end
12
+ let(:path) { fixture_path('git_hooks.yml') }
23
13
 
24
14
  it 'has the pre commits specified on hook file' do
25
15
  is_expected.to eq(%w(foo bar))
26
16
  end
17
+
18
+ context 'when the given file does not exist' do
19
+ let(:path) { 'some-not-existent-file' }
20
+
21
+ it { is_expected.to eq([]) }
22
+ end
27
23
  end
28
24
  end
29
25
  end
@@ -0,0 +1,107 @@
1
+ describe GitHooks::Installer do
2
+ subject(:installer) { described_class.new(hook) }
3
+
4
+ let(:hook) { 'pre-commit' }
5
+
6
+ let(:hook_real_path) do
7
+ File.join(GitHooks.base_path, 'hook.sample')
8
+ end
9
+
10
+ let(:absolute_path) do
11
+ File.join(GitHooks.base_path, '.git', 'hooks', hook)
12
+ end
13
+
14
+ let(:git_hook_path) { ".git/hooks/#{hook}" }
15
+
16
+ describe '.install' do
17
+ subject(:install) { installer.install }
18
+
19
+ before do
20
+ allow(installer).to receive(:installed?).and_return(false)
21
+ allow(FileUtils).to receive(:symlink).and_return(true)
22
+ end
23
+
24
+ it 'creates symlink' do
25
+ expect(FileUtils)
26
+ .to receive(:symlink)
27
+ .with(hook_real_path, git_hook_path, force: false)
28
+
29
+ install
30
+ end
31
+
32
+ it { is_expected.to be_truthy }
33
+
34
+ context 'when there is a unknown hook' do
35
+ before do
36
+ allow(FileUtils).to receive(:symlink).and_raise(Errno::EEXIST)
37
+ end
38
+
39
+ it 'raises an error' do
40
+ expect { install }.to raise_error(
41
+ GitHooks::Exceptions::UnknowHookPresent
42
+ )
43
+ end
44
+ end
45
+
46
+ context 'when there is a unknown hook but I want to force installation' do
47
+ subject(:install) { installer.install true }
48
+
49
+ it 'creates symlink with force option' do
50
+ expect(FileUtils)
51
+ .to receive(:symlink)
52
+ .with(hook_real_path, git_hook_path, force: true)
53
+
54
+ install
55
+ end
56
+
57
+ it { is_expected.to be_truthy }
58
+ end
59
+
60
+ context 'when hook is already installed' do
61
+ before do
62
+ allow(installer).to receive(:installed?).and_return(true)
63
+ end
64
+
65
+ it 'does not create symlink' do
66
+ expect(FileUtils)
67
+ .to_not receive(:symlink)
68
+
69
+ install
70
+ end
71
+
72
+ it { is_expected.to be_truthy }
73
+ end
74
+ end
75
+
76
+ describe '.installed?' do
77
+ subject(:installed?) { installer.installed? }
78
+
79
+ let(:symlink?) { true }
80
+
81
+ before do
82
+ allow(File).to receive(:symlink?).and_return(symlink?)
83
+ allow(File).to receive(:realpath).and_return(hook_real_path)
84
+ end
85
+
86
+ it 'validates file is a symlink' do
87
+ expect(File).to receive(:symlink?).with(absolute_path)
88
+ installed?
89
+ end
90
+
91
+ it { is_expected.to be_truthy }
92
+
93
+ context 'when file is not a symlink' do
94
+ let(:symlink?) { false }
95
+
96
+ it { is_expected.to be_falsy }
97
+ end
98
+
99
+ context 'when is not the GitHooks file' do
100
+ before do
101
+ allow(File).to receive(:realpath).and_return('/tmp/foo')
102
+ end
103
+
104
+ it { is_expected.to be_falsy }
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,72 @@
1
+ module GitHooks
2
+ module PreCommit
3
+ describe PreventDebugger do
4
+ subject(:prevent_debugger) { described_class.new git_repository }
5
+
6
+ let(:git_repository) do
7
+ instance_double(GitHooks::Git, added_or_modified: files)
8
+ end
9
+
10
+ let(:files) { ['some_file.rb'] }
11
+
12
+ describe '#validate' do
13
+ subject(:validate) { -> { prevent_debugger.validate } }
14
+
15
+ let(:file_content) { 'this is a big file without' }
16
+
17
+ before do
18
+ allow(File)
19
+ .to receive(:read)
20
+ .with(files.first)
21
+ .and_return(file_content)
22
+
23
+ allow($stderr).to receive(:write).and_return('')
24
+ end
25
+
26
+ it { is_expected.to_not raise_error }
27
+
28
+ %w(
29
+ binding.pry
30
+ binding.remote_pry
31
+ save_and_open_page
32
+ debugger
33
+ ).each do |debugger_string|
34
+ context "when has #{debugger_string}" do
35
+ let(:file_content) { "this is a big file with #{debugger_string}" }
36
+
37
+ it { is_expected.to raise_error(SystemExit) }
38
+ end
39
+ end
40
+ end
41
+
42
+ describe '.validate' do
43
+ subject(:validate) { described_class.validate }
44
+
45
+ let(:prevent_debugger) { instance_double(PreventDebugger) }
46
+ let(:git) { instance_double(GitHooks::Git) }
47
+
48
+ let(:configurations) do
49
+ instance_double(Configurations, git_repository: git)
50
+ end
51
+
52
+ before do
53
+ allow(GitHooks).to receive(:configurations).and_return(configurations)
54
+ allow(described_class).to receive(:new).and_return(prevent_debugger)
55
+ allow(prevent_debugger).to receive(:validate).and_return(nil)
56
+ end
57
+
58
+ it 'creates object with GitHooks.git_repository' do
59
+ expect(PreventDebugger).to receive(:new).with(git)
60
+
61
+ validate
62
+ end
63
+
64
+ it 'validates' do
65
+ expect(prevent_debugger).to receive(:validate)
66
+
67
+ validate
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,82 @@
1
+ module GitHooks
2
+ module PreCommit
3
+ describe TrailingWhitespace do
4
+ subject(:whitespace) do
5
+ described_class.new(git_repository, whitespace_validator)
6
+ end
7
+
8
+ let(:git_repository) do
9
+ instance_double(GitHooks::Git, added_or_modified: added_or_modified)
10
+ end
11
+
12
+ let(:whitespace_validator) do
13
+ instance_double(GitHooks::TrailingWhitespaceValidator, errors?: errors?)
14
+ end
15
+
16
+ let(:added_or_modified) { [] }
17
+ let(:errors?) { false }
18
+
19
+ describe '#validate' do
20
+ subject(:validate) { whitespace.validate }
21
+
22
+ let(:added_or_modified) { [ruby_file, 'foo.txt'] }
23
+ let(:ruby_file) { 'foo.rb' }
24
+
25
+ it 'only validates ruby files' do
26
+ expect(whitespace_validator)
27
+ .to receive(:errors?)
28
+ .with([ruby_file])
29
+ validate
30
+ end
31
+
32
+ context 'with errors' do
33
+ let(:errors?) { true }
34
+
35
+ before do
36
+ allow($stderr).to receive(:write).and_return('')
37
+ end
38
+
39
+ it { expect(-> { validate }).to raise_error(SystemExit) }
40
+ end
41
+
42
+ context 'without errors' do
43
+ let(:errors?) { false }
44
+
45
+ it { expect(-> { validate }).to_not raise_error }
46
+ end
47
+ end
48
+
49
+ describe '.validate' do
50
+ subject(:validate) { described_class.validate }
51
+
52
+ let(:whitespace) { instance_double(TrailingWhitespace) }
53
+ let(:git) { instance_double(Git) }
54
+ let(:whitespace_validator) do
55
+ instance_double(TrailingWhitespaceValidator)
56
+ end
57
+
58
+ before do
59
+ allow(described_class).to receive(:new).and_return(whitespace)
60
+ allow(whitespace).to receive(:validate).and_return(nil)
61
+
62
+ allow(GitHooks).to receive(:git_repository).and_return(git)
63
+ allow(TrailingWhitespaceValidator).to receive(:new)
64
+ .and_return(whitespace_validator)
65
+ end
66
+
67
+ it 'creates object with GitHooks.git_repository' do
68
+ expect(TrailingWhitespace).to receive(:new)
69
+ .with(git, whitespace_validator)
70
+
71
+ validate
72
+ end
73
+
74
+ it 'validates' do
75
+ expect(whitespace).to receive(:validate)
76
+
77
+ validate
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,39 @@
1
+ module GitHooks
2
+ describe TrailingSpaceValidator do
3
+ subject(:validator) { described_class.new }
4
+
5
+ let(:file_names) { %w(a.rb b.rb) }
6
+ let(:files) { [file] * 2 }
7
+ let(:file) { instance_double(File) }
8
+
9
+ before do
10
+ allow(File).to receive(:open).and_return(file)
11
+ allow(file).to receive(:read).and_return('I no have no whitespace!')
12
+ end
13
+
14
+ describe '#errors?' do
15
+ subject(:errors?) { validator.errors?(files) }
16
+
17
+ context 'with files' do
18
+ context 'when files has no offences' do
19
+
20
+ it { is_expected.to be_falsy }
21
+ end
22
+
23
+ context 'when some file has offences' do
24
+ before do
25
+ allow(file).to receive(:read).and_return('My text editor sucks ')
26
+ end
27
+
28
+ it { is_expected.to be_truthy }
29
+ end
30
+ end
31
+
32
+ context 'with empty files array' do
33
+ let(:files) { [] }
34
+
35
+ it { is_expected.to be_falsy }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -2,34 +2,39 @@ describe GitHooks do
2
2
  describe '#validate_hooks!' do
3
3
  subject { -> { described_class.validate_hooks! } }
4
4
 
5
- before { GitHooks.configurations = configs }
5
+ before do
6
+ allow(GitHooks::Installer)
7
+ .to receive(:new)
8
+ .with(GitHooks::PRE_COMMIT)
9
+ .and_return(installer)
6
10
 
7
- let(:configs) do
8
- instance_double(GitHooks::Configurations, pre_commits: pre_commits)
11
+ GitHooks.configurations = configs
9
12
  end
10
13
 
11
- let(:pre_commits) { [] }
14
+ let(:configs) do
15
+ GitHooks::Configurations.new(config_file: config_file)
16
+ end
12
17
 
13
- it { is_expected.to_not raise_error }
18
+ let(:config_file) do
19
+ GitHooks::ConfigFile.new(fixture_path('git_hooks.yml'))
20
+ end
14
21
 
15
- context 'with pre-commit hooks configured' do
16
- let(:pre_commits) { %w(foo bar) }
17
- let(:hook_installed?) { true }
22
+ let(:installed?) { true }
23
+ let(:installer) { instance_double(GitHooks::Installer) }
18
24
 
19
- before do
20
- allow(GitHooks).to receive(:hook_installed?).and_return(hook_installed?)
21
- end
25
+ before do
26
+ allow(installer).to receive(:installed?).and_return(installed?)
27
+ end
22
28
 
23
- it { is_expected.to_not raise_error }
29
+ it { is_expected.to_not raise_error }
24
30
 
25
- context 'but without pre-commit installed' do
26
- let(:hook_installed?) { false }
31
+ context 'but without pre-commit installed' do
32
+ let(:installed?) { false }
27
33
 
28
- let(:message) { 'Please install pre-commit hook.' }
34
+ let(:message) { 'Please install pre-commit hook.' }
29
35
 
30
- it do
31
- is_expected.to raise_error(GitHooks::Exceptions::MissingHook, message)
32
- end
36
+ it do
37
+ is_expected.to raise_error(GitHooks::Exceptions::MissingHook, message)
33
38
  end
34
39
  end
35
40
  end
@@ -49,26 +54,27 @@ describe GitHooks do
49
54
  describe '.configurations' do
50
55
  subject(:configurations) { described_class.configurations }
51
56
 
52
- before do
53
- GitHooks.configurations = nil
54
- allow(GitHooks::Configurations).to receive(:new).and_return(configs)
55
- end
57
+ before { GitHooks.configurations = nil }
56
58
 
57
59
  let(:configs) { instance_double(GitHooks::Configurations) }
58
60
 
59
61
  it 'creates with default params' do
60
- expect(GitHooks::Configurations).to receive(:new).with(no_args)
62
+ expect(GitHooks::Configurations)
63
+ .to receive(:new)
64
+ .with(no_args)
65
+ .and_return(configs)
61
66
 
62
67
  is_expected.to eq(configs)
63
68
  end
64
69
  end
65
70
 
66
71
  describe 'configurations=' do
67
- subject(:set_configurations) { described_class.configurations = configs }
72
+ subject(:set_configurations) { GitHooks.configurations = configs }
68
73
 
69
74
  let(:configs) { instance_double(GitHooks::Configurations) }
70
75
 
71
76
  before do
77
+ GitHooks.configurations = nil
72
78
  allow(GitHooks::Configurations).to receive(:new).and_return(nil)
73
79
  end
74
80
 
@@ -76,65 +82,6 @@ describe GitHooks do
76
82
  expect { set_configurations }.to change {
77
83
  GitHooks.configurations
78
84
  }.to(configs)
79
-
80
- is_expected.to eq(configs)
81
- end
82
- end
83
-
84
- describe '.install_hook' do
85
- subject(:install_hook) { described_class.install_hook(hook) }
86
-
87
- let(:hook) { 'pre-commit' }
88
- let(:hook_real_path) { File.join(GitHooks.base_path, 'hook.sample') }
89
- let(:git_hook_path) { ".git/hooks/#{hook}" }
90
-
91
- before do
92
- allow(File).to receive(:symlink).and_return(true)
93
- end
94
-
95
- it 'creates symlink' do
96
- expect(File)
97
- .to receive(:symlink)
98
- .with(hook_real_path, git_hook_path)
99
- install_hook
100
- end
101
-
102
- it { is_expected.to be_truthy }
103
- end
104
-
105
- describe '.hook_installed?' do
106
- subject(:installed?) { described_class.hook_installed?(hook) }
107
-
108
- let(:hook) { 'pre-commit' }
109
- let(:hook_real_path) { File.join(GitHooks.base_path, 'hook.sample') }
110
- let(:symlink?) { true }
111
-
112
- let(:absolute_path) { File.join(GitHooks.base_path, '.git', 'hooks', hook) }
113
-
114
- before do
115
- allow(File).to receive(:symlink?).and_return(symlink?)
116
- allow(File).to receive(:realpath).and_return(hook_real_path)
117
- end
118
-
119
- it 'validates file is a symlink' do
120
- expect(File).to receive(:symlink?).with(absolute_path)
121
- installed?
122
- end
123
-
124
- it { is_expected.to be_truthy }
125
-
126
- context 'when file is not a symlink' do
127
- let(:symlink?) { false }
128
-
129
- it { is_expected.to be_falsy }
130
- end
131
-
132
- context 'when is not the GitHooks file' do
133
- before do
134
- allow(File).to receive(:realpath).and_return('/tmp/foo')
135
- end
136
-
137
- it { is_expected.to be_falsy }
138
85
  end
139
86
  end
140
87
  end
data/spec/spec_helper.rb CHANGED
@@ -1 +1,15 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ Coveralls::SimpleCov::Formatter
7
+ ]
8
+ SimpleCov.start
9
+
1
10
  require_relative '../lib/git-hooks'
11
+
12
+ def fixture_path(filename)
13
+ return '' if filename == ''
14
+ File.join(File.absolute_path(File.dirname(__FILE__)), 'fixtures', filename)
15
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-hooks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafael da Silva Almeida
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-22 00:00:00.000000000 Z
11
+ date: 2014-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.6'
83
+ - !ruby/object:Gem::Dependency
84
+ name: coveralls
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 0.7.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 0.7.0
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rspec
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +108,20 @@ dependencies:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
110
  version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
97
125
  description: It stores git hooks and force git hooks installation.
98
126
  email:
99
127
  - eusou@rafaelalmeida.net
@@ -106,6 +134,8 @@ files:
106
134
  - ".rspec"
107
135
  - ".rubocop.yml"
108
136
  - ".rubocop_todo.yml"
137
+ - ".travis.yml"
138
+ - CHANGELOG
109
139
  - Gemfile
110
140
  - README.md
111
141
  - bin/git_hooks
@@ -118,22 +148,32 @@ files:
118
148
  - lib/git_hooks/configurations.rb
119
149
  - lib/git_hooks/exceptions.rb
120
150
  - lib/git_hooks/exceptions/missing_hooks.rb
151
+ - lib/git_hooks/exceptions/unknown_hook_present.rb
121
152
  - lib/git_hooks/git.rb
153
+ - lib/git_hooks/installer.rb
122
154
  - lib/git_hooks/pre_commit.rb
155
+ - lib/git_hooks/pre_commit/prevent_debugger.rb
123
156
  - lib/git_hooks/pre_commit/prevent_master.rb
124
157
  - lib/git_hooks/pre_commit/rspec.rb
125
158
  - lib/git_hooks/pre_commit/rubocop.rb
159
+ - lib/git_hooks/pre_commit/trailing_whitespace.rb
126
160
  - lib/git_hooks/rspec_executor.rb
127
161
  - lib/git_hooks/rubocop_validator.rb
162
+ - lib/git_hooks/trailing_whitespace_validator.rb
128
163
  - lib/git_hooks/version.rb
164
+ - spec/fixtures/git_hooks.yml
129
165
  - spec/git_hooks/config_file_spec.rb
130
166
  - spec/git_hooks/configurations_spec.rb
131
167
  - spec/git_hooks/git_spec.rb
168
+ - spec/git_hooks/installer_spec.rb
169
+ - spec/git_hooks/pre_commit/prevent_debugger_spec.rb
132
170
  - spec/git_hooks/pre_commit/prevent_master_spec.rb
133
171
  - spec/git_hooks/pre_commit/rspec_spec.rb
134
172
  - spec/git_hooks/pre_commit/rubocop_spec.rb
173
+ - spec/git_hooks/pre_commit/trailing_whitespace_spec.rb
135
174
  - spec/git_hooks/rspec_executor_spec.rb
136
175
  - spec/git_hooks/rubocop_validator_spec.rb
176
+ - spec/git_hooks/trailing_space_validator.rb
137
177
  - spec/git_hooks_spec.rb
138
178
  - spec/spec_helper.rb
139
179
  homepage: http://github.com/stupied4ever/ruby-git-hooks
@@ -161,14 +201,19 @@ signing_key:
161
201
  specification_version: 4
162
202
  summary: Help to keep git hooks organized.
163
203
  test_files:
204
+ - spec/fixtures/git_hooks.yml
164
205
  - spec/git_hooks/config_file_spec.rb
165
206
  - spec/git_hooks/configurations_spec.rb
166
207
  - spec/git_hooks/git_spec.rb
208
+ - spec/git_hooks/installer_spec.rb
209
+ - spec/git_hooks/pre_commit/prevent_debugger_spec.rb
167
210
  - spec/git_hooks/pre_commit/prevent_master_spec.rb
168
211
  - spec/git_hooks/pre_commit/rspec_spec.rb
169
212
  - spec/git_hooks/pre_commit/rubocop_spec.rb
213
+ - spec/git_hooks/pre_commit/trailing_whitespace_spec.rb
170
214
  - spec/git_hooks/rspec_executor_spec.rb
171
215
  - spec/git_hooks/rubocop_validator_spec.rb
216
+ - spec/git_hooks/trailing_space_validator.rb
172
217
  - spec/git_hooks_spec.rb
173
218
  - spec/spec_helper.rb
174
219
  has_rdoc: