github.com/golang/dep@v0.5.4/internal/importers/godep/importer.go (about)

     1  // Copyright 2017 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 godep
     6  
     7  import (
     8  	"encoding/json"
     9  	"io/ioutil"
    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 godepPath = "Godeps" + string(os.PathSeparator) + "Godeps.json"
    22  
    23  // Importer imports godep configuration into the dep configuration format.
    24  type Importer struct {
    25  	*base.Importer
    26  	json godepJSON
    27  }
    28  
    29  // NewImporter for godep.
    30  func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer {
    31  	return &Importer{Importer: base.NewImporter(logger, verbose, sm)}
    32  }
    33  
    34  type godepJSON struct {
    35  	Required []string       `json:"Packages"`
    36  	Imports  []godepPackage `json:"Deps"`
    37  }
    38  
    39  type godepPackage struct {
    40  	ImportPath string `json:"ImportPath"`
    41  	Rev        string `json:"Rev"`
    42  	Comment    string `json:"Comment"`
    43  }
    44  
    45  // Name of the importer.
    46  func (g *Importer) Name() string {
    47  	return "godep"
    48  }
    49  
    50  // HasDepMetadata checks if a directory contains config that the importer can handle.
    51  func (g *Importer) HasDepMetadata(dir string) bool {
    52  	y := filepath.Join(dir, godepPath)
    53  	if _, err := os.Stat(y); err != nil {
    54  		return false
    55  	}
    56  
    57  	return true
    58  }
    59  
    60  // Import the config found in the directory.
    61  func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) {
    62  	err := g.load(dir)
    63  	if err != nil {
    64  		return nil, nil, err
    65  	}
    66  
    67  	m, l := g.convert(pr)
    68  	return m, l, nil
    69  }
    70  
    71  func (g *Importer) load(projectDir string) error {
    72  	g.Logger.Println("Detected godep configuration files...")
    73  	j := filepath.Join(projectDir, godepPath)
    74  	if g.Verbose {
    75  		g.Logger.Printf("  Loading %s", j)
    76  	}
    77  	jb, err := ioutil.ReadFile(j)
    78  	if err != nil {
    79  		return errors.Wrapf(err, "unable to read %s", j)
    80  	}
    81  	err = json.Unmarshal(jb, &g.json)
    82  	if err != nil {
    83  		return errors.Wrapf(err, "unable to parse %s", j)
    84  	}
    85  
    86  	return nil
    87  }
    88  
    89  func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) {
    90  	g.Logger.Println("Converting from Godeps.json ...")
    91  
    92  	packages := make([]base.ImportedPackage, 0, len(g.json.Imports))
    93  	for _, pkg := range g.json.Imports {
    94  		// Validate
    95  		if pkg.ImportPath == "" {
    96  			g.Logger.Println(
    97  				"  Warning: Skipping project. Invalid godep configuration, ImportPath is required",
    98  			)
    99  			continue
   100  		}
   101  
   102  		if pkg.Rev == "" {
   103  			g.Logger.Printf(
   104  				"  Warning: Invalid godep configuration, Rev not found for ImportPath %q\n",
   105  				pkg.ImportPath,
   106  			)
   107  		}
   108  
   109  		ip := base.ImportedPackage{
   110  			Name:           pkg.ImportPath,
   111  			LockHint:       pkg.Rev,
   112  			ConstraintHint: pkg.Comment,
   113  		}
   114  		packages = append(packages, ip)
   115  	}
   116  
   117  	g.ImportPackages(packages, true)
   118  	required := make([]string, 0, len(g.json.Required))
   119  	for _, req := range g.json.Required {
   120  		if !strings.HasPrefix(req, ".") { // ignore project packages
   121  			required = append(required, req)
   122  		}
   123  	}
   124  	if len(required) > 0 {
   125  		g.Manifest.Required = required
   126  	}
   127  	return g.Manifest, g.Lock
   128  }