Inital release of kanbn2md
Renders json output of `kanbn board -j` as a markdown table.
This commit is contained in:
commit
b9acf6cc67
20
.github/workflows/release-please.yml
vendored
Normal file
20
.github/workflows/release-please.yml
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
name: release-please
|
||||
jobs:
|
||||
release-please:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
release_created: ${{ steps.release.outputs.release_created }}
|
||||
steps:
|
||||
- uses: GoogleCloudPlatform/release-please-action@v2
|
||||
id: release
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
release-type: simple
|
||||
bump-minor-pre-major: Yes
|
||||
package-name: kanbn2md
|
||||
|
||||
|
20
.gitignore
vendored
Normal file
20
.gitignore
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
#### joe made this: http://goel.io/joe
|
||||
|
||||
#### go ####
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
.kanbn
|
27
README.md
Normal file
27
README.md
Normal file
@ -0,0 +1,27 @@
|
||||
# kanbn2md
|
||||
|
||||
[Kanbn](https://github.com/basementuniverse/kanbn) is a CLI Kanban board. It stores
|
||||
the task information in markdown format and has a [vscode extension](https://github.com/basementuniverse/vscode-kanbn)
|
||||
for viewing and editing the board from vscode. What is missing is a way to render the board as a markdown table.
|
||||
This simple program takes JSON output of `kanbn board -j` on stdin and renders a markdown table on stdout.
|
||||
|
||||
## Installation
|
||||
|
||||
Download a binary from the releases page or install via go with
|
||||
|
||||
```bash
|
||||
go install github.com/tjdavis3/kanbn2md
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
kanbn board -j | kanbn2md > board.md
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
| Backlog | Todo | In Progress | Done |
|
||||
| --- | --- | --- | --- |
|
||||
| Comment the code | Create github repo | Create a README.md | Build app |
|
||||
| Add tests | Add error handling | | |
|
114
main.go
Normal file
114
main.go
Normal file
@ -0,0 +1,114 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
// KanbnColumns are the board columns as represented in the kanbn json
|
||||
type KanbnColumns [][]struct {
|
||||
Column string `json:"column"`
|
||||
Comments []interface{} `json:"comments"`
|
||||
Description string `json:"description"`
|
||||
ID string `json:"id"`
|
||||
Metadata struct {
|
||||
Assigned string `json:"assigned"`
|
||||
Created string `json:"created"`
|
||||
Progress int `json:"progress"`
|
||||
Started *string `json:"started,omitempty"`
|
||||
Tags []interface{} `json:"tags"`
|
||||
Updated string `json:"updated"`
|
||||
} `json:"metadata"`
|
||||
Name string `json:"name"`
|
||||
Progress int `json:"progress"`
|
||||
Relations []interface{} `json:"relations"`
|
||||
RemainingWorkload int `json:"remainingWorkload"`
|
||||
SubTasks []struct {
|
||||
Completed bool `json:"completed"`
|
||||
Text string `json:"text"`
|
||||
} `json:"subTasks"`
|
||||
Workload int `json:"workload"`
|
||||
}
|
||||
|
||||
// KanbnBoard represents the JSON output of `kanbn board -j`
|
||||
type KanbnBoard struct {
|
||||
Headings []struct {
|
||||
Heading string `json:"heading"`
|
||||
Name string `json:"name"`
|
||||
} `json:"headings"`
|
||||
Lanes []struct {
|
||||
Columns KanbnColumns `json:"columns"`
|
||||
Name string `json:"name"`
|
||||
} `json:"lanes"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
err := renderBoard(os.Stdin, os.Stdout)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// renderBoard takes care of reading the kanbn json
|
||||
// and rendering it as a markdown table
|
||||
func renderBoard(r io.Reader, w io.Writer) error {
|
||||
var kanbn KanbnBoard
|
||||
var rows [][]string
|
||||
board, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = json.Unmarshal(board, &kanbn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Determine how many columns exists and print the header row
|
||||
columnCount := len(kanbn.Headings)
|
||||
for _, col := range kanbn.Headings {
|
||||
fmt.Fprintf(w, "| %s ", col.Name)
|
||||
}
|
||||
fmt.Fprintln(w, "|")
|
||||
for i := 0; i < columnCount; i++ {
|
||||
fmt.Fprint(w, "| --- ")
|
||||
}
|
||||
fmt.Fprintln(w, "|")
|
||||
|
||||
// read the swimlanes
|
||||
// The lanes themselves are not printed on the table
|
||||
for _, lane := range kanbn.Lanes {
|
||||
maxRows := determineMaxRows(lane.Columns)
|
||||
// initialize an array of rows
|
||||
rows = make([][]string, maxRows)
|
||||
for i := range rows {
|
||||
rows[i] = make([]string, columnCount)
|
||||
}
|
||||
// convert columns of rows into rows of columns
|
||||
for curCol, column := range lane.Columns {
|
||||
for colRow, task := range column {
|
||||
rows[colRow][curCol] = task.Name
|
||||
}
|
||||
}
|
||||
// print the rows
|
||||
for _, row := range rows {
|
||||
for _, col := range row {
|
||||
fmt.Fprintf(w, "| %s ", col)
|
||||
}
|
||||
fmt.Fprintln(w, "|")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func determineMaxRows(cols KanbnColumns) int {
|
||||
var maxRows int
|
||||
for _, column := range cols {
|
||||
if len(column) > maxRows {
|
||||
maxRows = len(column)
|
||||
}
|
||||
}
|
||||
return maxRows
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user