2017-02-20 27 views
2

В смешанной команде разработчиков Mac/Windows/Linux, используя Maven и Git. Некоторые из файлов и папок содержат : (двоеточие), который действителен всюду, кроме Windows. В частности, это папка jcr:content, используемая Apache Sling/Adobe AEM.Как я могу проверить, содержит ли имя файла в моем проекте Maven определенные символы (а затем сбой сборки)?

При клонировании проекта с использованием Git он терпит неудачу, потому что он не может создать эти файлы/папки.

Можно ли проверить все файлы для символов, не разрешенных на этих платформах? Я хочу скомпрометировать сборку Maven, чтобы разработчик знал, что нужно переименовать папку, чтобы она работала на всех платформах.

Я искал плагины Maven, но не нашел ничего, что могло бы сделать эту работу. Если это возможно, как крючок Git, это будет подходящей альтернативой, но я тоже не видел ничего жизнеспособного.

+0

Что вы используете для проверки содержимого из AEM и сериализации? Я никогда не сталкивался с этой проблемой, и я являюсь пользователем Windows. Когда я использую [Vault] (https://docs.adobe.com/docs/en/aem/6-2/develop/dev-tools/ht-vlttool.html), он просто переименовывает все соответствующие файлы для использования подчеркиваний вокруг префикс ('_cq_dialog.xml',' _cq_editConfig.xml' и т. д.). Кроме того, Vault стремится сериализовать узлы 'jcr: content' как элементы XML, а не папки. – toniedzwiedz

+0

Что касается плагинов Maven, ознакомьтесь с ['content-package-maven-plugin'] (https://docs.adobe.com/docs/en/aem/6-2/develop/dev-tools/vlt-mavenplugin .html) или ['maven-crx-plugin'] (https://github.com/Cognifide/Maven-CRX-Plugin), они оба используют' vlt' внутренне. – toniedzwiedz

+1

Содержимое AEM было извлечено из пакета содержимого и помещено в 'src/test/resources/SLING-INF' для использования с тестами Prosper. Похоже, что менеджер пакетов ведет себя иначе, чем 'vlt' – antonyh

ответ

3

Чтобы не выполнить сборку, когда каталог содержит нежелательный символ, вы можете использовать Maven Enforcer Plugin и write a custom rule, которые будут выполнять эту проверку, поскольку для этого нет специальных правил.

При этом вы также можете использовать правило evaluateBeanshell для этой цели: это правило оценивает код Beanshell и не выполняет сборку, если скрипт возвращает false. В этом случае правило использует FileUtils.getDirectoryNames, метод, который возвращает список каталогов, рекурсивное совпадение, включает/исключает шаблоны стиля Ant, начиная с базового каталога. Ниже перечислены все каталоги в каталоге src, содержащие двоеточие :; этот список должен быть пустым для продолжения сборки.

<plugin> 
    <artifactId>maven-enforcer-plugin</artifactId> 
    <version>1.4.1</version> 
    <executions> 
    <execution> 
     <id>enforce-beanshell</id> 
     <goals> 
     <goal>enforce</goal> 
     </goals> 
     <configuration> 
     <rules> 
      <evaluateBeanshell> 
      <condition>org.codehaus.plexus.util.FileUtils.getDirectoryNames(new File("src"), "**/*:*", null, false).isEmpty()</condition> 
      </evaluateBeanshell> 
     </rules> 
     </configuration> 
    </execution> 
    </executions> 
</plugin> 

Сплетение Utils is already a dependency of the plugin, так что вам не нужно, чтобы добавить его снова, но было бы предпочтительнее, чтобы все-таки сделать это в случае, если будущие версии не имеют его. Весь путь относится к базовому каталогу проекта, поэтому нет необходимости указывать его в файле для начала поиска.

Обратите внимание, что это только файлы проверки в каталоге src; в случае, если вы хотите проверить другие каталоги, вы можете добавить дополнительные условия. И, кроме того, он работает на этапе validate, поэтому, если вы хотите проверить папки, созданные во время сборки, вам понадобится использовать другую фазу.

+0

Спасибо! Это сработало очень хорошо, мне пришлось изменить 'src' на' .', потому что он объявлен в родительском pom (без исходного кода), и я добавил '', чтобы сделать ошибку легкой для понимания. – antonyh

0

Можно использовать Git Крючки блокировать имена файлов:

https://github.com/t-b/git-pre-commit-hook-windows-filenames/blob/master/pre-commit

#!/bin/bash 
# 
# Copyright thomas dot braun aeht virtuell minus zuhause dot de, 2013 
# 
# A hook script to check that the to-be-commited files are valid 
# filenames on a windows platform. 
# Sources: 
# - http://stackoverflow.com/a/62888 
# - http://msdn.microsoft.com/en-us/library/aa365247.aspx 
# 
# To enable this hook, rename this file to "pre-commit", move it to ".git/hook" and make it executable. 

if git rev-parse --verify HEAD >/dev/null 2>&1 
then 
    against=HEAD 
else 
    # Initial commit: diff against an empty tree object 
    against= 
fi 

enforcecompatiblefilenames=$(git config hooks.enforcecompatiblefilenames) 

# Redirect output to stderr. 
exec 1>&2 

if test "$enforcecompatiblefilenames" != "true" 
then 
    exit 0 
fi 

git diff --cached --name-only --diff-filter=A -z $against | while IFS= read -r -d '' filename; do 
    # Non-printable characters from ASCII range 0-31 
    nonprintablechars=$(echo -n "$filename" | LC_ALL=C tr -d '[ -~]' | wc -c) 

    # Illegal characters: < > : "/\ | ? * 
    # We don't test for/(forward slash) here as that is even on *nix not allowed in *filename* 
    illegalchars=$(echo -n "$filename" | LC_ALL=C grep -E '(<|>|:|"|\\|\||\?|\*)' | wc -c) 

    # Reserved names plus possible extension 
    # CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9 
    reservednames=$(echo -n "$filename" | LC_ALL=C grep -i -E '(CON|PRN|AUX|NUL|COM1|COM2|COM3|COM4|COM5|COM6|COM7|COM8|COM9|LPT1|LPT2|LPT3|LPT4|LPT5|LPT6|LPT7|LPT8|LPT9).[a-z]{3}' | wc -c) 

    # No trailing period or space 
    trailingperiodorspace=$(echo -n "$filename" | LC_ALL=C grep -E '(\.|)$' | wc -c) 

    # File name is all periods 
    filenameallperiods=$(echo -n "$filename" | LC_ALL=C grep -E '^\.+$' | wc -c) 

    # Check complete path length to be smaller than 260 characters 
    # This test can not be really accurate as we don't know if PWD on the windows filesystem itself is not very long 
    absolutepathtoolong=0 
    if test $(echo "$filename" | wc -c) -ge 260 
    then 
    absolutepathtoolong=1 
    fi 

    # debug output 
    if test -n "$GIT_TRACE" 
    then 
    echo "File: ${filename}" 
    echo nonprintablechars=$nonprintablechars 
    echo illegalchars=$illegalchars 
    echo reservednames=$reservednames 
    echo trailingperiodorspace=$trailingperiodorspace 
    echo filenameallperiods=$filenameallperiods 
    echo absolutepathtoolong=$absolutepathtoolong 
    fi 

    if test $nonprintablechars -ne 0 \ 
    || test $illegalchars -ne 0 \ 
    || test $reservednames -ne 0 \ 
    || test $trailingperiodorspace -ne 0 \ 
    || test $filenameallperiods -ne 0 \ 
    || test $absolutepathtoolong -ne 0 
    then 
    echo "Error: Attempt to add a file name which is incompatible to windows file systems." 
    echo 
    echo "If you know what you are doing you can disable this" 
    echo "check using:" 
    echo 
    echo "git config hooks.enforcecompatiblefilenames false" 
    echo 
    exit 1 
    fi 
done 

Недостатком этого является необходимость установить его на месте для каждого разработчика, так как к сожалению, не все услуги Репо сервер поддержки Git (смотри на вас, GitHub).

0

Спасибо за решение beanshell, это действительно помогло мне. Я также хотел бы показать свой ответ, потому что я также использую регулярное выражение и некоторые сообщения для отладки, чтобы помочь понять, что происходит.Это работает на моей машине (TM):

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-enforcer-plugin</artifactId> 
    <version>1.4.1</version> 
    <executions> 
     <execution> 
      <id>migration-filename-convention</id> 
      <goals> 
       <goal>enforce</goal> 
      </goals> 
      <phase>validate</phase> 
      <configuration> 
       <rules> 
        <evaluateBeanshell> 
         <condition> 
           List filenames = org.codehaus.plexus.util.FileUtils.getFileNames(
            new File("src"), 
            "**/*.sql", 
            null, 
            false); 

           for (Iterator it = filenames.iterator(); it.hasNext();) { 
            String file = it.next(); 
            print("Found SQL file: " + file); 
            passesValidation = java.util.regex.Pattern.matches("^.+[\\/\\\\]V[0-9]{4}([0-1][0-9])([0-3][0-9])[0-9]{6}__BDV.sql$", file); 
            if (passesValidation) { 
             print("Filename passes validation"); 
             it.remove(); 
            } else { 
             print("Did not pass validation"); 
            }; 
           }; 

           filenames.isEmpty()</condition> 
         </evaluateBeanshell> 
        </rules> 
       <fail>true</fail> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 

Преимущество здесь состоит в том, что код BeanShell более читаемым и печатает файлы, которые он находит по пути:

[INFO] 
[INFO] --- maven-enforcer-plugin:1.4.1:enforce (migration-filename-convention) @ inventory-microservice --- 
Found SQL file: main\resources\database\V20170803113900__BDV.sql 
Filename passes validation 
[INFO] ------------------------------------------------------------------------ 
[INFO] BUILD SUCCESS 

Это может быть использовано для проверки того, что SQL-скрипты соответствуют условному обозначению имен на основе метки.

Он также прикреплен к проверке жизненного цикла Maven, поэтому mvn validate также вызовет это.