1package repository
 2
 3import (
 4	"io"
 5
 6	"github.com/ProtonMail/go-crypto/openpgp"
 7	"github.com/ProtonMail/go-crypto/openpgp/armor"
 8	"github.com/ProtonMail/go-crypto/openpgp/errors"
 9)
10
11// nonNativeListCommits is an implementation for ListCommits, for the case where
12// the underlying git implementation doesn't support if natively.
13func nonNativeListCommits(repo RepoData, ref string) ([]Hash, error) {
14	var result []Hash
15
16	stack := make([]Hash, 0, 32)
17	visited := make(map[Hash]struct{})
18
19	hash, err := repo.ResolveRef(ref)
20	if err != nil {
21		return nil, err
22	}
23
24	stack = append(stack, hash)
25
26	for len(stack) > 0 {
27		// pop
28		hash := stack[len(stack)-1]
29		stack = stack[:len(stack)-1]
30
31		if _, ok := visited[hash]; ok {
32			continue
33		}
34
35		// mark as visited
36		visited[hash] = struct{}{}
37		result = append(result, hash)
38
39		commit, err := repo.ReadCommit(hash)
40		if err != nil {
41			return nil, err
42		}
43
44		for _, parent := range commit.Parents {
45			stack = append(stack, parent)
46		}
47	}
48
49	// reverse
50	for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
51		result[i], result[j] = result[j], result[i]
52	}
53
54	return result, nil
55}
56
57// deArmorSignature convert an armored (text serialized) signature into raw binary
58func deArmorSignature(armoredSig io.Reader) (io.Reader, error) {
59	block, err := armor.Decode(armoredSig)
60	if err != nil {
61		return nil, err
62	}
63	if block.Type != openpgp.SignatureType {
64		return nil, errors.InvalidArgumentError("expected '" + openpgp.SignatureType + "', got: " + block.Type)
65	}
66	return block.Body, nil
67}