如何在API中获得完整的TFS迭代详细信息

时间:2015-07-09 23:35:32

标签: c# tfs iteration workitem

我正在尝试扫描曾经在冲刺中的WorkItems的TFS。 现在通过正常的TFS查询,您可以在Iteration Id上搜索并使用Was Ever运算符,但要获取该ID,您必须拥有一个已知的WorkItem,它已经在某个时间点,当前或在它的历史。

我已经能够在路径是积压或冲刺迭代的地方组装,开始这些迭代的停止日期,而不是ID

理想情况下,我想提供其Guid或其路径来获取其ID, 但是我无法在哪里获得

的简单整数ID

目前,我使用以下内容获取迭代树:

public static IterationTreeItem GetIterationTree()
{
    var structures = TfsShared.Instance.CommonStructureService.ListStructures(TfsShared.Instance.ProjectInfo.Uri);
    var iterationNode = structures.First(_ => _.Name == "Iteration");

    var rawIterationTree = TfsShared.Instance.CommonStructureService.GetNodesXml(new[] { iterationNode.Uri }, true);
    var iterationTree = rawIterationTree.FirstChild;

    var teams = TfsShared.Instance.AllTeams.ToList();

    var configs = TfsShared.Instance.TeamSettingsConfigurationService
                     .GetTeamConfigurations(teams.Select(_ => _.Identity)
                                                 .Select(_ => _.TeamFoundationId));

    var backLogPaths = configs.Select(_ => _.TeamSettings.BacklogIterationPath)
                                  .OrderBy(_ => _)
                                  .Distinct()
                                  .ToArray();

    var fullTree = new IterationTreeItem(iterationTree);

    var iterationList = IterationTreeItem.Flatten(fullTree).ToList();

    IterationTreeItem.SetBackLogsOrSprints(iterationList, backLogPaths);
    return fullTree;
}

我从ICommonStructureServices返回的结构看起来像,但包含更多的团队和冲刺:

<?xml version="1.0" encoding="utf-8"?>
<Nodes xmlns="">
    <Node NodeID="vstfs:///Classification/Node/43eaa612-c4b1-4043-bbd6-62f56387a7c8" Name="Iteration" Path="\coresystems\Iteration" ProjectID="vstfs:///Classification/TeamProject/4f1ea3c6-5306-4671-b806-8c2df536d218" StructureType="ProjectLifecycle">
        <Children>
            <Node NodeID="vstfs:///Classification/Node/6c123a22-c647-489a-a683-ca6a5bb19f92" Name="Team01" ParentID="vstfs:///Classification/Node/43eaa612-c4b1-4043-bbd6-62f56387a7c8" Path="\coresystems\Iteration\Team01" ProjectID="vstfs:///Classification/TeamProject/4f1ea3c6-5306-4671-b806-8c2df536d218" StructureType="ProjectLifecycle">
                <Children>
                    <Node NodeID="vstfs:///Classification/Node/27efc3cf-270f-463b-9aec-1569d7eaec8a" Name="Sprint1" ParentID="vstfs:///Classification/Node/6c123a22-c647-489a-a683-ca6a5bb19f92" Path="\coresystems\Iteration\Team01\Sprint1" ProjectID="vstfs:///Classification/TeamProject/4f1ea3c6-5306-4671-b806-8c2df536d218" StructureType="ProjectLifecycle" />
                    <Node NodeID="vstfs:///Classification/Node/987b4bae-83ea-4f6f-beba-697ab8bb039f" Name="Sprint2" ParentID="vstfs:///Classification/Node/6c123a22-c647-489a-a683-ca6a5bb19f92" Path="\coresystems\Iteration\Team01\Sprint2" ProjectID="vstfs:///Classification/TeamProject/4f1ea3c6-5306-4671-b806-8c2df536d218" StructureType="ProjectLifecycle" />
                </Children>
            </Node>
        </Children>
    </Node>
</Nodes>

现在IterationTreeItem类如下所示:

[DebuggerDisplay("{CleanIterationPath,nq}")]
public class IterationTreeItem
{
    private readonly List<IterationTreeItem> _children = new List<IterationTreeItem>();

    public IterationTreeItem(XmlNode node)
    {
        if (node != null)
        {
            XmlNode = node;

            var nodeId = GetNodeId(node);

            NodeInfo = TfsShared.Instance.CommonStructureService.GetNode(nodeId);
            if (node.FirstChild != null)
            {
                var children = node.FirstChild.ChildNodes.OfType<XmlNode>()
                                   .Select(_ => new IterationTreeItem(_, this))
                                   .ToArray();

                Children.AddRange(children);
            }
        }
    }

    private IterationTreeItem(XmlNode node, IterationTreeItem parent)
        : this(node)
    {
        Parent = parent;
    }

    public List<IterationTreeItem> Children
    {
        get { return _children; }
    }

    public string CleanBacklogPath
    {
        get
        {
            var parts = CleanIterationPath.Split('\\').ToArray();
            return string.Join("\\", parts.Take(Math.Max(parts.Length - 1, 1)));
        }
    }

    public string CleanIterationPath
    {
        get
        {
            if (NodeInfo != null)
            {
                var notStartedWithSlashes = NodeInfo.Path.Substring(1);
                return notStartedWithSlashes.Replace("\\Iteration", string.Empty);
            }
            return string.Empty;
        }
    }
    public bool? IsProductBackLogIteration { get; private set; }

    public bool? IsSprintIteration { get; private set; }

    public NodeInfo NodeInfo { get; private set; }

    public IterationTreeItem Parent { get; private set; }

    public XmlNode XmlNode { get; private set; }

    public static IEnumerable<IterationTreeItem> Flatten(IterationTreeItem item)
    {
        yield return item;
        foreach (var childChild in item.Children.SelectMany(Flatten))
        {
            yield return childChild;
        }
    }

    public static void SetBackLogsOrSprints(IEnumerable<IterationTreeItem> items, IEnumerable<string> knownBacklogs)
    {
        var backLogs = knownBacklogs as List<string> ?? knownBacklogs.ToList();
        foreach (var iterationTreeItem in items)
        {
            if (backLogs.Any(_ => _ == iterationTreeItem.CleanIterationPath))
            {
                iterationTreeItem.IsProductBackLogIteration = true;
                iterationTreeItem.IsSprintIteration = false;
            }
            else
            {
                iterationTreeItem.IsProductBackLogIteration = false;
                iterationTreeItem.IsSprintIteration = true;
            }
        }
    }

    private static string GetNodeId(XmlNode node)
    {
        if (node.Attributes != null)
        {
            var otherNodeId = node.Attributes.OfType<XmlAttribute>().First(_ => _.Name == "NodeID").Value;
            return otherNodeId;
        }

        var xml = node.OuterXml;
        const string first = "NodeID=\"";
        var start = xml.IndexOf(first, StringComparison.Ordinal) + first.Length;
        var end = xml.IndexOf("\"", start, StringComparison.Ordinal);
        return xml.Substring(start, (end - start));
    }
}

0 个答案:

没有答案