github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/ctl/ctl.go (about)

     1  package ctl
     2  
     3  import (
     4  	"bytes"
     5  	"embed"
     6  	_ "embed"
     7  	"fmt"
     8  	"io/fs"
     9  	"io/ioutil"
    10  	"os"
    11  	"strconv"
    12  	"strings"
    13  	"text/template"
    14  
    15  	"github.com/bingoohuang/gg/pkg/v"
    16  )
    17  
    18  type Config struct {
    19  	Initing      bool
    20  	PrintVersion bool
    21  	InitFiles    *embed.FS
    22  }
    23  
    24  // ProcessInit generates ctl and conf.yml files for -init argument.
    25  func (c Config) ProcessInit() {
    26  	if c.Initing {
    27  		if err := initCtl(); err != nil {
    28  			fmt.Printf(err.Error())
    29  		}
    30  		if err := c.initFiles(); err != nil {
    31  			fmt.Printf(err.Error())
    32  		}
    33  	}
    34  
    35  	if c.PrintVersion {
    36  		if vv := v.Version(); strings.HasSuffix(vv, "\n") {
    37  			fmt.Print(vv)
    38  		} else {
    39  			fmt.Println(vv)
    40  		}
    41  	}
    42  
    43  	if c.Initing || c.PrintVersion {
    44  		os.Exit(0)
    45  	}
    46  }
    47  
    48  func (c Config) initFiles() error {
    49  	if c.InitFiles == nil {
    50  		return nil
    51  	}
    52  
    53  	firstDir := false
    54  	return fs.WalkDir(c.InitFiles, ".", func(path string, d fs.DirEntry, err error) error {
    55  		if err != nil {
    56  			return err
    57  		}
    58  
    59  		if path == "." {
    60  			return nil
    61  		}
    62  
    63  		if d.IsDir() {
    64  			if firstDir {
    65  				return fs.SkipDir
    66  			}
    67  
    68  			firstDir = true
    69  			return nil
    70  		}
    71  
    72  		if _, err := os.Stat(d.Name()); err == nil {
    73  			fmt.Println(d.Name(), "already exists, ignored!")
    74  			return nil
    75  		}
    76  
    77  		// 0644->即用户具有读写权限,组用户和其它用户具有只读权限;
    78  		data, err := c.InitFiles.ReadFile(path)
    79  		if err != nil {
    80  			return err
    81  		}
    82  		if err := ioutil.WriteFile(d.Name(), data, 0o644); err != nil {
    83  			return err
    84  		}
    85  
    86  		fmt.Println(d.Name(), "created!")
    87  		return nil
    88  	})
    89  }
    90  
    91  //go:embed ctl
    92  var ctlRaw string
    93  
    94  func initCtl() error {
    95  	_, err := os.Stat("ctl")
    96  	if err == nil {
    97  		fmt.Println("ctl already exists, ignored!")
    98  		return nil
    99  	}
   100  
   101  	tpl, err := template.New("ctl").Parse(ctlRaw)
   102  	if err != nil {
   103  		return err
   104  	}
   105  
   106  	binArgs := argsExcludeInit()
   107  
   108  	m := map[string]string{"BinName": os.Args[0], "BinArgs": strings.Join(binArgs, " ")}
   109  
   110  	var content bytes.Buffer
   111  	if err := tpl.Execute(&content, m); err != nil {
   112  		return err
   113  	}
   114  
   115  	// 0755->即用户具有读/写/执行权限,组用户和其它用户具有读写权限;
   116  	if err = ioutil.WriteFile("ctl", content.Bytes(), 0o755); err != nil {
   117  		return err
   118  	}
   119  
   120  	fmt.Println("ctl created!")
   121  
   122  	return nil
   123  }
   124  
   125  func argsExcludeInit() []string {
   126  	binArgs := make([]string, 0, len(os.Args)-2)
   127  
   128  	for i, arg := range os.Args {
   129  		if i == 0 || strings.Index(arg, "-i") == 0 || strings.Index(arg, "--init") == 0 {
   130  			continue
   131  		}
   132  
   133  		if strings.Index(arg, "-") != 0 {
   134  			arg = strconv.Quote(arg)
   135  		}
   136  
   137  		binArgs = append(binArgs, arg)
   138  	}
   139  
   140  	return binArgs
   141  }