github.com/jonsyu1/godel@v0.0.0-20171017211503-64567a0cf169/apps/distgo/cmd/docker/products.go (about) 1 // Copyright 2016 Palantir Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package docker 16 17 import ( 18 "sort" 19 20 "github.com/pkg/errors" 21 22 "github.com/palantir/godel/apps/distgo/params" 23 ) 24 25 func productsToDistAndBuildImage( 26 products []string, 27 cfg params.Project, 28 ) ( 29 productsToDist []string, 30 productsToBuildImage []string, 31 err error, 32 ) { 33 if len(products) == 0 { 34 for product := range cfg.FilteredProducts() { 35 products = append(products, product) 36 } 37 } 38 sort.Strings(products) 39 if err := validateProducts(products, cfg); err != nil { 40 return nil, nil, err 41 } 42 43 visited := make(map[string]struct{}) 44 distProducts := make(map[string]struct{}) 45 imageProducts := make(map[string]struct{}) 46 productQueue := make([]string, len(products)) 47 copy(productQueue, products) 48 for len(productQueue) > 0 { 49 productName := productQueue[0] 50 productQueue = productQueue[1:] 51 visited[productName] = struct{}{} 52 productSpec := cfg.Products[productName] 53 if len(productSpec.DockerImages) > 0 { 54 imageProducts[productName] = struct{}{} 55 } 56 for _, image := range productSpec.DockerImages { 57 for _, dep := range image.Deps { 58 if isDist(dep.Type) { 59 distProducts[productName] = struct{}{} 60 } 61 if dep.Type == params.DockerDepDocker { 62 // has a docker image dependency. Add to product queue if not visited 63 if _, ok := visited[dep.Product]; ok { 64 continue 65 } 66 productQueue = append(productQueue, dep.Product) 67 } 68 } 69 } 70 } 71 return setToSlice(distProducts), setToSlice(imageProducts), nil 72 } 73 74 func validateProducts(products []string, cfg params.Project) error { 75 var unknownProducts []string 76 for _, product := range products { 77 if _, ok := cfg.Products[product]; !ok { 78 unknownProducts = append(unknownProducts, product) 79 } 80 } 81 sort.Strings(unknownProducts) 82 if len(unknownProducts) != 0 { 83 var filteredProducts []string 84 for product := range cfg.FilteredProducts() { 85 filteredProducts = append(filteredProducts, product) 86 } 87 sort.Strings(filteredProducts) 88 return errors.Errorf( 89 "Invalid products: %v. Valid products are: %v", 90 unknownProducts, 91 filteredProducts, 92 ) 93 } 94 return nil 95 } 96 97 func isDist(dep params.DockerDepType) bool { 98 switch dep { 99 case params.DockerDepSLS, params.DockerDepBin, params.DockerDepRPM: 100 return true 101 default: 102 return false 103 } 104 } 105 106 func setToSlice(s map[string]struct{}) []string { 107 var result []string 108 for item := range s { 109 result = append(result, item) 110 } 111 sort.Strings(result) 112 return result 113 }