From e5b978a49ddcf1623d96799b738158cbd933cdf2 Mon Sep 17 00:00:00 2001 From: Ujstor Date: Sun, 2 Feb 2025 15:21:10 +0100 Subject: [PATCH] -backend-framework --- README.md | 5 +- cmd/create.go | 52 +++++++-------- cmd/flags/backend.go | 34 +++++----- cmd/program/advanced.go | 4 +- cmd/program/frontend.go | 4 +- cmd/program/helpers.go | 8 +-- cmd/program/program.go | 64 +++++++++---------- cmd/steps/steps.go | 8 +-- .../advanced/files/docker/dockerfile.tmpl | 3 +- .../{backend.md => backend-frameworks.md} | 0 docs/docs/creating-project/project-init.md | 2 +- docs/docs/index.md | 2 +- docs/mkdocs.yml | 2 +- 13 files changed, 91 insertions(+), 97 deletions(-) rename docs/docs/blueprint-core/{backend.md => backend-frameworks.md} (100%) diff --git a/README.md b/README.md index d51a3d30..9e814f86 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,13 @@ gives the option to integrate with one of the more popular backend and fronted f - Easy to set up and install - Have the entire Go structure already established - Setting up a Go HTTP server (or Fasthttp with Fiber) +- Integrates with a popular backend and frontend frameworks - Focus on the actual code of your application ## Table of Contents - [Install](#install) -- [Backend Frameworks](#backends) +- [BackendFramework Frameworks](#backends) - [Database Support](#database-support) - [Frontend Frameworks](#frontend) - [Advanced Features](#advanced-features) @@ -76,7 +77,7 @@ Usage: Flags: -a, --advanced Get prompts for advanced features --feature AdvancedFeatures Advanced feature to use. Allowed values: githubaction, websocket, docker - -b, --backend Backend Backend to use. Allowed values: chi, gin, fiber, gorilla/mux, standard-library, echo + -b, --backend-framework BackendFramework Backend framework to use. Allowed values: chi, gin, fiber, gorilla/mux, standard-library, echo -d, --driver Database Database drivers to use. Allowed values: mysql, postgres, sqlite, mongo, redis, scylla, none -f, --frontend Get prompts for frontend frameworks --frontend-framework Frontendframework Frontend framework to use. Allowed values: htmx, react diff --git a/cmd/create.go b/cmd/create.go index 98493b4e..54e0c329 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -40,7 +40,7 @@ var ( ) func init() { - var flagBackend flags.Backend + var flagBackendFramework flags.BackendFramework var flagDBDriver flags.Database var frontendFrameworks flags.FrontendFramework var frontendAdvanced flags.FrontendAdvanced @@ -50,7 +50,7 @@ func init() { // Main flags createCmd.Flags().StringP("name", "n", "", "Name of project to create") - createCmd.Flags().VarP(&flagBackend, "backend", "b", fmt.Sprintf("Backend to use. Allowed values: %s", strings.Join(flags.AllowedBackedTypes, ", "))) + createCmd.Flags().VarP(&flagBackendFramework, "backend-framework", "b", fmt.Sprintf("Backend framework to use. Allowed values: %s", strings.Join(flags.AllowedBackendFrameworkTypes, ", "))) createCmd.Flags().VarP(&flagDBDriver, "driver", "d", fmt.Sprintf("Database drivers to use. Allowed values: %s", strings.Join(flags.AllowedDBDrivers, ", "))) createCmd.Flags().VarP(&flagGit, "git", "g", fmt.Sprintf("Git to use. Allowed values: %s", strings.Join(flags.AllowedGitsOptions, ", "))) @@ -62,17 +62,11 @@ func init() { // Advanced features group createCmd.Flags().BoolP("advanced", "a", false, "Get prompts for advanced features") createCmd.Flags().Var(&advancedFeatures, "feature", fmt.Sprintf("Advanced feature to use. Allowed values: %s", strings.Join(flags.AllowedAdvancedFeatures, ", "))) - - // // Mark dependencies for frontend flags - // createCmd.MarkFlagsRequiredTogether("frontend", "frontend-framework") - // - // // Mark feature flag as requiring --advanced - // createCmd.MarkFlagsRequiredTogether("advanced", "feature") } type Options struct { ProjectName *textinput.Output - ProjectType *multiInput.Selection + BackendFramework *multiInput.Selection DBDriver *multiInput.Selection FrontendFramework *multiInput.Selection FrontendAdvanced *multiSelect.Selection @@ -106,14 +100,14 @@ var createCmd = &cobra.Command{ // VarP already validates the contents of the framework flag. // If this flag is filled, it is always valid - flagBackend := flags.Backend(cmd.Flag("backend").Value.String()) + flagBackendFramework := flags.BackendFramework(cmd.Flag("backend-framework").Value.String()) flagDBDriver := flags.Database(cmd.Flag("driver").Value.String()) flagFrontendFremwork := flags.FrontendFramework(cmd.Flag("frontend-framework").Value.String()) flagGit := flags.Git(cmd.Flag("git").Value.String()) options := Options{ ProjectName: &textinput.Output{}, - ProjectType: &multiInput.Selection{}, + BackendFramework: &multiInput.Selection{}, DBDriver: &multiInput.Selection{}, FrontendFramework: &multiInput.Selection{}, FrontendAdvanced: &multiSelect.Selection{ @@ -126,18 +120,18 @@ var createCmd = &cobra.Command{ } project := &program.Project{ - ProjectName: flagName, - ProjectType: flagBackend, - DBDriver: flagDBDriver, - BackendMap: make(map[flags.Backend]program.Backend), - DBDriverMap: make(map[flags.Database]program.Driver), - FrontendFramework: flagFrontendFremwork, - FrontendOptions: make(map[string]bool), - AdvancedOptions: make(map[string]bool), - GitOptions: flagGit, + ProjectName: flagName, + BackendFramework: flagBackendFramework, + DBDriver: flagDBDriver, + BackendFrameworkMap: make(map[flags.BackendFramework]program.BackendFramework), + DBDriverMap: make(map[flags.Database]program.Driver), + FrontendFramework: flagFrontendFremwork, + FrontendOptions: make(map[string]bool), + AdvancedOptions: make(map[string]bool), + GitOptions: flagGit, } - steps := steps.InitSteps(flagBackend, flagDBDriver, flagFrontendFremwork, flagGit) + steps := steps.InitSteps(flagBackendFramework, flagDBDriver, flagFrontendFremwork, flagGit) fmt.Printf("%s\n", logoStyle.Render(logo)) // Frontend option steps: @@ -187,23 +181,23 @@ var createCmd = &cobra.Command{ } } - if project.ProjectType == "" { + if project.BackendFramework == "" { isInteractive = true - step := steps.Steps["backend"] - tprogram = tea.NewProgram(multiInput.InitialModelMulti(step.Options, options.ProjectType, step.Headers, project)) + step := steps.Steps["backend-framework"] + tprogram = tea.NewProgram(multiInput.InitialModelMulti(step.Options, options.BackendFramework, step.Headers, project)) if _, err := tprogram.Run(); err != nil { cobra.CheckErr(textinput.CreateErrorInputModel(err).Err()) } project.ExitCLI(tprogram) - step.Field = options.ProjectType.Choice + step.Field = options.BackendFramework.Choice // this type casting is always safe since the user interface can - // only pass strings that can be cast to a flags.Backend instance - project.ProjectType = flags.Backend(strings.ToLower(options.ProjectType.Choice)) - err := cmd.Flag("backend").Value.Set(project.ProjectType.String()) + // only pass strings that can be cast to a flags.BackendFramework instance + project.BackendFramework = flags.BackendFramework(strings.ToLower(options.BackendFramework.Choice)) + err := cmd.Flag("backend-framework").Value.Set(project.BackendFramework.String()) if err != nil { - log.Fatal("failed to set the backend flag value", err) + log.Fatal("failed to set the backendFramework flag value", err) } } diff --git a/cmd/flags/backend.go b/cmd/flags/backend.go index dedcd1c4..6407d6c7 100644 --- a/cmd/flags/backend.go +++ b/cmd/flags/backend.go @@ -5,39 +5,39 @@ import ( "strings" ) -type Backend string +type BackendFramework string // These are all the current backends supported. If you want to add one, you // can simply copy and paste a line here. Do not forget to also add it into the -// AllowedBackedTypes slice too! +// AllowedBackendTypes slice too! const ( - Chi Backend = "chi" - Gin Backend = "gin" - Fiber Backend = "fiber" - GorillaMux Backend = "gorilla/mux" - StandardLibrary Backend = "standard-library" - Echo Backend = "echo" + Chi BackendFramework = "chi" + Gin BackendFramework = "gin" + Fiber BackendFramework = "fiber" + GorillaMux BackendFramework = "gorilla/mux" + StandardLibrary BackendFramework = "standard-library" + Echo BackendFramework = "echo" ) -var AllowedBackedTypes = []string{string(Chi), string(Gin), string(Fiber), string(GorillaMux), string(StandardLibrary), string(Echo)} +var AllowedBackendFrameworkTypes = []string{string(Chi), string(Gin), string(Fiber), string(GorillaMux), string(StandardLibrary), string(Echo)} -func (f Backend) String() string { +func (f BackendFramework) String() string { return string(f) } -func (f *Backend) Type() string { - return "Backend" +func (f *BackendFramework) Type() string { + return "BackendFramework" } -func (f *Backend) Set(value string) error { +func (f *BackendFramework) Set(value string) error { // Contains isn't available in 1.20 yet - // if AllowedBackedTypes.Contains(value) { - for _, project := range AllowedBackedTypes { + // if AllowedBackendTypes.Contains(value) { + for _, project := range AllowedBackendFrameworkTypes { if project == value { - *f = Backend(value) + *f = BackendFramework(value) return nil } } - return fmt.Errorf("Backend to use. Allowed values: %s", strings.Join(AllowedBackedTypes, ", ")) + return fmt.Errorf("BackendFramework to use. Allowed values: %s", strings.Join(AllowedBackendFrameworkTypes, ", ")) } diff --git a/cmd/program/advanced.go b/cmd/program/advanced.go index 01f9d927..e8105984 100644 --- a/cmd/program/advanced.go +++ b/cmd/program/advanced.go @@ -12,7 +12,7 @@ import ( func (p *Project) CreateWebsocketImports(appDir string) { websocketDependency := []string{"github.com/coder/websocket"} - if p.ProjectType == flags.Fiber { + if p.BackendFramework == flags.Fiber { websocketDependency = []string{"github.com/gofiber/contrib/websocket"} } @@ -24,7 +24,7 @@ func (p *Project) CreateWebsocketImports(appDir string) { log.Fatal(err) } - importsPlaceHolder := string(p.BackendMap[p.ProjectType].templater.WebsocketImports()) + importsPlaceHolder := string(p.BackendFrameworkMap[p.BackendFramework].templater.WebsocketImports()) importTmpl, err := template.New("imports").Parse(importsPlaceHolder) if err != nil { diff --git a/cmd/program/frontend.go b/cmd/program/frontend.go index 4e527440..a89e018b 100644 --- a/cmd/program/frontend.go +++ b/cmd/program/frontend.go @@ -148,8 +148,8 @@ func (p *Project) CreateHtmxTemplates() { routesPlaceHolder := "" importsPlaceHolder := "" if p.FrontendFramework == flags.Htmx { - routesPlaceHolder += string(p.BackendMap[p.ProjectType].templater.HtmxTemplRoutes()) - importsPlaceHolder += string(p.BackendMap[p.ProjectType].templater.HtmxTemplImports()) + routesPlaceHolder += string(p.BackendFrameworkMap[p.BackendFramework].templater.HtmxTemplRoutes()) + importsPlaceHolder += string(p.BackendFrameworkMap[p.BackendFramework].templater.HtmxTemplImports()) } routeTmpl, err := template.New("routes").Parse(routesPlaceHolder) diff --git a/cmd/program/helpers.go b/cmd/program/helpers.go index 567d3d3c..bd6f8a05 100644 --- a/cmd/program/helpers.go +++ b/cmd/program/helpers.go @@ -64,13 +64,13 @@ func (p *Project) CreateFileWithInjection(pathToCreate string, projectPath strin switch methodName { case "main": - createdTemplate := template.Must(template.New(fileName).Parse(string(p.BackendMap[p.ProjectType].templater.Main()))) + createdTemplate := template.Must(template.New(fileName).Parse(string(p.BackendFrameworkMap[p.BackendFramework].templater.Main()))) err = createdTemplate.Execute(createdFile, p) case "server": - createdTemplate := template.Must(template.New(fileName).Parse(string(p.BackendMap[p.ProjectType].templater.Server()))) + createdTemplate := template.Must(template.New(fileName).Parse(string(p.BackendFrameworkMap[p.BackendFramework].templater.Server()))) err = createdTemplate.Execute(createdFile, p) case "routes": - routeFileBytes := p.BackendMap[p.ProjectType].templater.Routes() + routeFileBytes := p.BackendFrameworkMap[p.BackendFramework].templater.Routes() createdTemplate := template.Must(template.New(fileName).Parse(string(routeFileBytes))) err = createdTemplate.Execute(createdFile, p) case "releaser": @@ -92,7 +92,7 @@ func (p *Project) CreateFileWithInjection(pathToCreate string, projectPath strin createdTemplate := template.Must(template.New(fileName).Parse(string(p.DBDriverMap[p.DBDriver].templater.Tests()))) err = createdTemplate.Execute(createdFile, p) case "tests": - createdTemplate := template.Must(template.New(fileName).Parse(string(p.BackendMap[p.ProjectType].templater.TestHandler()))) + createdTemplate := template.Must(template.New(fileName).Parse(string(p.BackendFrameworkMap[p.BackendFramework].templater.TestHandler()))) err = createdTemplate.Execute(createdFile, p) case "env": if p.DBDriver != "none" { diff --git a/cmd/program/program.go b/cmd/program/program.go index f7fec308..45975588 100644 --- a/cmd/program/program.go +++ b/cmd/program/program.go @@ -23,22 +23,22 @@ import ( // A Project contains the data for the project folder // being created, and methods that help with that process type Project struct { - ProjectName string - Exit bool - AbsolutePath string - ProjectType flags.Backend - DBDriver flags.Database - Docker flags.Database - FrontendFramework flags.FrontendFramework - BackendMap map[flags.Backend]Backend - DBDriverMap map[flags.Database]Driver - DockerMap map[flags.Database]Docker - FrontendTemplates FrontendTemplates - FrontendOptions map[string]bool - AdvancedTemplates AdvancedTemplates - AdvancedOptions map[string]bool - GitOptions flags.Git - OSCheck map[string]bool + ProjectName string + Exit bool + AbsolutePath string + BackendFramework flags.BackendFramework + DBDriver flags.Database + Docker flags.Database + FrontendFramework flags.FrontendFramework + BackendFrameworkMap map[flags.BackendFramework]BackendFramework + DBDriverMap map[flags.Database]Driver + DockerMap map[flags.Database]Docker + FrontendTemplates FrontendTemplates + FrontendOptions map[string]bool + AdvancedTemplates AdvancedTemplates + AdvancedOptions map[string]bool + GitOptions flags.Git + OSCheck map[string]bool } type FrontendTemplates struct { @@ -51,9 +51,9 @@ type AdvancedTemplates struct { TemplateImports string } -// A Backend contains the name and templater for a -// given Backend -type Backend struct { +// A Backend Framework contains the name and templater for a +// given Backend Framework +type BackendFramework struct { packageName []string templater Templater } @@ -69,7 +69,7 @@ type Docker struct { } // A Templater has the methods that help build the files -// in the Project folder, and is specific to a Backend +// in the Project folder, and is specific to a BackendFramework type Templater interface { Main() []byte Server() []byte @@ -137,34 +137,34 @@ func (p *Project) ExitCLI(tprogram *tea.Program) { } // createFrameWorkMap adds the current supported -// Backends into a Project's BackendMap -func (p *Project) createBackendMap() { - p.BackendMap[flags.Chi] = Backend{ +// BackendFrameworks into a Project's BackendFrameworkMap +func (p *Project) createBackendFrameworkMap() { + p.BackendFrameworkMap[flags.Chi] = BackendFramework{ packageName: chiPackage, templater: backend.ChiTemplates{}, } - p.BackendMap[flags.StandardLibrary] = Backend{ + p.BackendFrameworkMap[flags.StandardLibrary] = BackendFramework{ packageName: []string{}, templater: backend.StandardLibTemplate{}, } - p.BackendMap[flags.Gin] = Backend{ + p.BackendFrameworkMap[flags.Gin] = BackendFramework{ packageName: ginPackage, templater: backend.GinTemplates{}, } - p.BackendMap[flags.Fiber] = Backend{ + p.BackendFrameworkMap[flags.Fiber] = BackendFramework{ packageName: fiberPackage, templater: backend.FiberTemplates{}, } - p.BackendMap[flags.GorillaMux] = Backend{ + p.BackendFrameworkMap[flags.GorillaMux] = BackendFramework{ packageName: gorillaPackage, templater: backend.GorillaTemplates{}, } - p.BackendMap[flags.Echo] = Backend{ + p.BackendFrameworkMap[flags.Echo] = BackendFramework{ packageName: echoPackage, templater: backend.EchoTemplates{}, } @@ -254,7 +254,7 @@ func (p *Project) CreateMainFile() error { p.CheckOS() // Create the map for our program - p.createBackendMap() + p.createBackendFrameworkMap() // Create go.mod err = utils.InitGoMod(p.ProjectName, projectPath) @@ -264,8 +264,8 @@ func (p *Project) CreateMainFile() error { } // Install the correct package for the selected backend - if p.ProjectType != flags.StandardLibrary { - err = utils.GoGetPackage(projectPath, p.BackendMap[p.ProjectType].packageName) + if p.BackendFramework != flags.StandardLibrary { + err = utils.GoGetPackage(projectPath, p.BackendFrameworkMap[p.BackendFramework].packageName) if err != nil { log.Printf("Could not install go dependency for the chosen backend %v\n", err) return err @@ -505,7 +505,7 @@ func (p *Project) CreateMainFile() error { } defer efsFile.Close() - if p.ProjectType == "fiber" { + if p.BackendFramework == "fiber" { helloGoTemplate := template.Must(template.New("efs").Parse((string(frontend.HelloFiberGoTemplate())))) err = helloGoTemplate.Execute(helloGoFile, p) if err != nil { diff --git a/cmd/steps/steps.go b/cmd/steps/steps.go index ae92e5b6..fa240d0f 100644 --- a/cmd/steps/steps.go +++ b/cmd/steps/steps.go @@ -27,11 +27,11 @@ type Item struct { } // InitSteps initializes and returns the *Steps to be used in the CLI program -func InitSteps(projectType flags.Backend, databaseType flags.Database, frontendFrameworkType flags.FrontendFramework, gitType flags.Git) *Steps { +func InitSteps(projectType flags.BackendFramework, databaseType flags.Database, frontendFrameworkType flags.FrontendFramework, gitType flags.Git) *Steps { steps := &Steps{ map[string]StepSchema{ - "backend": { - StepName: "Go Project Backend", + "backend-framework": { + StepName: "Go Project Backend Framework", Options: []Item{ { Title: "Standard-library", @@ -58,7 +58,7 @@ func InitSteps(projectType flags.Backend, databaseType flags.Database, frontendF Desc: "High performance, extensible, minimalist Go web framework", }, }, - Headers: "What backend do you want to use in your Go project?", + Headers: "What backend framework do you want to use in your Go project?", Field: projectType.String(), }, "driver": { diff --git a/cmd/template/advanced/files/docker/dockerfile.tmpl b/cmd/template/advanced/files/docker/dockerfile.tmpl index 15f8263e..d0ab5814 100644 --- a/cmd/template/advanced/files/docker/dockerfile.tmpl +++ b/cmd/template/advanced/files/docker/dockerfile.tmpl @@ -14,8 +14,7 @@ COPY . . RUN go install github.com/a-h/templ/cmd/templ@latest && \ templ generate{{- if .FrontendOptions.tailwind}} && \{{- end}} {{- end}} - -{{- if .FrontendOptions.tailwind}} +{{- if and (.FrontendOptions.tailwind) (eq .FrontendFramework "htmx") }} curl -sL https://github.com/tailwindlabs/tailwindcss/releases/download/v3.4.10/tailwindcss-linux-x64 -o tailwindcss && \ chmod +x tailwindcss && \ ./tailwindcss -i cmd/web/styles/input.css -o cmd/web/assets/css/output.css diff --git a/docs/docs/blueprint-core/backend.md b/docs/docs/blueprint-core/backend-frameworks.md similarity index 100% rename from docs/docs/blueprint-core/backend.md rename to docs/docs/blueprint-core/backend-frameworks.md diff --git a/docs/docs/creating-project/project-init.md b/docs/docs/creating-project/project-init.md index a92ec498..044a3977 100644 --- a/docs/docs/creating-project/project-init.md +++ b/docs/docs/creating-project/project-init.md @@ -21,7 +21,7 @@ go-blueprint create -n my-project -b chi -d postgres -g commit In this example: - `-n` or `--name`: Specifies the name of the project (replace "my-project" with your desired project name). -- `-b` or `--backend`: Specifies the Go backend to be used (e.g., "gin"). +- `-b` or `--backend-framework`: Specifies the Go backend to be used (e.g., "gin"). - `-d` or `--driver`: Specifies the database driver to be integrated (e.g., "postgres"). - `-g` or `--git`: Specifies the git configuration option of the project (e.g., "commit"). diff --git a/docs/docs/index.md b/docs/docs/index.md index aaa8becc..d9585c57 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -34,7 +34,7 @@ Usage: Flags: -a, --advanced Get prompts for advanced features --feature AdvancedFeatures Advanced feature to use. Allowed values: githubaction, websocket, docker - -b, --backend Backend Backend to use. Allowed values: chi, gin, fiber, gorilla/mux, standard-library, echo + -b, --backend-framework BackendFramework Backend framework to use. Allowed values: chi, gin, fiber, gorilla/mux, standard-library, echo -d, --driver Database Database drivers to use. Allowed values: mysql, postgres, sqlite, mongo, redis, scylla, none -f, --frontend Get prompts for frontend frameworks --frontend-framework Frontendframework Frontend framework to use. Allowed values: htmx, react diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 5ee9c0a3..97370b46 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -36,7 +36,7 @@ nav: - Makefile: creating-project/makefile.md - Air: creating-project/air.md - Blueprint Core: - - Backend: blueprint-core/backend.md + - Backend Frameworks: blueprint-core/backend-frameworks.md - DB Drivers: blueprint-core/db-drivers.md - Frontend: - HTMX and Templ: frontend/htmx-templ.md