1package main
2
3import (
4	"context"
5
6	"github.com/restic/restic/internal/repository"
7	"github.com/restic/restic/internal/restic"
8)
9
10// FindFilteredSnapshots yields Snapshots, either given explicitly by `snapshotIDs` or filtered from the list of all snapshots.
11func FindFilteredSnapshots(ctx context.Context, repo *repository.Repository, hosts []string, tags []restic.TagList, paths []string, snapshotIDs []string) <-chan *restic.Snapshot {
12	out := make(chan *restic.Snapshot)
13	go func() {
14		defer close(out)
15		if len(snapshotIDs) != 0 {
16			var (
17				id         restic.ID
18				usedFilter bool
19				err        error
20			)
21			ids := make(restic.IDs, 0, len(snapshotIDs))
22			// Process all snapshot IDs given as arguments.
23			for _, s := range snapshotIDs {
24				if s == "latest" {
25					usedFilter = true
26					id, err = restic.FindLatestSnapshot(ctx, repo, paths, tags, hosts)
27					if err != nil {
28						Warnf("Ignoring %q, no snapshot matched given filter (Paths:%v Tags:%v Hosts:%v)\n", s, paths, tags, hosts)
29						continue
30					}
31				} else {
32					id, err = restic.FindSnapshot(ctx, repo, s)
33					if err != nil {
34						Warnf("Ignoring %q, it is not a snapshot id\n", s)
35						continue
36					}
37				}
38				ids = append(ids, id)
39			}
40
41			// Give the user some indication their filters are not used.
42			if !usedFilter && (len(hosts) != 0 || len(tags) != 0 || len(paths) != 0) {
43				Warnf("Ignoring filters as there are explicit snapshot ids given\n")
44			}
45
46			for _, id := range ids.Uniq() {
47				sn, err := restic.LoadSnapshot(ctx, repo, id)
48				if err != nil {
49					Warnf("Ignoring %q, could not load snapshot: %v\n", id, err)
50					continue
51				}
52				select {
53				case <-ctx.Done():
54					return
55				case out <- sn:
56				}
57			}
58			return
59		}
60
61		snapshots, err := restic.FindFilteredSnapshots(ctx, repo, hosts, tags, paths)
62		if err != nil {
63			Warnf("could not load snapshots: %v\n", err)
64			return
65		}
66
67		for _, sn := range snapshots {
68			select {
69			case <-ctx.Done():
70				return
71			case out <- sn:
72			}
73		}
74	}()
75	return out
76}
77