cli

package
v0.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2025 License: MIT Imports: 12 Imported by: 0

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

View Source
var BuildCommand = &cli.Command{
	Name:  "build",
	Usage: "Compile all .server.go files into .so plugins for production use",
	Action: func(c *cli.Context) error {
		modName, err := getGoModuleName()
		if err != nil {
			return fmt.Errorf("failed to determine module name from go.mod: %w", err)
		}

		for _, root := range []string{"routes", "api"} {
			err = filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error {
				if err != nil || d.IsDir() {
					return nil
				}
				if filepath.Base(path) != "index.server.go" {
					return nil
				}

				dir := filepath.Dir(path)
				pluginOut := filepath.Join(dir, "index.server.so")

				relImport := strings.TrimPrefix(dir, root)
				relImport = strings.TrimPrefix(relImport, string(filepath.Separator))
				relImport = filepath.ToSlash(filepath.Join(root, relImport))
				importPath := fmt.Sprintf("%s/%s", modName, relImport)

				tmpFile := filepath.Join(".barry-tmp", relImport, "plugin_wrapper.go")

				if err := osMkdirAllFunc(filepath.Dir(tmpFile), os.ModePerm); err != nil {
					return fmt.Errorf("failed to create wrapper directory: %w", err)
				}

				wrapper := fmt.Sprintf(`package main

import user "%s"

import (
	"net/http"
)

func HandleRequest(r *http.Request, p map[string]string) (map[string]interface{}, error) {
	return user.HandleRequest(r, p)
}
`, importPath)

				if err := osWriteFileFunc(tmpFile, []byte(wrapper), 0644); err != nil {
					return fmt.Errorf("failed to write wrapper for %s: %w", path, err)
				}

				cmd := buildExecCommand("go", "build", "-buildmode=plugin", "-o", pluginOut, tmpFile)
				cmd.Dir = "."
				cmd.Stdout = os.Stdout
				cmd.Stderr = os.Stderr
				cwd, _ := os.Getwd()
				fmt.Println("πŸ“¦ Building from:", cwd)
				fmt.Println("πŸ”§ Building:", pluginOut)
				if err := cmd.Run(); err != nil {
					return fmt.Errorf("failed to build plugin for %s: %w", path, err)
				}
				return nil
			})

			if err != nil {
				return err
			}
		}

		fmt.Println("βœ… All plugins built successfully.")
		return nil
	},
}
View Source
var CheckCommand = &cli.Command{
	Name:  "check",
	Usage: "Validate templates, components, and layouts",
	Action: func(c *cli.Context) error {
		var failed bool

		var components []string
		filepath.Walk("components", func(path string, info os.FileInfo, err error) error {
			if err == nil && !info.IsDir() && strings.HasSuffix(path, ".html") {
				components = append(components, path)
			}
			return nil
		})

		filepath.Walk("routes", func(path string, info os.FileInfo, err error) error {
			if err != nil || !info.IsDir() {
				return nil
			}

			htmlPath := filepath.Join(path, "index.html")
			if _, err := os.Stat(htmlPath); err != nil {
				return nil
			}

			layoutPath := ""
			if content, err := os.ReadFile(htmlPath); err == nil {
				lines := strings.Split(string(content), "\n")
				for _, line := range lines {
					line = strings.TrimSpace(line)
					if strings.HasPrefix(line, "<!-- layout:") && strings.HasSuffix(line, "-->") {
						layoutPath = strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(line, "<!-- layout:"), "-->"))
						break
					}
				}
			}

			files := append([]string{htmlPath}, components...)
			if layoutPath != "" {
				files = append([]string{layoutPath}, files...)
			}

			rel, _ := filepath.Rel("routes", path)
			if rel == "." {
				rel = "/"
			} else {
				rel = "/" + rel
			}

			var tmpl *template.Template
			tmpl = template.New(filepath.Base(files[0])).Funcs(core.BarryTemplateFuncs("dev", "cache"))
			tmpl, err = tmpl.ParseFiles(files...)

			if err != nil {
				failed = true
				fmt.Printf("❌ %s β†’ parse error: %v\n", rel, err)
				return nil
			}

			var buf bytes.Buffer
			err = tmpl.ExecuteTemplate(&buf, "layout", map[string]interface{}{})
			if err != nil {
				failed = true
				fmt.Printf("❌ %s β†’ exec error: %v\n", rel, err)
			} else {
				fmt.Printf("βœ… %s\n", rel)
			}

			return nil
		})

		if failed {
			return cli.Exit("some templates failed to compile", 1)
		}

		fmt.Println("βœ… All templates validated successfully.")
		return nil
	},
}
View Source
var CleanCommand = &cli.Command{
	Name:      "clean",
	Usage:     "Delete cached HTML from the output directory (default: outputDir in barry.config.yml)",
	ArgsUsage: "[route (optional)]",
	Action: func(c *cli.Context) error {
		config := core.LoadConfig("barry.config.yml")
		target := config.OutputDir

		if c.Args().Len() > 0 {
			route := c.Args().Get(0)
			route = strings.TrimPrefix(route, "/")
			target = filepath.Join(config.OutputDir, route)
		}

		info, err := os.Stat(target)
		if err != nil {
			if os.IsNotExist(err) {
				fmt.Println("🧼 Nothing to clean:", target)
				return nil
			}
			return fmt.Errorf("failed to access path: %w", err)
		}

		if !info.IsDir() {
			return fmt.Errorf("not a directory: %s", target)
		}

		fmt.Println("🧹 Cleaning:", target)
		err = os.RemoveAll(target)
		if err != nil {
			return fmt.Errorf("failed to clean cache: %w", err)
		}

		fmt.Println("βœ… Done.")
		return nil
	},
}
View Source
var DevCommand = &cli.Command{
	Name:  "dev",
	Usage: "Start Barry in dev mode (no caching, live reload)",
	Action: func(c *cli.Context) error {
		cfg := barry.RuntimeConfig{
			Env:         "dev",
			EnableCache: false,
			Port:        8080,
		}
		barry.Start(cfg)
		return nil
	},
}
View Source
var InfoCommand = &cli.Command{
	Name:  "info",
	Usage: "Print project structure and cache summary",
	Action: func(c *cli.Context) error {
		config := core.LoadConfig("barry.config.yml")

		fmt.Println("πŸ“ Output Directory:", config.OutputDir)
		fmt.Println("πŸ” Cache Enabled:", config.CacheEnabled)
		fmt.Println("πŸ” Debug Headers Enabled:", config.DebugHeaders)
		fmt.Println("πŸ” Debug Logs Enabled:", config.DebugLogs)
		fmt.Println()

		componentCount := 0
		filepath.Walk("components", func(path string, info os.FileInfo, err error) error {
			if err == nil && !info.IsDir() && strings.HasSuffix(path, ".html") {
				componentCount++
			}
			return nil
		})

		routeCount := 0
		filepath.Walk("routes", func(path string, info os.FileInfo, err error) error {
			if err == nil && info.IsDir() {
				indexFile := filepath.Join(path, "index.html")
				if _, err := os.Stat(indexFile); err == nil {
					routeCount++
				}
			}
			return nil
		})

		cacheCount := 0
		filepath.Walk(config.OutputDir, func(path string, info os.FileInfo, err error) error {
			if err == nil && !info.IsDir() && strings.HasSuffix(path, ".html") {
				cacheCount++
			}
			return nil
		})

		fmt.Println("πŸ—‚οΈ  Routes Found:", routeCount)
		fmt.Println("πŸ“¦ Components Found:", componentCount)
		fmt.Println("πŸ’Ύ Cached Pages:", cacheCount)

		return nil
	},
}
View Source
var InitCommand = &cli.Command{
	Name:  "init",
	Usage: "Create a new Barry project from the default starter",
	Action: func(c *cli.Context) error {
		targetDir, _ := os.Getwd()
		fmt.Println("πŸš€ Creating Barry project in:", targetDir)

		err := copyEmbeddedDir(starterFS, "_starter", targetDir)
		if err != nil {
			return fmt.Errorf("failed to create project: %w", err)
		}

		mainFile := filepath.Join(targetDir, "main.go")
		modFile := filepath.Join(targetDir, "go.mod")

		if _, err := os.Stat(mainFile); err == nil {
			if _, err := os.Stat(modFile); os.IsNotExist(err) {
				moduleName := filepath.Base(targetDir)
				fmt.Println("πŸ”§ Initialising Go module:", moduleName)

				cmd := exec.Command("go", "mod", "init", moduleName)
				cmd.Stdout = os.Stdout
				cmd.Stderr = os.Stderr
				cmd.Dir = targetDir
				if err := cmd.Run(); err != nil {
					return fmt.Errorf("failed to run go mod init: %w", err)
				}

				cmd = exec.Command("go", "mod", "tidy")
				cmd.Stdout = os.Stdout
				cmd.Stderr = os.Stderr
				cmd.Dir = targetDir
				if err := cmd.Run(); err != nil {
					return fmt.Errorf("failed to run go mod tidy: %w", err)
				}
			}
		}

		fmt.Println("βœ… Project created successfully.")
		fmt.Println("β–Ά  Run: barry dev")
		return nil
	},
}
View Source
var ProdCommand = &cli.Command{
	Name:  "prod",
	Usage: "Start Barry in production mode (caching on by default)",
	Action: func(c *cli.Context) error {
		cfg := barry.RuntimeConfig{
			Env:         "prod",
			EnableCache: true,
			Port:        8080,
		}
		barry.Start(cfg)
		return nil
	},
}

Functions ΒΆ

This section is empty.

Types ΒΆ

This section is empty.

Directories ΒΆ

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL