air-verse / air

☁️ Live reload for Go apps
GNU General Public License v3.0
16.32k stars 770 forks source link

Issue when compiling static files #612

Open gopherine opened 3 weeks ago

gopherine commented 3 weeks ago

So I have been trying to run htmx and have this project structure, this does work when all of these three files i.e main.go static_prod.go and static_dev.go is in root of the project alongside embed.go but with below structure it does not work

cmd/app
    main.go
    static_prod.go
    static_dev.go
embed.go

// embed.go
package static

import "embed"

//go:embed public/**/*
var PublicFS embed.FS
// static_prod.go
//go:build !dev
// +build !dev

package main

import (
    "net/http"

    static "github.com/goemon"
)

func public() http.Handler {
    return http.FileServerFS(static.PublicFS)
}
static_dev.go

//go:build dev
// +build dev

package main

import (
    "fmt"
    "net/http"
    "os"
)

func public() http.Handler {
    fmt.Println("Building static files for development")
    return http.StripPrefix("../public/**/*", http.FileServerFS(os.DirFS("public")))
}
package main

import (
    "context"
    "fmt"
    "log"
    "net/http"
    "os"
    "os/signal"
    "time"

    static "github.com/goemon"
    "github.com/goemon/internals/handlers"
    "github.com/joho/godotenv"
    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
)

func main() {
    if err := godotenv.Load(); err != nil {
        log.Fatal(err)
    }

    // Echo instance
    e := echo.New()

    e.GET("/", func(c echo.Context) error {
        time.Sleep(5 * time.Second)
        return c.JSON(http.StatusOK, "OK")
    })

    // Middleware
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    // Routes
    e.GET("/*", echo.WrapHandler(http.FileServer(http.FS(static.PublicFS))))
    e.GET("/", handlers.Make(handlers.Hello))

    // Start server
    ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
    defer stop()
    // Start server
    go func() {
        if err := e.Start(fmt.Sprintf(":%s", os.Getenv("LISTEN_ADDR"))); err != nil && err != http.ErrServerClosed {
            e.Logger.Fatal("shutting down the server")
        }
    }()

    // Wait for interrupt signal to gracefully shutdown the server with a timeout of 10 seconds.
    <-ctx.Done()
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    if err := e.Shutdown(ctx); err != nil {
        e.Logger.Fatal(err)
    }
}

Now this works perfectly fine when building and running it manually

however with air it does not work

  1. initially it asks for permissions to tmp folder
  2. once i set permission via chmod , I get below error

Now, I could understand the error could be in code but this works perfectly fine when building and running it manually

/Users/arvee/Documents/interview/amm-ui/goemx/tmp/main: line 1: syntax error near unexpected token `newline'
/Users/arvee/Documents/interview/amm-ui/goemx/tmp/main: line 1: `!<arch>'
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
args_bin = []
bin = "./tmp/main"
cmd = "go build -tags '!dev' -o tmp/main ./cmd/app/."

delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata", "node_modules"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "templ", "html"]
kill_delay = "0s"
log = "build-errors.log"
send_interrupt = false
stop_on_error = true

[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "blue"

[log]
time = false

[misc]
clean_on_exit = false

[screen]
clear_on_rebuild = false