Lint / lint (push) Waiting to run
Release / Release (push) Waiting to run
Scan for secrets / test (push) Waiting to run
Snifftest / Run Snifftest (push) Waiting to run
Test / test (push) Waiting to run
Test / test-detectors (push) Waiting to run
Test / test-community (push) Waiting to run
* Init attempt at tui with bubble tea. Co-authored-by: mcastorina <[email protected]> * Add starting and source selection options Co-authored-by: mcastorina <[email protected]> * Rewrite models into a state machine * Update source descriptions * Make subpages implement tea.Model * Rename page0 and page1 to be more descriptive * Adjust styling and adding color consts Co-authored-by: mcastorina <[email protected]> * Add helper generic function to call Update and type cast * Setup plumbing for source configuration page * Use CLI introspection for source configuration (WIP) * Experiment with table view * Replace table with form fields Co-authored-by: mcastorina <[email protected]> * Change 🔒 to 💸 * Copy components from soft-serve Co-authored-by: hxnyk <[email protected]> * Copy styles from soft-serve Co-authored-by: hxnyk <[email protected]> * Copy common from soft-serve Co-authored-by: hxnyk <[email protected]> * Refactor into pages This is still a WIP, but the main structure is there. Co-authored-by: hxnyk <[email protected]> * Trying out selector for wizard intro Co-authored-by: mcastorina <[email protected]> * Use selector with custom View Co-authored-by: hxnyk <[email protected]> * Change Item to be an enum Co-authored-by: hxnyk <[email protected]> * Add link pages Co-authored-by: mcastorina <[email protected]> * Update source select to use selector Co-authored-by: mcastorina <[email protected]> * Delete source configure page and add blank tabs Co-authored-by: hxnyk <[email protected]> * Add tab placeholder pages for configurationi Co-authored-by: mcastorina <[email protected]> * Added headers and style to each tab Co-authored-by: hxnyk <[email protected]> * Update with new sources * Remove kingpin attribute from SourceItem * Add basic form field and source structuring * Hookup git form fields with an underlying textinput component Co-authored-by: hxnyk <[email protected]> * Update forms for git and github Co-authored-by: mcastorina <[email protected]> * Add labels per text input * Add sources and adjust styling * add basic trufflehog configuration page * Add skip button to textinputs component * Emit and handle textinputs skip/submit button commands * Don't quit when q is pressed on the sourceConfigurePage * Build trufflehog command based on source config vals Co-authored-by: mcastorina <[email protected]> * Build flags based on truffle config inputs * Update summary section * Add generated truffle fields Co-authored-by: mcastorina <[email protected]> * update summary to correctly print info * Go back a page when escape key is pressed * WIP run page list Co-authored-by: hxnyk <[email protected]> * Allow running trufflehog from the run page Co-authored-by: hxnyk <[email protected]> * Add option to view help docs Co-authored-by: mcastorina <[email protected]> * comment out unused styles and remove unused types * Capitalize H in TruffleHog * remove unneeded fmt.Sprintf --------- Co-authored-by: mcastorina <[email protected]>
138 lines
3.7 KiB
Go
138 lines
3.7 KiB
Go
package wizard_intro
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
|
|
"github.com/charmbracelet/bubbles/key"
|
|
"github.com/charmbracelet/bubbles/list"
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
"github.com/charmbracelet/lipgloss"
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/tui/common"
|
|
)
|
|
|
|
// Item represents a single item in the selector.
|
|
type Item int
|
|
|
|
// ID implements selector.IdentifiableItem.
|
|
func (i Item) ID() string {
|
|
return i.String()
|
|
}
|
|
|
|
// Title returns the item title. Implements list.DefaultItem.
|
|
func (i Item) Title() string { return i.String() }
|
|
|
|
// Description returns the item description. Implements list.DefaultItem.
|
|
func (i Item) Description() string { return "" }
|
|
|
|
// FilterValue implements list.Item.
|
|
func (i Item) FilterValue() string { return i.Title() }
|
|
|
|
// Command returns the item Command view.
|
|
func (i Item) Command() string {
|
|
return i.Title()
|
|
}
|
|
|
|
// ItemDelegate is the delegate for the item.
|
|
type ItemDelegate struct {
|
|
common *common.Common
|
|
}
|
|
|
|
// Width returns the item width.
|
|
func (d ItemDelegate) Width() int {
|
|
width := d.common.Styles.MenuItem.GetHorizontalFrameSize() + d.common.Styles.MenuItem.GetWidth()
|
|
return width
|
|
}
|
|
|
|
// Height returns the item height. Implements list.ItemDelegate.
|
|
func (d ItemDelegate) Height() int {
|
|
height := d.common.Styles.MenuItem.GetVerticalFrameSize() + d.common.Styles.MenuItem.GetHeight()
|
|
return height
|
|
}
|
|
|
|
// Spacing returns the spacing between items. Implements list.ItemDelegate.
|
|
func (d ItemDelegate) Spacing() int { return 1 }
|
|
|
|
// Update implements list.ItemDelegate.
|
|
func (d ItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd {
|
|
idx := m.Index()
|
|
item, ok := m.SelectedItem().(Item)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
switch msg := msg.(type) {
|
|
case tea.KeyMsg:
|
|
switch {
|
|
case key.Matches(msg, d.common.KeyMap.Copy):
|
|
d.common.Copy.Copy(item.Command())
|
|
return m.SetItem(idx, item)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Render implements list.ItemDelegate.
|
|
func (d ItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
|
|
i := listItem.(Item)
|
|
s := strings.Builder{}
|
|
var matchedRunes []int
|
|
|
|
// Conditions
|
|
var (
|
|
isSelected = index == m.Index()
|
|
isFiltered = m.FilterState() == list.Filtering || m.FilterState() == list.FilterApplied
|
|
)
|
|
|
|
styles := d.common.Styles.RepoSelector.Normal
|
|
if isSelected {
|
|
styles = d.common.Styles.RepoSelector.Active
|
|
}
|
|
|
|
title := i.Title()
|
|
title = common.TruncateString(title, m.Width()-styles.Base.GetHorizontalFrameSize())
|
|
// if i.repo.IsPrivate() {
|
|
// title += " 🔒"
|
|
// }
|
|
if isSelected {
|
|
title += " "
|
|
}
|
|
updatedStr := " Updated"
|
|
if m.Width()-styles.Base.GetHorizontalFrameSize()-lipgloss.Width(updatedStr)-lipgloss.Width(title) <= 0 {
|
|
updatedStr = ""
|
|
}
|
|
updatedStyle := styles.Updated.Copy().
|
|
Align(lipgloss.Right).
|
|
Width(m.Width() - styles.Base.GetHorizontalFrameSize() - lipgloss.Width(title))
|
|
updated := updatedStyle.Render(updatedStr)
|
|
|
|
if isFiltered && index < len(m.VisibleItems()) {
|
|
// Get indices of matched characters
|
|
matchedRunes = m.MatchesForItem(index)
|
|
}
|
|
|
|
if isFiltered {
|
|
unmatched := styles.Title.Copy().Inline(true)
|
|
matched := unmatched.Copy().Underline(true)
|
|
title = lipgloss.StyleRunes(title, matchedRunes, matched, unmatched)
|
|
}
|
|
title = styles.Title.Render(title)
|
|
desc := i.Description()
|
|
desc = common.TruncateString(desc, m.Width()-styles.Base.GetHorizontalFrameSize())
|
|
desc = styles.Desc.Render(desc)
|
|
|
|
s.WriteString(lipgloss.JoinHorizontal(lipgloss.Bottom, title, updated))
|
|
s.WriteRune('\n')
|
|
s.WriteString(desc)
|
|
s.WriteRune('\n')
|
|
cmd := common.TruncateString(i.Command(), m.Width()-styles.Base.GetHorizontalFrameSize())
|
|
cmd = styles.Command.Render(cmd)
|
|
|
|
s.WriteString(cmd)
|
|
fmt.Fprint(w,
|
|
d.common.Zone.Mark(i.ID(),
|
|
styles.Base.Render(s.String()),
|
|
),
|
|
)
|
|
}
|