views:

558

answers:

5

Is there a way to prompt the user for input during a NAnt build? I want to execute a command that takes a password, but I don't want to put the password into the build script.

+4  A: 

A solution I have used many times is to have a local config file containing such things as passwords, connection strings etc. that are specific to each developer. The NAnt build script will include these settings when building.

The local config file does not exist in the version control system so passwords are not exposed. The first time a developer checks out a code base and tries to build he has to create this config file. To make it easy for him, there could be a template file available such as my.config.template containing all the properties that can be customized.

Jonas Kongslund
I considered that, but it seems more work than necessary for each developer. If I end up with several settings, I might switch to that.
Don Kirkby
This is something you will only have to do once when building for the first time. I would certainly prefer that instead of having to enter a password every time I want to build.
Jonas Kongslund
+2  A: 

Try this :

<script language="C#" prefix="test" >
          <code>
            <![CDATA[
              [Function("get-password")]
              public static string GetPassword(  ) {
                  Console.WriteLine("Please enter the password");
                  ConsoleColor oldForegroundColor = Console.ForegroundColor;           
             Console.ForegroundColor = Console.BackgroundColor;
                  string password = Console.ReadLine();
             Console.ForegroundColor = oldForegroundColor;
     return password;
              }
            ]]>
          </code>
</script>

<target name="test.password">
 <echo message='${test::get-password()}'/>
</target>

-->
sundar venugopal
I was experimenting with something similar, but changing the ForegroundColor is a great idea!
Don Kirkby
+4  A: 

I'm using a script for now, but I'd love to hear if there's a prebuilt method already available. Many thanks to sundar for the ForegroundColor trick.

I'm not sure if it matters whether you use Project.Log or go direct to Console.WriteLine(), any NAnt ninjas want to educate me?

Here's the script and a sample target that uses it:

<target name="input">
    <script language="C#" prefix="password" >
        <code><![CDATA[
            [Function("ask")]
            public string AskPassword(string prompt) {
                Project.Log(Level.Info, prompt);
                ConsoleColor oldColor = Console.ForegroundColor;
                Console.ForegroundColor = Console.BackgroundColor;
                try
                {
                    return Console.ReadLine();
                }
                finally
                {
                    Console.ForegroundColor = oldColor;
                }
            }
        ]]></code>
    </script>

    <echo message="Password is ${password::ask('What is the password?')}"/>
</target>
Don Kirkby
A: 

Don , I like the way you presented the answer, message is same, but with a big difference.

Thanks i got to learn presentation.

sundar venugopal
I appreciate the help, so if you want to clean up your answer, I'll delete mine and let you get the votes.
Don Kirkby
+2  A: 

This displays asterisks as you type the password:

    <code><![CDATA[
        [Function("ask")]
        public string AskPassword(string prompt) {
            Project.Log(Level.Info, prompt);
            string password = "";

            // get the first character of the password
            ConsoleKeyInfo nextKey = Console.ReadKey(true);

            while (nextKey.Key != ConsoleKey.Enter)
            {
                if (nextKey.Key == ConsoleKey.Backspace)
                {
                    if (password.Length > 0)
                    {
                        password = password.Substring(0, password.Length - 1);

                        // erase the last * as well
                        Console.Write(nextKey.KeyChar);
                        Console.Write(" ");
                        Console.Write(nextKey.KeyChar);
                    }
                }
                else
                {
                    password += nextKey.KeyChar;
                    Console.Write("*");
                }

                nextKey = Console.ReadKey(true);
            }

            Console.WriteLine();

            return password;
        }
    ]]></code>
cc