github.com/wawandco/oxpecker@v1.5.7-0.20210910201653-5958d4afdd89/tools/standard/fixer.go (about)

     1  package standard
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/wawandco/oxpecker/lifecycle/fix"
    11  	"github.com/wawandco/oxpecker/plugins"
    12  	"golang.org/x/mod/modfile"
    13  )
    14  
    15  var (
    16  	_ plugins.Plugin = (*Fixer)(nil)
    17  	_ fix.Fixer      = (*Fixer)(nil)
    18  
    19  	ErrModuleNameNeeded   = errors.New("module name needed")
    20  	ErrModuleNameNotFound = errors.New("module name not found")
    21  	ErrFileMainNotExist   = errors.New("main.go file does not exist")
    22  )
    23  
    24  // Fixer is in charge of performing a Fix operation
    25  // that moves the main.go to cmd/[name-of-the-module]/main.go
    26  type Fixer struct{}
    27  
    28  func (f Fixer) Name() string {
    29  	return "main"
    30  }
    31  
    32  // Fix does the main.go magic
    33  // - Determine if the file exists
    34  // - Determine if there is a go.mod
    35  // - Determine the name of the module (last part when slicing go.mod by /)
    36  // - Create folder
    37  // - Copy/move main.go to that folder
    38  func (f Fixer) Fix(ctx context.Context, root string, args []string) error {
    39  	_, err := f.fileExists()
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	base, err := f.findModuleName()
    45  	if err != nil {
    46  		return err
    47  	}
    48  
    49  	err = f.moveFile(base)
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	return nil
    55  }
    56  
    57  func (f Fixer) moveFile(s string) error {
    58  	if s == "" {
    59  		return ErrModuleNameNeeded
    60  	}
    61  
    62  	name := "main.go"
    63  	s = "cmd/" + s
    64  	err := os.MkdirAll(s, 0755)
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	finLoc := s + "/" + name
    70  	err = os.Rename(name, finLoc)
    71  	if err != nil {
    72  		return err
    73  	}
    74  
    75  	return nil
    76  }
    77  
    78  // Look for go.mod and extract the last part.
    79  func (f Fixer) findModuleName() (string, error) {
    80  	mp := "go.mod"
    81  	file, err := ioutil.ReadFile(mp)
    82  	if err != nil {
    83  		return "", err
    84  	}
    85  
    86  	base := filepath.Base(modfile.ModulePath(file))
    87  
    88  	if base != "." {
    89  		return base, nil
    90  	}
    91  	if base == "." {
    92  		return "", ErrModuleNameNotFound
    93  	}
    94  	return "", ErrModuleNameNotFound
    95  }
    96  
    97  func (f Fixer) fileExists() (bool, error) {
    98  	files, err := ioutil.ReadDir(".")
    99  	if err != nil {
   100  		return false, err
   101  	}
   102  
   103  	for _, f := range files {
   104  		if f.Name() == "main.go" {
   105  			return true, nil
   106  		}
   107  	}
   108  
   109  	return false, ErrFileMainNotExist
   110  }