Skip to content

Commit

Permalink
Merge pull request #5 from TuhinBar/v1
Browse files Browse the repository at this point in the history
feat: added air for auto reload
  • Loading branch information
tuhinexe authored Sep 28, 2024
2 parents c4a1b8d + e2e7b69 commit b74286d
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 19 deletions.
39 changes: 29 additions & 10 deletions lib/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,62 @@ import (
"embed"
"fmt"
"os"
"os/exec"
"path/filepath"
"text/template"

"github.com/TuhinBar/optical/lib/helper"
)

//go:embed templates/*.tmpl
var templateFS embed.FS


func GenerateProject(name, path string,ghUsername string) error {
func GenerateProject(name, path string,ghUsername string,hasAir bool) error {
projectPath := filepath.Join(path, name)

if err := os.MkdirAll(projectPath, os.ModePerm); err != nil {
return fmt.Errorf("❗ Failed to create project directory: %w", err)
}

dirs := []string{"cmd", "internal/handlers", "internal/middleware", "internal/models","internal/routes","internal/services", "config"}
dirs := []string{ "handlers", "middleware", "models","routes","services", "config"}
for _, dir := range dirs {
if err := os.MkdirAll(filepath.Join(projectPath, dir), os.ModePerm); err != nil {
return fmt.Errorf("❗Failed to create directory %s: %w", dir, err)
}
}

files := map[string]string{
"cmd/main.go": "main.go.tmpl",
"internal/handlers/handler.go": "handler.go.tmpl",
"internal/middleware/middleware.go": "middleware.go.tmpl",
"internal/services/service.go": "service.go.tmpl",
"internal/models/models.go": "models.go.tmpl",
"internal/routes/routes.go": "routes.go.tmpl",
"config/config.go": "config.go.tmpl",
"go.mod": "go.mod.tmpl",
"main.go": "main.go.tmpl",
"handlers/handler.go": "handler.go.tmpl",
"middleware/middleware.go": "middleware.go.tmpl",
"services/service.go": "service.go.tmpl",
"models/models.go": "models.go.tmpl",
"routes/routes.go": "routes.go.tmpl",
"config/config.go": "config.go.tmpl",
"go.mod": "go.mod.tmpl",
".air.toml": ".air.toml.tmpl",
}

for filePath, templateName := range files {
if err := generateFileFromTemplate(projectPath, filePath, templateName, name,ghUsername); err != nil {
return fmt.Errorf("❗Failed to create %s: %w", filePath, err)
}
};

if !hasAir {
done := make(chan bool)
go helper.ShowLoadingIndicator(done)
cmd := exec.Command("go", "install", "github.com/air-verse/air@latest")
cmd.Dir = projectPath

if output, err := cmd.CombinedOutput(); err != nil {
done <- true
fmt.Printf("❗Failed to install air in your project: %v\nOutput: %s\n", err, string(output))
} else {
done <- true
fmt.Println("✅ Successfully installed air for auto-reload")
}
}

return nil
Expand Down
51 changes: 51 additions & 0 deletions lib/generator/templates/.air.toml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
args_bin = []
bin = "./tmp/main"
cmd = "go build -o ./tmp/main ."
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = []
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false

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

[log]
main_only = false
time = false

[misc]
clean_on_exit = false

[proxy]
app_port = 0
enabled = false
proxy_port = 0

[screen]
clear_on_rebuild = false
keep_scroll = true
5 changes: 4 additions & 1 deletion lib/generator/templates/go.mod.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ module github.com/{{.GitHubUsername}}/{{.ProjectName}}

go 1.22

require github.com/gofiber/fiber/v2 v2.52.5
require (
github.com/gofiber/fiber/v2 v2.52.5
github.com/air-verse/air v1.52.3 // indirect
)
2 changes: 1 addition & 1 deletion lib/generator/templates/handler.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package handlers

import (
"github.com/gofiber/fiber/v2"
"github.com/{{.GitHubUsername}}/{{.ProjectName}}/internal/services")
"github.com/{{.GitHubUsername}}/{{.ProjectName}}/services")


func Greet(c *fiber.Ctx) error {
Expand Down
2 changes: 1 addition & 1 deletion lib/generator/templates/main.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"log"

"github.com/gofiber/fiber/v2"
"github.com/{{.GitHubUsername}}/{{.ProjectName}}/internal/routes"
"github.com/{{.GitHubUsername}}/{{.ProjectName}}/routes"
)

func main() {
Expand Down
2 changes: 1 addition & 1 deletion lib/generator/templates/routes.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"log"

"github.com/gofiber/fiber/v2"
"github.com/{{.GitHubUsername}}/{{.ProjectName}}/internal/handlers"
"github.com/{{.GitHubUsername}}/{{.ProjectName}}/handlers"
)

func SetupRoutes(app *fiber.App) {
Expand Down
4 changes: 3 additions & 1 deletion lib/generator/templates/service.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ package services
import "github.com/gofiber/fiber/v2"

func GreetUser(c *fiber.Ctx) error {
return c.SendString("Hello, World!")
return c.JSON(map[string]string{
"message":"Hello User",
})
}
28 changes: 25 additions & 3 deletions lib/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import (
"flag"
"fmt"
"os"
"time"

"github.com/charmbracelet/huh"
)
type Prompts struct{
ProjectName string;
GhUserName string;
HasAir bool
DbType string;

}
Expand Down Expand Up @@ -44,19 +46,23 @@ func CreateForm() (*huh.Form,*Prompts) {
prompts := Prompts{}
form := huh.NewForm(
huh.NewGroup(
huh.NewInput().Title("What is the name of your project?(e.g 'my-fiber-api','./')").Value(&prompts.ProjectName).Validate(func(str string) error {
huh.NewInput().Title("What is the name of your project?(e.g 'my-fiber-api','./')").Description("A new folder with this name will be created.").Value(&prompts.ProjectName).Validate(func(str string) error {
if str == "" {
return errors.New("project name can't be empty")

}
return nil
}),
huh.NewInput().Title("Enter your GitHub username.").Value(&prompts.GhUserName).Validate(func(s string) error {
huh.NewInput().Title("Enter your GitHub username.").Description("This is required to create the go.mod file").Value(&prompts.GhUserName).Validate(func(s string) error {
if s == "" {
return errors.New("github username is required")
}
return nil
}),
huh.NewSelect[bool]().Title("Do you have air installed ?").Description("Air is required for auto-reload").Options(
huh.NewOption("Yes",true),
huh.NewOption("No",false),
).Value(&prompts.HasAir),
),
)

Expand All @@ -71,6 +77,22 @@ func PrintSuccessMsg(name string) {
To run the project follow these steps:
1. cd ` + name + `
2. go mod tidy
3. go run ./cmd/main.go
3. air
`)
}

func ShowLoadingIndicator(done chan bool) {
loadingChars := []rune{'|', '/', '-', '\\'}
i := 0
for {
select {
case <-done:
fmt.Print("\r")
return
default:
fmt.Printf("\rInstalling air... %c", loadingChars[i%len(loadingChars)])
i++
time.Sleep(100 * time.Millisecond)
}
}
}
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func main() {

}

projectErr := generator.GenerateProject(prompts.ProjectName,".",prompts.GhUserName)
projectErr := generator.GenerateProject(prompts.ProjectName,".",prompts.GhUserName,prompts.HasAir)

if projectErr != nil {
fmt.Printf("❗Error generating project: %v\n", projectErr)
Expand Down

0 comments on commit b74286d

Please sign in to comment.