Damian Nowak is a CEO at Virtkick. He's a Ruby coder, an Arch Linux hacker, and drinks good beer.

Maven – podmiana ciągu znaków przed kompilacjąJuly 2009

Dzisiaj w trakcie pracy nad Scrumowym pluginem dla Atlassian JIRA odczułem głęboką potrzebę skonfigurowania Mavenowego skryptu budowania w taki sposób, aby wszystkie wystąpienia tokena ${plugin.version} zostały zamieniane na pewien ciąg znaków jeszcze przed kompilacją.

Moim celem jest stworzenie paczek JAR dwóch różnych wersji JIRA Scrum Cards Print Plugin - jednej freeware'owej i drugiej - komercyjnej. Różnica między nimi jest taka, że komercyjna ma więcej możliwości, m.in. na karteczkach można wstawić logo swojej firmy. Od strony kodu wygląda to tak, że wywołuję Config.getInstance(“freeware”), aby otrzymać konfigurację dla wersji darmowej oraz odpowiednio Config.getInstance(“commercial”) dla wersji płatnej. Wersja darrmowa ma zaszyte w konfiguracji logo firmy Spartez na stałe, zaś komercyjna wyciąga logo klienta z konfiguracji pluginu w administracji Atlassian JIRA.

Jako, że nie chcę tworzyć dwóch osobnych projektów tylko z powodu zmiany w jednej linii kodu, podmiana tokena przed kompilacją wydaje się być najrozsądniejsza. Można co prawda kombinować z nadaniem svn:external i ustawieniem zależności na część wspólną kodu, ale jest to rozwiązanie trudniejsze. I chyba nawet niedostosowane do niewielkiego rozmiaru problemu.

Ostatecznie, token ${plugin.version} w linii Config.getInstance(“${plugin.version}”) zostanie zamieniony na pożądany tekst, freeware lub commercial, w zależności od tego jaką paczkę JAR chcę w danej chwili otrzymać.

Rozwiązanie

<project ...>

    [...]

    <properties>
        [...]
        <token.example>Atlassian JIRA</token.version>
        <token.nwkr>Damian Nowak</token.nwkr>
    </properties>

    <build>
        <resources>
            <!-- Nie możemy porzucić wartości z parent pom-ów, dlatego trzeba prześledzić rodziców i umieścić ich zawartość tutaj. -->
            <!-- W moim przypadku zawartość ~/.m2/repository/com/atlassian/pom/atlassian-plugin-pom/9/atlassian-plugin-pom-9.pom poniżej. -->
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>atlassian-plugin.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>false</filtering>
                <excludes>
                    <exclude>atlassian-plugin.xml</exclude>
                </excludes>
            </resource>
            <!-- Koniec -->
            <resource>
                <directory>src/main/java</directory> <!-- Ścieżka, wewnątrz której wszystkie wystąpienia zostaną zamienione -->
                <filtering>true</filtering>
                <targetPath>../filtered-sources/java</targetPath>
            </resource>
        </resources>
        <sourceDirectory>target/filtered-sources/java</sourceDirectory>
    </build>
</project>

Teraz każde wystąpienie ${token.example} zostanie zastąpione przez Atlassian JIRA, a ${token.nwkr} przez Damian Nowak. Trzeba tylko uważać, by przypadkiem nie wskazać ścieżki, wewnątrz której znajdują się dane binarne. Może to skutkować ich uszkodzeniem. ;-) Nie zapomnij też dodać ścieżki target/filtered-sources na listę wykluczeń z buildu. Jeśli tego nie zrobisz, IntelliJ IDEA będzie zgłaszała błąd o duplikujących się klasach.

Damian Nowak
CEO & Ruby Developer