Skip to content

Commit

Permalink
feat: add commands for installing and updating dependencies (#26)
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
renanbastos93 authored Dec 9, 2024
2 parents 98cf6e6 + 94f5ca0 commit dee5627
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 22 deletions.
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -82,20 +80,25 @@ Usage: boneless [target]
Targets:
help Show commands for use
version Show version
new <sql|sqlite3> Create a project from scratch using Weaver, SQLC, and go-migrate
new <sql|sqlite3> Create a project from scratch using Weaver, SQLC, and go-migrate
create-scratch <sql|sqlite3> Create a project from scratch using Weaver, SQLC, and go-migrate
build Build the Weaver component with SQLC
make-migrate <app-name> <name> Create a new migration for an app
migrate <app-name> <up|down> Run migrations for an app
create-app <app-name> Create a new app based on a template
build-app <app-name> Build an app using Weaver and SQLC
delete-app <app-name> 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:
<app-name> Name of the app to create or run migrations on
<name> Name of the migration to create
<up|down> Specify "up" to apply migrations or "down" to rollback migrations
<sql|sqlite> Specify "sql" to use some SQL "sqlite3" to use sqlite3 and it is the default
<sql|sqlite> 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
Expand All @@ -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.

Expand Down
17 changes: 16 additions & 1 deletion cmd/boneless/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,25 @@ const usage = `Usage: boneless [target]
Targets:
help Show commands for use
version Show version
new <sql|sqlite3> Create a project from scratch using Weaver, SQLC, and go-migrate
new <sql|sqlite3> Create a project from scratch using Weaver, SQLC, and go-migrate
create-scratch <sql|sqlite3> Create a project from scratch using Weaver, SQLC, and go-migrate
build Build the Weaver component with SQLC
make-migrate <app-name> <name> Create a new migration for an app
migrate <app-name> <up|down> Run migrations for an app
create-app <app-name> Create a new app based on a template
build-app <app-name> Build an app using Weaver and SQLC
delete-app <app-name> 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:
<app-name> Name of the app to create or run migrations on
<name> Name of the migration to create
<up|down> Specify "up" to apply migrations or "down" to rollback migrations
<sql|sqlite> 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
Expand All @@ -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
`
Expand All @@ -55,6 +63,8 @@ const (
cmdBuildApp = "build-app"
cmdDeleteApp = "delete-app"
cmdRun = "run"
cmdInstallDeps = "install-deps"
cmdUpdateDeps = "update-deps"

DefaultComponentName = "app"
)
Expand All @@ -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()
Expand All @@ -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()
}
Expand Down
9 changes: 7 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -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
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
9 changes: 9 additions & 0 deletions internal/consts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package internal

const (
goCLI = "go"
sqlcCLI = "sqlc"
weaverCLI = "weaver"
migrateCLI = "migrate"
installCmd = "install"
)
69 changes: 69 additions & 0 deletions internal/intall_deps.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
14 changes: 7 additions & 7 deletions internal/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func sqlcGenerateByComponent(filePath string) {
return
}

_ = runCmd("sqlc", "generate", "-f", filePath)
_ = runCmd(sqlcCLI, "generate", "-f", filePath)
}

func SqlcGenerate(componentName ...string) {
Expand All @@ -48,29 +48,29 @@ 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)
}
}

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)
}
Expand All @@ -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()
Expand Down
33 changes: 33 additions & 0 deletions internal/mod_init.go
Original file line number Diff line number Diff line change
@@ -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
}
18 changes: 12 additions & 6 deletions internal/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
}
}

0 comments on commit dee5627

Please sign in to comment.