Skip to content

Commit

Permalink
Added Golang CLI creation
Browse files Browse the repository at this point in the history
  • Loading branch information
jsdaniell committed Mar 21, 2021
1 parent 6d50323 commit 1ad7766
Show file tree
Hide file tree
Showing 12 changed files with 746 additions and 30 deletions.
4 changes: 2 additions & 2 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

80 changes: 63 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,71 @@
- Built-in helper scripts (build.sh in some projects).
- Self-learning helper comments (Detailed instructions to customize the files, like instructions to controllers, views, models)

### Installing

To install you can use npm to get globally on your machine:

`npm i -g recipe-cli`

After this you can get the list of project typing `recipe-cli` or init some project with `recipe-cli {language}`, like:

`recipe-cli golang`

A bunch of options will be showed to configure your project.

## Golang Projects Boilerplates

**API Structure**
**1. API Project Structure (Mux Router)**

- Two database pre-configured configurations and models (Firebase || MongoDB) || Empty structure.
- Heroku configuration files and build scripts.
- MVP Project Structure with routes example, ready to customize.
- Utilities package for JSON responses and Token validation already created.
- Pre-configured Github Action script for deploy on heroku.
- Pre-configured CORS.

```
project
├── api
│ ├── controllers
│ │ └── entity.go (controller example, customize your own from here)
│ ├── db
│ │ └── database.go (two options pre-configured - Firebase / MongoDB | also can be boilerplated with empty if no database choosed)
│ ├── models
│ │ ├── Entity.go (depends of the database selected)
│ │ └── Token.go
│ ├── repository
│ │ └── entity_repository
│ ├── responses
│ │ └── responses.go
│ └── server.go
├── go.mod
└── main.go
```
├── Procfile
├── api
│ ├── controllers
│ │ └── entity.go (controller used on entity_routes inside routes package)
│ ├── db
│ │ └── database.go (database connection - Firebase || MongoDB || Empty)
│ ├── middlewares
│ │ └── middlewares.go (middleware functions to deal with cors configuration)
│ ├── models
│ │ ├── Entity.go (example of model in accord with database choosed)
│ │ └── Token.go (token model to be used with token validation function in security package)
│ ├── repository
│ │ └── entity_repository (example of repository function used inside controllers)
│ ├── responses
│ │ └── responses.go (utility to format JSON responses from the API)
│ ├── router
│ │ ├── router.go
│ │ └── routes (route pre-configured for each controller)
│ ├── server.go
│ └── utils
│ ├── json_utility (utility to work with Structs -> JSON management)
│ └── security (utility for validate token)
├── build.sh
├── config
│ └── config.go
├── deploy_to_heroku.sh (deploy to heroku with sh deploy_to_heroku.sh file)
├── go.mod
├── go.sum
├── heroku.yml (heroku configuration file for go projects)
├── main.go
└── vendor (vendoring of the dependencies)
...
30 directories, 17 files
```

**2. CLI Project Structure**

- Utilities for command-line interface, like **selectors** and input user commands with validation.
- Utility to integrate shell commands inside your application.
- Pre-configured release configuration and script.
- CI CD Scripts for publish release pre-configured.
- NPM deploy script configured, production-ready.
23 changes: 14 additions & 9 deletions cmd/golang/golang.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"github.com/jsdaniell/recipe-cli/cli"
"github.com/jsdaniell/recipe-cli/cmd/golang/golang_api"
"github.com/jsdaniell/recipe-cli/cmd/golang/golang_cli"
"github.com/spf13/cobra"
"log"
)
Expand All @@ -30,31 +31,35 @@ const (
// GoCmd handles all the golang project types.
var GoCmd = &cobra.Command{
Use: "golang",
Short: "Choose the type of project",
Long: `All software has versions. This is Hugo's`,
Short: "Choose the type of project:",
Long: `Different golang projects options for boilerplate.`,
Run: func(cmd *cobra.Command, args []string) {
projectType, err := cli.SelectorCli("Choose the type of golang project:", API, CLI)
if err != nil {
log.Fatal(err)
}

projectDatabase, err := cli.SelectorCli("Choose the database used on project:", MongoDBDatabase, FirebaseDatabase, NoSelection)
projectName, err := cli.UserInput("Type the name of the project", validateProjectName)
if err != nil {
log.Fatal(err)
}

projectName, err := cli.UserInput("Type the name of the project" ,validateProjectName)
if err != nil {
log.Fatal(err)
}

username, err := cli.UserInput("Type your username, naturally the package of go api will be (github.com/username/project_name):" ,validateProjectName)
username, err := cli.UserInput("Type your username, naturally the package of go api will be (github.com/username/project_name):", validateProjectName)
if err != nil {
log.Fatal(err)
}

if projectType == API {
projectDatabase, err := cli.SelectorCli("Choose the database used on project:", MongoDBDatabase, FirebaseDatabase, NoSelection)
if err != nil {
log.Fatal(err)
}

golang_api.InitRoot(username, projectName, projectDatabase)
}

if projectType == CLI {
golang_cli.InitRoot(username, projectName)
}
},
}
64 changes: 64 additions & 0 deletions cmd/golang/golang_cli/golang_cli_content_files/ci_github_files.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package golang_cli_content_files

