【问题标题】:How to create a Visual Source Safe branch using NAnt如何使用 NAnt 创建 Visual Source Safe 分支
【发布时间】:2010-08-19 17:04:13
【问题描述】:

总结
我目前有一个NAnt 构建脚本,它在最新的源代码或特定分支(使用${branch} 参数)上执行vssget

每当我们进行生产构建/部署时,所构建的代码树都会创建一个分支,(这样我们就可以继续开发并且仍然知道生产中的代码库是什么,非常标准的东西......)

问题
该分支的创建过程仍然是手动的,由进入 Visual Source Safe Explorer 并执行分支过程的人执行。我想知道NAnt 中是否有任何方法可以创建 VSS 分支。

当前计划
我已经知道使用<exec program="ss"> 并试图避免这种情况,但在没有更好的解决方案的情况下,这是我最可能采取的方法。

有谁知道这是否有 NAntNAntContrib 目标,或者是否有人有他们过去曾经这样做过的脚本任务并且可以为此提供代码,那将是非常非常感谢。

免责声明
我了解 cvs、svn、git 和所有其他源代码管理解决方案,目前无法更改工具 p>

【问题讨论】:

    标签: version-control branch nant visual-sourcesafe nantcontrib


    【解决方案1】:

    我们在我工作的地方确实需要这个。我拼凑了一个名为“vssbranch”的小任务(不是特别有创意,但这里是代码……一个示例构建文件及其执行的输出:

    代码:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    
    using SourceSafeTypeLib;
    
    using NAnt.Core;
    using NAnt.Core.Attributes;
    
    namespace NAnt.Contrib.Tasks.SourceSafe
    {
        [TaskName("vssbranch")]
        public sealed class BranchTask : BaseTask
        {
            /// <summary>
            /// The label comment.
            /// </summary>
            [TaskAttribute("comment")]
            public String Comment { get; set; }
    
            /// <summary>
            /// Determines whether to perform the branch recursively.
            /// The default is <see langword="true"/>
            /// </summary>
            [TaskAttribute("recursive"),
            BooleanValidator()]
            public Boolean Recursive { get; set; }
    
            [TaskAttribute("branchname", Required = true)]
            public String BranchName { get; set; }
    
    
            protected override void ExecuteTask()
            {
                this.Open();
                try
                {
                    if (VSSItemType.VSSITEM_PROJECT != (VSSItemType)this.Item.Type)
                        throw new BuildException("Only vss projects can be branched", this.Location);
    
                    IVSSItem newShare = null;
                    this.Comment = String.IsNullOrEmpty(this.Comment) ? String.Empty : this.Comment;
                    if (null != this.Item.Parent)
                        newShare = this.Item.Parent.NewSubproject(this.BranchName, this.Comment);
    
                    if (null != newShare)
                    {
                        newShare.Share(this.Item as VSSItem, this.Comment,
                            (this.Recursive) ?
                                (int)VSSFlags.VSSFLAG_RECURSYES : 0);
                        foreach (IVSSItem item in newShare.get_Items(false))
                            this.BranchItem(item, this.Recursive);
                    }
                }
                catch (Exception ex)
                {
                    throw new BuildException(String.Format("Failed to branch '{0}' to '{1}'", this.Item.Name, this.BranchName), this.Location, ex);
                }
            }
    
            private void BranchItem(IVSSItem itemToBranch, Boolean recursive)
            {
                if (null == itemToBranch) return;
    
                if (this.Verbose)
                    this.Log(Level.Info, String.Format("Branching {0} path: {1}", itemToBranch.Name, itemToBranch.Spec));
    
                if (VSSItemType.VSSITEM_FILE == (VSSItemType)itemToBranch.Type)
                    itemToBranch.Branch(this.Comment, 0);
                else if (recursive)
                {
                    foreach (IVSSItem item in itemToBranch.get_Items(false))
                        this.BranchItem(item, recursive);
                }
            }
        }
    }
    

    构建文件:

            <echo message="About to execute: VSS Branch" />
    
            <echo message="Source Safe Path: ${SourceSafeRootPath}/${CURRENT_FILE}" />
    
            <vssbranch
                  username="my_user_name"
                  password="my_password"
                  recursive="true"
                  comment="attempt to make a branch"
                  branchname="test-branch"
                  dbpath="${SourceSafeDBPath}"
                  path="${SourceSafeRootPath}/${CURRENT_FILE}"
                  verbose="true"
                />
    
        </foreach>
    </target>
    

    输出:

    NAnt 0.85(内部版本 0.85.2478.0;发布;2006 年 10 月 14 日) 版权所有 (C) 2001-2006 Gerry Shaw http://nant.sourceforge.net

    构建文件:file:///C:/scm/custom/src/VssBranch/bin/Debug/test.build 目标框架:Microsoft .NET Framework 2.0 指定的目标:运行

    运行:

    [loadtasks] 扫描程序集“NAnt.Contrib.Tasks”的扩展。 [loadtasks] 扫描程序集“VssBranch”以获取扩展。 [echo] 即将执行:VSS 分支

    ....

    [vssbranch] 分支 SecurityProto 路径:$/VSS/Endur's Source/C#/DailyLive/proto/test-branch/SecurityProto

    ....

    构建成功

    总时间:12.9 秒。

    显然输出会有所不同,我从名为“params.txt”的文本文件中拉入要分支的项目。此任务执行 VSS 世界中所谓的“共享和分支”(共享后立即分支)...其他源代码控制系统不需要在分支之前共享,嗯...改天了

    【讨论】:

    • 我是否必须在单独的 DLL 中构建它,还是应该将它放在原始 NAntContrib 解决方案文件中?如果我将它构建到原始的 NAntContrib 解决方案中,我是否应该使用构建的 DLL 来替换我当前的 NAntContnrib dll?
    • 对不起...我没有包含说明...我在自己的项目中编译了源代码,只是引用了 NAntContrib(以及所有 NAntContrib 引用的项目...在这种情况下,它们是 SourceSafe .Interop.dll 和 NAnt.Core.dll)
    • 谢谢,我会试试的。我获取了 NAntContrib 源代码,并将 vssbranch 任务构建到其中,并让它工作。我确实找到了一个错误,它似乎正在截断文件名,然后抛出一个找不到文件的异常,这似乎是 API 中的一个错误(不确定)。我确实想添加一个failonerror 属性,如果一个文件中断,它会跳过并继续分支...
    【解决方案2】:

    vss 任务存在于 NAntContrib 项目中,不,目前没有支持分支的任务。不过,按照 NAntContrib 中现有 vss 任务(添加、签出、签入等)的模型,您可以grab the source 并自己扩展它。也就是说,如果 VSS API 支持分支。

    【讨论】:

    • 这正是我所怀疑的,但感谢您的确认。我实际上已经下载了 NAntContrib 源并开始摆弄它,但我怀疑我是否会有足够的“官方”时间来编写我自己的 vssbranch 任务,所以我可能会将 exec 与 ss.exe 一起使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多