/
app.go
110 lines (95 loc) · 3.19 KB
/
app.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Package app provides the root application capabilities for the
// goledger commandline interface.
//
// This includes loading the ledger, tools for printing the ledger,
// and common-configuration across all of goledger.
package app
import (
"fmt"
"github.com/mescanne/goledger/book"
"github.com/mescanne/goledger/loader"
"github.com/spf13/cobra"
"os"
)
const (
custom_func = `
__goledger_handle_noun() {
c=$((c+1))
}
`
)
// Configuration for an Application
type App struct {
Ledger string // Location of ledger file
BaseCCY string // Conversion CCY for reporting
Verbose bool // Verbose modw
Divider string // Default (normally ":")
Colour bool // Use Ansi Colour
All bool // Use all accounts, rather than just accounts with a non-zero balance
Lang string // Language for formatting
}
// Default configuration if none specified
var DefaultApp App = App{
Ledger: "main.ledger",
Verbose: false,
Lang: "en",
Divider: ":",
Colour: true,
All: false,
}
func init() {
l, ok := os.LookupEnv("LANG")
if ok {
DefaultApp.Lang = l
}
}
// Load a book from the configured ledger file
func (app *App) LoadBook() (*book.Book, error) {
bbuilder := book.NewBookBuilder()
if err := loader.ParseFile(bbuilder, app.Ledger); err != nil {
return nil, err
}
b := bbuilder.Build()
return b, nil
}
const version = "0.1"
const goledger_long = `goledger is a text-based accounting.
It is in the same spirit as Plain Text Accounting (https://plaintextaccounting.org/)
and ledger cli (https://www.ledger-cli.org/)
`
// Load the root application cobra command
func (app *App) LoadCommand() *cobra.Command {
var appCmd = &cobra.Command{
Use: "goledger",
Short: "goledger text-based account application",
Long: goledger_long,
BashCompletionFunction: custom_func,
Version: version,
DisableAutoGenTag: true,
SilenceUsage: true,
SilenceErrors: true,
// Prior to the RunE method running, suppress any usage output
// if there is an error -- at this point all CLI syntax-related
// errors should be resolved. This is just for runtime errors.
PersistentPreRun: func(cmd *cobra.Command, args []string) {
cmd.SilenceUsage = true
cmd.SilenceErrors = true
},
}
appCmd.PersistentFlags().StringVarP(&app.Ledger, "ledger", "l", app.Ledger, "ledger to read")
appCmd.PersistentFlags().StringVar(&app.BaseCCY, "ccy", app.BaseCCY, "base currency")
appCmd.PersistentFlags().StringVar(&app.Divider, "divider", app.Divider, "divider for account components for reports")
appCmd.PersistentFlags().StringVar(&app.Lang, "lang", app.Lang, "language")
appCmd.PersistentFlags().BoolVar(&app.Verbose, "verbose", app.Verbose, "verbose")
appCmd.PersistentFlags().BoolVar(&app.Colour, "colour", app.Colour, "colour (ansi) for reports")
appCmd.PersistentFlags().BoolVar(&app.All, "all", app.All, "all accounts, not just non-zero balance")
appCmd.InitDefaultHelpCmd()
appCmd.InitDefaultHelpFlag()
appCmd.InitDefaultVersionFlag()
// This should never happen. Only where ledger isn't a valid flag.
if err := appCmd.MarkFlagFilename("ledger"); err != nil {
fmt.Printf("%v\n", err)
os.Exit(2)
}
return appCmd
}