mirror of
https://github.com/cubixle/tuukoti-cli.git
synced 2026-04-24 18:24:47 +01:00
start of creating a new project cmd
This commit is contained in:
8
README.md
Normal file
8
README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Tuukoti CLI
|
||||
|
||||
## Commands
|
||||
|
||||
- `tuukoti new sitename` - creates a new project directory with "sitename".
|
||||
- `tuukoti serve` - serves your app locally.
|
||||
- `tuukoti build` - builds the binary and any resources.
|
||||
- `tuukoti update`
|
||||
106
main.go
Normal file
106
main.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/tuukoti/cli/maker"
|
||||
)
|
||||
|
||||
const colorRed = "\033[0;31m"
|
||||
const colorGreen = "\033[0;32m"
|
||||
const colorBlue = "\033[0;34m"
|
||||
const colorYellow = "\033[93m"
|
||||
const colorNone = "\033[0m"
|
||||
const newLine = "\n"
|
||||
|
||||
var Version = "develop"
|
||||
|
||||
//go:embed templates
|
||||
var fs embed.FS
|
||||
|
||||
func main() {
|
||||
if err := runCLI(); err != nil {
|
||||
fmt.Printf("%s%s%s", colorRed, err, newLine)
|
||||
}
|
||||
|
||||
fmt.Println("")
|
||||
}
|
||||
|
||||
func runCLI() error {
|
||||
|
||||
fmt.Println("------------------")
|
||||
fmt.Printf("Tuukoti CLI - %s%s", Version, newLine)
|
||||
fmt.Println("------------------")
|
||||
fmt.Println("")
|
||||
|
||||
args := os.Args
|
||||
if len(args) == 1 {
|
||||
err := fmt.Errorf("missing command, try `tuukoti list` to see what you can run.")
|
||||
|
||||
fmt.Println(err)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
switch os.Args[1] {
|
||||
case "list":
|
||||
printCmd("new sitename", "create a new project within the directory of sitename")
|
||||
printCmd("serve", "serves your app locally")
|
||||
printCmd("build", "build the binary and any resources configured")
|
||||
printCmd("list", "list displays a list of all commands")
|
||||
printCmd("version", "displays the cli tools current version")
|
||||
fmt.Println("")
|
||||
printHeader("make")
|
||||
printCmd("make resource", "creates a new route file and a ")
|
||||
case "version":
|
||||
fmt.Println("")
|
||||
version()
|
||||
case "new":
|
||||
err := maker.Project(fs, os.Args[2])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("%sproject %s has been created%s", colorGreen, os.Args[2], newLine)
|
||||
case "serve":
|
||||
|
||||
case "build":
|
||||
|
||||
case "make":
|
||||
if len(os.Args) == 2 {
|
||||
fmt.Printf("missing what we should make %s", newLine)
|
||||
return nil
|
||||
}
|
||||
|
||||
switch os.Args[2] {
|
||||
case "resource":
|
||||
resourceName := os.Args[3]
|
||||
|
||||
err := maker.Resource(resourceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
err := fmt.Errorf("missing command, try `tuukoti list` to see what you can run.")
|
||||
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func version() {
|
||||
fmt.Printf("Version: %s%s", Version, newLine)
|
||||
}
|
||||
|
||||
func printCmd(commandName, desc string) {
|
||||
fmt.Printf(" %s%-12s %s- %s.%s", colorGreen, commandName, colorNone, desc, newLine)
|
||||
}
|
||||
|
||||
func printHeader(h string) {
|
||||
fmt.Printf("%s%s%s", colorYellow, h, newLine)
|
||||
}
|
||||
189
maker/project.go
Normal file
189
maker/project.go
Normal file
@@ -0,0 +1,189 @@
|
||||
package maker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func Project(fs fs.FS, name string) error {
|
||||
_, err := os.Stat(name)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
return fmt.Errorf("project folder already exists")
|
||||
}
|
||||
|
||||
absPath, err := filepath.Abs(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.Mkdir(absPath, 0777)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create the project folder, %w", err)
|
||||
}
|
||||
|
||||
err = makeProject(fs, absPath, name)
|
||||
if err != nil {
|
||||
rerr := os.RemoveAll(absPath)
|
||||
if rerr != nil {
|
||||
return rerr
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeProject(fs fs.FS, absPath, name string) error {
|
||||
// check if folder already exists
|
||||
err := mainfile(fs, absPath, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = defaultHTTPRoutes(fs, absPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = defaultHomepage(fs, absPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = defaultConfig(fs, absPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func mainfile(fs fs.FS, path, projectName string) error {
|
||||
path = filepath.Join(path, "cmd", projectName)
|
||||
|
||||
err := os.MkdirAll(path, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(path, "main.go"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := fs.Open("templates/main.go")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.Copy(f, tmpl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// defaultHTTPRoutes will create a ./http dir with a http.go file.
|
||||
// In this file we will register 1 route and 2 route handlers.
|
||||
// The first handle is the home "/" handler.
|
||||
// The second handler is a 404 handler.
|
||||
func defaultHTTPRoutes(fs fs.FS, path string) error {
|
||||
path = filepath.Join(path, "internal", "http")
|
||||
|
||||
err := os.MkdirAll(path, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(path, "http.go"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := fs.Open("templates/http/http.go")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.Copy(f, tmpl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func defaultHomepage(fs fs.FS, path string) error {
|
||||
err := os.Mkdir(filepath.Join(path, "template"), 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(path, "templates", "index.html"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := fs.Open("templates/index.html")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.Copy(f, tmpl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func defaultConfig(fs fs.FS, path string) error {
|
||||
f, err := os.Create(filepath.Join(path, "config.yml"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpl, err := fs.Open("templates/config.yml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.Copy(f, tmpl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
5
maker/resource.go
Normal file
5
maker/resource.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package maker
|
||||
|
||||
func Resource(name string) error {
|
||||
return nil
|
||||
}
|
||||
2
templates/config.yml
Normal file
2
templates/config.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
host: localhost:8080
|
||||
debug: false
|
||||
25
templates/internal/http/default.go
Normal file
25
templates/internal/http/default.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func (h *HTTP) DefaultHandler(c echo.Context) error {
|
||||
return c.Render(http.StatusOK, "index.html", nil)
|
||||
}
|
||||
|
||||
func (h *HTTP) DefaultErrorHandler(err error, c echo.Context) {
|
||||
code := http.StatusInternalServerError
|
||||
if he, ok := err.(*echo.HTTPError); ok {
|
||||
code = he.Code
|
||||
}
|
||||
|
||||
h.log.Error(err)
|
||||
|
||||
err = c.Render(code, "error.html", nil)
|
||||
if err != nil {
|
||||
h.log.Error(err)
|
||||
}
|
||||
}
|
||||
18
templates/internal/http/http.go
Normal file
18
templates/internal/http/http.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type HTTP struct {
|
||||
log *logrus.Logger
|
||||
}
|
||||
|
||||
func RegisterRoutes(e *echo.Echo, log *logrus.Logger) {
|
||||
h := HTTP{log: log}
|
||||
|
||||
e.HTTPErrorHandler = h.DefaultErrorHandler
|
||||
|
||||
e.GET("/", h.DefaultHandler)
|
||||
}
|
||||
43
templates/main.go.tmpl
Normal file
43
templates/main.go.tmpl
Normal file
@@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/cubixle/testing/internal/http"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/tuukoti/framework/config"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
cfgPath := getEnv("TUUKOTI_CONFIG", "./config.yml")
|
||||
|
||||
cfg, err := config.Load(cfgPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log := logrus.New()
|
||||
|
||||
e := echo.New()
|
||||
|
||||
http.RegisterRoutes(e, log)
|
||||
|
||||
return e.Start(cfg.Host)
|
||||
}
|
||||
|
||||
func getEnv(name, defaultValue string) string {
|
||||
v := os.Getenv(name)
|
||||
if v == "" {
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
0
templates/views/error.html
Normal file
0
templates/views/error.html
Normal file
11
templates/views/index.html
Normal file
11
templates/views/index.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Tuukoti</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Tuukoti</h1>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user