Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace characters and change the case of letters #317

Closed
NicolaSpreafico opened this issue Sep 9, 2017 · 12 comments
Closed

Replace characters and change the case of letters #317

NicolaSpreafico opened this issue Sep 9, 2017 · 12 comments

Comments

@NicolaSpreafico
Copy link

NicolaSpreafico commented Sep 9, 2017

This is my plugin configuration

<plugin>
	<groupId>pl.project13.maven</groupId>
	<artifactId>git-commit-id-plugin</artifactId>
	<version>2.2.3</version>
	<configuration>
		<dotGitDirectory>${project.basedir}/../.git</dotGitDirectory>
		<injectAllReactorProjects>true</injectAllReactorProjects>
	</configuration>
	<executions>
		<execution>
			<id>get-the-git-infos</id>
			<goals>
				<goal>revision</goal>
			</goals>
		</execution>
	</executions>
</plugin>

As already discussed in issue #287, I'm trying to use the git.branch property as a version name for a web application. This value need to be url-safe with the following rules:

May only contain lowercase letters, digits, and hyphens.
Must begin and end with a letter or digit.
Must not exceed 63 characters.

As I discovered looking into the wiki, exists a very new configuration (from 2.2.3) replacementProperties that can achieve this kind of need.

My idea is replacing all the forbidden characters with a - characters

<replacementProperty>
	<property>git.branch</property>
	<token>[^a-z0-9\-]</token>
	<value>-</value>
	<regex>true</regex>
</replacementProperty>

Input: feature/this_is_my_feature_#23
Output: feature-this-is-my-feature--23

and after that removing all the duplicated -

<replacementProperty>
	<property>git.branch</property>
	<token>[-]{2,}</token>
	<value>-</value>
	<regex>true</regex>
</replacementProperty>

Input: feature-this------is-my---------feature--23
Output: feature-this-is-my-feature-23

I'm a little stuck changing the case of the letters. I need to lowercase the letter BEFORE the first replacement, or the pattern will convert all the uppercase letters in - character.
Of course if this cannot be made I will simply use lowercase letters for my feature names, it is not a big problem. But if this transformation can be done is useful as well.

Can the case of the letters be changed?

@TheSnoozer
Copy link
Collaborator

Interesting use-case. Thanks for creating this ticket and sharing your idea!

As of right now the plugin doesn't support this.

What comes closes to this is the following:
https://stackoverflow.com/questions/10521860/property-autocapitalization-in-maven
Also the Guava CaseFormat comes close to what you want to achieve.

I would be happy to implement some sort of transformation rule, but want to make sure its somewhat generic.
What I can think of right now:

  • a switch to control if it should be applied before or after the regex - ideally one could specify a rule that is being applied before the regex and another rule that is being applied after the regex
  • a mechanism to convert everything in lowercase
  • a mechanism to convert everything in uppercase
  • a mechanism to convert as capitalization (not sure if this would need to have some sort of extra delimiter e.g. space vs. underscore vs. dash)
  • a mechanism to invert the casing

Not sure if there would need to be an option that would allow multiple casing transformation rules to be performed after each other (e.g. apply capitalization and invert).

As far it seems the rest can be achieved using regex.

@NicolaSpreafico
Copy link
Author

I don't know which regex engine you use, but it seems that Perl provides the operator \L which can be used to convert cases.

Something like
Find: (\w) Replace With: \L$1
I tried this pattern on plugin but it does not replace the letter.

@NicolaSpreafico
Copy link
Author

Inside the link you suggested there is a sample use of the GMaven plugin, which I tried

<plugin>
	<groupId>org.codehaus.gmaven</groupId>
	<artifactId>gmaven-plugin</artifactId>
	<version>1.5</version>
	<executions>
		<execution>
			<phase>initialize</phase>
			<goals>
				<goal>execute</goal>
			</goals>
			<configuration>
				<source>
					import org.apache.commons.lang.StringUtils
					project.properties["git.branch"] = StringUtils.lowerCase(project.properties["git.branch"])
				</source>
			</configuration>
		</execution>
	</executions>
</plugin>

This was the input: feature/Uppercase_Feature
This was the output: feature-ppercase-eature

The uppercase letters are removed, so I think that this plugin regex replacer came first, before the GMaven plugin (or the GMaven plugin came even before the git.branch property is created, so there is nothing to replace).

Maybe some sort of Maven configuration between the phases of execution.

@TheSnoozer
Copy link
Collaborator

I also saw this perl-thing, but unfortunately we have a java-project here so this doesn't work ;-)

We use plain java-features with Java-Pattern.

