Merge pull request #65 from cenkalti/package2

Convert to importable package
This commit is contained in:
2025-12-15 07:36:54 -06:00
committed by GitHub
13 changed files with 117 additions and 85 deletions
+2 -2
View File
@@ -27,8 +27,8 @@ build
# Binaries # Binaries
*.exe *.exe
boltbrowser /boltbrowser
boltbrowser.* /boltbrowser.*
# Test Database # Test Database
test.db test.db
@@ -1,4 +1,4 @@
package main package boltbrowser
import ( import (
"errors" "errors"
+1 -1
View File
@@ -1,4 +1,4 @@
package main package boltbrowser
type Cursor struct { type Cursor struct {
x int x int
+79
View File
@@ -0,0 +1,79 @@
package boltbrowser
import (
"fmt"
"os"
"time"
"github.com/nsf/termbox-go"
"go.etcd.io/bbolt"
)
var ProgramName = "boltbrowser"
var VersionNum = 2.0
var AppArgs Args
var databaseFiles []string
var db *bbolt.DB
var memBolt *BoltDB
var currentFilename string
const DefaultDBOpenTimeout = time.Second
type Args struct {
DBOpenTimeout time.Duration
ReadOnly bool
NoValue bool
}
func DefaultArgs() Args {
return Args{
DBOpenTimeout: DefaultDBOpenTimeout,
}
}
func Main(args Args, files []string) error {
// Set the global args. This is done to convert main package into a library with minimal changes.
AppArgs, databaseFiles = args, files
var err error
err = termbox.Init()
if err != nil {
return err
}
defer termbox.Close()
style := defaultStyle()
termbox.SetOutputMode(termbox.Output256)
for _, databaseFile := range databaseFiles {
currentFilename = databaseFile
db, err = bbolt.Open(databaseFile, 0600, &bbolt.Options{Timeout: AppArgs.DBOpenTimeout})
if err == bbolt.ErrTimeout {
termbox.Close()
fmt.Printf("File %s is locked. Make sure it's not used by another app and try again\n", databaseFile)
os.Exit(1)
} else if err != nil {
if len(databaseFiles) > 1 {
mainLoop(nil, style)
continue
} else {
termbox.Close()
fmt.Printf("Error reading file: %q\n", err.Error())
os.Exit(1)
}
}
// First things first, load the database into memory
memBolt.refreshDatabase()
if AppArgs.ReadOnly {
// If we're opening it in readonly mode, close it now
db.Close()
}
// Kick off the UI loop
mainLoop(memBolt, style)
defer db.Close()
}
return nil
}
@@ -1,7 +1,7 @@
//go:build !windows //go:build !windows
// +build !windows // +build !windows
package main package boltbrowser
import ( import (
"os" "os"
@@ -1,6 +1,6 @@
//go:build windows //go:build windows
package main package boltbrowser
// Windows doesn't support process backgrounding like *nix. // Windows doesn't support process backgrounding like *nix.
// So we have a separate loop for it. // So we have a separate loop for it.
+1 -1
View File
@@ -1,4 +1,4 @@
package main package boltbrowser
import "github.com/nsf/termbox-go" import "github.com/nsf/termbox-go"
@@ -1,4 +1,4 @@
package main package boltbrowser
import ( import (
"fmt" "fmt"
@@ -1,4 +1,4 @@
package main package boltbrowser
import ( import (
"encoding/json" "encoding/json"
@@ -1,4 +1,4 @@
package main package boltbrowser
import ( import (
"encoding/binary" "encoding/binary"
+1 -1
View File
@@ -1,4 +1,4 @@
package main package boltbrowser
import "github.com/nsf/termbox-go" import "github.com/nsf/termbox-go"
+18 -74
View File
@@ -7,33 +7,20 @@ import (
"strings" "strings"
"time" "time"
"github.com/nsf/termbox-go" "github.com/br0xen/boltbrowser/pkg/boltbrowser"
"go.etcd.io/bbolt"
) )
var ProgramName = "boltbrowser" func main() {
var VersionNum = 2.0 args := boltbrowser.DefaultArgs()
files := parseArgs(&args)
var databaseFiles []string err := boltbrowser.Main(args, files)
var db *bbolt.DB if err != nil {
var memBolt *BoltDB fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
var currentFilename string }
const DefaultDBOpenTimeout = time.Second
var AppArgs struct {
DBOpenTimeout time.Duration
ReadOnly bool
NoValue bool
} }
func init() { func parseArgs(args *boltbrowser.Args) (databaseFiles []string) {
AppArgs.DBOpenTimeout = DefaultDBOpenTimeout
AppArgs.ReadOnly = false
}
func parseArgs() {
var err error var err error
if len(os.Args) == 1 { if len(os.Args) == 1 {
printUsage(nil) printUsage(nil)
@@ -51,10 +38,10 @@ func parseArgs() {
key, val := pts[0], pts[1] key, val := pts[0], pts[1]
switch key { switch key {
case "-timeout": case "-timeout":
AppArgs.DBOpenTimeout, err = time.ParseDuration(val) args.DBOpenTimeout, err = time.ParseDuration(val)
if err != nil { if err != nil {
// See if we can successfully parse by adding a 's' // See if we can successfully parse by adding a 's'
AppArgs.DBOpenTimeout, err = time.ParseDuration(val + "s") args.DBOpenTimeout, err = time.ParseDuration(val + "s")
} }
// If err is still not nil, print usage // If err is still not nil, print usage
if err != nil { if err != nil {
@@ -62,11 +49,11 @@ func parseArgs() {
} }
case "-readonly", "-ro": case "-readonly", "-ro":
if val == "true" { if val == "true" {
AppArgs.ReadOnly = true args.ReadOnly = true
} }
case "-no-value": case "-no-value":
if val == "true" { if val == "true" {
AppArgs.NoValue = true args.NoValue = true
} }
case "-help": case "-help":
printUsage(nil) printUsage(nil)
@@ -77,9 +64,9 @@ func parseArgs() {
// Single-word arguments // Single-word arguments
switch parms[i] { switch parms[i] {
case "-readonly", "-ro": case "-readonly", "-ro":
AppArgs.ReadOnly = true args.ReadOnly = true
case "-no-value": case "-no-value":
AppArgs.NoValue = true args.NoValue = true
case "-help": case "-help":
printUsage(nil) printUsage(nil)
default: default:
@@ -87,58 +74,15 @@ func parseArgs() {
} }
} }
} }
return
} }
func printUsage(err error) { func printUsage(err error) {
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, err.Error()) fmt.Fprintf(os.Stderr, err.Error())
} }
fmt.Fprintf(os.Stderr, "Usage: %s [OPTIONS] <filename(s)>\nOptions:\n", ProgramName) fmt.Fprintf(os.Stderr, "Usage: boltbrowser [OPTIONS] <filename(s)>\nOptions:\n")
fmt.Fprintf(os.Stderr, " -timeout=duration\n DB file open timeout (default 1s)\n") fmt.Fprintf(os.Stderr, " -timeout=duration\n DB file open timeout (default 1s)\n")
fmt.Fprintf(os.Stderr, " -ro, -readonly \n Open the DB in read-only mode\n") fmt.Fprintf(os.Stderr, " -ro, -readonly \n Open the DB in read-only mode\n")
fmt.Fprintf(os.Stderr, " -no-value \n Do not display a value in left pane\n") fmt.Fprintf(os.Stderr, " -no-value \n Do not display a value in left pane\n")
} }
func main() {
var err error
parseArgs()
err = termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
style := defaultStyle()
termbox.SetOutputMode(termbox.Output256)
for _, databaseFile := range databaseFiles {
currentFilename = databaseFile
db, err = bbolt.Open(databaseFile, 0600, &bbolt.Options{Timeout: AppArgs.DBOpenTimeout})
if err == bbolt.ErrTimeout {
termbox.Close()
fmt.Printf("File %s is locked. Make sure it's not used by another app and try again\n", databaseFile)
os.Exit(1)
} else if err != nil {
if len(databaseFiles) > 1 {
mainLoop(nil, style)
continue
} else {
termbox.Close()
fmt.Printf("Error reading file: %q\n", err.Error())
os.Exit(1)
}
}
// First things first, load the database into memory
memBolt.refreshDatabase()
if AppArgs.ReadOnly {
// If we're opening it in readonly mode, close it now
db.Close()
}
// Kick off the UI loop
mainLoop(memBolt, style)
defer db.Close()
}
}
+9
View File
@@ -0,0 +1,9 @@
package boltbrowser
import internal "github.com/br0xen/boltbrowser/internal/boltbrowser"
type Args = internal.Args
var DefaultArgs = internal.DefaultArgs
var Main = internal.Main