Skip to content

Commit

Permalink
feat(console): editing a component definition (#648)
Browse files Browse the repository at this point in the history
* feat!(tui): initial commit

* chore(deps): update actions/upload-artifact action to v4.3.6 (#575)

| datasource  | package                 | from   | to     |
| ----------- | ----------------------- | ------ | ------ |
| github-tags | actions/upload-artifact | v4.3.4 | v4.3.6 |

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update module github.com/open-policy-agent/opa to v0.67.1 (#577)

| datasource | package                          | from    | to      |
| ---------- | -------------------------------- | ------- | ------- |
| go         | github.com/open-policy-agent/opa | v0.67.0 | v0.67.1 |

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Megan Wolf <[email protected]>

* chore(deps): update github/codeql-action action to v3.26.0 (#582)

| datasource  | package              | from     | to      |
| ----------- | -------------------- | -------- | ------- |
| github-tags | github/codeql-action | v3.25.15 | v3.26.0 |

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(generate): proposed transition of generation annotation to props (#574)

* fix(generate): generation annotation in a prop

* fix(generate): introduce framework flag to generate

* chore(docs): add generation ns docs

* feat(validation-result)!: bump to go-oscal v0.6.0 jsonschema v6 update (#544)

* feat(validation-result)!: remove validation-result in favor of new go-oscal behavior
chore(go-oscal): update w/ go-oscal jsonschema v6 changes

* docs(reference): update jsonschema url, run go mod tidy to remove lingering jsonschemav5 inderect dep

* test: update w/ current branch sha from go-oscal

* chore(deps): bump go-oscal to v0.6.0

* fix(unit): cleanup whitespaces for composed artifact

---------

Co-authored-by: Brandt Keller <[email protected]>

* fix(validate): get non-namespace scoped resources (#585)

* fix(validate): get non-namespace scoped resources

* fix(validate): alternate cluster-scoped resource get, schema mods

* fix: updated conditional statement

* docs: updated k8s domain doc

* chore(deps): update dependency commitlint to v19.4.0 (#583)

| datasource | package    | from   | to     |
| ---------- | ---------- | ------ | ------ |
| npm        | commitlint | 19.3.0 | 19.4.0 |

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(docs): initial SSP generation research docs (#548)

* feat: initial-ssp-generate-doc

* updated some wording

* split ssp docs, updated some assessment result spellings.

* ssp doc updates

* broke assessment results at somepoint

* updated note location

* chore(docs): minor adjustments to intent and terms

* chore(docs): cleanup testing artifacts

* chore(docs): fix typos and add to dict

---------

Co-authored-by: Brandt Keller <[email protected]>
Co-authored-by: Brandt Keller <[email protected]>

* chore(main): release 0.5.0 (#578)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore(docs): update issue template with expected deliverables line item (#590)

* chore(deps): update anchore/sbom-action action to v0.17.1 (#593)

| datasource  | package             | from    | to      |
| ----------- | ------------------- | ------- | ------- |
| github-tags | anchore/sbom-action | v0.17.0 | v0.17.1 |

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update github/codeql-action action to v3.26.1 (#595)

| datasource  | package              | from    | to      |
| ----------- | -------------------- | ------- | ------- |
| github-tags | github/codeql-action | v3.26.0 | v3.26.1 |

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(docs): updated namespace doc locations and associated prop namespace url (#602)

* fix: updated ns docs, ns prop

* fix: remove test file

feat: more tui design

feat: more tui design

feat: more tui design

feat: more tui design

* fix: removed debug bin

* fix: removed rest files

* fix: removed rest files

* fix: fixed test expectations

* feat: tui sizing, fixes

* feat: updated keybindings, help

* docs: tui docs

* docs: updated tui docs

* fix: nil handling for empty control

* fix: additional nil pointer errors

* fix: renamed to console

* fix: overlay focus navigation

* fix: updating keys/help

* feat(console): adding edit fcns

* feat(console): edit functionality updates

updates to edit, plus other housekeeping/tech-debt modifications to try
and simplify update functions

* fix: go deps, removed debug.log

* fix: updated testdata, redundant fcns

* fix: updating model_test

* fix: trying tempfile

* fix: key-maps/help updates

* fix: updated test files, increased timeout

* fix: msgs, keys

* test(console): additional console edit tests, testhelpers

* fix: removed inject changes, dead code comment

* docs(console): updated docs, gifs; added vhs tapes

* fix: doc change, removed comments

* fix: updated teatest

* fix: save then close

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Brandt Keller <[email protected]>
Co-authored-by: Cole (Mike) Winberry <[email protected]>
Co-authored-by: Brandt Keller <[email protected]>
Co-authored-by: Andy Mills <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
7 people authored Sep 20, 2024
1 parent e30a824 commit ae06e27
Show file tree
Hide file tree
Showing 38 changed files with 2,233 additions and 498 deletions.
43 changes: 43 additions & 0 deletions demo/console/component-edit.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Output images/component-defn-console-edit.gif

Require lula
Set FontSize 14
Set Width 1850
Set Height 925
Set Framerate 24
Set Padding 5

Hide
Type "lula console -f ./src/test/unit/common/oscal/valid-multi-component-validations.yaml" Enter
Sleep 1s
Show

# Navigate and select a control
Right
Sleep 500ms
Right
Sleep 500ms
Right
Sleep 1s
Enter
Sleep 1s

# Navigate to description
Right
Sleep 500ms
Right
Sleep 500ms
Type "e"
Sleep 1s

# Add new line and write some text
Ctrl+E
Sleep 500ms
Type "Here is some text"
Sleep 500ms
Enter
Sleep 2s

# Show save dialog
Ctrl+S
Sleep 2s
60 changes: 60 additions & 0 deletions demo/console/component-read.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Output images/component-defn-console-read.gif

Require lula
Set FontSize 14
Set Width 1850
Set Height 925
Set Framerate 24
Set Padding 5

Hide
Type "lula console -f ./src/test/unit/common/oscal/valid-multi-component-validations.yaml" Enter
Sleep 1s
Show

# Show the component picker
Right
Sleep 500ms
Enter
Sleep 500ms
Down
Sleep 500ms
Up
Sleep 1s
Enter
Sleep 1s

# Show the framework picker
Right
Sleep 500ms
Enter
Sleep 1s
Enter
Sleep 1s

# Navigate to a control and toggle though fields
Right
Sleep 500ms
Down
Sleep 500ms
Enter
Sleep 1s
Right
Sleep 500ms
Down
Sleep 500ms
Down
Sleep 500ms
Up
Sleep 500ms
Up
Sleep 500ms
Right
Sleep 1s
Right
Sleep 2s

# Quit + confirm
Ctrl+c
Sleep 2s
Enter
23 changes: 17 additions & 6 deletions docs/console/component-definition.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
# Component Definition

The Component Definition view currently allows for a read-only experience of the OSCAL Component Definition model. The view is tailored to the usage of the Component Definition in the context of Lula, and is not intended to be a comprehensive view of the model.
The Component Definition view currently allows for a read and limited write experience of the OSCAL Component Definition model. The view is tailored to the usage of the Component Definition in the context of Lula, and is not intended to be a comprehensive view of the model.

## Usage

To view an OSCAL Component Definition model in the Console:
```shell
lula console -f /path/to/oscal-component.yaml
```
The `oscal-component.yaml` will need to be a valid OSCAL model - to use with the Component Definition view, it must contain the `component-definition` top level key.

## Keys

The Component Definition model responds to the following keys for navigation and interaction:
The Component Definition model responds to the following keys for navigation and interaction (some widgets have additional key response, see respective help views for more information):

| Key | Description |
|-----|-------------|
Expand All @@ -21,12 +22,22 @@ The Component Definition model responds to the following keys for navigation and
| `shift+tab` | Tab left between models |
| `←/h` | Navigate left in model|
| `→/l` | Navigate right in model |
| `↑/k` | Move up in list OR scroll up |
| `↓/j` | Move down in list OR scroll down |
| `↑/k` | Move up in list OR scroll up in panel |
| `↓/j` | Move down in list OR scroll up in panel |
| `/` | Filter list |
| `` | Select item |
| `e` | Edit available fields (remarks and description) |
| `ctrl+s` | Save changes (Note: this will overwrite the original file) |
| `esc` | Cancel |

## View
During console viewing, the top-right corner will display the help keys availble in the context of the selected widget. When an overlay is open, the help keys will be displayed in the overlay.

<img align="right" src="../../images/component-defn-console.gif" alt="component definition console" style="width:100%; height:auto;">
## Views

### Read-Only Navigation

<img align="right" src="../../images/component-defn-console-read.gif" alt="component definition console read" style="width:100%; height:auto;">

### Editing Remarks and Description

<img align="right" src="../../images/component-defn-console-edit.gif" alt="component definition console edit" style="width:100%; height:auto;">
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ require (
github.com/charmbracelet/bubbles v0.20.0
github.com/charmbracelet/bubbletea v1.1.1
github.com/charmbracelet/lipgloss v0.13.0
github.com/charmbracelet/x/exp/teatest v0.0.0-20240918160051-227168dc0568
github.com/charmbracelet/x/exp/teatest v0.0.0-20240919170804-a4978c8e603a
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
github.com/defenseunicorns/go-oscal v0.6.0
github.com/defenseunicorns/pkg/helpers v1.1.3
github.com/hashicorp/go-version v1.7.0
Expand Down Expand Up @@ -47,12 +48,11 @@ require (
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/charmbracelet/x/ansi v0.2.3 // indirect
github.com/charmbracelet/x/exp/golden v0.0.0-20240904165849-e8e43e13f84b // indirect
github.com/charmbracelet/x/ansi v0.3.2 // indirect
github.com/charmbracelet/x/exp/golden v0.0.0-20240919170804-a4978c8e603a // indirect
github.com/charmbracelet/x/term v0.2.0 // indirect
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/daviddengcn/go-colortext v1.0.0 // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.2 // indirect
Expand Down
10 changes: 8 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,16 @@ github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA
github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqosGDEY=
github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/exp/golden v0.0.0-20240904165849-e8e43e13f84b h1:RgxGYl8ddy5ozXS6ZXcfkMynPzwReLeS54Xy1PBXoNo=
github.com/charmbracelet/x/exp/golden v0.0.0-20240904165849-e8e43e13f84b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
github.com/charmbracelet/x/ansi v0.3.2 h1:wsEwgAN+C9U06l9dCVMX0/L3x7ptvY1qmjMwyfE6USY=
github.com/charmbracelet/x/ansi v0.3.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b h1:MnAMdlwSltxJyULnrYbkZpp4k58Co7Tah3ciKhSNo0Q=
github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
github.com/charmbracelet/x/exp/golden v0.0.0-20240919170804-a4978c8e603a h1:IUy+N6nKpGfijckOe8KGnAQwBUT6xz63n3tbb0Gy8aY=
github.com/charmbracelet/x/exp/golden v0.0.0-20240919170804-a4978c8e603a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
github.com/charmbracelet/x/exp/teatest v0.0.0-20240918160051-227168dc0568 h1:MWPyZsxZMe/oKhkt5j34zAba/2nXOxWuf3CvQqO8SDA=
github.com/charmbracelet/x/exp/teatest v0.0.0-20240918160051-227168dc0568/go.mod h1:NDRRSMP6bZbCs4jyc4i1/4UG4M+0PEiQdpivQgD0Mio=
github.com/charmbracelet/x/exp/teatest v0.0.0-20240919170804-a4978c8e603a h1:sS42HbmCab8rCehUwNO/bQEZQoJ6GavhZyO+245mBwA=
github.com/charmbracelet/x/exp/teatest v0.0.0-20240919170804-a4978c8e603a/go.mod h1:NDRRSMP6bZbCs4jyc4i1/4UG4M+0PEiQdpivQgD0Mio=
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
Expand Down
Binary file added images/component-defn-console-edit.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/component-defn-console-read.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed images/component-defn-console.gif
Binary file not shown.
7 changes: 4 additions & 3 deletions src/cmd/console/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,16 @@ var consoleCmd = &cobra.Command{

// Add debugging
// TODO: need to integrate with the log file handled by messages
var dumpFile *os.File
if message.GetLogLevel() == message.DebugLevel {
f, err := tea.LogToFile("debug.log", "debug")
dumpFile, err = os.OpenFile("debug.log", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o644)
if err != nil {
message.Fatalf(err, err.Error())
}
defer f.Close()
defer dumpFile.Close()
}

p := tea.NewProgram(tui.NewOSCALModel(oscalModel), tea.WithAltScreen(), tea.WithMouseCellMotion())
p := tea.NewProgram(tui.NewOSCALModel(oscalModel, opts.InputFile, dumpFile), tea.WithAltScreen(), tea.WithMouseCellMotion())

if _, err := p.Run(); err != nil {
message.Fatalf(err, err.Error())
Expand Down
34 changes: 34 additions & 0 deletions src/internal/testhelpers/testhelpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package testhelpers

import (
"fmt"
"os"
"testing"

oscalTypes_1_1_2 "github.com/defenseunicorns/go-oscal/src/types/oscal-1-1-2"
"github.com/defenseunicorns/lula/src/pkg/common/oscal"
)

func OscalFromPath(t *testing.T, path string) *oscalTypes_1_1_2.OscalCompleteSchema {
t.Helper()
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("error reading file: %v", err)
}
oscalModel, err := oscal.NewOscalModel(data)
if err != nil {
t.Fatalf("error creating oscal model from file: %v", err)
}

return oscalModel
}

func CreateTempFile(t *testing.T, ext string) *os.File {
t.Helper()
tempFile, err := os.CreateTemp("", fmt.Sprintf("tmp-*.%s", ext))
if err != nil {
t.Fatalf("failed to create temp file: %v", err)
}

return tempFile
}
18 changes: 11 additions & 7 deletions src/internal/tui/assessment_results/assessment-results.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"regexp"
"strings"

"github.com/charmbracelet/bubbles/help"
"github.com/charmbracelet/bubbles/key"
blist "github.com/charmbracelet/bubbles/list"
"github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea"
Expand Down Expand Up @@ -75,9 +75,13 @@ func NewAssessmentResultsModel(assessmentResults *oscalTypes_1_1_2.AssessmentRes
observationSummary := viewport.New(width, height)
observationSummary.Style = common.PanelStyle

help := common.NewHelpModel(false)
help.OneLine = true
help.ShortHelp = []key.Binding{assessmentHotkeys.Help}

return Model{
keys: assessmentHotkeys,
help: help.New(),
help: help,
results: results,
resultsPicker: resultsPicker,
selectedResult: selectedResult,
Expand Down Expand Up @@ -183,7 +187,7 @@ func (m Model) View() string {
func (m Model) mainView() string {
// Add help panel at the top left
helpStyle := common.HelpStyle(m.width)
helpView := helpStyle.Render(m.help.View(m.keys))
helpView := helpStyle.Render(m.help.View())

// Add viewport styles
focusedViewport := common.PanelStyle.BorderForeground(common.Focused)
Expand Down Expand Up @@ -252,9 +256,9 @@ func (m Model) mainView() string {
}

func (m Model) updateViewportContent(resultType string) string {
helpStyle := common.HelpStyle(pickerWidth)
helpView := helpStyle.Render(help.New().View(common.PickerHotkeys))

// TODO: refactor this to use the PiickerModel
help := common.NewHelpModel(true)
help.ShortHelp = common.ShortHelpPicker
s := strings.Builder{}
s.WriteString(fmt.Sprintf("Select a result to %s:\n\n", resultType))

Expand All @@ -268,7 +272,7 @@ func (m Model) updateViewportContent(resultType string) string {
s.WriteString("\n")
}

return lipgloss.JoinVertical(lipgloss.Top, helpView, s.String())
return lipgloss.JoinVertical(lipgloss.Top, s.String(), help.View())
}

func (m Model) renderSummary() string {
Expand Down
32 changes: 10 additions & 22 deletions src/internal/tui/assessment_results/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ type keys struct {
}

var assessmentHotkeys = keys{
Quit: common.CommonHotkeys.Quit,
Help: common.CommonHotkeys.Help,
Quit: common.CommonKeys.Quit,
Help: common.CommonKeys.Help,
Validate: key.NewBinding(
key.WithKeys("v"),
key.WithHelp("v", "validate"),
Expand All @@ -31,26 +31,14 @@ var assessmentHotkeys = keys{
key.WithKeys("e"),
key.WithHelp("e", "evaluate"),
),
Confirm: common.PickerHotkeys.Confirm,
Cancel: common.PickerHotkeys.Cancel,
Navigation: key.NewBinding(
key.WithKeys("left", "h", "right", "l"),
key.WithHelp("←/h, →/l", "navigation"),
),
NavigateLeft: key.NewBinding(
key.WithKeys("left", "h"),
key.WithHelp("←/h", "navigate left"),
),
NavigateRight: key.NewBinding(
key.WithKeys("right", "l"),
key.WithHelp("→/l", "navigate right"),
),
SwitchModels: key.NewBinding(
key.WithKeys("tab", "shift+tab"),
key.WithHelp("tab/shift+tab", "switch models"),
),
Up: common.PickerHotkeys.Up,
Down: common.PickerHotkeys.Down,
Confirm: common.CommonKeys.Confirm,
Cancel: common.CommonKeys.Cancel,
Navigation: common.CommonKeys.Navigation,
NavigateLeft: common.CommonKeys.NavigateLeft,
NavigateRight: common.CommonKeys.NavigateRight,
SwitchModels: common.CommonKeys.NavigateModels,
Up: common.PickerKeys.Up,
Down: common.PickerKeys.Down,
}

func (k keys) ShortHelp() []key.Binding {
Expand Down
3 changes: 1 addition & 2 deletions src/internal/tui/assessment_results/types.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package assessmentresults

import (
"github.com/charmbracelet/bubbles/help"
blist "github.com/charmbracelet/bubbles/list"
"github.com/charmbracelet/bubbles/viewport"
oscalTypes_1_1_2 "github.com/defenseunicorns/go-oscal/src/types/oscal-1-1-2"
Expand All @@ -10,7 +9,7 @@ import (

type Model struct {
open bool
help help.Model
help common.HelpModel
keys keys
focus focus
inResultOverlay bool
Expand Down
Loading

0 comments on commit ae06e27

Please sign in to comment.