Skip to content

Commit

Permalink
Advanced flag (#149)
Browse files Browse the repository at this point in the history
Adding advanced flag and new major version
  • Loading branch information
briancbarrow authored Dec 26, 2023
1 parent dd6c8ab commit b534117
Show file tree
Hide file tree
Showing 50 changed files with 4,219 additions and 70 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/generate-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ jobs:
matrix:
framework:
[chi, gin, fiber, gorilla/mux, httprouter, standard-library, echo]
driver: [mysql, postgres, sqlite, mongo, none]
driver:
[mysql, postgres, sqlite, mongo, none]
goVersion: ["1.20"]
runs-on: ubuntu-latest
steps:
Expand Down
33 changes: 28 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ gives the option to integrate with one of the more popular Go frameworks (and th
- [Install](#install)
- [Frameworks Supported](#frameworks-supported)
- [Database Support](#database-support)
- [Advanced Features](#advanced-features)
- [Usage Example](#usage-example)
- [GitHub Stats](#github-stats)
- [License](#license)

<a id="install"></a>

<h2>
<picture>
<img src="./public/install.gif?raw=true" width="60px" style="margin-right: 1px;">
Expand Down Expand Up @@ -56,7 +56,6 @@ go-blueprint create --name my-project --framework gin --driver postgres
See `go-blueprint create -h` for all the options and shorthands.

<a id="frameworks-supported"></a>

<h2>
<picture>
<img src="./public/frameworks.gif?raw=true" width="60px" style="margin-right: 1px;">
Expand Down Expand Up @@ -91,8 +90,22 @@ Choose from a variety of supported database drivers:
- [Sqlite](https://github.com/mattn/go-sqlite3)
- [Mongo](go.mongodb.org/mongo-driver)

<a id="usage-example"></a>
<a id="advanced-features"></a>
<h2>
<picture>
<img src="./public/advanced.gif?raw=true" width="70px" style="margin-right: 1px;">
</picture>
Advanced Features
</h2>
Blueprint is focused on being as minimalistic as possible. That being said, we wanted to offer the ability to add other features people may want without bloating the overall experience.

You can now use the `--advanced` flag when running the `create` command to get access to the following features. This is a multi-option prompt; one or more features can be used at the same time:

- [HTMX](https://htmx.org/) support using [Templ](https://templ.guide/)
- CI/CD workflow setup using [Github Actions](https://docs.github.com/en/actions)


<a id="usage-example"></a>
<h2>
<picture>
<img src="./public/example.gif?raw=true" width="60px" style="margin-right: 1px;">
Expand All @@ -110,8 +123,17 @@ go-blueprint create --name my-project --framework gin --driver postgres
<img src="./public/blueprint_1.png" alt="Starter Image" width="800"/>
</p>

<a id="github-stats"></a>
Advanced features are accessible with the --advanced flag

```bash
go-blueprint create --advanced
```

<p align="center">
<img src="./public/blueprint_2.png" alt="Starter Image" width="800"/>
</p>

<a id="github-stats"></a>
<h2>
<picture>
<img src="./public/stats.gif?raw=true" width="45px" style="margin-right: 10px;">
Expand All @@ -124,12 +146,13 @@ go-blueprint create --name my-project --framework gin --driver postgres
</p>

<a id="license"></a>

<h2>
<picture>
<img src="./public/license.gif?raw=true" width="50px" style="margin-right: 1px;">
</picture>
License
</h2>

### Advanced Features

Licensed under [MIT License](./LICENSE)
79 changes: 59 additions & 20 deletions cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/melkeydev/go-blueprint/cmd/program"
"github.com/melkeydev/go-blueprint/cmd/steps"
"github.com/melkeydev/go-blueprint/cmd/ui/multiInput"
"github.com/melkeydev/go-blueprint/cmd/ui/multiSelect"
"github.com/melkeydev/go-blueprint/cmd/ui/spinner"
"github.com/melkeydev/go-blueprint/cmd/ui/textinput"
"github.com/melkeydev/go-blueprint/cmd/utils"
Expand Down Expand Up @@ -45,13 +46,16 @@ func init() {

createCmd.Flags().StringP("name", "n", "", "Name of project to create")
createCmd.Flags().VarP(&flagFramework, "framework", "f", fmt.Sprintf("Framework to use. Allowed values: %s", strings.Join(flags.AllowedProjectTypes, ", ")))
createCmd.Flags().VarP(&flagDBDriver, "driver", "d", fmt.Sprintf("database drivers to use. Allowed values: %s", strings.Join(flags.AllowedDBDrivers, ", ")))
createCmd.Flags().VarP(&flagDBDriver, "driver", "d", fmt.Sprintf("Database drivers to use. Allowed values: %s", strings.Join(flags.AllowedDBDrivers, ", ")))
createCmd.Flags().BoolP("advanced", "a", false, "Get prompts for advanced features")
}

type Options struct {
ProjectName *textinput.Output
ProjectType *multiInput.Selection
DBDriver *multiInput.Selection
Advanced *multiSelect.Selection
Workflow *multiInput.Selection
}

// createCmd defines the "create" command for the CLI
Expand All @@ -64,7 +68,7 @@ var createCmd = &cobra.Command{
var tprogram *tea.Program
var err error

isInteractive := !utils.HasChangedFlag(cmd.Flags())
isInteractive := false
flagName := cmd.Flag("name").Value.String()
if flagName != "" && doesDirectoryExistAndIsNotEmpty(flagName) {
err = fmt.Errorf("directory '%s' already exists and is not empty. Please choose a different name", flagName)
Expand All @@ -80,20 +84,35 @@ var createCmd = &cobra.Command{
ProjectName: &textinput.Output{},
ProjectType: &multiInput.Selection{},
DBDriver: &multiInput.Selection{},
Advanced: &multiSelect.Selection{
Choices: make(map[string]bool),
},
}

project := &program.Project{
ProjectName: flagName,
ProjectType: flagFramework,
DBDriver: flagDBDriver,
FrameworkMap: make(map[flags.Framework]program.Framework),
DBDriverMap: make(map[flags.Database]program.Driver),
ProjectName: flagName,
ProjectType: flagFramework,
DBDriver: flagDBDriver,
FrameworkMap: make(map[flags.Framework]program.Framework),
DBDriverMap: make(map[flags.Database]program.Driver),
AdvancedOptions: make(map[string]bool),
}

steps := steps.InitSteps(flagFramework, flagDBDriver)
fmt.Printf("%s\n", logoStyle.Render(logo))

// Advanced option steps:
flagAdvanced, err := cmd.Flags().GetBool("advanced")
if err != nil {
log.Fatal("failed to retrieve advanced flag")
}

if flagAdvanced {
fmt.Println(tipMsgStyle.Render("*** You are in advanced mode ***\n\n"))
}

if project.ProjectName == "" {
isInteractive = true
tprogram := tea.NewProgram(textinput.InitialTextInputModel(options.ProjectName, "What is the name of your project?", project))
if _, err := tprogram.Run(); err != nil {
log.Printf("Name of project contains an error: %v", err)
Expand All @@ -113,6 +132,7 @@ var createCmd = &cobra.Command{
}

if project.ProjectType == "" {
isInteractive = true
step := steps.Steps["framework"]
tprogram = tea.NewProgram(multiInput.InitialModelMulti(step.Options, options.ProjectType, step.Headers, project))
if _, err := tprogram.Run(); err != nil {
Expand All @@ -132,6 +152,7 @@ var createCmd = &cobra.Command{
}

if project.DBDriver == "" {
isInteractive = true
step := steps.Steps["driver"]
tprogram = tea.NewProgram(multiInput.InitialModelMulti(step.Options, options.DBDriver, step.Headers, project))
if _, err := tprogram.Run(); err != nil {
Expand All @@ -148,12 +169,30 @@ var createCmd = &cobra.Command{
}
}

if flagAdvanced {
isInteractive = true
step := steps.Steps["advanced"]
tprogram = tea.NewProgram((multiSelect.InitialModelMultiSelect(step.Options, options.Advanced, step.Headers, project)))
if _, err := tprogram.Run(); err != nil {
cobra.CheckErr(textinput.CreateErrorInputModel(err).Err())
}
project.ExitCLI(tprogram)
for key, opt := range options.Advanced.Choices {
project.AdvancedOptions[key] = opt
}
if err != nil {
log.Fatal("failed to set the htmx option", err)
}

}

currentWorkingDir, err := os.Getwd()
if err != nil {
log.Printf("could not get current working directory: %v", err)
cobra.CheckErr(textinput.CreateErrorInputModel(err).Err())
}
project.AbsolutePath = currentWorkingDir

spinner := tea.NewProgram(spinner.InitialModelNew())

// add synchronization to wait for spinner to finish
Expand All @@ -166,30 +205,30 @@ var createCmd = &cobra.Command{
}
}()

// This calls the templates
err = project.CreateMainFile()

// once the create is done, stop the spinner
spinner.Quit()

// wait for the spinner to finish
wg.Wait()
if err != nil {
log.Printf("Problem creating files for project. %v", err)
cobra.CheckErr(textinput.CreateErrorInputModel(err).Err())
}

fmt.Println(endingMsgStyle.Render("\nNext steps cd into the newly created project with:"))
fmt.Println(endingMsgStyle.Render(fmt.Sprintf("• cd %s\n", project.ProjectName)))
fmt.Println(endingMsgStyle.Render("\nNext steps:"))
fmt.Println(endingMsgStyle.Render(fmt.Sprintf("• cd into the newly created project with: `cd %s`\n", project.ProjectName)))

if options.Advanced.Choices["AddHTMXTempl"] {
fmt.Println(endingMsgStyle.Render("• Install the templ cli if you haven't already by running `go install github.com/a-h/templ/cmd/templ@latest`\n"))
fmt.Println(endingMsgStyle.Render("• Generate templ function files by running `templ generate`\n"))
}

if isInteractive {
nonInteractiveCommand := utils.NonInteractiveCommand(cmd.Use, cmd.Flags())
fmt.Println(tipMsgStyle.Render("Tip: Repeat the equivalent Blueprint with the following non-interactive command:"))
fmt.Println(tipMsgStyle.Italic(false).Render(fmt.Sprintf("• %s\n", nonInteractiveCommand)))
err = tprogram.ReleaseTerminal()
if err != nil {
log.Printf("Could not release terminal: %v", err)
cobra.CheckErr(err)
}
}
err = spinner.ReleaseTerminal()
if err != nil {
log.Printf("Could not release terminal: %v", err)
cobra.CheckErr(err)
}
},
}
Expand Down
Loading

0 comments on commit b534117

Please sign in to comment.