Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ensure script filtering is aware of --allow-unnamed #341

Merged
merged 4 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions internal/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,20 +132,10 @@ func getProject() (proj project.Project, err error) {
func getCodeBlocks() (document.CodeBlocks, error) {
return project.GetCodeBlocks(
filepath.Join(fChdir, fFileName),
fAllowUnknown,
fAllowUnnamed,
nil,
)
}

func lookupCodeBlock(blocks document.CodeBlocks, name string) (*document.CodeBlock, error) {
block := blocks.Lookup(name)
if block == nil {
return nil, errors.Errorf("command %q not found; known command names: %s", name, blocks.Names())
}
return block, nil
}

func validCmdNames(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
blocks, err := getCodeBlocks()
if err != nil {
Expand Down Expand Up @@ -434,13 +424,24 @@ func loadFiles(proj project.Project, w io.Writer, r io.Reader) ([]string, error)
return m.files, nil
}

func loadTasks(proj project.Project, w io.Writer, r io.Reader) (project.CodeBlocks, error) {
func loadTasks(proj project.Project, w io.Writer, r io.Reader, filter bool) (project.CodeBlocks, error) {
m, err := runTasksModel(proj, false, w, r)
if err != nil {
return nil, err
}

return m.tasks, nil
tasks := m.tasks

if filter {
tasks = project.FilterCodeBlocks[project.CodeBlock](m.tasks, fAllowUnknown, fAllowUnnamed)

if len(tasks) == 0 {
// try again without filtering unnamed
tasks = project.FilterCodeBlocks[project.CodeBlock](m.tasks, fAllowUnknown, true)
}
}

return tasks, nil
}

func runTasksModel(proj project.Project, filesOnly bool, w io.Writer, r io.Reader) (*loadTasksModel, error) {
Expand Down
11 changes: 9 additions & 2 deletions internal/cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func listCmd() *cobra.Command {
return err
}

allBlocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin())
allBlocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin(), true)
if err != nil {
return err
}
Expand All @@ -41,7 +41,7 @@ func listCmd() *cobra.Command {
return err
}

if len(blocks) < 1 && !fAllowUnnamed {
if len(blocks) <= 0 && !fAllowUnnamed {
return errors.Errorf("no named code blocks, consider adding flag --allow-unnamed")
}

Expand All @@ -57,17 +57,24 @@ func listCmd() *cobra.Command {
table.AddField(strings.ToUpper("File"), nil, nil)
table.AddField(strings.ToUpper("First Command"), nil, nil)
table.AddField(strings.ToUpper("Description"), nil, nil)
table.AddField(strings.ToUpper("Named"), nil, nil)
table.EndRow()

for _, fileBlock := range blocks {
block := fileBlock.Block

lines := block.Lines()

isNamedField := "True"
if block.IsUnnamed() {
isNamedField = "False"
}

table.AddField(block.Name(), nil, nil)
table.AddField(fileBlock.File, nil, nil)
table.AddField(shell.TryGetNonCommentLine(lines), nil, nil)
table.AddField(block.Intro(), nil, nil)
table.AddField(isNamedField, nil, nil)
table.EndRow()
}

Expand Down
9 changes: 8 additions & 1 deletion internal/cmd/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/stateful/runme/internal/project"
)

func printCmd() *cobra.Command {
Expand All @@ -20,13 +21,19 @@ func printCmd() *cobra.Command {
return err
}

blocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin())
generateBlocks:
blocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin(), true)
if err != nil {
return err
}

fileBlock, err := lookupCodeBlockWithPrompt(cmd, args[0], blocks)
if err != nil {
if project.IsCodeBlockNotFoundError(err) && !fAllowUnnamed {
fAllowUnnamed = true
goto generateBlocks
}

return err
}

Expand Down
18 changes: 15 additions & 3 deletions internal/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ func runCmd() *cobra.Command {
runBlocks := make([]project.FileCodeBlock, 0)

{
blocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin())
searchBlocks:
blocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin(), true)
if err != nil {
return err
}
Expand All @@ -93,13 +94,20 @@ func runCmd() *cobra.Command {
runBlocks = append(runBlocks, fileBlock)
}
}
if len(runBlocks) == 0 {
return errors.New("No tasks to execute with the category provided")

if len(runBlocks) == 0 && !fAllowUnnamed {
fAllowUnnamed = true
goto searchBlocks
}
} else {
for _, arg := range args {
block, err := lookupCodeBlockWithPrompt(cmd, arg, blocks)
if err != nil {
if project.IsCodeBlockNotFoundError(err) && !fAllowUnnamed {
fAllowUnnamed = true
goto searchBlocks
}

return err
}

Expand All @@ -112,6 +120,10 @@ func runCmd() *cobra.Command {
}
}

if len(runBlocks) == 0 {
return errors.New("No tasks to execute with the category provided")
}

ctx, cancel := ctxWithSigCancel(cmd.Context())
defer cancel()

Expand Down
20 changes: 16 additions & 4 deletions internal/cmd/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/stateful/runme/internal/project"
"github.com/stateful/runme/internal/tasks"
)

Expand All @@ -15,19 +16,30 @@ func tasksCmd() *cobra.Command {
Hidden: true,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
blocks, err := getCodeBlocks()
proj, err := getProject()
if err != nil {
return err
}

block, err := lookupCodeBlock(blocks, args[0])
generateBlocks:
blocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin(), true)
if err != nil {
return err
}

block, err := lookupCodeBlockWithPrompt(cmd, args[0], blocks)
if err != nil {
if project.IsCodeBlockNotFoundError(err) && !fAllowUnnamed {
fAllowUnnamed = true
goto generateBlocks
}

return err
}

tasksDef, err := tasks.GenerateFromShellCommand(
block.Name(),
block.Lines()[0],
block.Block.Name(),
block.Block.Lines()[0],
&tasks.ShellCommandOpts{
Cwd: fChdir,
},
Expand Down
86 changes: 77 additions & 9 deletions internal/cmd/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,20 @@ func tuiCmd() *cobra.Command {
return err
}

blocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin())
blocks, err := loadTasks(proj, cmd.OutOrStdout(), cmd.InOrStdin(), false)
if err != nil {
return err
}

defaultAllowUnnamed := fAllowUnnamed

if !defaultAllowUnnamed {
newBlocks := project.FilterCodeBlocks(blocks, fAllowUnknown, false)
if len(newBlocks) == 0 {
defaultAllowUnnamed = true
}
}

blocks = sortBlocks(blocks)

if len(blocks) == 0 {
Expand Down Expand Up @@ -102,16 +111,21 @@ func tuiCmd() *cobra.Command {
}

model := tuiModel{
blocks: blocks,
unfilteredBlocks: blocks,
header: fmt.Sprintf(
"%s %s\n\n",
ansi.Color("runme", "57+b"),
ansi.Color(version.BuildVersion, "white+d"),
),
visibleEntries: visibleEntries,
expanded: make(map[int]struct{}),

allowUnnamed: defaultAllowUnnamed,
allowUnknown: fAllowUnknown,
}

model.filterCodeBlocks()

sessionEnvs, err := runnerClient.GetEnvs(context.Background())
if err != nil {
return err
Expand Down Expand Up @@ -188,13 +202,16 @@ func tuiCmd() *cobra.Command {
}

type tuiModel struct {
blocks project.CodeBlocks
header string
visibleEntries int
expanded map[int]struct{}
cursor int
scroll int
result tuiResult
unfilteredBlocks project.CodeBlocks
blocks project.CodeBlocks
header string
visibleEntries int
expanded map[int]struct{}
cursor int
scroll int
result tuiResult
allowUnnamed bool
allowUnknown bool
}

type tuiResult struct {
Expand All @@ -217,6 +234,40 @@ func (m *tuiModel) scrollBy(delta int) {
)
}

func (m *tuiModel) filterCodeBlocks() {
hasInitialized := m.blocks != nil

var oldSelection project.CodeBlock
if hasInitialized {
oldSelection = m.blocks[m.cursor]
}

m.blocks = project.FilterCodeBlocks(m.unfilteredBlocks, m.allowUnknown, m.allowUnnamed)

if !hasInitialized {
return
}

foundOldSelection := false
for i, block := range m.blocks {
if block == oldSelection {
m.moveCursorTo(i)
foundOldSelection = true
break
}
}

if !foundOldSelection {
if m.cursor >= len(m.blocks) {
m.moveCursorTo(len(m.blocks) - 1)
}
}
}

func (m *tuiModel) moveCursorTo(newPos int) {
m.moveCursor(newPos - m.cursor)
}

func (m *tuiModel) moveCursor(delta int) {
m.cursor = rmath.Clamp(
m.cursor+delta,
Expand Down Expand Up @@ -258,6 +309,11 @@ func (m tuiModel) View() string {

{
name := block.Name()

if block.IsUnnamed() {
name += " (unnamed)"
}

filename := ansi.Color(fileBlock.File, "white+d")

if active {
Expand Down Expand Up @@ -296,13 +352,21 @@ func (m tuiModel) View() string {

_, _ = s.WriteRune('\n')

var unnamedVerb string
if m.allowUnnamed {
unnamedVerb = "Hide"
} else {
unnamedVerb = "Show"
}

{
help := strings.Join(
[]string{
fmt.Sprintf("%d/%d", m.cursor+1, len(m.blocks)),
"Choose ↑↓←→",
"Run [Enter]",
"Expand [Space]",
fmt.Sprintf("%s Unnamed [u]", unnamedVerb),
"Quit [q]",
},
tab,
Expand Down Expand Up @@ -351,6 +415,10 @@ func (m tuiModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}

return m, tea.Quit

case "u":
m.allowUnnamed = !m.allowUnnamed
m.filterCodeBlocks()
}
}

Expand Down
7 changes: 6 additions & 1 deletion internal/document/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strconv"
"strings"

"github.com/stateful/runme/internal/executable"
"github.com/stateful/runme/internal/shell"
"github.com/yuin/goldmark/ast"

Expand Down Expand Up @@ -153,10 +154,14 @@ func (b *CodeBlock) Name() string {
return b.name
}

func (b *CodeBlock) NameGenerated() bool {
func (b *CodeBlock) IsUnnamed() bool {
return b.nameGenerated
}

func (b *CodeBlock) IsUnknown() bool {
return b.Language() == "" || !executable.IsSupported(b.Language())
}

func (b *CodeBlock) Unwrap() ast.Node {
return b.inner
}
Expand Down
Loading
Loading