Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Don Johnson committed May 13, 2024
1 parent 2e759ce commit c00a502
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 1 deletion.
35 changes: 35 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Release

on:
push:
tags:
- 'v*'

jobs:
build:
name: Build and Release
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: '^1.21'

- name: Build binaries for all platforms
run: |
GOOS=windows GOARCH=amd64 go build -o jsonviz-windows-amd64.exe
GOOS=linux GOARCH=amd64 go build -o jsonviz-linux-amd64
GOOS=darwin GOARCH=amd64 go build -o jsonviz-darwin-amd64
- name: Upload releases
uses: softprops/action-gh-release@v1
with:
files: |
jsonviz-windows-amd64.exe
jsonviz-linux-amd64
jsonviz-darwin-amd64
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58 changes: 57 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,58 @@
# jsonviz
visualize json files in the terminal

`jsonviz` is a command-line tool built in Go that visualizes JSON file structures in a navigable tree format using the `termui` library. This tool is designed to help developers and data scientists quickly understand and explore the structure of complex JSON data from the terminal.

## Features

- **Interactive Tree View**: Display JSON files as expandable and collapsible trees.
- **Color Coding**: Different colors for root, keys, and values to enhance readability.
- **Keyboard Navigation**: Use keyboard shortcuts to navigate through the JSON structure.
- **Resizable UI**: Adapt to terminal size changes dynamically.

## Installation

To install `jsonviz`, clone this repository and build the tool using Go.

```bash
git clone https://github.com/copyleftdev/jsonviz.git
cd jsonviz
go build
```

## Usage

After building the tool, you can run it by specifying the JSON file you want to visualize:

```bash
./jsonviz path/to/your/file.json
```

### Keyboard Shortcuts

- **Arrow Up (`k`)**: Move up in the tree.
- **Arrow Down (`j`)**: Move down in the tree.
- **Enter**: Expand or collapse the selected node.
- **CTRL+C**: Exit the application.

## Requirements

- Go 1.15 or higher
- `termui` library (automatically installed with go get)

## Contributing

Contributions are welcome! Feel free to submit pull requests, create issues for bugs you've found, or suggest new features.

1. Fork the repository.
2. Create your feature branch (`git checkout -b feature/fooBar`).
3. Commit your changes (`git commit -am 'Add some fooBar'`).
4. Push to the branch (`git push origin feature/fooBar`).
5. Create a new Pull Request.

## License

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE) file for details.

## Contact

- GitHub: [@copyleftdev](https://github.com/copyleftdev)
124 changes: 124 additions & 0 deletions jsonviz.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package main

import (
"encoding/json"
"fmt"
"io"
"log"
"os"

ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
)

type nodeValue struct {
Key string
Value interface{}
}

var (
rootStyle = ui.NewStyle(ui.ColorGreen)
keyStyle = ui.NewStyle(ui.ColorGreen)
valueStyle = ui.NewStyle(ui.ColorWhite)
selectedStyle = ui.NewStyle(ui.ColorYellow, ui.ColorClear, ui.ModifierBold) // Correctly apply style with modifiers
)

func (nv nodeValue) String() string {
if nv.Key == "root" {
return fmt.Sprintf("[%s](fg:green)", nv.Key)
}
switch v := nv.Value.(type) {
case string, float64, bool, int:
return fmt.Sprintf("[%s: %v](fg:white)", nv.Key, v)
default:
return fmt.Sprintf("[%s](fg:green)", nv.Key)
}
}

func parseJSONToTree(key string, data interface{}) *widgets.TreeNode {
node := &widgets.TreeNode{
Value: nodeValue{Key: key},
}

switch v := data.(type) {
case map[string]interface{}:
children := []*widgets.TreeNode{}
for k, val := range v {
child := parseJSONToTree(k, val)
children = append(children, child)
}
node.Nodes = children
case []interface{}:
children := []*widgets.TreeNode{}
for i, val := range v {
child := parseJSONToTree(fmt.Sprintf("%s[%d]", key, i), val)
children = append(children, child)
}
node.Nodes = children
default:
node.Value = nodeValue{Key: key, Value: v}
}

return node
}

func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: jsonviz [filename]")
os.Exit(1)
}

filename := os.Args[1]

fmt.Println("Initializing UI... Press CTRL+C to exit.")

if err := ui.Init(); err != nil {
log.Fatalf("failed to initialize termui: %v", err)
}
defer ui.Close()

jsonFile, err := os.Open(filename)
if err != nil {
log.Fatalf("failed to open JSON file: %v", err)
}
defer jsonFile.Close()

byteValue, _ := io.ReadAll(jsonFile)

var result interface{}
json.Unmarshal(byteValue, &result)

root := parseJSONToTree("root", result)
tree := widgets.NewTree()
tree.Title = "JSON Visualizer (Press CTRL+C to exit)"
tree.TextStyle = ui.NewStyle(ui.ColorWhite)
tree.SelectedRowStyle = selectedStyle
tree.WrapText = false
tree.SetNodes([]*widgets.TreeNode{root})

x, y := ui.TerminalDimensions()
tree.SetRect(0, 0, x, y)

ui.Render(tree)

uiEvents := ui.PollEvents()
for {
e := <-uiEvents
switch e.ID {
case "q", "<C-c>":
return
case "j", "<Down>":
tree.ScrollDown()
case "k", "<Up>":
tree.ScrollUp()
case "<Enter>":
tree.ToggleExpand()
case "<Resize>":
x, y := ui.TerminalDimensions()
tree.SetRect(0, 0, x, y)
ui.Render(tree)
}

ui.Render(tree)
}
}

0 comments on commit c00a502

Please sign in to comment.