From 8bbb07a1bc5db944ba95fa5951ed40c3c1b968aa Mon Sep 17 00:00:00 2001 From: Lunar Date: Fri, 31 May 2013 22:30:57 +0200 Subject: [PATCH] Next step in pre-commit hook implementation --- bin/pre-commit-hook | 42 +++++++++++++++++++ ...-hooks.feature => pre-commit-hook.feature} | 12 +++--- features/step_definitions/commandes.rb | 3 -- features/step_definitions/commands.rb | 7 ++++ features/step_definitions/git.rb | 9 +++- features/step_definitions/subscriptions.rb | 7 +++- features/support/env.rb | 2 + features/support/fixtures.rb | 16 ++++--- 8 files changed, 81 insertions(+), 17 deletions(-) create mode 100755 bin/pre-commit-hook rename features/{git-hooks.feature => pre-commit-hook.feature} (54%) delete mode 100644 features/step_definitions/commandes.rb create mode 100644 features/step_definitions/commands.rb diff --git a/bin/pre-commit-hook b/bin/pre-commit-hook new file mode 100755 index 0000000..aa60ccb --- /dev/null +++ b/bin/pre-commit-hook @@ -0,0 +1,42 @@ +#!/usr/bin/ruby1.9.1 +#-*- coding: utf-8 -*- + +require 'rubygems' +require 'bundler' +Bundler.setup + +require 'safe_yaml' +SafeYAML::OPTIONS[:default_mode] = :safe + +if system('git rev-parse --quiet --verify HEAD >/dev/null') + against = 'HEAD' +else + # Initial commit: diff against an empty tree object + against = '4b825dc642cb6eb9a060e54bf8d69288fbee4904' +end + +def is_valid_subscription?(content) + content.length != 0 && YAML.load(content) +end + +def is_valid_subscription_file?(file) + IO.popen(['git', 'show', ":#{file}"]) do |f| + is_valid_subscription?(f.read) + end +end + +modified = [] +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) + modified << file + if !is_valid_subscription_file?(file) + $stderr.puts "Désolé : #{file} n'a pas le bon format !" + exit 1 + end + end + end +end + diff --git a/features/git-hooks.feature b/features/pre-commit-hook.feature similarity index 54% rename from features/git-hooks.feature rename to features/pre-commit-hook.feature index 29f8098..a03fff0 100644 --- a/features/git-hooks.feature +++ b/features/pre-commit-hook.feature @@ -1,16 +1,18 @@ # language: fr -Fonctionnalité: Git hooks - En tant qu'être humain, je suis susceptible de faire des erreurs. Il faut - donc que Git vérifie que je ne met pas des informations incompréhensibles - dans la base des membres. +Fonctionnalité: pre-commit hook Git + En tant que membres du C.A. de Nos oignons, je dois pouvoir remplir + les fiches des membres sans introduire de problème dans le système. + Il faut donc que Git m'empêche d'enregistrer des informations + invalides. Contexte: Soit un clone du Git contenant les adhésions + Et le « pre-commit hook » correctement configuré Scénario: Commit d'une nouvelle adhésion dans le format qui convient Lorsque j'ajoute une fiche correcte pour une nouvelle adhésion - Et que je fait un `commit` du nouveau fichier + Et que je fais un `commit` du nouveau fichier Alors je ne dois pas avoir eu d'erreur Scénario: Commit d'un fichier vide diff --git a/features/step_definitions/commandes.rb b/features/step_definitions/commandes.rb deleted file mode 100644 index 471f8dd..0000000 --- a/features/step_definitions/commandes.rb +++ /dev/null @@ -1,3 +0,0 @@ -Then /^je ne dois pas avoir eu d'erreur$/ do - assert_exit_status(0) -end diff --git a/features/step_definitions/commands.rb b/features/step_definitions/commands.rb new file mode 100644 index 0000000..d069730 --- /dev/null +++ b/features/step_definitions/commands.rb @@ -0,0 +1,7 @@ +Then /^je ne dois pas avoir eu d'erreur$/ do + assert_exit_status(0) +end + +Then /^je dois voir comme erreur "(.*?)"$/ do |expected| + assert_failing_with(expected) +end diff --git a/features/step_definitions/git.rb b/features/step_definitions/git.rb index 30d6e7c..27d22a7 100644 --- a/features/step_definitions/git.rb +++ b/features/step_definitions/git.rb @@ -19,7 +19,12 @@ Given /^un clone du Git contenant les adhésions$/ do cd 'clone' end -When /je fait un `commit` du nouveau fichier$/ do +Given /^le « pre-commit hook » correctement configuré$/ do + FileUtils.ln_s File.expand_path('../../../bin/pre-commit-hook', __FILE__), + "#{current_dir}/.git/hooks/pre-commit" +end + +When /je fais un `commit` du nouveau fichier$/ do run_simple "git add #{@file}" - run_simple "git commit #{@file} -m 'new file'" + run_simple "git commit #{@file} -m 'new file'", false # do not fail on error end diff --git a/features/step_definitions/subscriptions.rb b/features/step_definitions/subscriptions.rb index 4fab6a3..76a4a1a 100644 --- a/features/step_definitions/subscriptions.rb +++ b/features/step_definitions/subscriptions.rb @@ -1,6 +1,9 @@ When /^j'ajoute une fiche correcte pour une nouvelle adhésion$/ do - new_id = Dir.glob("#{current_dir}/Membres/*.mdwn"). - collect { |f| File.basename(f).gsub(/\.mdwn$/, '').to_i }.max + 1 @file = subscription_filename_for_id(new_id) write_file @file, render_subscription_file(EXTRA_SUBSCRIPTION) end + +When /^j'ajoute une fiche vide$/ do + @file = subscription_filename_for_id(new_id) + write_file @file, '' +end diff --git a/features/support/env.rb b/features/support/env.rb index 936dc53..e647e2f 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -9,6 +9,8 @@ require 'safe_yaml' SafeYAML::OPTIONS[:default_mode] = :safe Before do + ENV['GIT_COMMITTER_NAME'] = ENV['GIT_AUTHOR_NAME'] = 'J. Test' + ENV['GIT_COMMITTER_EMAIL'] = ENV['GIT_AUTHOR_EMAIL'] = 'test@example.org' @tmpdir = Dir.mktmpdir('gestion-adh') @dirs = [@tmpdir] end diff --git a/features/support/fixtures.rb b/features/support/fixtures.rb index d3e3353..47290c7 100644 --- a/features/support/fixtures.rb +++ b/features/support/fixtures.rb @@ -7,7 +7,7 @@ require 'yaml' BASE_SUBSCRIPTIONS = YAML.load(< -address: - <%= address %> +address: | +<%= address.gsub(/^/, ' ').rstrip %> email: <%= email %> mumbership_fee_paid_on: <%= membership_fee_paid_on %> --- @@ -67,3 +68,8 @@ end def render_subscription_file(locals) ERB.new(SUBSCRIPTION_FILE_TEMPLATE).result(OpenStruct.new(locals).instance_eval { binding }) end + +def new_id + new_id = Dir.glob("#{current_dir}/Membres/*.mdwn"). + collect { |f| File.basename(f).gsub(/\.mdwn$/, '').to_i }.max + 1 +end -- 2.39.5