git-hooks 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: