2017-02-20 77 views
2

在混合的Mac/Windows/Linux开发团队中,使用Maven和Git。某些文件和文件夹包含:(冒号),除了Windows以外,其他地方都是有效的。具体而言,这是Apache Sling/Adob​​e AEM使用的jcr:content文件夹。如何检查我的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 Pluginwrite a custom rule,因为没有专门的规则。

也就是说,您也可以使用evaluateBeanshell规则来实现此目的:如果脚本返回false,则此规则将评估Beanshell代码并生成构建失败。在这种情况下,规则使用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也会调用它。

相关问题