Skip to content

Commit

Permalink
Merge pull request #26 from kcmvp/latest-plugin
Browse files Browse the repository at this point in the history
#25: use latest version when no version speciied
  • Loading branch information
kcmvp authored Dec 26, 2023
2 parents 204b819 + 16f7c86 commit 0b8f737
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 38 deletions.
56 changes: 40 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,58 +37,75 @@ Golang Project Boot
<span id="nav-2"></span>

## Introduction
Although the Golang programming ecosystem is becoming more and more mature,
these tools and frameworks exist independently to solve specific problems.
Whenever a new Golang project is started, it requires a series of initialization;
What’s worse is that whenever your switch the development environment, same process have to be repeated!
This project is built to solve this problem by providing a method similar to [Maven](https://maven.apache.org/) or [Gradle](https://gradle.com/) in the **Java** ecosystem.

Although the Golang programming ecosystem is becoming more and more mature,
these tools and frameworks exist independently to solve specific problems.
Whenever a new Golang project is started, it requires a series of initialization;
What’s worse is that whenever your switch the development environment, same process have to be repeated!
This project is built to solve this problem by providing a method similar to [Maven](https://maven.apache.org/)
or [Gradle](https://gradle.com/) in the **Java** ecosystem.

<span id="nav-3"></span>

## Features

**Everything is a plugin !**
**Everything is a plugin, simple yet powerful !**

You just need to use **three** commands to achieve whatever you want

1. Initialization project with

```shell
gob init
```

2. Install a tool as a plugin

```shell
gob install github.com/golangci/golangci-lint/cmd/golangci-lint lint
```
- This command install the **latest** [golangci-lint](https://golangci-lint.run/) as a plugin with alias **lint**
- You can also install a tool with specified version as

- This command install the **latest** [golangci-lint](https://golangci-lint.run/) as a plugin with alias **lint**
- You can also install a tool with specified version as

```shell
gob install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.0 lint
```
- Compare to go default ```go install```, gob support multiple version tool installation. eg

- Compare to go default ```go install```, gob support multiple version tool installation. eg

```shell
ls -althr golangci-lint-v1.55*
-rwxr-xr-x@ 1 kcmvp staff 40M Dec 25 16:08 golangci-lint-v1.55.1
-rwxr-xr-x 1 kcmvp staff 41M Dec 25 16:10 golangci-lint-v1.55.0
```

This will make your project is build with constant tools set

3. Execute the tool as a gob plugin(execute golangci-lint)

```shell
gob lint
```
4. Run `gob -h` get comprehensive and beauty help information

4. Run `gob -h` get comprehensive and beauty help information

## Quick Start

- Install `gob` with below command

```go
go install github.com/kcmvp/gob
```

- Navigate to project directory, initialize project with below command

```go
gob init
```

This command will create a configuration named `gob.yaml` in the project root directory as below:

```yaml
exec:
commit-msg-hook: ^#[0-9]+:\s*.{10,}$
Expand All @@ -103,30 +120,37 @@ plugins:
command: run, ./...
url: github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.1
```
1. The `exec` section is designed to be executed by external; the `init` command will setup three
git local hook: `commit-msg-hook`, `pre-commit-hook` and `pre-push-hook`
2. The `plugins` section define all the plugins(tools) used by this project. **Any tool can be installed as a gob plugin**,
`init` command would install [golangci-lint](https://golangci-lint.run/) as a gob `plugin`
git local hook: `commit-msg-hook`, `pre-commit-hook` and `pre-push-hook`
2. The `plugins` section define all the plugins(tools) used by this project. **Any tool can be installed as a gob plugin
**,
`init` command would install [golangci-lint](https://golangci-lint.run/) as a gob `plugin`

## Features
This tool supply comprehensive help message, you can always get detail information & usage of each command by **-h** flag

This tool supply comprehensive help message, you can always get detail information & usage of each command by **-h**
flag
The main features mainly categorize as below

#### Build & Package
There are mainly 4 built-in commands for project building: **clean, test, lint, build**.

There are mainly 4 built-in commands for project building: **clean, test, lint, build**.

#### Setup (gob setup)

- Setup Git Hook
- Setup onion architecture
- Scaffold of popular frameworks

#### Plugin(gob plugin)

If you want to chain a tool into your project phrase you can install it as a plugin. for example
gb has builtin **golangci-lint** as the part of git hook.

#### Diagram(on the roadmap)


<span id="nav-4"></span>

## FAQ

28 changes: 19 additions & 9 deletions cmd/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/fatih/color"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
"github.com/kcmvp/gob/cmd/action"
"github.com/kcmvp/gob/internal"
"github.com/samber/lo"
"github.com/spf13/cobra"
Expand All @@ -23,16 +24,24 @@ var alias string
var command string

// Install the specified tool as gob plugin
func install(args ...string) error {
if strings.HasSuffix(args[0], "@master") || strings.HasSuffix(args[0], "@latest") {
return fmt.Errorf("please use specific version instead of 'master' or 'latest'")
func install(args ...string) (string, error) {
var ver string
var err error
url := args[0]
parts := strings.Split(url, "@")
if len(parts) != 2 || strings.HasPrefix(parts[1], "latest") {
ver, err = action.LatestVersion(parts[0], "")
if err != nil {
return ver, fmt.Errorf("please use specific version of the tool")
}
url = fmt.Sprintf("%s@%s", parts[0], ver)
}
err := internal.CurProject().InstallPlugin(args[0], alias, command)
err = internal.CurProject().InstallPlugin(url, alias, command)
if errors.Is(err, internal.PluginExists) {
color.Yellow("Plugin %s exists", args[0])
color.Yellow("Plugin %s exists", url)
err = nil
}
return err
return ver, err
}

func list() {
Expand All @@ -57,8 +66,8 @@ func list() {
// pluginCmd represents the plugin command
var pluginCmd = &cobra.Command{
Use: "plugin",
Short: "List all configured plugins",
Long: `List all configured plugins`,
Short: "Install, update or list plugins",
Long: `Install, update or list plugins`,
Run: func(cmd *cobra.Command, args []string) {
list()
},
Expand All @@ -76,7 +85,8 @@ var installPluginCmd = &cobra.Command{
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
return install(args...)
_, err := install(args...)
return err
},
}

Expand Down
23 changes: 23 additions & 0 deletions cmd/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"bytes"
"github.com/kcmvp/gob/cmd/action"
"github.com/kcmvp/gob/internal"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -73,5 +74,27 @@ func TestInstallPlugin(t *testing.T) {
assert.Equal(t, "lint-run", plugin.C)
assert.Equal(t, fiximports, plugin.D)
assert.Equal(t, 2, len(internal.CurProject().Plugins()))
}

func TestInstallPluginWithVersion(t *testing.T) {
ver, err := action.LatestVersion("github.com/hhatto/gocloc/cmd/gocloc", "")
assert.NoError(t, err)
tests := []struct {
name string
url string
wantErr bool
}{
{"no version", "github.com/hhatto/gocloc/cmd/gocloc", false},
{"latest version", "github.com/hhatto/gocloc/cmd/gocloc@latest", false},
{"incorrect version", "github.com/hhatto/gocloc/cmd/gocloc@abc", true},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ver1, err1 := install(test.url)
assert.True(t, test.wantErr == (err1 != nil))
if err1 == nil {
assert.Equal(t, ver, ver1)
}
})
}
}
26 changes: 15 additions & 11 deletions gob.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
exec:
commit-msg-hook: ^#[0-9]+:\s*.{10,}$
pre-commit-hook:
- lint
- test
pre-push-hook:
- lint
- test
commit-msg-hook: ^#[0-9]+:\s*.{10,}$
pre-commit-hook:
- lint
- test
pre-push-hook:
- lint
- test
plugins:
golangci-lint:
alias: lint
command: run, ./...
url: github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.1
gocloc:
alias: ""
command: ""
url: github.com/hhatto/gocloc/cmd/gocloc@v0.5.2
golangci-lint:
alias: lint
command: run, ./...
url: github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.1
3 changes: 1 addition & 2 deletions internal/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ const (
CommitMsg = "commit-msg"
PreCommit = "pre-commit"
PrePush = "pre-push"
////exec command name
)

var CommitMsgCmd = fmt.Sprintf("%s-hook", CommitMsg)
Expand Down Expand Up @@ -73,7 +72,7 @@ func (project *Project) Setup(init bool) {
hook := map[string]any{
fmt.Sprintf("%s.%s", ExecKey, CommitMsgCmd): "^#[0-9]+:\\s*.{10,}$",
fmt.Sprintf("%s.%s", ExecKey, PreCommitCmd): []string{"lint", "test"},
fmt.Sprintf("%s.%s", ExecKey, PrePushCmd): []string{"lint", "test"},
fmt.Sprintf("%s.%s", ExecKey, PrePushCmd): []string{"test"},
}
project.viper.MergeConfigMap(hook)
project.viper.WriteConfigAs(project.Configuration())
Expand Down

0 comments on commit 0b8f737

Please sign in to comment.