├── .gitignore ├── README.md ├── entity ├── codes │ ├── env_code.go │ ├── error_code.go │ ├── init_code.go │ ├── main_code.go │ └── mysql_code.go ├── files │ └── create.go └── layer │ └── spec.go ├── go.mod ├── go.sum ├── main.go └── utils ├── helpers ├── dir.go ├── error.go ├── layer.go └── version.go ├── writeToFiles.go └── writeToFiles_impl.go /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | test/ 3 | .idea 4 | Dockerfile 5 | docker-compose.yaml 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Go QuickStart v2.0.3 2 | Accelerate the development of your REST API!\ 3 | This cutting-edge tool empowers you to swiftly generate a blazing-fast REST API without the hassle of manual database configuration.\ 4 | Kickstart with `Go-QuickStart -pkg=awesomeProject` and behold the extraordinary results unfold before your eyes. 5 | ## Installation 6 | `go install github.com/fanchann/Go-QuickStart` 7 | 8 | ## Configuration 9 | Set your environment variable 10 | #### Open .env to configuration 11 | ``` 12 | DB_DRIVER=mysql 13 | DB_AUTH_USERNAME=root 14 | DB_AUTH_PASSWORD=root 15 | DB_NAME=local_production 16 | DB_URL=127.0.0.1 17 | DB_PORT=3306 18 | ``` 19 | ## Project Structure 20 | ``` 21 | . 22 | ├── .env 23 | ├── go.mod 24 | ├── go.sum 25 | ├── interface 26 | │   ├── controller 27 | │   └── middleware 28 | ├── internal 29 | │   ├── models 30 | │   │   ├── domain 31 | │   │   └── web 32 | │   ├── repositories 33 | │   └── services 34 | ├── main.go 35 | ├── pkg 36 | │   ├── config 37 | │   │   └── config.go 38 | │   ├── database 39 | │   │   └── mysql.go 40 | │   └── utils 41 | │   └── error.go 42 | ├── README.md 43 | └── tests 44 | 45 | 46 | ``` 47 | 48 | # Explanation for each layer in the Go-QuickStart structure: 49 | 50 | #### Interface 51 | Contains the sub-layers "controller" and "middleware". 52 | 53 | * Controller\ 54 | Handles user's HTTP requests and connects them to the application logic. 55 | * Middleware\ 56 | Adds additional features like authentication, authorization, logging, etc. 57 | 58 | #### Internal 59 | Contains the sub-layers "models", "repositories", and "services". 60 | 61 | * Models\ 62 | Provides definitions for the data structures used in the application. 63 | * Repositories\ 64 | Interacts with the data storage, such as a database. 65 | * Services\ 66 | Provides the business logic of the application. 67 | 68 | #### Pkg 69 | Contains utilities, configuration files, and connections to external resources. 70 | * Config\ 71 | Application configuration files. 72 | * Database\ 73 | Implementation of the database connection. 74 | * Utils\ 75 | Common utilities used in the application. 76 | 77 | #### Tests 78 | Contains unit tests or automated tests to ensure the functionality of the application 79 | 80 | ## Thanks ! 81 | -------------------------------------------------------------------------------- /entity/codes/env_code.go: -------------------------------------------------------------------------------- 1 | package codes 2 | 3 | const ( 4 | ConfigGo = `package config 5 | 6 | import ( 7 | "os" 8 | 9 | "{{.PackageName}}/pkg/utils" 10 | "github.com/joho/godotenv" 11 | ) 12 | 13 | var ( 14 | Driver string 15 | Username string 16 | Password string 17 | Db_name string 18 | Db_url string 19 | Db_port string 20 | ) 21 | 22 | func LoadEnv() { 23 | errEnv := godotenv.Load(".env") 24 | utils.LogErrorWithPanic(errEnv) 25 | 26 | Driver = os.Getenv("DB_DRIVER") 27 | Username = os.Getenv("DB_AUTH_USERNAME") 28 | Password = os.Getenv("DB_AUTH_PASSWORD") 29 | Db_name = os.Getenv("DB_NAME") 30 | Db_url = os.Getenv("DB_URL") 31 | Db_port = os.Getenv("DB_PORT") 32 | }` 33 | 34 | EnvConfiguration = `DB_DRIVER = mysql 35 | DB_AUTH_USERNAME = 36 | DB_AUTH_PASSWORD = 37 | DB_NAME = 38 | DB_URL = 39 | DB_PORT =` 40 | ) 41 | -------------------------------------------------------------------------------- /entity/codes/error_code.go: -------------------------------------------------------------------------------- 1 | package codes 2 | 3 | const ( 4 | UtilsError = `package utils 5 | 6 | import "log" 7 | 8 | func LogErrorWithPanic(err error) { 9 | if err != nil { 10 | log.Panicf("error : %s", err) 11 | } 12 | } 13 | ` 14 | ) 15 | -------------------------------------------------------------------------------- /entity/codes/init_code.go: -------------------------------------------------------------------------------- 1 | package codes 2 | 3 | import "fmt" 4 | 5 | const ( 6 | GoMod = `module {{.PackageName}} 7 | 8 | go {{.GoVersion}} 9 | 10 | require ( 11 | github.com/go-sql-driver/mysql v1.7.0 12 | github.com/joho/godotenv v1.5.1 13 | ) 14 | ` 15 | GoSum = `github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= 16 | github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= 17 | github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= 18 | github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= 19 | ` 20 | ) 21 | 22 | var Readme = fmt.Sprintf("# Read This\n- add package with\\\n```go mod download```\n# Configuration\n#### Open .env to configuration\n```\nDB_DRIVER=mysql\nDB_AUTH_USERNAME=\nDB_AUTH_PASSWORD=\nDB_NAME=\nDB_URL=\nDB_PORT=\n```\n\n#### Example\n```\nDB_DRIVER=mysql\nDB_AUTH_USERNAME=root\nDB_AUTH_PASSWORD=root\nDB_NAME=local_production\nDB_URL=127.0.0.1\nDB_PORT=3306\n```\nhappy coding with MySQL and Go!\n") 23 | -------------------------------------------------------------------------------- /entity/codes/main_code.go: -------------------------------------------------------------------------------- 1 | package codes 2 | 3 | const ( 4 | MainCode = `package main 5 | 6 | import ( 7 | "fmt" 8 | 9 | "{{.PackageName}}/pkg/database" 10 | "{{.PackageName}}/pkg/utils" 11 | ) 12 | 13 | func main() { 14 | db, err := database.MysqlConnect() 15 | utils.LogErrorWithPanic(err) 16 | err = db.Ping() 17 | utils.LogErrorWithPanic(err) 18 | 19 | //success 20 | fmt.Println("Success connected to database") 21 | } 22 | ` 23 | ) 24 | -------------------------------------------------------------------------------- /entity/codes/mysql_code.go: -------------------------------------------------------------------------------- 1 | package codes 2 | 3 | const ( 4 | MysqlConnection = `package database 5 | 6 | import ( 7 | "database/sql" 8 | "fmt" 9 | "time" 10 | 11 | "{{.PackageName}}/pkg/config" 12 | _ "github.com/go-sql-driver/mysql" 13 | ) 14 | 15 | func MysqlConnect() (*sql.DB, error) { 16 | // Load config .env 17 | config.LoadEnv() 18 | 19 | dataSource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", config.Username, config.Password, config.Db_url, config.Db_port, config.Db_name) 20 | db, err := sql.Open(config.Driver, dataSource) 21 | if err != nil { 22 | return nil, err 23 | } 24 | 25 | db.SetConnMaxIdleTime(30 * time.Minute) 26 | db.SetConnMaxLifetime(60 * time.Minute) 27 | db.SetMaxIdleConns(25) 28 | db.SetMaxOpenConns(50) 29 | 30 | return db, nil 31 | } 32 | ` 33 | ) 34 | -------------------------------------------------------------------------------- /entity/files/create.go: -------------------------------------------------------------------------------- 1 | package files 2 | 3 | import ( 4 | "flag" 5 | "os" 6 | 7 | "github.com/mitchellh/colorstring" 8 | 9 | "github.com/fanchann/Go-QuickStart/entity/codes" 10 | "github.com/fanchann/Go-QuickStart/entity/layer" 11 | "github.com/fanchann/Go-QuickStart/utils" 12 | "github.com/fanchann/Go-QuickStart/utils/helpers" 13 | ) 14 | 15 | func GenerateLayer() { 16 | packageName := flag.String("pkg", "", "package name is required") 17 | flag.Parse() 18 | 19 | if *packageName == "" { 20 | colorstring.Println("[red][-] [white]please fill in the package name, example : `-pkg=`") 21 | os.Exit(1) 22 | } 23 | 24 | files := []layer.FileSpec{ 25 | {Location: layer.Domain["databaseInPackage"] + "/", PackageName: *packageName, ScCode: codes.MysqlConnection, FileName: "mysql.go"}, 26 | {Location: layer.Domain["utilsInPackage"] + "/", PackageName: *packageName, ScCode: codes.UtilsError, FileName: "error.go"}, 27 | {Location: helpers.GetWorkingDirectory(), PackageName: *packageName, GoVersion: helpers.GetGoVersion(), ScCode: codes.GoMod, FileName: "go.mod"}, 28 | {Location: helpers.GetWorkingDirectory(), PackageName: *packageName, ScCode: codes.GoSum, FileName: "go.sum"}, 29 | {Location: layer.Domain["configInPackage"] + "/", PackageName: *packageName, ScCode: codes.ConfigGo, FileName: "config.go"}, 30 | {Location: helpers.GetWorkingDirectory(), PackageName: "", ScCode: codes.Readme, FileName: "README.md"}, 31 | {Location: helpers.GetWorkingDirectory(), PackageName: "", ScCode: codes.EnvConfiguration, FileName: ".env"}, 32 | {Location: helpers.GetWorkingDirectory(), PackageName: *packageName, ScCode: codes.MainCode, FileName: "main.go"}, 33 | } 34 | 35 | newWrite := utils.NewWriteToFiles() 36 | defer newWrite.CreateFile(files) 37 | 38 | for _, layered := range layer.DomainKeys { 39 | newWrite.CreateFolderProject(layer.Domain[layered], layer.Perm) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /entity/layer/spec.go: -------------------------------------------------------------------------------- 1 | package layer 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/fanchann/Go-QuickStart/utils/helpers" 7 | ) 8 | 9 | type ( 10 | FileSpec struct { 11 | Location string 12 | PackageName string 13 | GoVersion string 14 | ScCode string 15 | FileName string 16 | } 17 | ) 18 | 19 | var ( 20 | DomainKeys = []string{ 21 | "domain", 22 | "modelsInDomain", 23 | "domainInDomain", 24 | "webInDomain", 25 | "repoInDomain", 26 | "serviceInDomain", 27 | "package", 28 | "utilsInPackage", 29 | "databaseInPackage", 30 | "configInPackage", 31 | "interface", 32 | "controllerInInterface", 33 | "middlewareInInterface", 34 | "tests", 35 | } 36 | 37 | Perm = 0755 38 | 39 | InternalLayer = "internal" 40 | ModelsLayer = "models" 41 | DomainLayer = "domain" 42 | WebLayer = "web" 43 | RepoLayer = "repositories" 44 | ServicesLayer = "services" 45 | 46 | PackageLayer = "pkg" 47 | UtilsLayer = "utils" 48 | DatabaseLayer = "database" 49 | ConfigLayer = "config" 50 | 51 | InterfaceLayer = "interface" 52 | ControllerLayer = "controller" 53 | MiddlewareLayer = "middleware" 54 | 55 | TestLayer = "tests" 56 | 57 | Domain = map[string]string{ 58 | "domain": fmt.Sprintf("%s/%s", helpers.GetWorkingDirectory(), InternalLayer), 59 | "modelsInDomain": fmt.Sprintf("%s/%s/%s", helpers.GetWorkingDirectory(), InternalLayer, ModelsLayer), 60 | "domainInDomain": fmt.Sprintf("%s/%s/%s/%s", helpers.GetWorkingDirectory(), InternalLayer, ModelsLayer, DomainLayer), 61 | "webInDomain": fmt.Sprintf("%s/%s/%s/%s", helpers.GetWorkingDirectory(), InternalLayer, ModelsLayer, WebLayer), 62 | "repoInDomain": fmt.Sprintf("%s/%s/%s", helpers.GetWorkingDirectory(), InternalLayer, RepoLayer), 63 | "serviceInDomain": fmt.Sprintf("%s/%s/%s", helpers.GetWorkingDirectory(), InternalLayer, ServicesLayer), 64 | "package": fmt.Sprintf("%s/%s", helpers.GetWorkingDirectory(), PackageLayer), 65 | "utilsInPackage": fmt.Sprintf("%s/%s/%s", helpers.GetWorkingDirectory(), PackageLayer, UtilsLayer), 66 | "databaseInPackage": fmt.Sprintf("%s/%s/%s", helpers.GetWorkingDirectory(), PackageLayer, DatabaseLayer), 67 | "configInPackage": fmt.Sprintf("%s/%s/%s", helpers.GetWorkingDirectory(), PackageLayer, ConfigLayer), 68 | "interface": fmt.Sprintf("%s/%s", helpers.GetWorkingDirectory(), InterfaceLayer), 69 | "controllerInInterface": fmt.Sprintf("%s/%s/%s", helpers.GetWorkingDirectory(), InterfaceLayer, ControllerLayer), 70 | "middlewareInInterface": fmt.Sprintf("%s/%s/%s", helpers.GetWorkingDirectory(), InterfaceLayer, MiddlewareLayer), 71 | "tests": fmt.Sprintf("%s/%s", helpers.GetWorkingDirectory(), TestLayer), 72 | } 73 | ) 74 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/fanchann/Go-QuickStart 2 | 3 | go 1.20 4 | 5 | require github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= 2 | github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= 3 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/mitchellh/colorstring" 5 | 6 | "github.com/fanchann/Go-QuickStart/entity/files" 7 | ) 8 | 9 | func main() { 10 | files.GenerateLayer() 11 | colorstring.Printf(`[red] 12 | ╋╋╋╋╋╋╋┏━━━┓╋╋╋╋╋╋┏┓╋┏━━━┓┏┓╋╋╋╋╋┏┓ 13 | ╋╋╋╋╋╋╋┃┏━┓┃╋╋╋╋╋╋┃┃╋┃┏━┓┣┛┗┓╋╋╋┏┛┗┓ 14 | ┏━━┳━━┓┃┃╋┃┣┓┏┳┳━━┫┃┏┫┗━━╋┓┏╋━━┳┻┓┏┛ 15 | ┃┏┓┃┏┓┃┃┃╋┃┃┃┃┣┫┏━┫┗┛┻━━┓┃┃┃┃┏┓┃┏┫┃ 16 | ┃┗┛┃┗┛┃┃┗━┛┃┗┛┃┃┗━┫┏┓┫┗━┛┃┃┗┫┏┓┃┃┃┗┓ 17 | ┗━┓┣━━┛┗━━┓┣━━┻┻━━┻┛┗┻━━━┛┗━┻┛┗┻┛┗━┛ 18 | ┏━┛┃╋╋╋╋╋╋┗┛ 19 | ┗━━┛ [cyan]v.2.0.3 20 | [white]INFO : [green]%s `, "success generate template!") 21 | } 22 | -------------------------------------------------------------------------------- /utils/helpers/dir.go: -------------------------------------------------------------------------------- 1 | package helpers 2 | 3 | import "os" 4 | 5 | func GetWorkingDirectory() string { 6 | directory, err := os.Getwd() 7 | if err != nil { 8 | panic(err) 9 | } 10 | 11 | return directory 12 | } 13 | -------------------------------------------------------------------------------- /utils/helpers/error.go: -------------------------------------------------------------------------------- 1 | package helpers 2 | 3 | import "log" 4 | 5 | func LogErrorWithPanic(err error) { 6 | if err != nil { 7 | log.Panicf("error : %s", err) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /utils/helpers/layer.go: -------------------------------------------------------------------------------- 1 | package helpers 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | type Path struct { 9 | layers []string 10 | } 11 | 12 | func NewPath(layers ...string) *Path { 13 | return &Path{layers: layers} 14 | } 15 | 16 | func (p *Path) Subpath(paths ...string) *Path { 17 | sublayers := make([]string, len(p.layers)+len(paths)) 18 | copy(sublayers, p.layers) 19 | copy(sublayers[len(p.layers):], paths) 20 | return &Path{layers: sublayers} 21 | } 22 | 23 | func (p *Path) String() string { 24 | return fmt.Sprintf("%s/%s", GetWorkingDirectory(), p.JoinLayers("/")) 25 | } 26 | 27 | func (p *Path) JoinLayers(separator string) string { 28 | return JoinStrings(p.layers, separator) 29 | } 30 | 31 | func JoinStrings(slice []string, separator string) string { 32 | return sliceToString(slice, separator) 33 | } 34 | 35 | func sliceToString(slice []string, separator string) string { 36 | if len(slice) == 0 { 37 | return "" 38 | } 39 | if len(slice) == 1 { 40 | return slice[0] 41 | } 42 | var builder strings.Builder 43 | builder.WriteString(slice[0]) 44 | for _, s := range slice[1:] { 45 | builder.WriteString(separator) 46 | builder.WriteString(s) 47 | } 48 | return builder.String() 49 | } 50 | -------------------------------------------------------------------------------- /utils/helpers/version.go: -------------------------------------------------------------------------------- 1 | package helpers 2 | 3 | import ( 4 | "os/exec" 5 | "regexp" 6 | ) 7 | 8 | func GetGoVersion() string { 9 | execRes, err := exec.Command("go", "version").Output() 10 | if err != nil { 11 | panic(err) 12 | } 13 | getVer := regexp.MustCompile(`\d+\.\d+`) 14 | version := getVer.FindString(string(execRes)) 15 | 16 | return version 17 | } 18 | -------------------------------------------------------------------------------- /utils/writeToFiles.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "github.com/fanchann/Go-QuickStart/entity/layer" 4 | 5 | type IWriteToFiles interface { 6 | CreateFile(format []layer.FileSpec) 7 | CreateFolderProject(name string, perm int) 8 | CreateGoFile(format layer.FileSpec) error 9 | } 10 | -------------------------------------------------------------------------------- /utils/writeToFiles_impl.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/fs" 7 | "os" 8 | "path/filepath" 9 | "text/template" 10 | 11 | "github.com/fanchann/Go-QuickStart/entity/layer" 12 | "github.com/fanchann/Go-QuickStart/utils/helpers" 13 | ) 14 | 15 | type WriteToFiles struct{} 16 | 17 | func NewWriteToFiles() IWriteToFiles { 18 | return &WriteToFiles{} 19 | } 20 | 21 | func (write *WriteToFiles) CreateFile(format []layer.FileSpec) { 22 | for _, file := range format { 23 | err := write.CreateGoFile(file) 24 | helpers.LogErrorWithPanic(err) 25 | } 26 | } 27 | 28 | func (write *WriteToFiles) CreateFolderProject(name string, perm int) { 29 | err := os.Mkdir(name, fs.FileMode(perm)) 30 | helpers.LogErrorWithPanic(err) 31 | } 32 | 33 | func (write *WriteToFiles) CreateGoFile(format layer.FileSpec) error { 34 | codeTemplate, err := template.New("").Parse(format.ScCode) 35 | if err != nil { 36 | return fmt.Errorf("failed to parse template: %v", err) 37 | } 38 | 39 | var tpl bytes.Buffer 40 | 41 | if err = codeTemplate.Execute(&tpl, struct { 42 | GoVersion string 43 | PackageName string 44 | }{ 45 | GoVersion: format.GoVersion, 46 | PackageName: format.PackageName, 47 | }); err != nil { 48 | return fmt.Errorf("failed to execute template: %v", err) 49 | } 50 | 51 | file, err := os.Create(format.FileName) 52 | if err != nil { 53 | return fmt.Errorf("failed to create file: %v", err) 54 | } 55 | defer file.Close() 56 | 57 | _, err = tpl.WriteTo(file) 58 | if err != nil { 59 | return fmt.Errorf("failed to write to file: %v", err) 60 | } 61 | 62 | if format.Location != "" { 63 | newLocation := filepath.Join(format.Location, filepath.Base(format.FileName)) 64 | if err := os.Rename(format.FileName, newLocation); err != nil { 65 | return fmt.Errorf("failed to move file to %s: %v", newLocation, err) 66 | } 67 | } 68 | 69 | return nil 70 | } 71 | --------------------------------------------------------------------------------