import (
"log"
"os"
)

func CreateCIGithubFiles(projectName string) {
err := os.Mkdir(projectName + "/.github", os.FileMode(0777))
if err != nil {
log.Fatal(err)
}
err = os.Mkdir(projectName + "/.github/workflows", os.FileMode(0777))
if err != nil {
log.Fatal(err)
}

writeGithubWorkflowFile(projectName)


}

func writeGithubWorkflowFile(projectName string){
var content = `name: goreleaser
on:
push:
tags:
- '*'
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
-
name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.16
-
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.TOKEN_GO_RELEASE }}
`

file, err := os.Create(projectName + "/.github/workflows/release.yml")
if err != nil {
log.Fatal(err)
}

_, err = file.WriteString(content)
if err != nil {
log.Fatal(err)
}
}
115 changes: 115 additions & 0 deletions cmd/golang/golang_cli/golang_cli_content_files/cli_files.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package golang_cli_content_files

import (
"log"
"os"
)

func CreateCLIPackage(projectName string) {
err := os.Mkdir(projectName + "/cli", os.FileMode(0777))
if err != nil {
log.Fatal(err)
}

writeCLISelectorFile(projectName)
writeUserInputFile(projectName)


}

func writeCLISelectorFile(projectName string){
var content = `package cli
import (
"github.com/manifoldco/promptui"
"log"
)
// SelectorCli helps to get user input showing a selector with the passed options and label.
func SelectorCli(label string, options ...string) (string, error) {
s := promptui.Select{
Label: label,
Items: options,
}
_, result, err := s.Run()
if err != nil {
log.Fatal(err)
}
return result, nil
}
`

file, err := os.Create(projectName + "/cli/selector_cli.go")
if err != nil {
log.Fatal(err)
}

_, err = file.WriteString(content)
if err != nil {
log.Fatal(err)
}
}

func writeUserInputFile(projectName string){
var content = `package cli
import (
"errors"
"fmt"
"github.com/manifoldco/promptui"
)
// An example of validate function:
//
// validate := func(input string) error {
// _, err := strconv.ParseFloat(input, 64)
// if err != nil {
// return errors.New("Invalid number")
// }
// return nil
// }
// UserInput allow to get the user input with optional validate function.
func UserInput(label string, validate ...promptui.ValidateFunc) (string, error){
var validation promptui.ValidateFunc
if len(validate) == 0 {
validation = promptui.ValidateFunc(func(s string) error {
return nil
})
} else if len(validate) == 1 {
validation = validate[0]
} else if len(validate) > 1 {
return "", errors.New("it's permited only one validation function parameter.")
}
prompt := promptui.Prompt{
Label: label,
Validate: validation,
}
result, err := prompt.Run()
if err != nil {
fmt.Printf("Prompt failed %v\n", err)
return "", err
}
return result, nil
}
`

file, err := os.Create(projectName + "/cli/user_input.go")
if err != nil {
log.Fatal(err)
}

_, err = file.WriteString(content)
if err != nil {
log.Fatal(err)
}
}
Loading

0 comments on commit 1ad7766

Please sign in to comment.