github.com/sirkon/goproxy@v1.4.8/plugin/vcs/plugin.go (about)

     1  package vcs
     2  
     3  import (
     4  	"net/http"
     5  	"os"
     6  	"sync"
     7  
     8  	"github.com/sirkon/goproxy/internal/errors"
     9  
    10  	"github.com/sirkon/goproxy"
    11  	"github.com/sirkon/goproxy/internal/modfetch"
    12  )
    13  
    14  // plugin creates source for VCS repositories
    15  type plugin struct {
    16  	rootDir string
    17  
    18  	// accessLock is for access to inWork
    19  	accessLock sync.Locker
    20  	inWork     map[string]modfetch.Repo
    21  }
    22  
    23  func (f *plugin) String() string {
    24  	return "legacy"
    25  }
    26  
    27  // NewPlugin creates new valid plugin instance
    28  func NewPlugin(rootDir string) (f goproxy.Plugin, err error) {
    29  	setupEnv(rootDir)
    30  	stat, err := os.Stat(rootDir)
    31  	if os.IsNotExist(err) {
    32  		if err := os.MkdirAll(rootDir, 0755); err != nil {
    33  			return nil, errors.Wrapf(err, "vcs creating directory `%s`", rootDir)
    34  		}
    35  	} else {
    36  		if !stat.IsDir() {
    37  			return nil, errors.Newf("vcs %s is not a directory", rootDir)
    38  		}
    39  	}
    40  	if err = os.Chdir(rootDir); err != nil {
    41  		return nil, errors.Wrapf(err, "vcs cding into `%s`", rootDir)
    42  	}
    43  
    44  	if err = os.Setenv("GOPATH", rootDir); err != nil {
    45  		return nil, errors.Wrapf(err, "vcs setting up GOPATH environment variable")
    46  	}
    47  
    48  	if err = os.Setenv("GO111MODULE", "on"); err != nil {
    49  		return nil, errors.Wrapf(err, "vcs setting up GO111MODULE environment variable")
    50  	}
    51  
    52  	return &plugin{
    53  		rootDir:    rootDir,
    54  		inWork:     map[string]modfetch.Repo{},
    55  		accessLock: &sync.Mutex{},
    56  	}, nil
    57  }
    58  
    59  // Module creates a source for a module with given path
    60  func (f *plugin) Module(req *http.Request, prefix string) (goproxy.Module, error) {
    61  	path, _, err := goproxy.GetModInfo(req, prefix)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	repo, err := f.getRepo(path)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	return &vcsModule{
    72  		repo: repo,
    73  	}, nil
    74  }
    75  
    76  // Leave unset a lock of a given module
    77  func (f *plugin) Leave(s goproxy.Module) error {
    78  	return nil
    79  }
    80  
    81  // Close ...
    82  func (f *plugin) Close() error {
    83  	return nil
    84  }
    85  
    86  func (f *plugin) getRepo(path string) (repo modfetch.Repo, err error) {
    87  	f.accessLock.Lock()
    88  	defer f.accessLock.Unlock()
    89  	repo, ok := f.inWork[path]
    90  	if !ok {
    91  		repo, err = modfetch.Lookup(path)
    92  		if err != nil {
    93  			return nil, errors.Wrapf(err, "vcs getting module for `%s`", path)
    94  		}
    95  	}
    96  	f.inWork[path] = repo
    97  	return repo, nil
    98  }