Проверка, не соответствует ли какой-либо файл, созданный для git commit, белому списку - PullRequest
0 голосов
/ 27 июня 2018

Из-за некоторых проблем со скриптом, который автоматически фиксирует и отправляет, я хотел бы реализовать белый список.

План таков, что допускаются только коммиты с шаблоном 'foo' и 'bar' в path.

#!/bin/sh

WHITELIST="foo bar"
WRKDIR=/home/athur/workwork/test/repo


cd $WRKDIR
git add -A

for file in `git diff --cached -p --name-status | cut -c3-`; do
  if [[ "$file" == *"$WHITELIST"* ]] ; then
    echo "$file is on whitelist"
  else
    echo "$file is not on whitelist. Commit aborted."
    exit 1
  fi
done

Проблема в том, что он всегда использует предложение 'else'. Я не могу найти проблему. Спасибо

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

В качестве подхода наилучшей практики рассмотрим:

#!/usr/bin/env bash
#              ^^^^ important: [[ ]] is not guaranteed to work with bin/sh

whitelist_re='(foo|bar)'
workdir=/home/athur/workwork/test/repo

cd -- "$workdir" || exit
git add -A

while IFS= read -r filename; do
  if [[ $file =~ $whitelist ]]; then
    echo "$file is on whitelist" >&2
  else
    echo "$file is not on whitelist; commit aborted." >&2
    exit 1
  fi
done < <(git diff --cached --name-only)

Чтобы пройти через изменения:

  • Shebang указывает bash как оболочку, которая гарантирует, что расширения, такие как [[ ]] и <(...), будут доступны - гарантия не сделана с /bin/sh.
  • Цикл while read используется вместо того, чтобы пытаться перебрать ориентированные на строки данные с for; см. DontReadLinesWithFor для объяснения причин этого изменения.
  • Белый список задается как ERE-совместимое регулярное выражение, так что =~ можно использовать для проверки соответствия значения.
  • Вместо использования git diff --cached --name-status и последующего использования cut для последующего удаления данных о статусе мы используем --name-only для генерации только имен.
  • Использование имен переменных в нижнем регистре соответствует соглашениям, приведенным в http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html,, определяя, что определяемые POSIX инструменты будут использовать имена переменных оболочки и окружения all-caps для своих собственных целей, и что имена, содержащие как минимум один символ нижнего регистра, являются зарезервировано для использования приложения. (Имейте в виду, что установка переменной оболочки перезаписывает любую переменную среды с таким же именем, поэтому эти соглашения применяются, даже если export не используется).

Кстати, если вы просто хотите узнать, существуют ли какие-либо несоответствия, не зная, какие это файлы, вы можете использовать:

#!/bin/sh
#      ^^ actually safe here, as no non-POSIX functionality is used

whitelist_re='foo|bar'

if git diff --cached --name-only | grep -qEv "$whitelist_re"; then
  echo "At least one file is not on whitelist; commit aborted" >&2
  exit 1
fi
0 голосов
/ 27 июня 2018

Использование явного списка

В этом случае == не является симметричным, и, похоже, ** используется плохо.

Попробуйте "$WHITELIST" == *"$file"*.

(По мотивам Как проверить, существует ли переменная в списке в BASH )

Обратите внимание, что при использовании WHITELIST только файлы foo и bar будут добавлены в белый список.

Обнаружение шаблона

Если вам нужно обнаружить отдельные шаблоны, вам может потребоваться создать такую ​​функцию, как:

for entry in $WHITELIST ; do 
  if [[ "$file" =~ $entry ]] ; then
    return 0
  fi
done
return 1
...