Hi Ian:
I looked at the code; my comments are below. I wasn't able to run and test the code because my ClearCase trial license has expired.
This implementation is fairly similar to <exec>, in that it allows any generic command to be run, but because it is so generic does not offer fine-grained control.
Positives:
* allows you to run any cleartool command.
* doesn't require you to know where cleartool.exe (but, by default, the ClearCase installation puts cleartool in your path. So an <exec> with just cleartool.exe as the executable would work.)
* uses interop, which probably gives it a performance boost.
Negatives:
* as best I can tell, the pass/fail logic of this is that if a COMException is thrown in Execute(), the task fails. If not, it passes. This is fairly crude. I'm not sure about this, though, because I couldn't test the code.
* requires you to dig through the docs to find the correct commandline syntax. More specific tasks, like my clearcase-update and vssget, have specific attributes for each piece of information. For example, specifying <vssget user="john" password="foo" ... /> is easier and more elegant than knowing Visual SourceSafe's command line: ss.exe get ... -Yjohn,foo ...
I suggest including this task after testing to see how the pass/fail logic works. You may also ask the author.
I also would include mine. For a ClearCase update, I'd use my task. For any others, I'd use ClearToolTask.
Best,
Garrett Smith
Ian MacLean <[EMAIL PROTECTED]>
05/17/2004 10:06 PM |
To: Garrett Smith <[EMAIL PROTECTED]> cc: Subject: Re: [NAntC-Dev] ClearCase support submitted |
Hi Garret,
Heres the other clearcase task. It uses the clearcase com api rather
than wrapping the exe. Whats your feeling on that ? Is the com library
likely to change prequently between versions thereby breaking any task
based on it ?
Ian
Garrett Smith wrote:
>Ian:
>
>It's good news you got two submissions. I'll take a look at it and
>provide comments.
>
>Would you mind e-mailing me the source? I didn't get the attachment via
>my digests from the list.
>
>My intuition would be the code that uses the interop dll would be better.
>Although "any valid cleartool command" would imply that you'd just pass
>arguments in via the nant script. If that's the case, how does the other
>code differ from just using an <exec> on cleartool.exe?
>
>Best,
>Garrett
>
>
>
>
>
>Ian MacLean <[EMAIL PROTECTED]>
>05/14/2004 11:18 PM
>
> To: Garrett Smith <[EMAIL PROTECTED]>
> cc: [EMAIL PROTECTED]
> Subject: Re: [NAntC-Dev] ClearCase support submitted
>
>
>Thanks Garret,
>We've also just received another clear case task - on the same day- one
>that uses the automation library and can run any clearcase command. See
>my recent post where I forwarded the code to the list. I don't run clear
>case but add the moment I'd lean towards adding the automation based
>version. Would you mind looking at the alternative implementation and
>let me know if it is feature compatible with your s ?
>
>As a heads up - when developing a nant task that wraps an executable its
>easier and more consistent to derive your task from ExternalProgramBase.
>This base class handles all the mechanics of calling the process and
>gathering its output and error streams - saving you from having to
>duplicate it.
>
>Ian
>
>
>Garrett Smith wrote:
>
>
>
>>I've submitted a patch (#953622) that provides the ability to update
>>source via ClearCase. Send me a message if you have any questions.
>>
>>Best,
>>Garrett
>>
>>
>>
>>
>
>
>
--
Ian MacLean, Developer,
ActiveState, a division of Sophos
http://www.ActiveState.com
//
// NAntContrib
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Tom Whitner ([EMAIL PROTECTED]
using System;
using System.IO;
using System.Xml;
using NAnt.Core;
using NAnt.Core.Attributes;
using ClearCase;
namespace NAnt.Contrib.Tasks {
/// <summary>
/// Executes any ClearTool command from within NAnt scripts.
/// </summary>
/// <remarks>
/// <para>This task requires the ClearCase client software to be installed.</para>
/// <para>Please refer to ClearCase documentation for ClearTool command syntax.</para>
/// </remarks>
/// <example>
/// <para>Updates the view at c:\views\myview and stores the ClearTool output in the 'cleartool.result' property.</para>
/// <code>
/// <![CDATA[
/// <cleartool command="update c:\views\myview" property="cleartool.result"/>
/// ]]>
/// </code>
/// </example>
/// <example>
/// <para>Checks out the file c:\views\myview\sample.cs without comment and discards the ClearTool output.</para>
/// <code>
/// <![CDATA[
/// <cleartool command="checkout -nc c:\views\myview\sample.cs"/>
/// ]]>
/// </code>
/// </example>
[TaskName("cleartool")]
public class ClearToolTask : Task {
#region Private Instance Fields
string _command = null;
string _property = null;
#endregion Private Instance Fields
#region Private Static Fields
private static IClearTool _clearTool = null;
#endregion Private Static Fields
#region Public Instance Properties
/// <summary>
/// The ClearTool command to be executed.
/// </summary>
[TaskAttribute("command", Required=true)]
public string Command {
get { return _command; }
set { _command = value; }
}
/// <summary>
/// The property where the result of the requested command will be stored.
/// </summary>
[TaskAttribute("property", Required=false)]
public string Property {
get { return _property; }
set { _property = value; }
}
#endregion Public Instance Properties
#region Private Instance Properties
/// <summary>
/// Retrieves a single isntance of the ClearTool aotumation object for a build
/// </summary>
private IClearTool ClearTool {
get {
if (_clearTool == null) {
try {
_clearTool = new ClearToolClass();
}
catch (Exception ex) {
throw new BuildException("ClearTool object could not be created.", Location, ex);
}
}
return _clearTool;
}
}
#endregion Private Instance Properties
#region Override implementation of Task
/// <summary>
/// Executes the ClearTool command using automation
/// </summary>
protected override void ExecuteTask() {
Require(_command, "command");
IClearTool ct = this.ClearTool;
string ctResult = null;
try {
Log(Level.Info, LogPrefix + "ClearTool: {0}", _command);
ctResult = ct.CmdExec(_command);
Log(Level.Info, LogPrefix + " Result: {0}", ctResult);
}
catch (Exception ex) {
throw new BuildException(string.Format("ClearTool command '{0}' failed to execute.", _command), Location, ex);
}
if ((_property != null) && (_property.Length > 0)) {
Properties[_property] = ctResult;
}
}
#endregion Override implementation of Task
#region Private Instance Methods
/// <summary>
/// Requires a <see cref="string"/> to be present or throws an exception.
/// </summary>
/// <param name="s">The string to test</param>
/// <param name="name">The name of the string to be included in the exception description</param>
/// <exception cref="BuildException">Thrown if <paramref name="s"/> is <see langword="null"/> or zero length.</exception>
protected void Require(string s, string name) {
if ((s == null) || (s.Length == 0)) {
throw new BuildException(string.Format("{0} is required.", name), Location);
}
}
#endregion Private Instance Methods
}
}