Garret Wilson
Garret Wilson

Reputation: 21496

Maven antrun move not deleting source file

Developing on Windows 10 I have a Java project in Maven that has a Linux "launcher" shell script for the FooBar utility stored in the repository at src/bin/foobar.sh. It uses resource filtering to substitute in the correct executable JAR path so that what gets built is a foobar.sh script that launches the executable JAR in the same directory.

The POM uses org.apache.maven.plugins:maven-antrun-plugin:1.8 to enable the executable flag on the foobar.sh script in the target/bin directory (which has been already been copied using Maven resource filtering, with that directory path stored in the ${binOutputDirectory} property):

<chmod dir="${binOutputDirectory}" includes="**/*.sh" perm="+x" />

Then it renames the foobar.sh file to simply foobar (i.e. it removes the extension) to follow best practices for shell scripts:

<move todir="${binOutputDirectory}">
  <fileset dir="${binOutputDirectory}">
    <include name="**/*.sh" />
  </fileset>
  <mapper type="glob" from="*.sh" to="*" />
</move>

You can see e.g. globalmentor-root pom.xml at c31ae410143f86ebf2bf10467214214d87b2eb61 for the full POM source code. Actual child POMs will simply enable the AntRun operations by providing their executions an appropriate phase like this:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
    <execution>
      <id>set-shell-scripts-executable</id>
      <phase>process-resources</phase>
    </execution>
    <execution>
      <id>remove-shell-script-extensions</id>
      <phase>process-resources</phase>
    </execution>
  </executions>
</plugin>

The essential part of that is working fine, and I wind up with a foobar file in my distributable ZIP file, with its executable flag enabled as desired. Unfortunately I also wind up with the original foobar.sh file as well, and I can see in target/bin (where the .sh extension gets removed) that both files are there as well. So it would appear that AntRun <move> is behaving as <copy>.

To see this in action, build the Guise Mummy 0.1.0 project and look in the cli/target/bin directory; you'll see that guise.sh has not been deleted.

To work around the problem, I can add an extraneous <delete> command; this will successfully remove foobar.sh. (The difference in <fileset> syntax is irrelevant; I switched only because it was more concise.)

<move todir="${binOutputDirectory}">
  <fileset dir="${binOutputDirectory}" includes="**/*.sh"/>
  <mapper type="glob" from="*.sh" to="*" />
</move>
<delete>
  <fileset dir="${binOutputDirectory}" includes="**/*.sh"/>
</delete>

Why is AntRun <move> by itself not removing the original target/bin/foobar.sh file after it copies it to target/bin/foobar as part of the move operation?

Upvotes: 4

Views: 346

Answers (2)

Garret Wilson
Garret Wilson

Reputation: 21496

Upgrading to org.apache.maven.plugins:maven-antrun-plugin:3.1.0 seems to have fixed the problem. When I created this question I had been using v1.8. I can only suppose that org.apache.maven.plugins:maven-antrun-plugin:1.8 is buggy.

Upvotes: 2

djmonki
djmonki

Reputation: 3957

Noticed in the pom, within the antrun goals, you are modifying permissions of the .sh script. This does not confirm if the shell script is writeable, it may be read-only:

<execution>
  <id>set-shell-scripts-executable</id>
  <!--
  Enable execute permission for the shell scripts in `${binOutputDirectory}`.
  Enable by specifying a phase (e.g. `process-resources`) in child POM.
  -->
  <phase>none</phase>
  <goals>
    <goal>run</goal>
  </goals>
  <configuration>
    <target>
      <chmod dir="${binOutputDirectory}" includes="**/*.sh" perm="+x" />
    </target>
  </configuration>
</execution>

Try the following, apply the overwrite attribute, like so:

(overwrite overwrite existing files even if the destination files are newer)

<move todir="${binOutputDirectory}" overwrite="true">
  <fileset dir="${binOutputDirectory}">
    <include name="**/*.sh" />
  </fileset>
  <mapper type="glob" from="*.sh" to="*" />
</move>

If that does not work, also add the force attribute, like so:

(force Overwrite read-only destination files)

<move todir="${binOutputDirectory}" overwrite="true" force="true">
  <fileset dir="${binOutputDirectory}">
    <include name="**/*.sh" />
  </fileset>
  <mapper type="glob" from="*.sh" to="*" />
</move>

Upvotes: -1

Related Questions