The appraoch with the gmaven-plugin should technically work. Double check the phases where the plugins are executed. What you also could try is instead of overwriting the git.branch try to write it to a different property (e.g. project.properties["git.branch.lower"] = StringUtils.lowerCase(project.properties["git.branch"])) to rule out that the plugin is not capable of overwriting already existing properties (already saw similar things)...

@NicolaSpreafico
Copy link
Author

NicolaSpreafico commented Sep 10, 2017

Looking around I found the build-helper-maven-plugin plugin and after some tests and playing around I found a working configuration.

In addition to regex replacement, it offers 2 additional flags to convert in upper/lower case the output of the replacement. Here is my current configuration:

<plugin>
	<artifactId>maven-antrun-plugin</artifactId>
	<version>1.8</version>
	<executions>
		<execution>
			<id>regex-replace-echo</id>
			<phase>package</phase>
			<goals>
				<goal>run</goal>
			</goals>
			<configuration>
				<tasks>
					<echo>******** Displaying value of property ********</echo>
					<echo>${git.branch.lowercase}</echo>
				</tasks>
			</configuration>
		</execution>
	</executions>
</plugin>

<plugin>
	<groupId>pl.project13.maven</groupId>
	<artifactId>git-commit-id-plugin</artifactId>
	<version>2.2.3</version>
	<configuration>
		<dotGitDirectory>${project.basedir}/../.git</dotGitDirectory>
		<injectAllReactorProjects>true</injectAllReactorProjects>
	</configuration>
</plugin>

<plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>build-helper-maven-plugin</artifactId>
	<version>3.0.0</version>
	<executions>
		<execution>
			<id>git-branch-lowercase</id>
			<goals>
				<goal>regex-property</goal>
			</goals>
			<configuration>
				<name>git.branch.lowercase</name>
				<value>${git.branch}</value>
				<regex>[^A-Za-z0-9\-]</regex>
				<replacement>-</replacement>
				<toLowerCase>true</toLowerCase>
				<failIfNoMatch>false</failIfNoMatch>
			</configuration>
		</execution>
		<execution>
			<id>git-branch-multiple-hyphens</id>
			<goals>
				<goal>regex-property</goal>
			</goals>
			<configuration>
				<name>git.branch.lowercase</name>
				<value>${git.branch.lowercase}</value>
				<regex>[-]{2,}</regex>
				<replacement>-</replacement>
				<failIfNoMatch>false</failIfNoMatch>
			</configuration>
		</execution>
	</executions>
</plugin>

I created 2 different executions (one for remove forbidden characters+lowercase and one for removing the multiple hyphens. I found the regexPropertySettings setting that as I can understand can do multiple replace at once but I was unable to make it working.

With the provided configuration is my current situation:
Here is my branch name: feature/git_maven_plugin___UPPERCASE
Here is the antrun output: [echo] feature-git-maven-plugin-uppercase

EDIT:
I was early to call it a success. Probably for the same reason as issue #287, I had the value properly printed by the echo task, but during deploy operation the version was generated using the original value of the property (or in this case having the ${..} not resolved because the property is created by the plugin itself'

After reading in the documentation that this plugin is triggered by default on validate phase, I edited once again the launch profile in order to force the validate after the git plugin, like follows:
mvn clean git-commit-id:revision validate appengine:deploy

After this modification the entire build seems to be work fine

@TheSnoozer
Copy link
Collaborator

Agree, it seems that you run into the same problem as outlined in #287.
Try:
mvn clean git-commit-id:revision build-helper:regex-property appengine:deploy
I would also recommend to checkout the Maven Prefix Resolution the plugin prefix can be obtained from META-INF/maven/plugin.xml and goal Prefix (e.g. <goalPrefix>build-helper</goalPrefix>) that resides inside the plugin (download the jar and extract it to check...)

@NicolaSpreafico
Copy link
Author

I agree with you, your suggestion
mvn clean git-commit-id:revision build-helper:regex-property appengine:deploy
was the first I tried (following the experience from #287)

But after I discovered that this generates an error, I then tried with the validate

[ERROR] Failed to execute goal org.codehaus.mojo:build-helper-maven-plugin:3.0.0:regex-property (default-cli) on project: The parameters 'regex', 'name', 'value' for goal org.codehaus.mojo:build-helper-maven-plugin:3.0.0:regex-property are missing or invalid -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:build-helper-maven-plugin:3.0.0:regex-property (default-cli) on project: The parameters 'regex', 'name', 'value' for goal org.codehaus.mojo:build-helper-maven-plugin:3.0.0:regex-property are missing or invalid
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:213)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:154)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:146)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:309)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:194)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:107)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:993)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:345)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:191)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.PluginParameterException: The parameters 'regex', 'name', 'value' for goal org.codehaus.mojo:build-helper-maven-plugin:3.0.0:regex-property are missing or invalid
        at org.apache.maven.plugin.internal.DefaultMavenPluginManager.populatePluginFields(DefaultMavenPluginManager.java:643)
        at org.apache.maven.plugin.internal.DefaultMavenPluginManager.getConfiguredMojo(DefaultMavenPluginManager.java:596)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:121)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
        ... 20 more

