1package cmd 2 3import ( 4 "fmt" 5 "sort" 6 "strings" 7 8 "github.com/aptly-dev/aptly/deb" 9 "github.com/aptly-dev/aptly/query" 10 "github.com/smira/commander" 11 "github.com/smira/flag" 12) 13 14func aptlySnapshotFilter(cmd *commander.Command, args []string) error { 15 var err error 16 if len(args) < 3 { 17 cmd.Usage() 18 return commander.ErrCommandError 19 } 20 21 withDeps := context.Flags().Lookup("with-deps").Value.Get().(bool) 22 23 // Load <source> snapshot 24 source, err := context.CollectionFactory().SnapshotCollection().ByName(args[0]) 25 if err != nil { 26 return fmt.Errorf("unable to filter: %s", err) 27 } 28 29 err = context.CollectionFactory().SnapshotCollection().LoadComplete(source) 30 if err != nil { 31 return fmt.Errorf("unable to filter: %s", err) 32 } 33 34 // Convert snapshot to package list 35 context.Progress().Printf("Loading packages (%d)...\n", source.RefList().Len()) 36 packageList, err := deb.NewPackageListFromRefList(source.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) 37 if err != nil { 38 return fmt.Errorf("unable to load packages: %s", err) 39 } 40 41 context.Progress().Printf("Building indexes...\n") 42 packageList.PrepareIndex() 43 44 // Calculate architectures 45 var architecturesList []string 46 47 if len(context.ArchitecturesList()) > 0 { 48 architecturesList = context.ArchitecturesList() 49 } else { 50 architecturesList = packageList.Architectures(false) 51 } 52 53 sort.Strings(architecturesList) 54 55 if len(architecturesList) == 0 && withDeps { 56 return fmt.Errorf("unable to determine list of architectures, please specify explicitly") 57 } 58 59 // Initial queries out of arguments 60 queries := make([]deb.PackageQuery, len(args)-2) 61 for i, arg := range args[2:] { 62 queries[i], err = query.Parse(arg) 63 if err != nil { 64 return fmt.Errorf("unable to parse query: %s", err) 65 } 66 } 67 68 // Filter with dependencies as requested 69 result, err := packageList.FilterWithProgress(queries, withDeps, nil, context.DependencyOptions(), architecturesList, context.Progress()) 70 if err != nil { 71 return fmt.Errorf("unable to filter: %s", err) 72 } 73 74 // Create <destination> snapshot 75 destination := deb.NewSnapshotFromPackageList(args[1], []*deb.Snapshot{source}, result, 76 fmt.Sprintf("Filtered '%s', query was: '%s'", source.Name, strings.Join(args[2:], " "))) 77 78 err = context.CollectionFactory().SnapshotCollection().Add(destination) 79 if err != nil { 80 return fmt.Errorf("unable to create snapshot: %s", err) 81 } 82 83 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) 84 85 return err 86} 87 88func makeCmdSnapshotFilter() *commander.Command { 89 cmd := &commander.Command{ 90 Run: aptlySnapshotFilter, 91 UsageLine: "filter <source> <destination> <package-query> ...", 92 Short: "filter packages in snapshot producing another snapshot", 93 Long: ` 94Command filter does filtering in snapshot <source>, producing another 95snapshot <destination>. Packages could be specified simply 96as 'package-name' or as package queries. 97 98Example: 99 100 $ aptly snapshot filter wheezy-main wheezy-required 'Priorioty (required)' 101`, 102 Flag: *flag.NewFlagSet("aptly-snapshot-filter", flag.ExitOnError), 103 } 104 105 cmd.Flag.Bool("with-deps", false, "include dependent packages as well") 106 107 return cmd 108} 109