titusn
titusn

Reputation: 1224

How to find path to executable in Ant

In my Ant build file I want to test whether the mysql command is found on the environment path. This should be system independent.

What I did until now was the following:

        <trycatch property="mysql.error">
        <try>
            <echo message="Testing mysql..." />
            <exec executable="mysql" outputproperty="null" append="true" />
            <echo message="MySQL executable found in path." />
            <property name="mysql.command" value="mysql"/>
        </try>
        <catch>
            <echo message="MySQL executable not found in path, trying to locate default folder." />
            <if>
                <istrue value="${isWindows}"/>
                <then>
                    <antcallback target="search-file-windows" return="search.result"> 
                        <param name="search.target" value="mysql.exe"/>
                    </antcallback>
                    <property name="mysql.command" value="${search.result}"/>
                </then>
                <else>
                    <property name="mysql.command" value="/usr/local/mysql/bin/mysql"/>
                </else>
            </if>
            <echo message="MySQL executable found at location: ${mysql.command}." />
            <trycatch property="mysql.error">
                <try>
                    <echo message="Possible path found, testing again..." />
                    <exec executable="${mysql.command}" outputproperty="null" append="true" />
                    <echo message="MySQL executable found at location: ${mysql.command}." />
                </try>
                <catch>
                    <fail message="Unable to locate MySQL executable. Please add your local MySQL installation to the PATH environment variable."/>
                </catch>
            </trycatch>
        </catch>
    </trycatch>

So I just execute the mysql command and if that fails, I will run a batch file which does some magic to efficiently search for mysql. However the check fails if there is any error in calling mysql, even if it is found in the path. On my Windows machine this happens, because just starting mysql gives the following error: ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost'

This error is fixable of course, but I am really looking for a generic solution. Now the PATH variable contains "C:\Program Files\MySQL\MySQL Server 5.6\bin" so the solutions in this question will not work: Check if executable command exists using ant

Any ideas?

Upvotes: 2

Views: 2622

Answers (2)

Chad Nouis
Chad Nouis

Reputation: 7051

The following Ant script uses the third-party Ant-Contrib library's <for> task:

<project name="ant-first-match-on-path" default="run">
  <taskdef resource="net/sf/antcontrib/antlib.xml"/>

  <target name="run">
    <property name="executable-name" value="mysql"/>
    <condition property="executable-filename" 
        value="${executable-name}.exe" 
        else="${executable-name}"
    >
        <os family="windows"/>
    </condition>
    <property environment="env" />

    <for param="dir">
        <path>
          <pathelement path="${env.PATH}"/>
          <pathelement path="${env.Path}"/>
        </path>
      <sequential>
        <if>
          <not>
            <isset property="first-match"/>
          </not>
          <then>
            <local name="executable-absolute-path"/>
            <property 
                name="executable-absolute-path" 
                location="@{dir}/${executable-filename}"
            />
            <available 
                file="${executable-absolute-path}" 
                property="first-match" 
                value="${executable-absolute-path}"
            />
          </then>
        </if>
      </sequential>
    </for>

    <condition property="echo-message" 
        value="First [${executable-filename}] found at [${first-match}]." 
        else="[${executable-filename}] not found on PATH."
    >
      <isset property="first-match"/>
    </condition>
    <echo message="${echo-message}"/>
  </target>
</project>

Upvotes: -1

user4524982
user4524982

Reputation:

available can do the trick for you, you "only" need to deal with the differences between Windows and Unix-likes.

Something like this

<!-- load environment variables into properties -->
<property environment="env"/>
<!-- On Windows the Environment-Variable is not all uppercase -->
<path id="combined-PATH">
  <pathelement path="${env.PATH}"/>
  <pathelement path="${env.Path}"/>
</path>
<!-- toString() -->
<property name="PATH" refid="combined-PATH"/>
<condition property="mysql.found">
  <or>
    <available file="mysql.exe" filepath="${PATH}"/>
    <available file="mysql" filepath="${PATH}"/>
  </or>
</condition>

will set the property mysql.found if and only if mysql is on the PATH.

Upvotes: 4

Related Questions