-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Don Johnson
committed
May 13, 2024
1 parent
2e759ce
commit c00a502
Showing
3 changed files
with
216 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} |