github.com/golang/dep@v0.5.4/internal/importers/gvt/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 gvt
     6  
     7  import (
     8  	"encoding/json"
     9  	"io/ioutil"
    10  	"log"
    11  	"os"
    12  	"path/filepath"
    13  
    14  	"github.com/golang/dep"
    15  	"github.com/golang/dep/gps"
    16  	"github.com/golang/dep/internal/importers/base"
    17  	"github.com/pkg/errors"
    18  )
    19  
    20  const gvtPath = "vendor" + string(os.PathSeparator) + "manifest"
    21  
    22  // Importer imports gvt configuration into the dep configuration format.
    23  type Importer struct {
    24  	*base.Importer
    25  	gvtConfig gvtManifest
    26  }
    27  
    28  // NewImporter for gvt. It handles gb (gb-vendor) too as they share a common manifest file & format
    29  func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer {
    30  	return &Importer{Importer: base.NewImporter(logger, verbose, sm)}
    31  }
    32  
    33  type gvtManifest struct {
    34  	Deps []gvtPkg `json:"dependencies"`
    35  }
    36  
    37  type gvtPkg struct {
    38  	ImportPath string
    39  	Repository string
    40  	Revision   string
    41  	Branch     string
    42  }
    43  
    44  // Name of the importer.
    45  func (g *Importer) Name() string {
    46  	return "gvt"
    47  }
    48  
    49  // HasDepMetadata checks if a directory contains config that the importer can handle.
    50  func (g *Importer) HasDepMetadata(dir string) bool {
    51  	y := filepath.Join(dir, gvtPath)
    52  	if _, err := os.Stat(y); err != nil {
    53  		return false
    54  	}
    55  
    56  	return true
    57  }
    58  
    59  // Import the config found in the directory.
    60  func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) {
    61  	err := g.load(dir)
    62  	if err != nil {
    63  		return nil, nil, err
    64  	}
    65  
    66  	m, l := g.convert(pr)
    67  	return m, l, nil
    68  }
    69  
    70  func (g *Importer) load(projectDir string) error {
    71  	g.Logger.Println("Detected gb/gvt configuration files...")
    72  	j := filepath.Join(projectDir, gvtPath)
    73  	if g.Verbose {
    74  		g.Logger.Printf("  Loading %s", j)
    75  	}
    76  	jb, err := ioutil.ReadFile(j)
    77  	if err != nil {
    78  		return errors.Wrapf(err, "unable to read %s", j)
    79  	}
    80  	err = json.Unmarshal(jb, &g.gvtConfig)
    81  	if err != nil {
    82  		return errors.Wrapf(err, "unable to parse %s", j)
    83  	}
    84  
    85  	return nil
    86  }
    87  
    88  func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) {
    89  	g.Logger.Println("Converting from vendor/manifest ...")
    90  
    91  	packages := make([]base.ImportedPackage, 0, len(g.gvtConfig.Deps))
    92  	for _, pkg := range g.gvtConfig.Deps {
    93  		// Validate
    94  		if pkg.ImportPath == "" {
    95  			g.Logger.Println(
    96  				"  Warning: Skipping project. Invalid gvt configuration, ImportPath is required",
    97  			)
    98  			continue
    99  		}
   100  
   101  		if pkg.Revision == "" {
   102  			g.Logger.Printf(
   103  				"  Warning: Invalid gvt configuration, Revision not found for ImportPath %q\n",
   104  				pkg.ImportPath,
   105  			)
   106  		}
   107  
   108  		var contstraintHint = ""
   109  		if pkg.Branch == "HEAD" {
   110  			// gb-vendor sets "branch" to "HEAD", if the package was feteched via -tag or -revision,
   111  			// we pass the revision as the constraint hint
   112  			contstraintHint = pkg.Revision
   113  		} else if pkg.Branch != "master" {
   114  			// both gvt & gb-vendor set "branch" to "master" unless a different branch was requested.
   115  			// so it's not really a constraint unless it's a different branch
   116  			contstraintHint = pkg.Branch
   117  		}
   118  
   119  		ip := base.ImportedPackage{
   120  			Name:           pkg.ImportPath,
   121  			Source:         pkg.Repository,
   122  			LockHint:       pkg.Revision,
   123  			ConstraintHint: contstraintHint,
   124  		}
   125  		packages = append(packages, ip)
   126  	}
   127  
   128  	g.ImportPackages(packages, true)
   129  	return g.Manifest, g.Lock
   130  }