From 9cac4d21a4b418a3ec1a1dc337b31dbe905c5907 Mon Sep 17 00:00:00 2001 From: renanbastos93 Date: Mon, 9 Dec 2024 14:23:29 -0300 Subject: [PATCH 1/5] fix: check version --- internal/version.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/internal/version.go b/internal/version.go index 9e6be06..b2e13e2 100644 --- a/internal/version.go +++ b/internal/version.go @@ -5,12 +5,14 @@ import ( "fmt" "os/exec" "strings" + + "golang.org/x/mod/semver" ) -const Version = "v0.6.0" +const Version = "v0.7.0" func ValidateLatestVersion() { - cmd := exec.Command("go", "list", "-m", "github.com/renanbastos93/boneless@latest") + cmd := exec.Command(goCLI, "list", "-m", "github.com/renanbastos93/boneless@latest") var stdOut bytes.Buffer cmd.Stdout = &stdOut if cmd.Run() != nil { @@ -20,10 +22,14 @@ func ValidateLatestVersion() { if result := stdOut.String(); result != "" { _, v, _ := strings.Cut(result, " ") v = v[:len(v)-1] - if v != Version { - msg := "\033[31mNew version available! Check out our release and update the Boneless!\n" - msg += "\033[0m\033[1mMore details: \033[0mhttps://github.com/renanbastos93/boneless/releases/tag/%s\n---\n" - fmt.Printf(msg, v) + + // Check if the latest version is greater than the current version + if semver.Compare(Version, v) > 0 || v == Version { + return } + + msg := "\033[31mNew version available! Check out our release and update the Boneless!\n" + msg += "\033[0m\033[1mMore details: \033[0mhttps://github.com/renanbastos93/boneless/releases/tag/%s\n---\n" + fmt.Printf(msg, v) } } From 2e148519e713d43d284732e2885382e92ef90ae3 Mon Sep 17 00:00:00 2001 From: renanbastos93 Date: Mon, 9 Dec 2024 15:46:25 -0300 Subject: [PATCH 2/5] feat: create consts for use in commands exec --- internal/consts.go | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 internal/consts.go diff --git a/internal/consts.go b/internal/consts.go new file mode 100644 index 0000000..a8fc628 --- /dev/null +++ b/internal/consts.go @@ -0,0 +1,9 @@ +package internal + +const ( + goCLI = "go" + sqlcCLI = "sqlc" + weaverCLI = "weaver" + migrateCLI = "migrate" + installCmd = "install" +) From 6b94dc9c9d1b05c8524c8fd0ed48ac7c4da62aeb Mon Sep 17 00:00:00 2001 From: renanbastos93 Date: Mon, 9 Dec 2024 15:47:05 -0300 Subject: [PATCH 3/5] chore: bump deps with semver --- go.mod | 9 +++++++-- go.sum | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index cbbcc44..c0852f6 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,10 @@ module github.com/renanbastos93/boneless -go 1.20 +go 1.22.0 -require github.com/pelletier/go-toml/v2 v2.0.8 +toolchain go1.22.4 + +require ( + github.com/pelletier/go-toml/v2 v2.0.8 + golang.org/x/mod v0.22.0 +) diff --git a/go.sum b/go.sum index ec2379f..6566a7c 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= From 0af18ce423b29d2739a9d02d77e9e51f976c18bd Mon Sep 17 00:00:00 2001 From: renanbastos93 Date: Mon, 9 Dec 2024 15:47:26 -0300 Subject: [PATCH 4/5] feat: created go.mod interactive with user --- internal/mod_init.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 internal/mod_init.go diff --git a/internal/mod_init.go b/internal/mod_init.go new file mode 100644 index 0000000..e19a36f --- /dev/null +++ b/internal/mod_init.go @@ -0,0 +1,33 @@ +package internal + +import "fmt" + +func ModInit() { + moduleName, err := getModuleNameFromUserInput() + if err != nil { + panic(err) + } + + args := []string{"mod", "init"} + if moduleName != "" { + args = append(args, moduleName) + } + + err = runCmd(goCLI, args...) + if err != nil { + panic(err) + } + +} + +func getModuleNameFromUserInput() (string, error) { + print("What is the module name for your project? (e.g., github.com/renanbastos93/boneless) ") + + var moduleName string + _, err := fmt.Scanf("%s\n", &moduleName) + if err != nil { + return "", err + } + + return moduleName, nil +} From 94f5ca0e541b2309a4611633eeea7accfee943e3 Mon Sep 17 00:00:00 2001 From: renanbastos93 Date: Mon, 9 Dec 2024 15:59:20 -0300 Subject: [PATCH 5/5] feat: add commands for installing and updating dependencies - Added `install-deps` command to install all required dependencies. - Added `update-deps` command to update all dependencies or specific ones individually. - Refactored to use constants (e.g., `go`, `weaver`) for better maintainability and easier implementation of future unit tests. - Enhanced project initialization by ensuring a `go.mod` file is created automatically. These changes streamline dependency management and improve code maintainability. --- README.md | 21 +++++++++---- cmd/boneless/main.go | 17 +++++++++- internal/intall_deps.go | 69 +++++++++++++++++++++++++++++++++++++++++ internal/internal.go | 14 ++++----- 4 files changed, 107 insertions(+), 14 deletions(-) create mode 100644 internal/intall_deps.go diff --git a/README.md b/README.md index 4627aa0..31e8a83 100644 --- a/README.md +++ b/README.md @@ -65,12 +65,10 @@ This directory and file structure reflects the adopted architecture in the repos Let's create our first project from scratch using Boneless! ### Installing dependencies -First, we need to install the binary of Service Weaver, Go Migrate, SQLC, and Boneless. Even so, I suggest you read the documentation of all of them on your official websites. +First, we need to install Boneless. Then, use the `install-deps` command to ensure its dependencies are installed correctly. If you encounter any issues, open an issue or check the official websites of the dependencies, such as SQLC, Service Weaver, and Go Migrate, for more information. ```sh -$ go install -tags 'mysql sqlite3' github.com/golang-migrate/migrate/v4/cmd/migrate@latest -$ go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest -$ go install github.com/ServiceWeaver/weaver/cmd/weaver@latest $ go install github.com/renanbastos93/boneless/cmd/boneless@latest +$ boneless install-deps ``` To ensure a smooth setup of your Boneless project, let's install all the dependencies, including Boneless itself. If you're not using macOS, you can access their website for detailed instructions on installing Boneless and its dependencies specific to your operating system. @@ -82,20 +80,25 @@ Usage: boneless [target] Targets: help Show commands for use version Show version - new Create a project from scratch using Weaver, SQLC, and go-migrate + new Create a project from scratch using Weaver, SQLC, and go-migrate create-scratch Create a project from scratch using Weaver, SQLC, and go-migrate build Build the Weaver component with SQLC make-migrate Create a new migration for an app migrate Run migrations for an app create-app Create a new app based on a template build-app Build an app using Weaver and SQLC + delete-app Delete an app created + install-deps [package] Installs external dependencies required by Boneless (e.g., weaver, sqlc). If no package is specified, all dependencies are updated. + update-deps [package] Updates the specified external dependency (e.g., weaver, migrate). If no package is specified, all dependencies are updated. run Run the project using Weaver Parameters: Name of the app to create or run migrations on Name of the migration to create Specify "up" to apply migrations or "down" to rollback migrations - Specify "sql" to use some SQL "sqlite3" to use sqlite3 and it is the default + Specify "sql" to use some SQL "sqlite3" to use sqlite3 and it is the default + [package] Specify the package to update or install like "weaver, sqlc, golang-migrate" + Examples: boneless help @@ -106,7 +109,13 @@ Examples: boneless migrate my-app up boneless create-app my-app boneless build-app my-app + boneless delete-app my-app + boneless install-deps + boneless install-deps weaver + boneless update-deps + boneless update-deps sqlc boneless run + ``` After that is installed, let's create our first project from scratch using Boneless, a framework based on clean architecture, to efficiently generate and organize the project structure, implement functionality, and deploy it with ease. diff --git a/cmd/boneless/main.go b/cmd/boneless/main.go index ecfccf9..8702a2a 100644 --- a/cmd/boneless/main.go +++ b/cmd/boneless/main.go @@ -13,7 +13,7 @@ const usage = `Usage: boneless [target] Targets: help Show commands for use version Show version - new Create a project from scratch using Weaver, SQLC, and go-migrate + new Create a project from scratch using Weaver, SQLC, and go-migrate create-scratch Create a project from scratch using Weaver, SQLC, and go-migrate build Build the Weaver component with SQLC make-migrate Create a new migration for an app @@ -21,6 +21,8 @@ Targets: create-app Create a new app based on a template build-app Build an app using Weaver and SQLC delete-app Delete an app created + install-deps [package] Installs external dependencies required by Boneless (e.g., weaver, sqlc). If no package is specified, all dependencies are updated. + update-deps [package] Updates the specified external dependency (e.g., weaver, migrate). If no package is specified, all dependencies are updated. run Run the project using Weaver Parameters: @@ -28,6 +30,8 @@ Parameters: Name of the migration to create Specify "up" to apply migrations or "down" to rollback migrations Specify "sql" to use some SQL "sqlite3" to use sqlite3 and it is the default + [package] Specify the package to update or install like "weaver, sqlc, golang-migrate" + Examples: boneless help @@ -39,6 +43,10 @@ Examples: boneless create-app my-app boneless build-app my-app boneless delete-app my-app + boneless install-deps + boneless install-deps weaver + boneless update-deps + boneless update-deps sqlc boneless run ` @@ -55,6 +63,8 @@ const ( cmdBuildApp = "build-app" cmdDeleteApp = "delete-app" cmdRun = "run" + cmdInstallDeps = "install-deps" + cmdUpdateDeps = "update-deps" DefaultComponentName = "app" ) @@ -78,6 +88,7 @@ func main() { case cmdVersion: fmt.Fprintln(os.Stdout, internal.Version) case cmdCreateScratch, cmdNew: + internal.ModInit() internal.Build(DefaultComponentName, internal.KindAll, flag.Arg(1)) internal.SqlcGenerate() internal.ModTidy() @@ -101,6 +112,10 @@ func main() { internal.RunMigrate(flag.Arg(1), flag.Arg(2)) case cmdRun: internal.Start() + case cmdInstallDeps: + internal.InstallDeps(flag.Arg(1)) + case cmdUpdateDeps: + internal.UpdateDeps(flag.Arg(1)) default: flag.Usage() } diff --git a/internal/intall_deps.go b/internal/intall_deps.go new file mode 100644 index 0000000..8bc06b4 --- /dev/null +++ b/internal/intall_deps.go @@ -0,0 +1,69 @@ +package internal + +import ( + "os/exec" +) + +type packages struct { + name, pkg string +} + +var PackagesForInstall = []packages{ + {"golang-migrate", "github.com/golang-migrate/migrate/v4/cmd/migrate@latest"}, + {"sqlc", "github.com/sqlc-dev/sqlc/cmd/sqlc@latest"}, + {"weaver", "github.com/ServiceWeaver/weaver/cmd/weaver@latest"}, +} + +func InstallDeps(name string) { + if name != "" { + for _, p := range PackagesForInstall { + if p.name == name { + installDeps(p) + } + } + } else { + installDeps(PackagesForInstall...) + } +} + +func installDeps(packages ...packages) { + for _, p := range packages { + if IsInstalled(p.pkg) { + println(p.name, "already installed!") + continue + } + GoInstall(p.name, p.pkg) + } +} + +func IsInstalled(packageName string) bool { + pathBin, err := exec.LookPath(packageName) + return err != nil || pathBin == "" +} + +func GoInstall(packageName string, args ...string) { + cmdArgs := append([]string{installCmd}, args...) + err := runCmd(goCLI, cmdArgs...) + if err != nil { + panic(err) + } + println(packageName, "installed!") +} + +func UpdateDeps(name string) { + if name != "" { + for _, p := range PackagesForInstall { + if p.name == name { + updateDeps(p) + } + } + } else { + updateDeps(PackagesForInstall...) + } +} + +func updateDeps(packages ...packages) { + for _, p := range packages { + GoInstall(p.name, p.pkg) + } +} diff --git a/internal/internal.go b/internal/internal.go index 6253048..516fe79 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -31,7 +31,7 @@ func sqlcGenerateByComponent(filePath string) { return } - _ = runCmd("sqlc", "generate", "-f", filePath) + _ = runCmd(sqlcCLI, "generate", "-f", filePath) } func SqlcGenerate(componentName ...string) { @@ -48,14 +48,14 @@ func SqlcGenerate(componentName ...string) { filepath.Walk(pwd, func(path string, info fs.FileInfo, err error) error { if !info.IsDir() && strings.HasSuffix(info.Name(), "sqlc.yaml") { - _ = runCmd("sqlc", "generate", "-f", path) + _ = runCmd(sqlcCLI, "generate", "-f", path) } return nil }) } func WeaverGenerate() { - err := runCmd("weaver", "generate", "./...") + err := runCmd(weaverCLI, "generate", "./...") if err != nil { panic(err) } @@ -63,14 +63,14 @@ func WeaverGenerate() { func RunMakeMigrate(componentName string, name string) { dir := findComponentPath(componentName) - err := runCmd("migrate", "create", "-ext", "sql", "-dir", dir+"/db/migrations/", name) + err := runCmd(migrateCLI, "create", "-ext", "sql", "-dir", dir+"/db/migrations/", name) if err != nil { panic(err) } } func ModTidy() { - err := runCmd("go", "mod", "tidy") + err := runCmd(goCLI, "mod", "tidy") if err != nil { panic(err) } @@ -89,11 +89,11 @@ func RunMigrate(componentName, upDown string) { var dir = findComponentPath(componentName) queryConn := ReadToml(componentName) - _ = runCmd("migrate", "-path", dir+"/db/migrations/", "-database", queryConn, "-verbose", upDown) + _ = runCmd(migrateCLI, "-path", dir+"/db/migrations/", "-database", queryConn, "-verbose", upDown) } func wasInstalledDriversDB() { - cmd := exec.Command("migrate", "-h") + cmd := exec.Command(migrateCLI, "-h") var errb bytes.Buffer cmd.Stderr = &errb _ = cmd.Run()