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
                }
}

Reply via email to