How to Set the Working Directory in NAnt?
Asked Answered
O

6

6

I am just getting started using NAnt. I was working from a tutorial, and just trying to set a target to clean my solution on build. My Visual Studio Solution structure is as follows:

  • Solution Folder
    • Project Folder
    • Project Folder
    • Tools Folder
      • NAnt Folder

The NAnt .exe file resides in the Tools/NAnt folder. My .build file is also in there. Here is my .build file:

<?xml version="1.0" encoding="utf-8" ?>
<project name="NAntTest" default="build" xmlns="http://nant.sf.net/release/0.86-beta1/nant.xsd">
  <property name="solution.file.name" value="NAntTest.sln" />
  <property name="project.config" value="debug" />

  <target name="build" depends="clean.source" />

  <target name="clean.source">
    <exec program="${framework::get-framework-directory(framework::get-target-framework())}\msbuild.exe"
          commandline="${solution.file.name} /t:Clean /p:Configuration=${project.config} /v:q" 
          workingdir="."/>
  </target>

</project>

This is how the example I am following was formatted. If I try to run this build, I get an error stating that the project file does not exist. In the clean.source target, if I replace the workingdir attribute with a hard coded path to my base solution folder, the script compiles and runs correctly. Obviously, this is not ideal for portability if I need to move the project anywhere.

How do I get NAnt to see the base working directory?

Ophthalmology answered 16/4, 2009 at 11:34 Comment(0)
I
7

My recommendation is to always place the build file at solution level. Then all relative paths in the build file will be equal to that of the solution.

Immorality answered 16/4, 2009 at 11:51 Comment(2)
Moving this up into the solution directory worked. Thanks for the help!Ophthalmology
It'll work, but I mean, the advice isn't exactly sound. Just set basedir appropriately. (Btw, wasn't me that downvoted.)Samathasamau
H
7

There is not builtin function to change the current directory, but you can create one in a script block :

  <target name="foo">
    <echo message="Current directory set to ${directory::set-current-directory('C:')}"/>
    <echo message="Current directory is now ${directory::get-current-directory()}"/>
  </target>

  <script language="C#" prefix="directory">
    <code><![CDATA[
    [Function("set-current-directory")]
    public static string SetCurrentDirectory(string path)
    {
      System.IO.Directory.SetCurrentDirectory(path);
      return path;
    }
    ]]></code>
  </script>

Of course, you should avoid relying on the current directory in your scripts or in your code.

Hellenic answered 18/3, 2011 at 8:1 Comment(0)
T
2

You could try setting the basedir attribute of the project node. This may resolve your problem.

<project name="NAntTest" default="build" basedir="C:\Code\MyProject" xmlns="http://nant.sf.net/release/0.86-beta1/nant.xsd">
Tiffanietiffanle answered 16/4, 2009 at 11:48 Comment(2)
You should probably set the basedir using a relative path (i.e. "..\..").Samathasamau
This is the correct answer, along with the comment to use a relative path.Patroon
U
1

If you set the verbose attribute of the nant exec task then it will spit out the exact command line that it generated. Not sure what your specific problem is regarding executing msbuild - I've been using the nantcontrib msbuild task instead.

Unhesitating answered 16/4, 2009 at 11:56 Comment(0)
V
0

There is now a workingdir attribute you can define on your exec element.

According to the documentation, workingdir refers to "The directory in which the command will be executed.".

Vachell answered 26/1, 2015 at 21:44 Comment(0)
T
0

As a task instead of a function:

<?xml version="1.0"?>
<project name="test" default="build">
    <script language="C#" prefix="path" >
        <code>
            <![CDATA[
            [TaskName("set-current-directory")]
            public class SetCurrentDirectory : Task {
                private string _path;

                [TaskAttribute("path", Required=true)]
                public string Path {
                    get { return _path; }
                    set { _path = value; }
                }

                protected override void ExecuteTask() {
                    System.IO.Directory.SetCurrentDirectory(_path);;
                }
            }
            ]]>
        </code>
    </script>

    <target name="build">
        <set-current-directory path="c:\Program Files" />
        <echo message="${directory::get-current-directory()}" />
     </target>
</project>

Output:

$ nant

build:

     [echo] c:\Program Files
Tuckerbag answered 26/10, 2017 at 9:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.