diff --git a/.github/workflows/generate-linter.yml b/.github/workflows/generate-linter.yml index a659bcae..090b96fb 100644 --- a/.github/workflows/generate-linter.yml +++ b/.github/workflows/generate-linter.yml @@ -28,10 +28,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: ${{ matrix.goVersion }} - name: build templates run: go run main.go create -n ${{ matrix.framework }} -f ${{ matrix.framework}} -d ${{ matrix.driver }} - name: golangci-lint @@ -40,3 +36,5 @@ jobs: version: v1.55.2 working-directory: ${{ matrix.framework }} args: --timeout=5m + - name: remove templates + run: rm -rf ${{ matrix.framework }} diff --git a/cmd/create.go b/cmd/create.go index 431726c3..d5e760cf 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -5,6 +5,7 @@ import ( "log" "os" "strings" + "sync" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" @@ -12,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/spinner" "github.com/melkeydev/go-blueprint/cmd/ui/textinput" "github.com/melkeydev/go-blueprint/cmd/utils" "github.com/spf13/cobra" @@ -152,9 +154,26 @@ var createCmd = &cobra.Command{ cobra.CheckErr(textinput.CreateErrorInputModel(err).Err()) } project.AbsolutePath = currentWorkingDir - - // This calls the templates + spinner := tea.NewProgram(spinner.InitialModelNew()) + // add synchronization to wait for spinner to finish + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + // only run the spinner if the command is interactive + if isInteractive { + if _, err := spinner.Run(); err != nil { + cobra.CheckErr(err) + } + } + }() err = project.CreateMainFile() + // once the create is done, stop the spinner + if isInteractive { + 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()) @@ -167,6 +186,11 @@ var createCmd = &cobra.Command{ 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) + } } }, } diff --git a/cmd/ui/spinner/spinner.go b/cmd/ui/spinner/spinner.go new file mode 100644 index 00000000..4fa0b940 --- /dev/null +++ b/cmd/ui/spinner/spinner.go @@ -0,0 +1,62 @@ +package spinner + +import ( + "fmt" + + "github.com/charmbracelet/bubbles/spinner" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" +) + +type errMsg error + +type model struct { + spinner spinner.Model + quitting bool + err error +} + +func InitialModelNew() model { + s := spinner.New() + s.Spinner = spinner.Line + s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205")) + return model{spinner: s} +} + +func (m model) Init() tea.Cmd { + return m.spinner.Tick +} + +func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.String() { + case "q", "esc", "ctrl+c": + m.quitting = true + return m, tea.Quit + default: + return m, nil + } + + case errMsg: + m.err = msg + return m, nil + + default: + var cmd tea.Cmd + m.spinner, cmd = m.spinner.Update(msg) + return m, cmd + } +} + +func (m model) View() string { + + if m.err != nil { + return m.err.Error() + } + str := fmt.Sprintf("\n\n %s Preparing...\n\n", m.spinner.View()) + if m.quitting { + return str + "\n" + } + return str +} diff --git a/cmd/ui/textinput/textinput.go b/cmd/ui/textinput/textinput.go index 4320ae56..33cb4424 100644 --- a/cmd/ui/textinput/textinput.go +++ b/cmd/ui/textinput/textinput.go @@ -17,6 +17,7 @@ var ( titleStyle = lipgloss.NewStyle().Background(lipgloss.Color("#01FAC6")).Foreground(lipgloss.Color("#030303")).Bold(true).Padding(0, 1, 0) errorStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#FF8700")).Bold(true).Padding(0, 0, 0) ) + type ( errMsg error )