vagrant-ebcommon 0.4.0 → 0.4.1

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: 3a85966114c79554c3b98a5eb1e06683d1532ee3
4
- data.tar.gz: d4a1872890065308cf65607e2ccffb01ded1bc75
3
+ metadata.gz: 1bc5b754d67042d96898ef1f40e7ad07b0dbbd16
4
+ data.tar.gz: b22718188431c1a35287ac27212488f8cf455f79
5
5
  SHA512:
6
- metadata.gz: 95fa38ffa061cd37301cb2d7c4232ec6897a6879bd7271c37fcd65c6845359052642bcc4ffef2fcb2df004a6d0b9eab71873fdf13a8ec97e0362b445893a2b98
7
- data.tar.gz: 4c4cf51b1b63482a38278897ec93231b01551cc315a68357b3461c331dfbfc9b67ab643e71dac0820bc373d2cc22afd3bd4a4388f554754f0b31b32831bc59ac
6
+ metadata.gz: 046450f57fc434dc9a989f19f181264506efdc2d088dfa0fbb8931733de7f2d182dccabca5424f3663a4fd9df00d483223be788c2c2294bf250362f04b6c767f
7
+ data.tar.gz: e54c06a92d976a396d183ccb8193855fee1918dc55b468f0ea46ee6fb63f96562c520bdd84cef3cc6b123c7f4a08b149ad722b9494456ca52459fabc66fa4d46
data/Vagrantfile CHANGED
@@ -7,8 +7,12 @@ Vagrant.configure('2') do |config|
7
7
  config.vm.box_url = 'http://files.vagrantup.com/precise64.box'
8
8
 
9
9
  config.ebcommon.vpn_urls = [
10
- "https://docs.evbhome.com",
11
- "https://reviews.evbhome.com",
10
+ 'https://docs.evbhome.com',
11
+ 'https://reviews.evbhome.com',
12
+ ]
13
+ config.ebcommon.git_hook_root_dir = '/Volumes/eb_home/work'
14
+ config.ebcommon.git_hook_repos = [
15
+ 'vagrant-ebcommon',
12
16
  ]
13
17
 
14
18
  config.vm.provision 'puppet' do |puppet|
@@ -1,3 +1,4 @@
1
+ require 'fileutils'
1
2
  require 'timeout'
2
3
  require 'socket'
3
4
  require_relative '../errors'
@@ -37,6 +38,25 @@ module VagrantPlugins
37
38
  end
38
39
  end
39
40
 
41
+ # Copy over our git commit hooks
42
+ def setup_git_hooks
43
+ plugin_hooks_dir = File.expand_path File.join(File.dirname(__FILE__), '..', 'files', 'git_hooks')
44
+ git_hooks = Dir.entries(plugin_hooks_dir).select {|f| !File.directory? f}
45
+ if @ebcommon.git_hook_repos
46
+ @env[:ui].info 'Copying over git commit hooks...'
47
+ end
48
+
49
+ @ebcommon.git_hook_repos.each do |repo_path|
50
+ target_directory = File.join @ebcommon.git_hook_root_dir, repo_path, '.git', 'hooks'
51
+ if File.directory? target_directory
52
+ git_hooks.each do |hook|
53
+ source = File.join plugin_hooks_dir, hook
54
+ FileUtils.cp source, target_directory
55
+ end
56
+ end
57
+ end
58
+ end
59
+
40
60
  # In order to provision vagrant, we require you to be in the office or
41
61
  # connected to VPN. There are several packages that are hosted
42
62
  # internally and everything will fail miserably if you're not on our
@@ -139,6 +159,7 @@ module VagrantPlugins
139
159
  if provision_enabled
140
160
  ensure_vpn()
141
161
  setup_ssh_keys()
162
+ setup_git_hooks()
142
163
  generate_git_commiter_facts()
143
164
  end
144
165
  @app.call(env)
@@ -2,13 +2,19 @@ module VagrantPlugins
2
2
  module Ebcommon
3
3
  class Config < Vagrant.plugin(2, :config)
4
4
  attr_accessor :vpn_urls
5
+ attr_accessor :git_hook_repos
6
+ attr_accessor :git_hook_root_dir
5
7
 
6
8
  def initialize
7
9
  @vpn_urls = UNSET_VALUE
10
+ @git_hook_repos = UNSET_VALUE
11
+ @git_hook_root_dir = UNSET_VALUE
8
12
  end
9
13
 
10
14
  def finalize!
11
15
  @vpn_urls = nil if @vpn_urls == UNSET_VALUE
16
+ @git_hook_repos = nil if @git_hook_repos == UNSET_VALUE
17
+ @git_hook_root_dir = nil if @git_hook_root_dir == UNSET_VALUE
12
18
  end
13
19
 
14
20
  def validate(machine)
@@ -25,6 +31,14 @@ module VagrantPlugins
25
31
  }
26
32
  end
27
33
  end
