From ca091d07cdf75c8637229b11c5bafdeaa79bb8a2 Mon Sep 17 00:00:00 2001 From: Lunar Date: Fri, 31 May 2013 23:50:39 +0200 Subject: [PATCH] Implement pre-receive hook --- Gemfile | 4 +-- Gemfile.lock | 8 +++++- bin/pre-commit-hook | 45 +++++++------------------------- bin/pre-receive-hook | 22 ++++++++++++++++ features/step_definitions/git.rb | 25 +++++++++++++----- lib/nos_oignons/git.rb | 9 +++++++ lib/nos_oignons/subscriptions.rb | 25 ++++++++++++++++++ nos_oignons.gemspec | 9 +++++++ 8 files changed, 101 insertions(+), 46 deletions(-) create mode 100755 bin/pre-receive-hook create mode 100644 lib/nos_oignons/git.rb create mode 100644 lib/nos_oignons/subscriptions.rb create mode 100644 nos_oignons.gemspec diff --git a/Gemfile b/Gemfile index 5df2cc3..fa75df1 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,3 @@ source 'https://rubygems.org' -gem 'cucumber' -gem 'aruba' -gem 'safe_yaml' +gemspec diff --git a/Gemfile.lock b/Gemfile.lock index 7291159..7917097 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,9 @@ +PATH + remote: . + specs: + nos_oignons (0.0.1.dev) + safe_yaml + GEM remote: https://rubygems.org/ specs: @@ -28,4 +34,4 @@ PLATFORMS DEPENDENCIES aruba cucumber - safe_yaml + nos_oignons! diff --git a/bin/pre-commit-hook b/bin/pre-commit-hook index 0b46db8..4571599 100755 --- a/bin/pre-commit-hook +++ b/bin/pre-commit-hook @@ -5,10 +5,8 @@ require 'rubygems' require 'bundler' Bundler.setup -require 'safe_yaml' -SafeYAML::OPTIONS[:default_mode] = :safe - -SUBSCRIPTIONS_ROOT = 'Membres' +require 'nos_oignons/git' +require 'nos_oignons/subscriptions' if system('git rev-parse --quiet --verify HEAD >/dev/null') against = 'HEAD' @@ -17,38 +15,13 @@ else against = '4b825dc642cb6eb9a060e54bf8d69288fbee4904' end -def is_valid_subscription?(content) - return false if content.length == 0 - return false unless content.start_with?("---\n") - begin - data = YAML.load(content) - rescue ArgumentError - # Parse error - return false - end - ['name', 'email'].each do |key| - return false unless data.include?(key) - end - true -end - -def is_valid_subscription_file?(file) - IO.popen(['git', 'show', ":#{file}"]) do |f| - is_valid_subscription?(f.read) - end -end - -IO.popen(['git', 'diff-index', '--cached', '--name-status', against]) do |f| - f.readlines.each do |line| - status, file = line.strip.split("\t", 2) - # Has file been added or modified? - if ['A', 'M'].include?(status) - next unless file.start_with?("#{SUBSCRIPTIONS_ROOT}/") - if !is_valid_subscription_file?(file) - $stderr.puts "Désolé : #{file} n'a pas le bon format !" - exit 1 - end +IO.popen(['git', 'diff-index', '--cached', '--name-status', against]) do |io| + handle_modified_files(io) do |file| + next unless file.start_with?("#{SUBSCRIPTIONS_ROOT}/") + # Use empty ref to get the index + if !is_valid_subscription_file?('', file) + $stderr.puts "Désolé : #{file} n'a pas le bon format !" + exit 1 end end end - diff --git a/bin/pre-receive-hook b/bin/pre-receive-hook new file mode 100755 index 0000000..46500b0 --- /dev/null +++ b/bin/pre-receive-hook @@ -0,0 +1,22 @@ +#!/usr/bin/ruby1.9.1 +#-*- coding: utf-8 -*- + +require 'rubygems' +require 'bundler' +Bundler.setup + +require 'nos_oignons/git' +require 'nos_oignons/subscriptions' + +$stdin.readlines.each do |ref_line| + old_value, new_value, ref_name = ref_line.rstrip.split(' ', 3) + IO.popen(['git', 'diff', '--name-status', "#{old_value}..#{new_value}"]) do |io| + handle_modified_files(io) do |file| + next unless file.start_with?("#{SUBSCRIPTIONS_ROOT}/") + if !is_valid_subscription_file?(new_value, file) + $stderr.puts "Désolé : #{file} n'a pas le bon format !" + exit 1 + end + end + end +end diff --git a/features/step_definitions/git.rb b/features/step_definitions/git.rb index 27d22a7..50624ff 100644 --- a/features/step_definitions/git.rb +++ b/features/step_definitions/git.rb @@ -4,7 +4,13 @@ Given /^un clone du Git contenant les adhésions$/ do # Create main repository create_dir 'main' cd 'main' - run_simple 'git init' + @main_repository_path = current_dir + run_simple 'git init --bare' + cd '..' + + # Clone it now + run_simple 'git clone main clone' + cd 'clone' create_dir 'Membres' BASE_SUBSCRIPTIONS.each_pair do |number, data| file = subscription_filename_for_id(number) @@ -12,11 +18,7 @@ Given /^un clone du Git contenant les adhésions$/ do run_simple "git add #{file}" end run_simple 'git commit -m "Initial data set from fixtures"' - cd '..' - - # Clone it now - run_simple 'git clone main clone' - cd 'clone' + run_simple 'git push origin master' end Given /^le « pre-commit hook » correctement configuré$/ do @@ -24,7 +26,18 @@ Given /^le « pre-commit hook » correctement configuré$/ do "#{current_dir}/.git/hooks/pre-commit" end +Given /^le « pre-receive hook » configuré sur le dépôt principal$/ do + FileUtils.ln_s File.expand_path('../../../bin/pre-receive-hook', __FILE__), + "#{@main_repository_path}/hooks/pre-receive" +end + When /je fais un `commit` du nouveau fichier$/ do run_simple "git add #{@file}" run_simple "git commit #{@file} -m 'new file'", false # do not fail on error end + +When /^que je pousse la modification$/ do + run_simple "git add #{@file}" + run_simple "git commit #{@file} -m 'new file'" + run_simple 'git push origin master', false # do not fail on error +end diff --git a/lib/nos_oignons/git.rb b/lib/nos_oignons/git.rb new file mode 100644 index 0000000..4a2d04d --- /dev/null +++ b/lib/nos_oignons/git.rb @@ -0,0 +1,9 @@ +def handle_modified_files(io) + io.readlines.each do |line| + status, file = line.strip.split("\t", 2) + # Has file been added or modified? + if ['A', 'M'].include?(status) + yield file + end + end +end diff --git a/lib/nos_oignons/subscriptions.rb b/lib/nos_oignons/subscriptions.rb new file mode 100644 index 0000000..eef7946 --- /dev/null +++ b/lib/nos_oignons/subscriptions.rb @@ -0,0 +1,25 @@ +require 'safe_yaml' +SafeYAML::OPTIONS[:default_mode] = :safe + +SUBSCRIPTIONS_ROOT = 'Membres' + +def is_valid_subscription?(content) + return false if content.length == 0 + return false unless content.start_with?("---\n") + begin + data = YAML.load(content) + rescue ArgumentError + # Parse error + return false + end + ['name', 'email'].each do |key| + return false unless data.include?(key) + end + true +end + +def is_valid_subscription_file?(ref, file) + IO.popen(['git', 'show', "#{ref}:#{file}"]) do |f| + is_valid_subscription?(f.read) + end +end diff --git a/nos_oignons.gemspec b/nos_oignons.gemspec new file mode 100644 index 0000000..585576f --- /dev/null +++ b/nos_oignons.gemspec @@ -0,0 +1,9 @@ +Gem::Specification.new do |s| + s.name = 'nos_oignons' + s.version = '0.0.1.dev' + s.require_paths = ['lib'] + + s.add_development_dependency 'cucumber' + s.add_development_dependency 'aruba' + s.add_runtime_dependency 'safe_yaml' +end -- 2.39.5