github.com/fibonacci1729/glide@v0.0.0-20160513190140-d9640dc62d0f/action/create.go (about) 1 package action 2 3 import ( 4 "os" 5 "path/filepath" 6 "sort" 7 "strings" 8 9 "github.com/Masterminds/glide/cfg" 10 "github.com/Masterminds/glide/dependency" 11 "github.com/Masterminds/glide/gb" 12 "github.com/Masterminds/glide/godep" 13 "github.com/Masterminds/glide/gpm" 14 "github.com/Masterminds/glide/msg" 15 gpath "github.com/Masterminds/glide/path" 16 "github.com/Masterminds/glide/util" 17 ) 18 19 // Create creates/initializes a new Glide repository. 20 // 21 // This will fail if a glide.yaml already exists. 22 // 23 // By default, this will scan the present source code directory for dependencies. 24 // 25 // If skipImport is set to true, this will not attempt to import from an existing 26 // GPM, Godep, or GB project if one should exist. However, it will still attempt 27 // to read the local source to determine required packages. 28 func Create(base string, skipImport bool) { 29 glidefile := gpath.GlideFile 30 // Guard against overwrites. 31 guardYAML(glidefile) 32 33 // Guess deps 34 conf := guessDeps(base, skipImport) 35 // Write YAML 36 if err := conf.WriteFile(glidefile); err != nil { 37 msg.Die("Could not save %s: %s", glidefile, err) 38 } 39 } 40 41 // guardYAML fails if the given file already exists. 42 // 43 // This prevents an important file from being overwritten. 44 func guardYAML(filename string) { 45 if _, err := os.Stat(filename); err == nil { 46 msg.Die("Cowardly refusing to overwrite existing YAML.") 47 } 48 } 49 50 // guessDeps attempts to resolve all of the dependencies for a given project. 51 // 52 // base is the directory to start with. 53 // skipImport will skip running the automatic imports. 54 // 55 // FIXME: This function is likely a one-off that has a more standard alternative. 56 // It's also long and could use a refactor. 57 func guessDeps(base string, skipImport bool) *cfg.Config { 58 buildContext, err := util.GetBuildContext() 59 if err != nil { 60 msg.Die("Failed to build an import context: %s", err) 61 } 62 name := buildContext.PackageName(base) 63 64 msg.Info("Generating a YAML configuration file and guessing the dependencies") 65 66 config := new(cfg.Config) 67 68 // Get the name of the top level package 69 config.Name = name 70 71 // Import by looking at other package managers and looking over the 72 // entire directory structure. 73 74 // Attempt to import from other package managers. 75 if !skipImport { 76 msg.Info("Attempting to import from other package managers (use --skip-import to skip)") 77 deps := []*cfg.Dependency{} 78 absBase, err := filepath.Abs(base) 79 if err != nil { 80 msg.Die("Failed to resolve location of %s: %s", base, err) 81 } 82 83 if d, ok := guessImportGodep(absBase); ok { 84 msg.Info("Importing Godep configuration") 85 msg.Warn("Godep uses commit id versions. Consider using Semantic Versions with Glide") 86 deps = d 87 } else if d, ok := guessImportGPM(absBase); ok { 88 msg.Info("Importing GPM configuration") 89 deps = d 90 } else if d, ok := guessImportGB(absBase); ok { 91 msg.Info("Importing GB configuration") 92 deps = d 93 } 94 95 for _, i := range deps { 96 msg.Info("Found imported reference to %s\n", i.Name) 97 config.Imports = append(config.Imports, i) 98 } 99 } 100 101 // Resolve dependencies by looking at the tree. 102 r, err := dependency.NewResolver(base) 103 if err != nil { 104 msg.Die("Error creating a dependency resolver: %s", err) 105 } 106 107 h := &dependency.DefaultMissingPackageHandler{Missing: []string{}, Gopath: []string{}} 108 r.Handler = h 109 110 sortable, err := r.ResolveLocal(false) 111 if err != nil { 112 msg.Die("Error resolving local dependencies: %s", err) 113 } 114 115 sort.Strings(sortable) 116 117 vpath := r.VendorDir 118 if !strings.HasSuffix(vpath, "/") { 119 vpath = vpath + string(os.PathSeparator) 120 } 121 122 for _, pa := range sortable { 123 n := strings.TrimPrefix(pa, vpath) 124 root, subpkg := util.NormalizeName(n) 125 126 if !config.HasDependency(root) { 127 msg.Info("Found reference to %s\n", n) 128 d := &cfg.Dependency{ 129 Name: root, 130 } 131 if len(subpkg) > 0 { 132 d.Subpackages = []string{subpkg} 133 } 134 config.Imports = append(config.Imports, d) 135 } else { 136 if len(subpkg) > 0 { 137 subpkg = strings.TrimPrefix(subpkg, "/") 138 d := config.Imports.Get(root) 139 if !d.HasSubpackage(subpkg) { 140 msg.Info("Adding sub-package %s to %s\n", subpkg, root) 141 d.Subpackages = append(d.Subpackages, subpkg) 142 } 143 } 144 } 145 } 146 147 return config 148 } 149 150 func guessImportGodep(dir string) ([]*cfg.Dependency, bool) { 151 d, err := godep.Parse(dir) 152 if err != nil || len(d) == 0 { 153 return []*cfg.Dependency{}, false 154 } 155 156 return d, true 157 } 158 159 func guessImportGPM(dir string) ([]*cfg.Dependency, bool) { 160 d, err := gpm.Parse(dir) 161 if err != nil || len(d) == 0 { 162 return []*cfg.Dependency{}, false 163 } 164 165 return d, true 166 } 167 168 func guessImportGB(dir string) ([]*cfg.Dependency, bool) { 169 d, err := gb.Parse(dir) 170 if err != nil || len(d) == 0 { 171 return []*cfg.Dependency{}, false 172 } 173 174 return d, true 175 }