github.com/skippbox/kompose-origin@v0.0.0-20160524133224-16a9dca7bac2/project/context.go (about) 1 package project 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path" 8 "path/filepath" 9 "regexp" 10 "strings" 11 12 "github.com/Sirupsen/logrus" 13 "github.com/docker/libcompose/config" 14 "github.com/docker/libcompose/logger" 15 ) 16 17 var projectRegexp = regexp.MustCompile("[^a-zA-Z0-9_.-]") 18 19 // Context holds context meta information about a libcompose project, like 20 // the project name, the compose file, etc. 21 type Context struct { 22 ComposeFiles []string 23 ComposeBytes [][]byte 24 ProjectName string 25 isOpen bool 26 ServiceFactory ServiceFactory 27 EnvironmentLookup config.EnvironmentLookup 28 ResourceLookup config.ResourceLookup 29 LoggerFactory logger.Factory 30 IgnoreMissingConfig bool 31 Project *Project 32 } 33 34 func (c *Context) readComposeFiles() error { 35 if c.ComposeBytes != nil { 36 return nil 37 } 38 39 logrus.Debugf("Opening compose files: %s", strings.Join(c.ComposeFiles, ",")) 40 41 // Handle STDIN (`-f -`) 42 if len(c.ComposeFiles) == 1 && c.ComposeFiles[0] == "-" { 43 composeBytes, err := ioutil.ReadAll(os.Stdin) 44 if err != nil { 45 logrus.Errorf("Failed to read compose file from stdin: %v", err) 46 return err 47 } 48 c.ComposeBytes = [][]byte{composeBytes} 49 return nil 50 } 51 52 for _, composeFile := range c.ComposeFiles { 53 composeBytes, err := ioutil.ReadFile(composeFile) 54 if err != nil && !os.IsNotExist(err) { 55 logrus.Errorf("Failed to open the compose file: %s", composeFile) 56 return err 57 } 58 if err != nil && !c.IgnoreMissingConfig { 59 logrus.Errorf("Failed to find the compose file: %s", composeFile) 60 return err 61 } 62 c.ComposeBytes = append(c.ComposeBytes, composeBytes) 63 } 64 65 return nil 66 } 67 68 func (c *Context) determineProject() error { 69 name, err := c.lookupProjectName() 70 if err != nil { 71 return err 72 } 73 74 c.ProjectName = normalizeName(name) 75 76 if c.ProjectName == "" { 77 return fmt.Errorf("Falied to determine project name") 78 } 79 80 return nil 81 } 82 83 func (c *Context) lookupProjectName() (string, error) { 84 if c.ProjectName != "" { 85 return c.ProjectName, nil 86 } 87 88 if envProject := os.Getenv("COMPOSE_PROJECT_NAME"); envProject != "" { 89 return envProject, nil 90 } 91 92 file := "." 93 if len(c.ComposeFiles) > 0 { 94 file = c.ComposeFiles[0] 95 } 96 97 f, err := filepath.Abs(file) 98 if err != nil { 99 logrus.Errorf("Failed to get absolute directory for: %s", file) 100 return "", err 101 } 102 103 f = toUnixPath(f) 104 105 parent := path.Base(path.Dir(f)) 106 if parent != "" && parent != "." { 107 return parent, nil 108 } else if wd, err := os.Getwd(); err != nil { 109 return "", err 110 } else { 111 return path.Base(toUnixPath(wd)), nil 112 } 113 } 114 115 func normalizeName(name string) string { 116 r := regexp.MustCompile("[^a-z0-9]+") 117 return r.ReplaceAllString(strings.ToLower(name), "") 118 } 119 120 func toUnixPath(p string) string { 121 return strings.Replace(p, "\\", "/", -1) 122 } 123 124 func (c *Context) open() error { 125 if c.isOpen { 126 return nil 127 } 128 129 if err := c.readComposeFiles(); err != nil { 130 return err 131 } 132 133 if err := c.determineProject(); err != nil { 134 return err 135 } 136 137 c.isOpen = true 138 return nil 139 }