2017-02-20 81 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也會調用它。

相關問題