ほんじゃらねっと

ダイエット中プログラマのブログ

NAntのカスタムタスクで実行時にユーザー入力を受け付ける

便利タスクを作っていく上で、実行時に処理対象を指定したりできた方がいい、
ということでユーザー入力を受け付ける方法を調査した。


方法としては2つあって、どちらもプロパティ(変数みたいなもの)に
ユーザーからの入力を代入するというもの。

  1. nantコマンド実行時に -D オプションでプロパティ名と値を指定する
  2. ユーザー入力を受け付けるカスタムファンクションを作成する


1つ目の -D オプションによるプロパティ定義は、buildファイルにpropertyタグを書くのと同じ効果。
こんな感じで指定する

nant タスク名 -D:プロパティ名=プロパティ値
nant greetings -D:message=Hello!


これは、buildファイルに下記のタグを書くのと同じ。

<property name="message" value="Hello!" />


実行時に入力を受け付けるにはこれで十分なのだけど、せっかく調べたので
カスタムファンクションを作成する方法も書いておく。


どうやらNAntにはユーザー入力を受け付ける関数なりタスクは用意されていないようで、
自分でカスタムファンクションとしてユーザーに入力を促す処理を書くことで実現する。


入力処理についてはここを参考にした。
http://www.mail-archive.com/nant-users%40lists.sourceforge.net/msg11606.html


カスタムファンクションについては、ソースを見るのが一番良いようだけど、
ここからヒントをもらった。
http://efreedom.com/Question/1-284120/NAnt-Extension-Function-Project-Object


上記を参考にこんなクラスを作成。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAnt.Core;
using NAnt.Core.Attributes;
namespace MyTasks.Funcs
{
[FunctionSet("basic", "Basic")]
class BasicFunctions : FunctionSetBase
{
public BasicFunctions(Project project, PropertyDictionary properties)
:base(project, properties)
{
}
[Function("getInput")]
public static string GetInput()
{
Console.WriteLine("Enter a string:");
string s = Console.ReadLine();
return s.ToString();
}
}
}


buildファイルに下記のようなpropertyタグを作成すると、ユーザー入力を促して
プロパティ値に設定することができる。

<property name="message" value="${basic::getInput()}" />


この2つの入力方法を組み合わせて、コマンド実行時にプロパティを指定していなければ
ユーザー入力を促す、という処理を作成するとしたら、こんな感じでビルドファイルに定義する。

...
<target name="greetings" depends="load">
<if test="${not property::exists('message')}">
<property name="message" value="${basic::getInput()}" />
</if>
<greetings mesg="${message}" />
</target>
...