github.com/golang/dep@v0.5.4/internal/importers/glock/importer.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package glock 6 7 import ( 8 "bufio" 9 "fmt" 10 "log" 11 "os" 12 "path/filepath" 13 "strings" 14 15 "github.com/golang/dep" 16 "github.com/golang/dep/gps" 17 "github.com/golang/dep/internal/importers/base" 18 "github.com/pkg/errors" 19 ) 20 21 const glockfile = "GLOCKFILE" 22 23 // Importer imports glock configuration into the dep configuration format. 24 type Importer struct { 25 *base.Importer 26 27 packages []glockPackage 28 } 29 30 // NewImporter for glock. 31 func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer { 32 return &Importer{Importer: base.NewImporter(logger, verbose, sm)} 33 } 34 35 // Name of the importer. 36 func (g *Importer) Name() string { 37 return "glock" 38 } 39 40 // HasDepMetadata checks if a directory contains config that the importer can handle. 41 func (g *Importer) HasDepMetadata(dir string) bool { 42 path := filepath.Join(dir, glockfile) 43 if _, err := os.Stat(path); err != nil { 44 return false 45 } 46 47 return true 48 } 49 50 // Import the config found in the directory. 51 func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) { 52 err := g.load(dir) 53 if err != nil { 54 return nil, nil, err 55 } 56 57 m, l := g.convert(pr) 58 return m, l, nil 59 } 60 61 type glockPackage struct { 62 importPath string 63 revision string 64 } 65 66 func (g *Importer) load(projectDir string) error { 67 g.Logger.Println("Detected glock configuration files...") 68 path := filepath.Join(projectDir, glockfile) 69 if g.Verbose { 70 g.Logger.Printf(" Loading %s", path) 71 } 72 73 f, err := os.Open(path) 74 if err != nil { 75 return errors.Wrapf(err, "unable to open %s", path) 76 } 77 defer f.Close() 78 79 scanner := bufio.NewScanner(f) 80 for scanner.Scan() { 81 pkg, err := parseGlockLine(scanner.Text()) 82 if err != nil { 83 g.Logger.Printf(" Warning: Skipping line. Unable to parse: %s\n", err) 84 continue 85 } 86 if pkg == nil { 87 continue 88 } 89 g.packages = append(g.packages, *pkg) 90 } 91 92 if err := scanner.Err(); err != nil { 93 g.Logger.Printf(" Warning: Ignoring errors found while parsing %s: %s\n", path, err) 94 } 95 96 return nil 97 } 98 99 func parseGlockLine(line string) (*glockPackage, error) { 100 fields := strings.Fields(line) 101 switch len(fields) { 102 case 2: // Valid. 103 case 0: // Skip empty lines. 104 return nil, nil 105 default: 106 return nil, fmt.Errorf("invalid glock configuration: %s", line) 107 } 108 109 // Skip commands. 110 if fields[0] == "cmd" { 111 return nil, nil 112 } 113 return &glockPackage{ 114 importPath: fields[0], 115 revision: fields[1], 116 }, nil 117 } 118 119 func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) { 120 g.Logger.Println("Converting from GLOCKFILE ...") 121 122 packages := make([]base.ImportedPackage, 0, len(g.packages)) 123 for _, pkg := range g.packages { 124 // Validate 125 if pkg.importPath == "" { 126 g.Logger.Println( 127 " Warning: Skipping project. Invalid glock configuration, import path is required", 128 ) 129 continue 130 } 131 132 if pkg.revision == "" { 133 // Do not add 'empty constraints' to the manifest. Solve will add to lock if required. 134 g.Logger.Printf( 135 " Warning: Skipping import with empty constraints. "+ 136 "The solve step will add the dependency to the lock if needed: %q\n", 137 pkg.importPath, 138 ) 139 continue 140 } 141 142 packages = append(packages, base.ImportedPackage{ 143 Name: pkg.importPath, 144 LockHint: pkg.revision, 145 }) 146 } 147 148 g.ImportPackages(packages, true) 149 return g.Manifest, g.Lock 150 }