예제 #1
0
    public async Task <Tuple <Parts, TreeResponse> > TreeFrom(Parts source, bool throwsIfNotFound)
    {
        Debug.Assert(source.Type == TreeEntryTargetType.Tree);

        if (treeCachePerPath.TryGetValue(source.Url, out var treeResponse))
        {
            return(treeResponse);
        }

        string sha;

        if (source.Path == null)
        {
            var commit = await RootCommitFrom(source);

            sha = commit.Tree.Sha;
        }
        else
        {
            var parentTreePart     = source.ParentTreePart;
            var parentTreeResponse = await TreeFrom(parentTreePart, throwsIfNotFound);

            if (parentTreeResponse == null)
            {
                return(null);
            }

            var name     = source.Path.Split('/').Last();
            var treeItem = parentTreeResponse.Item2.Tree.FirstOrDefault(ti => ti.Type == TreeType.Tree && ti.Path == name);

            if (treeItem == null)
            {
                if (throwsIfNotFound)
                {
                    throw new Exception($"[{source.Type}: {source.Url}] doesn't exist.");
                }

                return(null);
            }

            sha = treeItem.Sha;
        }

        log(string.Format("API Query - Retrieve tree '{0}' ({3}) details from '{1}/{2}'.",
                          sha.Substring(0, 7), source.Owner, source.Repository, source.Url));

        var tree = await client.Git.Tree.Get(source.Owner, source.Repository, sha);

        var parts = new Parts(source.Owner, source.Repository, TreeEntryTargetType.Tree, source.Branch, source.Path, tree.Sha);

        var treeFrom = AddToPathCache(parts, tree);

        AddToKnown <TreeResponse>(parts.Sha, parts.Owner, parts.Repository);

        foreach (var i in tree.Tree)
        {
            switch (i.Type.Value)
            {
            case TreeType.Blob:
                var p = parts.Combine(TreeEntryTargetType.Blob, i.Path, i.Sha);
                AddToPathCache(p, i);
                AddToKnown <Blob>(i.Sha, source.Owner, source.Repository);
                break;

            case TreeType.Tree:
                AddToKnown <TreeResponse>(i.Sha, parts.Owner, parts.Repository);
                break;

            default:
                throw new NotSupportedException();
            }
        }

        return(treeFrom);
    }