34
+ if @git_hook_repos
35
+ if not @git_hook_repos.kind_of?(Array)
36
+ errors << '`git_hook_repos` must be a list of paths to copy hooks to'
37
+ end
38
+ end
39
+ if @git_hook_repos and not @git_hook_root_dir
40
+ errors << '`git_hook_root_dir` must be set to the directory containing directories in `git_hook_repos`'
41
+ end
28
42
  return { 'ebcommon' => errors }
29
43
  end
30
44
 
@@ -0,0 +1,49 @@
1
+ #!/bin/bash
2
+
3
+ # Our pre-commit hook for python repositories. This is distributed via our
4
+ # vagrant plugin: https://github.com/eventbrite/vagrant-ebcommon.
5
+
6
+ #
7
+ # Opt out of git hook via:
8
+ # $ git config --global eventbrite.ignore-hook true
9
+ #
10
+ if [ "$(git config --get --bool 'eventbrite.ignore-hook')" = "true" ]
11
+ then
12
+ exit 0
13
+ fi
14
+
15
+ # stashing in the middle of a merge or cherry-pick conflict removes the
16
+ # reference to the fact that we're merging or cherry-picking. merges and
17
+ # cherry-picks mean the commits have already been verified, so skip
18
+ # verification here that can cause issues.
19
+ if [ -f .git/MERGE_HEAD ]
20
+ then
21
+ echo "merge detected, skipping pre_commit verification"
22
+ exit 0
23
+ fi
24
+
25
+ if [ -f .git/CHERRY_PICK_HEAD ]
26
+ then
27
+ echo "cherry-pick detected, skipping pre_commit verification"
28
+ exit 0
29
+ fi
30
+
31
+ if [ -f .git/REVERT_HEAD ]
32
+ then
33
+ echo "revert detected, skipping pre_commit verification"
34
+ exit 0
35
+ fi
36
+
37
+ GIT_STASH=`git stash --keep-index`
38
+ NO_CHANGES="No local changes to save"
39
+
40
+ PYTHON_PRE_COMMIT_HOOK=.git/hooks/pre_commit_hook.py
41
+ FILES=`git diff --cached --name-only | xargs`
42
+ python $PYTHON_PRE_COMMIT_HOOK $FILES
43
+ exit_value=$?
44
+
45
+ if [ "$GIT_STASH" != "$NO_CHANGES" ]
46
+ then
47
+ git stash pop -q
48
+ fi
49
+ exit $exit_value
@@ -0,0 +1,68 @@
1
+ #!/bin/sh
2
+
3
+ # Our pre-push hook for python repositories. This is distributed via our
4
+ # vagrant plugin: https://github.com/eventbrite/vagrant-ebcommon.
5
+
6
+ # Called by "git push" after it has checked the remote status,
7
+ # but before anything has been pushed.
8
+ #
9
+ # If this script exits with a non-zero status nothing will be pushed.
10
+ #
11
+ # Steps to install, from the root directory of your repo...
12
+ # 1. Copy the file into your repo at `.git/hooks/pre-push`
13
+ # 2. Set executable permissions, run `chmod +x .git/hooks/pre-push`
14
+ # 3. Or, use `rake hooks:pre_push` to install
15
+ #
16
+ # Try a force push to master, you should get a message `*** [Policy] never force push...`
17
+ #
18
+ # The commands below will not be allowed...
19
+ # `git push --force origin master`
20
+ # `git push --delete origin master`
21
+ # `git push origin :master`
22
+ #
23
+ # Nor will a force push while on the master branch be allowed...
24
+ # `git co master`
25
+ # `git push --force origin`
26
+ #
27
+ # Requires git 1.8.2 or newer
28
+ #
29
+ # Git 1.8.2 release notes cover the new pre-push hook:
30
+ # <https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt>
31
+ #
32
+ # See Sample pre-push script:
33
+ # <https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample>
34
+ #
35
+ # Credit to: https://gist.github.com/pixelhandler/5718585
36
+
37
+ protected_branch='master'
38
+
39
+ policy='[Policy] Never force push or delete the '$protected_branch' branch! (Prevented with pre-push hook.)'
40
+
41
+ current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
42
+
43
+ push_command=$(ps -ocommand= -p $PPID)
44
+
45
+ is_destructive='force|delete|\-f'
46
+
47
+ will_remove_protected_branch=':'$protected_branch
48
+
49
+ do_exit(){
50
+ echo $policy
51
+ exit 1
52
+ }
53
+
54
+ if [[ $push_command =~ $is_destructive ]] && [ $current_branch = $protected_branch ]; then
55
+ do_exit
56
+ fi
57
+
58
+ if [[ $push_command =~ $is_destructive ]] && [[ $push_command =~ $protected_branch ]]; then
59
+ do_exit
60
+ fi
61
+
62
+ if [[ $push_command =~ $will_remove_protected_branch ]]; then
63
+ do_exit
64
+ fi
65
+
66
+ unset do_exit
67
+
68
+ exit 0
@@ -0,0 +1,118 @@
1
+ import re
2
+ import os
3
+ import subprocess
4
+ import sys
5
+
6
+ FILE_TYPE_PYTHON = 'py'
7
+ FILE_TYPE_JS = 'js'
8
+
9
+ FORBIDDEN = {
10
+ FILE_TYPE_PYTHON: [
11
+ 'import ipdb',
12
+ 'import pdb',
13
+ ],
14
+ FILE_TYPE_JS: [
15
+ 'console\.',
16
+ 'debugger',
17
+ ],
18
+ 'all': [
19
+ ],
20
+ }
21
+
22
+ # spaces in the flake8 strings are required to ensure we're only matching these
23
+ # exact strings. for example, flake8 calls out "unable to detect undefined
24
+ # names" when "from package import *" is used. without spaces around "undefined
25
+ # name" we would match this.
26
+ FLAKE8_WARNINGS = [
27
+ ' imported but unused',
28
+ ' assigned to but never used',
29
+ ]
30
+ FLAKE8_ERRORS = [
31
+ ' undefined name ',
32
+ 'SyntaxError',
33
+ ]
34
+
35
+ REJECT_TEMPLATE = """
36
+ %(filename)s:
37
+ %(indx)s: %(line)s
38
+
39
+ COMMIT REJECTED. Please correct the aforementioned mistake.
40
+ """
41
+
42
+
43
+ def flake8_file(filename):
44
+ exit_code = 0
45
+
46
+ child = subprocess.Popen(['flake8', filename], stdout=subprocess.PIPE)
47
+ stdout, stderr = child.communicate()
48
+
49
+ # we only want to split out lines if you have a warning or error
50
+ lines = None
51
+ for warning in FLAKE8_WARNINGS:
52
+ if warning in stdout:
53
+ if lines is None:
54
+ lines = stdout.split('\n')
55
+ for line in lines:
56
+ if warning in line:
57
+ print 'FLAKE8 WARNING:', line
58
+
59
+ for error in FLAKE8_ERRORS:
60
+ if error in stdout:
61
+ if lines is None:
62
+ lines = stdout.split('\n')
63
+ for line in lines:
64
+ if error in line:
65
+ print 'COMMIT REJECTED. FLAKE8 ERROR:', line
66
+ exit_code = 1
67
+ return exit_code
68
+
69
+
70
+ def look_for_forbidden_items(filename):
71
+ exit_code = 0
72
+ regexes = FORBIDDEN['all']
73
+ file_type = None
74
+ if '.' in filename:
75
+ file_type = filename.rsplit('.', 1)[1]
76
+ regexes.extend(FORBIDDEN.get(file_type, []))
77
+ if regexes:
78
+ regex = '(' + '|'.join(regexes) + ')'
79
+
80
+ with open(filename) as filedata:
81
+ lines = filedata.readlines()
82
+ for indx, line in enumerate(lines):
83
+ line = line.strip()
84
+ if re.search(regex, line):
85
+ print REJECT_TEMPLATE % {
86
+ 'filename': filename,
87
+ 'indx': indx + 1,
88
+ 'line': line,
89
+ }
90
+ exit_code = 1
91
+
92
+ if (
93
+ not os.environ.get('EB_PRE_COMMIT_NO_FLAKE8') and
94
+ file_type and
95
+ file_type == FILE_TYPE_PYTHON
96
+ ):
97
+ try:
98
+ flake_exit = flake8_file(filename)
99
+ # make sure we don't override the exit_code above if flake succeeds
100
+ if flake_exit > 0:
101
+ exit_code = flake_exit
102
+ except OSError:
103
+ try:
104
+ import flake8
105
+ except ImportError:
106
+ print 'Please install flake8 to continue: pip install flake8'
107
+ exit_code = 1
108
+ return exit_code
109
+
110
+
111
+ if __name__ == '__main__':
112
+ files = sys.argv[1:]
113
+ for f in files:
114
+ # Ignore files that have been deleted.
115
+ if os.path.exists(os.path.abspath(f)):
116
+ exit_val = look_for_forbidden_items(f)
117
+ if exit_val:
118
+ sys.exit(exit_val)
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module Ebcommon
3
- VERSION = "0.4.0"
3
+ VERSION = "0.4.1"
4
4
  end
5
5
  end
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-ebcommon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Hahn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-04 00:00:00.000000000 Z
11
+ date: 2014-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -58,6 +58,9 @@ files:
58
58
  - lib/vagrant-ebcommon/commands/stop-selenium.rb
59
59
  - lib/vagrant-ebcommon/config.rb
60
60
  - lib/vagrant-ebcommon/errors.rb
61
+ - lib/vagrant-ebcommon/files/git_hooks/pre-commit
62
+ - lib/vagrant-ebcommon/files/git_hooks/pre-push
63
+ - lib/vagrant-ebcommon/files/git_hooks/pre_commit_hook.py
61
64
  - lib/vagrant-ebcommon/plugin.rb
62
65
  - lib/vagrant-ebcommon/version.rb
63
66
  - locales/en.yml