eclipse-m2e / m2e-core

Eclipse Public License 2.0
110 stars 111 forks source link

Archetype property-expansion is not performed and validationRegex is ignored #799

Closed hd42 closed 2 years ago

hd42 commented 2 years ago

We have an archetype (faktorips-maven-archetype, mostly works now thanks to #249) that uses parameter replacement to calculate the default value of a property, which works fine when executing the archetype on the command line, because the properties are evaluated one after the other. In Eclipse, the GAV-coordinates and all properties are displayed on one page, which is nice but breaks this inter-property dependency.

In our archetype-metadata.xml, we have

    <requiredProperties>
        [...]
        <requiredProperty key="IPS-RuntimeIdPrefix">
            <defaultValue>${artifactId.concat(".")}</defaultValue>
            <validationRegex>[a-zA-Z](?:\.?[a-zA-Z\d])*\.</validationRegex>
        </requiredProperty>
        [...]
    </requiredProperties>

Unfortunately, the artifactId is not replaced here. I'm not sure what a nice solution would look like, because changing the value constantly might confuse the user. Maybe one could evaluate the replacement as as long as the field's value has not been manually edited (so that for example changes to the artifactId are reflected) and then keep whatever the user entered.

The validationRegex also seems not to be evaluated.

laeubi commented 2 years ago

@hd42 thanks for reporting this, I think these are missing feature at the moment, I'll take a look at it.

For reference, here is the full archetype.xml: <?xml version="1.0" encoding="UTF-8"?>

<archetype-descriptor
    xmlns="https://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.1.0 http://maven.apache.org/xsd/archetype-descriptor-1.1.0.xsd"
    name="${artifactId}">

    <requiredProperties>
        <requiredProperty key="JavaVersion">
            <defaultValue>11</defaultValue>
            <validationRegex>\d\d?(?:\.\d\d?)*</validationRegex>
        </requiredProperty>
        <requiredProperty key="IPS-Language">
            <defaultValue>en</defaultValue>
            <validationRegex>de|DE|De|en|EN|En</validationRegex>
        </requiredProperty>
        <requiredProperty key="IPS-NamingConvention">
            <defaultValue>FIPS</defaultValue>
            <validationRegex>FIPS|VAA|PM</validationRegex>
        </requiredProperty>
        <requiredProperty key="IPS-IsModelProject">
            <defaultValue>true</defaultValue>
            <validationRegex>true|false</validationRegex>
        </requiredProperty>
        <requiredProperty key="IPS-IsProductDefinitionProject">
            <defaultValue>false</defaultValue>
            <validationRegex>true|false</validationRegex>
        </requiredProperty>
        <requiredProperty key="IPS-IsPersistentProject">
            <defaultValue>false</defaultValue>
            <validationRegex>true|false</validationRegex>
        </requiredProperty>
        <requiredProperty key="IPS-SourceFolder">
            <defaultValue>model</defaultValue>
            <validationRegex>[a-zA-Z][?:a-zA-Z\d]*</validationRegex>
        </requiredProperty>
        <requiredProperty key="IPS-TocXML">
            <defaultValue>faktorips-repository-toc</defaultValue>
            <validationRegex>[a-zA-Z](?:-?[a-zA-Z\d])*</validationRegex>
        </requiredProperty>
        <requiredProperty key="IPS-ValidationMessageBundle">
            <defaultValue>message-validation</defaultValue>
            <validationRegex>[a-zA-Z](?:-?[a-zA-Z\d])*</validationRegex>
        </requiredProperty>
        <requiredProperty key="IPS-IsGroovySupport">
            <defaultValue>false</defaultValue>
            <validationRegex>true|false</validationRegex>
        </requiredProperty>
        <requiredProperty key="IPS-RuntimeIdPrefix">
            <defaultValue>${artifactId.concat(".")}</defaultValue>
            <validationRegex>[a-zA-Z](?:\.?[a-zA-Z\d])*\.</validationRegex>
        </requiredProperty>
        <requiredProperty key="IPS-ConfigureIpsBuild">
            <defaultValue>true</defaultValue>
            <validationRegex>true|false</validationRegex>
        </requiredProperty>
    </requiredProperties>

    <fileSets>
        <fileSet filtered="true" packaged="true" encoding="UTF-8">
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.java</include>
            </includes>
        </fileSet>
        <fileSet filtered="true" packaged="false" encoding="UTF-8">
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </fileSet>
        <fileSet filtered="true" packaged="false" encoding="UTF-8">
            <directory>META-INF</directory>
            <includes>
                <include>MANIFEST.MF</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>__IPS-SourceFolder__</directory>
        </fileSet>
        <fileSet filtered="true" packaged="false" encoding="UTF-8">
            <directory />
            <includes>
                <include>.ipsprojectDE</include>
                <include>.ipsprojectEN</include>
            </includes>
        </fileSet>
        <fileSet filtered="false" packaged="false" encoding="UTF-8">
            <directory />
            <includes>
                <include>LICENSE.txt</include>
                <include>agpl-3.0.txt</include>
            </includes>
        </fileSet>
    </fileSets>
</archetype-descriptor>
laeubi commented 2 years ago

Regexp are now checked.

For the properties expansion it is a bit more complex, as you said, the Archetype Generator assigns values step by step and evaluates the value using Velocity.

I see two options:

  1. If there is an expression to evaluate we simply remove it from the wizard and let the user enter it on the commandline
  2. we try to embed velocity (again) even though @HannesWell recently removed it to get a smaller footprint and try to emulate the way archetype works as much as possible

@hd42 any concerns for option 1? Given that we want to delegate as much as possible to the maven part it seems the logical choice here, while 2 of course would maybe much more "magic" / comfortable?

hd42 commented 2 years ago

@laeubi I don't think that option 2 can handle all options, so some variant of option 1 would probably be better. Either (a) silently remove any property containing an expression for its default value, so that it has to be entered on the command line, or (b) keep it and just remove the default value, maybe adding a comment, why there is no value and maybe even presenting the expression as a tooltip.

I think option 1a is probably the best. 1b would allow an experienced user to enter all values in the UI table, but as we already have the console for any input needed by the groovy script, using it for any missing properties as well seems fitting.

HannesWell commented 2 years ago
2. we try to embed velocity (again) even though @HannesWell recently removed it to get a smaller footprint and try to emulate the way archetype works as much as possible

I'm currently not familiar enough with the topic to say what a good solution for the problem is, but if embedding more artifacts is necessary just remove the corresponding exclusion. As long as it is not groovy-all or ivy trying hard to avoid them is IMHO not necessary.

laeubi commented 2 years ago

The fix for this should appear shortly in the snapshots.

This issue was gently sponsored by Faktor Zehn GmbH.