dev: nft/ctl

This commit is contained in:
loveuer
2024-07-09 18:08:49 +08:00
parent bf1c5ad92f
commit 8a423c2887
7 changed files with 458 additions and 0 deletions

50
nft/nfctl/main.go Normal file
View File

@ -0,0 +1,50 @@
package main
import (
"github.com/go-git/go-billy/v5/memfs"
"github.com/go-git/go-git/v5"
_ "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/transport/http"
"github.com/go-git/go-git/v5/storage/memory"
"github.com/loveuer/nf/nft/log"
"io"
)
func main() {
memo := memory.NewStorage()
fs := memfs.New()
repo, err := git.Clone(memo, fs, &git.CloneOptions{
URL: "http://10.220.10.35/dev/template/ultone.git",
Auth: &http.BasicAuth{Username: "loveuer", Password: "uu_L6neSDseoWx55babJ"},
Depth: 1,
SingleBranch: true,
InsecureSkipTLS: true,
})
if err != nil {
panic(err)
}
infos, err := fs.ReadDir(".")
if err != nil {
panic(err)
}
for _, item := range infos {
log.Info("[fs.info] %s", item.Name())
if item.Name() == "main.go" {
file, err := fs.Open(item.Name())
if err != nil {
panic(err)
}
bs, err := io.ReadAll(file)
if err != nil {
panic(err)
}
log.Info("[fs.main]\n%s", string(bs))
}
}
_ = repo
}

78
nft/nfctl/tp/cmd_parse.go Normal file
View File

@ -0,0 +1,78 @@
package tp
import (
"bufio"
"bytes"
"fmt"
"strings"
)
func ParseCmd(pwd string, content []byte) ([]TpCmd, error) {
var (
err error
cmds = make([]TpCmd, 0)
start = false
)
scanner := bufio.NewScanner(bytes.NewReader(content))
scanner.Buffer(make([]byte, 1024), 1024*1024*10)
record := make([]string, 0)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if len(line) == 0 {
continue
}
if strings.HasPrefix(line, "#") {
continue
}
if strings.HasPrefix(line, "!") {
if start {
return nil, fmt.Errorf("invalid content: unEOF cmd block found")
}
start = true
record = append(record, line)
continue
}
if strings.HasPrefix(line, "EOF") {
start = false
if len(record) == 0 {
continue
}
var cmd TpCmd
if cmd, err = ParseBlock(pwd, record); err != nil {
return nil, err
}
cmds = append(cmds, cmd)
record = record[:0]
continue
}
if start {
record = append(record, line)
}
}
if err = scanner.Err(); err != nil {
return nil, err
}
return cmds, err
}
func ParseBlock(pwd string, lines []string) (TpCmd, error) {
switch lines[0] {
case "!replace":
return newReplace(pwd, lines[1:])
case "!generate":
return newGenerate(pwd, lines[1:])
}
return nil, fmt.Errorf("invalid cmd block: unknown type: %s", lines[0])
}

View File

@ -0,0 +1,61 @@
package tp
import (
"github.com/loveuer/nf/nft/log"
"os"
"testing"
)
func TestParseInitFile(t *testing.T) {
const init_bs = `
!replace
content
reg
*.go
ultone => {{.PROJECT_NAME}}
EOF
!replace
content
exact
go.mod
module ultone => module {{.PROJECT_NAME}}
EOF
!replace
name
main.go => loveuer.go
EOF
!generate
readme.md
# {{.PROJECT_NAME}}
### run
- ` + "`" + `go run . --help` + "`" + `
- ` + "`" + `go run .` + "`" + `
### build
- ` + "`" + `docker build -t {repo:tag} -f Dockerfile .` + "`" + `
EOF
`
data := map[string]any{
"PROJECT_NAME": "loveuer",
}
result, err := RenderVar([]byte(init_bs), data)
if err != nil {
log.Fatal(err.Error())
}
pwd, _ := os.Getwd()
cmds, err := ParseCmd(pwd, result)
if err != nil {
log.Fatal(err.Error())
}
for _, item := range cmds {
log.Info("one cmd => %s\n\n", item.String())
}
}

29
nft/nfctl/tp/template.go Normal file
View File

@ -0,0 +1,29 @@
package tp
import (
"bytes"
"text/template"
)
var (
_t *template.Template
)
func init() {
_t = template.New("tp")
}
func RenderVar(t []byte, data map[string]any) ([]byte, error) {
tr, err := _t.Parse(string(t))
if err != nil {
return nil, err
}
var buf bytes.Buffer
if err = tr.Execute(&buf, data); err != nil {
return nil, err
}
return buf.Bytes(), nil
}

92
nft/nfctl/tp/tp.go Normal file
View File

@ -0,0 +1,92 @@
package tp
import (
"fmt"
"os"
"path"
"strings"
)
type TpCmd interface {
String() string
Execute() error
}
var (
_ TpCmd = (*TpGenerate)(nil)
_ TpCmd = (*TpReplace)(nil)
)
type TpGenerate struct {
pwd string
filename string
content []string
}
func (t *TpGenerate) String() string {
//TODO implement me
panic("implement me")
}
func (t *TpGenerate) Execute() error {
var (
err error
location = t.filename
input *os.File
)
if !path.IsAbs(t.filename) {
location = path.Join(t.pwd, t.filename)
}
if err = os.MkdirAll(path.Dir(location), 0644); err != nil {
return err
}
if !strings.HasSuffix(location, "/") {
if input, err = os.OpenFile(location, os.O_CREATE|os.O_APPEND, 0744); err != nil {
return err
}
if len(t.content) > 0 {
content := strings.Join(t.content, "\n")
_, err = input.WriteString(content)
return err
}
}
return nil
}
func newGenerate(pwd string, lines []string) (*TpGenerate, error) {
if len(lines) == 0 {
return nil, fmt.Errorf("generate cmd require file/folder name")
}
return &TpGenerate{
pwd: pwd,
filename: lines[0],
content: lines[1:],
}, nil
}
type TpReplace struct {
pwd string
}
func (t *TpReplace) String() string {
//TODO implement me
panic("implement me")
}
func (t *TpReplace) Execute() error {
//TODO implement me
panic("implement me")
}
func newReplace(pwd string, lines []string) (*TpReplace, error) {
if len(lines) < 2 {
return nil, fmt.Errorf("invalid replace cmd")
}
return &TpReplace{pwd: pwd}, nil
}