There is something wrong with the build if all the 3 values are considered as empty. I also tried with a Maven property that exists for sure:

<execution>
	<id>version-urlsafe</id>
	<goals>
		<goal>regex-property</goal>
	</goals>
	<configuration>
		<name>project.version.urlsafe</name>
		<value>${project.version}</value>
		<regex>\.</regex>
		<replacement>-</replacement>
		<toLowerCase>true</toLowerCase>
		<failIfNoMatch>false</failIfNoMatch>
	</configuration>
</execution>

but the result is the same.

If value is empty I can relay that can be something wrong resolving the variables, but if even name and regex are considered empty there is something wrong at the basic of the configuration

At this point can be another problem here, not the usual one

@NicolaSpreafico
Copy link
Author

Hi,
I want you to know that I created a StackOverflow question for the problem related to the project.version, but I quoted the problem we already discussed

https://stackoverflow.com/questions/46149139/build-helper-maven-plugin-unable-to-use-replaced-value-with-other-plugins

@TheSnoozer
Copy link
Collaborator

TheSnoozer commented Sep 14, 2017

Thinking about this feature.
Could be done using the following configuration:

<replacementProperties>
	<replacementProperty>
		<!-- input -->
		<property>git.branch</property>
		<!-- optional output property -->
		<outputProperty>git.branch.replacemagic</outputProperty>
		<token>^([^\/]*)\/([^\/]*)$</token>
		<value>$1-$2</value>
		<regex>true</regex>
		<transformationRules>
			<transformationRule>
				<apply>BEFORE_REGEX</apply>
				<action>CAPITALIZATION</action>
			<transformationRule>
			<transformationRule>
				<apply>BEFORE_REGEX</apply>
				<action>INVERT_CASE</action>
			<transformationRule>
			<transformationRule>
				<apply>AFTER_REGEX</apply>
				<action>LOWER_CASE</action>
			<transformationRule>
		</transformationRules>
	</replacementProperty>
</replacementProperties>

transformationRules - would be optional - None by default
apply and action - would be required - a default here does not seem to make sense

This is the very first draft and thus, I'm not sure about the naming. I def. want something sounding very generic...eventhough it would be a pain to parse somehow the enums in a nested configuration object (yeah thats the most tricky part here).

Regardless of the naming this seems that could do the magic what is being asked for and with generic names could easily be extended...

@NicolaSpreafico
Copy link
Author

One advice I can think of, allow to declare a different output property for the regex.
I mean, maybe someone want to keep git.branch as the original one (w/o modifications) but also creating a new git.branch.something by the side.

Something like the "name" property of the build-help plugin

@TheSnoozer
Copy link
Collaborator

@NicolaSpreafico thanks for the feedback. Almost missed that...I added it to my previous comment; obviously this property definition would be optional and by default it would use the same property as given in the input...

Note for future references:
Filtering is applied after the replacement, thus one need to double check if the property is not excluded by accident...I would consider this as works as expected then...

TheSnoozer pushed a commit to TheSnoozer/git-commit-id-maven-plugin that referenced this issue Sep 21, 2017
TheSnoozer pushed a commit to TheSnoozer/git-commit-id-maven-plugin that referenced this issue Sep 23, 2017
…hlight potential future candidates (those would most likely require stringutils - additional dependency)
TheSnoozer pushed a commit that referenced this issue Sep 23, 2017
Improve properties replacement and allow to change the case of letters (#317) and fix the runningOnBuildServer check for detecting the branch name on Jenkins / Hudson to also check 'HUDSON_HOME' and 'JENKINS_HOME' (#326)
@TheSnoozer TheSnoozer added this to the 2.2.4 milestone Sep 23, 2017
@TheSnoozer
Copy link
Collaborator

Feature added with #327 will be available with the upcoming 2.2.4

TheSnoozer pushed a commit to TheSnoozer/git-commit-id-maven-plugin that referenced this issue Sep 24, 2017
…-profile that is being executed; note Maven is not required to use the constructer to create a Transformation rule and thus we need to set the applyRule and actionRule
TheSnoozer pushed a commit to TheSnoozer/git-commit-id-maven-plugin that referenced this issue Sep 24, 2017
…sted objects at least fail as early as possible with a somewhat meaningfull message when the required parameters are not set
TheSnoozer pushed a commit that referenced this issue Sep 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants