github.com/uk702/glide@v0.12.3/godep/strip/strip.go (about)

     1  // Package strip removes Godeps/_workspace and undoes the Godep rewrites. This
     2  // essentially removes the old style (pre-vendor) Godep vendoring.
     3  //
     4  // Note, this functionality is deprecated. Once more projects use the Godep
     5  // support for the core vendoring this will no longer be needed.
     6  package strip
     7  
     8  import (
     9  	"bytes"
    10  	"go/ast"
    11  	"go/parser"
    12  	"go/printer"
    13  	"go/token"
    14  	"os"
    15  	"path/filepath"
    16  	"strconv"
    17  	"strings"
    18  
    19  	"github.com/Masterminds/glide/msg"
    20  )
    21  
    22  var godepMark = map[string]bool{}
    23  
    24  var vPath = "vendor"
    25  
    26  // GodepWorkspace removes any Godeps/_workspace directories and makes sure
    27  // any rewrites are undone.
    28  // Note, this is not concuccency safe.
    29  func GodepWorkspace(v string) error {
    30  	vPath = v
    31  	if _, err := os.Stat(vPath); err != nil {
    32  		if os.IsNotExist(err) {
    33  			msg.Debug("Vendor directory does not exist.")
    34  		}
    35  
    36  		return err
    37  	}
    38  
    39  	err := filepath.Walk(vPath, stripGodepWorkspaceHandler)
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	// Walk the marked projects to make sure rewrites are undone.
    45  	for k := range godepMark {
    46  		msg.Info("Removing Godep rewrites for %s", k)
    47  		err := filepath.Walk(k, rewriteGodepfilesHandler)
    48  		if err != nil {
    49  			return err
    50  		}
    51  	}
    52  
    53  	return nil
    54  }
    55  
    56  func stripGodepWorkspaceHandler(path string, info os.FileInfo, err error) error {
    57  	// Skip the base vendor directory
    58  	if path == vPath {
    59  		return nil
    60  	}
    61  
    62  	name := info.Name()
    63  	p := filepath.Dir(path)
    64  	pn := filepath.Base(p)
    65  	if name == "_workspace" && pn == "Godeps" {
    66  		if _, err := os.Stat(path); err == nil {
    67  			if info.IsDir() {
    68  				// Marking this location to make sure rewrites are undone.
    69  				pp := filepath.Dir(p)
    70  				godepMark[pp] = true
    71  
    72  				msg.Info("Removing: %s", path)
    73  				return os.RemoveAll(path)
    74  			}
    75  
    76  			msg.Debug("%s is not a directory. Skipping removal", path)
    77  			return nil
    78  		}
    79  	}
    80  	return nil
    81  }
    82  
    83  func rewriteGodepfilesHandler(path string, info os.FileInfo, err error) error {
    84  	name := info.Name()
    85  
    86  	if info.IsDir() {
    87  		if name == "testdata" || name == "vendor" {
    88  			return filepath.SkipDir
    89  		}
    90  		return nil
    91  	}
    92  
    93  	if e := filepath.Ext(path); e != ".go" {
    94  		return nil
    95  	}
    96  
    97  	fset := token.NewFileSet()
    98  	f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
    99  	if err != nil {
   100  		return err
   101  	}
   102  
   103  	var changed bool
   104  	for _, s := range f.Imports {
   105  		n, err := strconv.Unquote(s.Path.Value)
   106  		if err != nil {
   107  			return err
   108  		}
   109  		q := rewriteGodepImport(n)
   110  		if q != name {
   111  			s.Path.Value = strconv.Quote(q)
   112  			changed = true
   113  		}
   114  	}
   115  	if !changed {
   116  		return nil
   117  	}
   118  
   119  	printerConfig := &printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}
   120  	var buffer bytes.Buffer
   121  	if err = printerConfig.Fprint(&buffer, fset, f); err != nil {
   122  		return err
   123  	}
   124  	fset = token.NewFileSet()
   125  	f, err = parser.ParseFile(fset, name, &buffer, parser.ParseComments)
   126  	ast.SortImports(fset, f)
   127  	tpath := path + ".temp"
   128  	t, err := os.Create(tpath)
   129  	if err != nil {
   130  		return err
   131  	}
   132  	if err = printerConfig.Fprint(t, fset, f); err != nil {
   133  		return err
   134  	}
   135  	if err = t.Close(); err != nil {
   136  		return err
   137  	}
   138  
   139  	msg.Debug("Rewriting Godep imports for %s", path)
   140  
   141  	// This is required before the rename on windows.
   142  	if err = os.Remove(path); err != nil {
   143  		return err
   144  	}
   145  	return os.Rename(tpath, path)
   146  }
   147  
   148  func rewriteGodepImport(n string) string {
   149  	if !strings.Contains(n, "Godeps/_workspace/src") {
   150  		return n
   151  	}
   152  
   153  	i := strings.LastIndex(n, "Godeps/_workspace/src")
   154  
   155  	return strings.TrimPrefix(n[i:], "Godeps/_workspace/src/")
   156  }