File: snapshot_filter.go

package info (click to toggle)
aptly 1.6.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 49,928 kB
  • sloc: python: 10,398; sh: 252; makefile: 184
file content (122 lines) | stat: -rw-r--r-- 3,666 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package cmd

import (
	"fmt"
	"sort"
	"strings"

	"github.com/aptly-dev/aptly/deb"
	"github.com/aptly-dev/aptly/query"
	"github.com/smira/commander"
	"github.com/smira/flag"
)

func aptlySnapshotFilter(cmd *commander.Command, args []string) error {
	var err error
	if len(args) < 3 {
		cmd.Usage()
		return commander.ErrCommandError
	}

	withDeps := context.Flags().Lookup("with-deps").Value.Get().(bool)
	collectionFactory := context.NewCollectionFactory()

	// Load <source> snapshot
	source, err := collectionFactory.SnapshotCollection().ByName(args[0])
	if err != nil {
		return fmt.Errorf("unable to filter: %s", err)
	}

	err = collectionFactory.SnapshotCollection().LoadComplete(source)
	if err != nil {
		return fmt.Errorf("unable to filter: %s", err)
	}

	// Convert snapshot to package list
	context.Progress().Printf("Loading packages (%d)...\n", source.RefList().Len())
	packageList, err := deb.NewPackageListFromRefList(source.RefList(), collectionFactory.PackageCollection(), context.Progress())
	if err != nil {
		return fmt.Errorf("unable to load packages: %s", err)
	}

	context.Progress().Printf("Building indexes...\n")
	packageList.PrepareIndex()

	// Calculate architectures
	var architecturesList []string

	if len(context.ArchitecturesList()) > 0 {
		architecturesList = context.ArchitecturesList()
	} else {
		architecturesList = packageList.Architectures(false)
	}

	sort.Strings(architecturesList)

	if len(architecturesList) == 0 && withDeps {
		return fmt.Errorf("unable to determine list of architectures, please specify explicitly")
	}

	// Initial queries out of arguments
	queries := make([]deb.PackageQuery, len(args)-2)
	for i, arg := range args[2:] {
		value, err := GetStringOrFileContent(arg)
		if err != nil {
			return fmt.Errorf("unable to read package query from file %s: %w", arg, err)
		}
		queries[i], err = query.Parse(value)
		if err != nil {
			return fmt.Errorf("unable to parse query: %s", err)
		}
	}

	// Filter with dependencies as requested
	result, err := packageList.Filter(deb.FilterOptions{
		Queries:           queries,
		WithDependencies:  withDeps,
		Source:            nil,
		DependencyOptions: context.DependencyOptions(),
		Architectures:     architecturesList,
		Progress:          context.Progress(),
	})
	if err != nil {
		return fmt.Errorf("unable to filter: %s", err)
	}

	// Create <destination> snapshot
	destination := deb.NewSnapshotFromPackageList(args[1], []*deb.Snapshot{source}, result,
		fmt.Sprintf("Filtered '%s', query was: '%s'", source.Name, strings.Join(args[2:], " ")))

	err = collectionFactory.SnapshotCollection().Add(destination)
	if err != nil {
		return fmt.Errorf("unable to create snapshot: %s", err)
	}

	context.Progress().Printf("\nSnapshot %s successfully filtered.\nYou can run 'aptly publish snapshot %s' to publish snapshot as Debian repository.\n", destination.Name, destination.Name)

	return err
}

func makeCmdSnapshotFilter() *commander.Command {
	cmd := &commander.Command{
		Run:       aptlySnapshotFilter,
		UsageLine: "filter <source> <destination> <package-query> ...",
		Short:     "filter packages in snapshot producing another snapshot",
		Long: `
Command filter does filtering in snapshot <source>, producing another
snapshot <destination>. Packages could be specified simply
as 'package-name' or as package queries.

Use '@file' syntax to read package queries from file and '@-' to read from stdin.

Example:

    $ aptly snapshot filter wheezy-main wheezy-required 'Priority (required)'
`,
		Flag: *flag.NewFlagSet("aptly-snapshot-filter", flag.ExitOnError),
	}

	cmd.Flag.Bool("with-deps", false, "include dependent packages as well")

	return cmd
}