Browse Source

restructured and separated cli stuffs

master
Loki Verloren 4 months ago
parent
commit
98777620f6

+ 2
- 1
.gitignore View File

@@ -17,4 +17,5 @@ test/config
17 17
 test/**
18 18
 bin/*
19 19
 .*
20
-!/.gitignore
20
+!/.gitignore
21
+9

+ 0
- 2
cmd/.gitignore View File

@@ -1,2 +0,0 @@
1
-main
2
-config

+ 2
- 1
cmd/app/appconf.go View File

@@ -1,13 +1,14 @@
1 1
 package app
2 2
 
3 3
 import (
4
+	"git.parallelcoin.io/dev/9/cmd/def"
4 5
 	"git.parallelcoin.io/dev/9/cmd/nine"
5 6
 	"git.parallelcoin.io/dev/9/cmd/node"
6 7
 )
7 8
 
8 9
 // MakeConfig links the configuration from the Cats to the Config used by all of
9 10
 // the suite
10
-func MakeConfig(c *App) (out *nine.Config) {
11
+func MakeConfig(c *def.App) (out *nine.Config) {
11 12
 	C := c.Cats
12 13
 	var configFile string
13 14
 	var tn, sn, rn bool

+ 126
- 243
cmd/app/generators.go View File

@@ -1,16 +1,15 @@
1 1
 package app
2 2
 
3 3
 import (
4
-	"encoding/json"
5 4
 	"fmt"
6 5
 	"math/rand"
7
-	"os"
8 6
 	"path/filepath"
9 7
 	"reflect"
10 8
 	"regexp"
11 9
 	"strconv"
12 10
 	"time"
13 11
 
12
+	"git.parallelcoin.io/dev/9/cmd/def"
14 13
 	"git.parallelcoin.io/dev/9/cmd/nine"
15 14
 	"git.parallelcoin.io/dev/9/pkg/ifc"
16 15
 	"git.parallelcoin.io/dev/9/pkg/util"
@@ -33,15 +32,15 @@ var NetParams = map[string]*nine.Params{
33 32
 }
34 33
 
35 34
 // NewApp generates a new App using a collection of generator functions passed to it
36
-func NewApp(name string, g ...AppGenerator) (out *App) {
37
-	gen := AppGenerators(g)
38
-	out = &App{
35
+func NewApp(name string, g ...def.AppGenerator) (out *def.App) {
36
+	gen := def.AppGenerators(g)
37
+	out = &def.App{
39 38
 		Name:     name,
40
-		Cats:     make(Cats),
41
-		Commands: make(Commands),
39
+		Cats:     make(def.Cats),
40
+		Commands: make(def.Commands),
42 41
 	}
43 42
 	gen.RunAll(out)
44
-	// set ref to App in each Row
43
+	// set ref to App in each def.Row
45 44
 	for _, x := range out.Cats {
46 45
 		for _, y := range x {
47 46
 			y.App = out
@@ -53,8 +52,8 @@ func NewApp(name string, g ...AppGenerator) (out *App) {
53 52
 // which is made from
54 53
 
55 54
 // Version fills the Version field of an App
56
-func Version(ver string) AppGenerator {
57
-	return func(ctx *App) {
55
+func Version(ver string) def.AppGenerator {
56
+	return func(ctx *def.App) {
58 57
 		ctx.Version = func() string {
59 58
 			return ver
60 59
 		}
@@ -62,86 +61,86 @@ func Version(ver string) AppGenerator {
62 61
 }
63 62
 
64 63
 // Tagline is a short text describing the application
65
-func Tagline(ver string) AppGenerator {
66
-	return func(ctx *App) {
64
+func Tagline(ver string) def.AppGenerator {
65
+	return func(ctx *def.App) {
67 66
 		ctx.Tagline = ver
68 67
 	}
69 68
 }
70 69
 
71 70
 // About is a longer text describing the application
72
-func About(ver string) AppGenerator {
73
-	return func(ctx *App) {
71
+func About(ver string) def.AppGenerator {
72
+	return func(ctx *def.App) {
74 73
 		ctx.About = ver
75 74
 	}
76 75
 }
77 76
 
78 77
 // DefaultRunner is the command that runs when no parameters are given
79
-func DefaultRunner(fn func(ctx *App) int) AppGenerator {
80
-	return func(ctx *App) {
78
+func DefaultRunner(fn func(ctx *def.App) int) def.AppGenerator {
79
+	return func(ctx *def.App) {
81 80
 		ctx.Default = fn
82 81
 	}
83 82
 }
84 83
 
85 84
 // Group is a collection of categories and bundles each category
86
-func Group(name string, g ...CatGenerator) AppGenerator {
87
-	G := CatGenerators(g)
88
-	return func(ctx *App) {
89
-		ctx.Cats[name] = make(Cat)
85
+func Group(name string, g ...def.CatGenerator) def.AppGenerator {
86
+	G := def.CatGenerators(g)
87
+	return func(ctx *def.App) {
88
+		ctx.Cats[name] = make(def.Cat)
90 89
 		G.RunAll(ctx.Cats[name])
91 90
 	}
92 91
 }
93 92
 
94 93
 // Cmd is a collection of subcommands
95
-func Cmd(name string, g ...CommandGenerator) AppGenerator {
96
-	G := CommandGenerators(g)
97
-	return func(ctx *App) {
94
+func Cmd(name string, g ...def.CommandGenerator) def.AppGenerator {
95
+	G := def.CommandGenerators(g)
96
+	return func(ctx *def.App) {
98 97
 		ctx.Commands[name] = G.RunAll()
99 98
 	}
100 99
 }
101 100
 
102
-// Command Item Generators
101
+// def.Command Item Generators
103 102
 
104 103
 // Pattern is the regular expression pattern that matches the CLI args for each
105
-// Command item
106
-func Pattern(patt string) CommandGenerator {
107
-	return func(ctx *Command) {
104
+// def.Command item
105
+func Pattern(patt string) def.CommandGenerator {
106
+	return func(ctx *def.Command) {
108 107
 		ctx.Pattern = patt
109 108
 		ctx.RE = regexp.MustCompile(ctx.Pattern)
110 109
 	}
111 110
 }
112 111
 
113
-// Short is the short help text for a Command
114
-func Short(usage string) CommandGenerator {
115
-	return func(ctx *Command) {
112
+// Short is the short help text for a def.Command
113
+func Short(usage string) def.CommandGenerator {
114
+	return func(ctx *def.Command) {
116 115
 		ctx.Short = usage
117 116
 	}
118 117
 }
119 118
 
120
-// Detail is the long help text for a Command
121
-func Detail(usage string) CommandGenerator {
122
-	return func(ctx *Command) {
119
+// Detail is the long help text for a def.Command
120
+func Detail(usage string) def.CommandGenerator {
121
+	return func(ctx *def.Command) {
123 122
 		ctx.Detail = usage
124 123
 	}
125 124
 }
126 125
 
127
-// Opts is the collection of valid options for a Command
128
-func Opts(opts ...string) CommandGenerator {
129
-	return func(ctx *Command) {
126
+// Opts is the collection of valid options for a def.Command
127
+func Opts(opts ...string) def.CommandGenerator {
128
+	return func(ctx *def.Command) {
130 129
 		ctx.Opts = opts
131 130
 	}
132 131
 }
133 132
 
134 133
 // Precs is the collection of tags for items that are preferentially selected when
135 134
 // an two or more items are specified (for example, help always overrides everything)
136
-func Precs(precs ...string) CommandGenerator {
137
-	return func(ctx *Command) {
135
+func Precs(precs ...string) def.CommandGenerator {
136
+	return func(ctx *def.Command) {
138 137
 		ctx.Precedent = precs
139 138
 	}
140 139
 }
141 140
 
142 141
 // Handler is the function that is called when a command is selected
143
-func Handler(hnd func(args []string, tokens Tokens, app *App) int) CommandGenerator {
144
-	return func(ctx *Command) {
142
+func Handler(hnd func(args []string, tokens def.Tokens, app *def.App) int) def.CommandGenerator {
143
+	return func(ctx *def.Command) {
145 144
 		ctx.Handler = hnd
146 145
 	}
147 146
 }
@@ -149,11 +148,11 @@ func Handler(hnd func(args []string, tokens Tokens, app *App) int) CommandGenera
149 148
 // Group Item Generators
150 149
 
151 150
 // File is an item storing a filename
152
-func File(name string, g ...RowGenerator) CatGenerator {
153
-	G := RowGenerators(g)
154
-	return func(ctx *Cat) {
155
-		c := &Row{}
156
-		c.Init = func(cc *Row) {
151
+func File(name string, g ...def.RowGenerator) def.CatGenerator {
152
+	G := def.RowGenerators(g)
153
+	return func(ctx *def.Cat) {
154
+		c := &def.Row{}
155
+		c.Init = func(cc *def.Row) {
157 156
 			cc.Name = name
158 157
 			cc.Type = "string"
159 158
 			cc.Validate = Valid.File
@@ -178,11 +177,11 @@ func File(name string, g ...RowGenerator) CatGenerator {
178 177
 }
179 178
 
180 179
 // Dir is an item storing a directory specification
181
-func Dir(name string, g ...RowGenerator) CatGenerator {
182
-	G := RowGenerators(g)
183
-	return func(ctx *Cat) {
184
-		c := &Row{}
185
-		c.Init = func(cc *Row) {
180
+func Dir(name string, g ...def.RowGenerator) def.CatGenerator {
181
+	G := def.RowGenerators(g)
182
+	return func(ctx *def.Cat) {
183
+		c := &def.Row{}
184
+		c.Init = func(cc *def.Row) {
186 185
 			cc.Name = name
187 186
 			cc.Type = "string"
188 187
 			cc.Validate = Valid.Dir
@@ -207,11 +206,11 @@ func Dir(name string, g ...RowGenerator) CatGenerator {
207 206
 }
208 207
 
209 208
 // Port is a 16 bit sized number that represents a network port number
210
-func Port(name string, g ...RowGenerator) CatGenerator {
211
-	G := RowGenerators(g)
212
-	return func(ctx *Cat) {
213
-		c := &Row{}
214
-		c.Init = func(cc *Row) {
209
+func Port(name string, g ...def.RowGenerator) def.CatGenerator {
210
+	G := def.RowGenerators(g)
211
+	return func(ctx *def.Cat) {
212
+		c := &def.Row{}
213
+		c.Init = func(cc *def.Row) {
215 214
 			cc.Name = name
216 215
 			cc.Type = "port"
217 216
 			cc.Validate = Valid.Port
@@ -235,11 +234,11 @@ func Port(name string, g ...RowGenerator) CatGenerator {
235 234
 }
236 235
 
237 236
 // Enable is a boolean item that is false by default
238
-func Enable(name string, g ...RowGenerator) CatGenerator {
239
-	G := RowGenerators(g)
240
-	return func(ctx *Cat) {
241
-		c := &Row{}
242
-		c.Init = func(cc *Row) {
237
+func Enable(name string, g ...def.RowGenerator) def.CatGenerator {
238
+	G := def.RowGenerators(g)
239
+	return func(ctx *def.Cat) {
240
+		c := &def.Row{}
241
+		c.Init = func(cc *def.Row) {
243 242
 			cc.Name = name
244 243
 			cc.Type = "bool"
245 244
 			cc.Get = func() interface{} {
@@ -264,11 +263,11 @@ func Enable(name string, g ...RowGenerator) CatGenerator {
264 263
 }
265 264
 
266 265
 // Enabled is an boolean item that is true by default
267
-func Enabled(name string, g ...RowGenerator) CatGenerator {
268
-	G := RowGenerators(g)
269
-	return func(ctx *Cat) {
270
-		c := &Row{}
271
-		c.Init = func(cc *Row) {
266
+func Enabled(name string, g ...def.RowGenerator) def.CatGenerator {
267
+	G := def.RowGenerators(g)
268
+	return func(ctx *def.Cat) {
269
+		c := &def.Row{}
270
+		c.Init = func(cc *def.Row) {
272 271
 			cc.Name = name
273 272
 			cc.Type = "bool"
274 273
 			cc.Get = func() interface{} {
@@ -293,11 +292,11 @@ func Enabled(name string, g ...RowGenerator) CatGenerator {
293 292
 }
294 293
 
295 294
 // Int stores an integer number (signed integer width of current platform's processor)
296
-func Int(name string, g ...RowGenerator) CatGenerator {
297
-	G := RowGenerators(g)
298
-	return func(ctx *Cat) {
299
-		c := &Row{}
300
-		c.Init = func(cc *Row) {
295
+func Int(name string, g ...def.RowGenerator) def.CatGenerator {
296
+	G := def.RowGenerators(g)
297
+	return func(ctx *def.Cat) {
298
+		c := &def.Row{}
299
+		c.Init = func(cc *def.Row) {
301 300
 			cc.Name = name
302 301
 			cc.Type = "int"
303 302
 			cc.Get = func() interface{} {
@@ -320,11 +319,11 @@ func Int(name string, g ...RowGenerator) CatGenerator {
320 319
 }
321 320
 
322 321
 // Tag is basically just a string that can store any string value
323
-func Tag(name string, g ...RowGenerator) CatGenerator {
324
-	G := RowGenerators(g)
325
-	return func(ctx *Cat) {
326
-		c := &Row{}
327
-		c.Init = func(cc *Row) {
322
+func Tag(name string, g ...def.RowGenerator) def.CatGenerator {
323
+	G := def.RowGenerators(g)
324
+	return func(ctx *def.Cat) {
325
+		c := &def.Row{}
326
+		c.Init = func(cc *def.Row) {
328 327
 			cc.Name = name
329 328
 			cc.Type = "string"
330 329
 			cc.Get = func() interface{} {
@@ -347,11 +346,11 @@ func Tag(name string, g ...RowGenerator) CatGenerator {
347 346
 }
348 347
 
349 348
 // Tags is a collection of strings containing arbitrary content
350
-func Tags(name string, g ...RowGenerator) CatGenerator {
351
-	G := RowGenerators(g)
352
-	return func(ctx *Cat) {
353
-		c := &Row{}
354
-		c.Init = func(cc *Row) {
349
+func Tags(name string, g ...def.RowGenerator) def.CatGenerator {
350
+	G := def.RowGenerators(g)
351
+	return func(ctx *def.Cat) {
352
+		c := &def.Row{}
353
+		c.Init = func(cc *def.Row) {
355 354
 			cc.Name = name
356 355
 			cc.Type = "stringslice"
357 356
 			cc.Get = func() interface{} {
@@ -374,11 +373,11 @@ func Tags(name string, g ...RowGenerator) CatGenerator {
374 373
 }
375 374
 
376 375
 // Addr is a network address specification for dialing
377
-func Addr(name string, defPort int, g ...RowGenerator) CatGenerator {
378
-	G := RowGenerators(g)
379
-	return func(ctx *Cat) {
380
-		c := &Row{}
381
-		c.Init = func(cc *Row) {
376
+func Addr(name string, defPort int, g ...def.RowGenerator) def.CatGenerator {
377
+	G := def.RowGenerators(g)
378
+	return func(ctx *def.Cat) {
379
+		c := &def.Row{}
380
+		c.Init = func(cc *def.Row) {
382 381
 			cc.Name = name
383 382
 			cc.Type = "string"
384 383
 			cc.Get = func() interface{} {
@@ -404,11 +403,11 @@ func Addr(name string, defPort int, g ...RowGenerator) CatGenerator {
404 403
 }
405 404
 
406 405
 // Addrs is a collection of addresses
407
-func Addrs(name string, defPort int, g ...RowGenerator) CatGenerator {
408
-	G := RowGenerators(g)
409
-	return func(ctx *Cat) {
410
-		c := &Row{}
411
-		c.Init = func(cc *Row) {
406
+func Addrs(name string, defPort int, g ...def.RowGenerator) def.CatGenerator {
407
+	G := def.RowGenerators(g)
408
+	return func(ctx *def.Cat) {
409
+		c := &def.Row{}
410
+		c.Init = func(cc *def.Row) {
412 411
 			cc.Name = name
413 412
 			cc.Type = "stringslice"
414 413
 			cc.Get = func() interface{} {
@@ -431,12 +430,12 @@ func Addrs(name string, defPort int, g ...RowGenerator) CatGenerator {
431 430
 }
432 431
 
433 432
 // Level is debug logging level specification one of a set of predefined values
434
-func Level(g ...RowGenerator) CatGenerator {
435
-	G := RowGenerators(g)
433
+func Level(g ...def.RowGenerator) def.CatGenerator {
434
+	G := def.RowGenerators(g)
436 435
 	const lvl = "level"
437
-	return func(ctx *Cat) {
438
-		c := &Row{}
439
-		c.Init = func(cc *Row) {
436
+	return func(ctx *def.Cat) {
437
+		c := &def.Row{}
438
+		c.Init = func(cc *def.Row) {
440 439
 			cc.Name = lvl
441 440
 			cc.Type = "options"
442 441
 			cc.Opts = cl.GetLevelOpts()
@@ -461,11 +460,11 @@ func Level(g ...RowGenerator) CatGenerator {
461 460
 
462 461
 // Algo is a multi-item select that contains all of the different block-algorithms
463 462
 // available to mine with, as well as algorithmic selectors
464
-func Algo(name string, g ...RowGenerator) CatGenerator {
465
-	G := RowGenerators(g)
466
-	return func(ctx *Cat) {
467
-		c := &Row{}
468
-		c.Init = func(cc *Row) {
463
+func Algo(name string, g ...def.RowGenerator) def.CatGenerator {
464
+	G := def.RowGenerators(g)
465
+	return func(ctx *def.Cat) {
466
+		c := &def.Row{}
467
+		c.Init = func(cc *def.Row) {
469 468
 			cc.Name = name
470 469
 			cc.Type = "options"
471 470
 			cc.Opts = getAlgoOptions()
@@ -489,11 +488,11 @@ func Algo(name string, g ...RowGenerator) CatGenerator {
489 488
 }
490 489
 
491 490
 // Float is a floating point number, 64 bits by default (same as JSON spec)
492
-func Float(name string, g ...RowGenerator) CatGenerator {
493
-	G := RowGenerators(g)
494
-	return func(ctx *Cat) {
495
-		c := &Row{}
496
-		c.Init = func(cc *Row) {
491
+func Float(name string, g ...def.RowGenerator) def.CatGenerator {
492
+	G := def.RowGenerators(g)
493
+	return func(ctx *def.Cat) {
494
+		c := &def.Row{}
495
+		c.Init = func(cc *def.Row) {
497 496
 			cc.Name = name
498 497
 			cc.Type = "float"
499 498
 			cc.Get = func() interface{} {
@@ -517,11 +516,11 @@ func Float(name string, g ...RowGenerator) CatGenerator {
517 516
 
518 517
 // Duration is a time library duration specification for an amount of time.
519 518
 // The value is a 64 bit integer being the number of nanoseconds for a period of time
520
-func Duration(name string, g ...RowGenerator) CatGenerator {
521
-	G := RowGenerators(g)
522
-	return func(ctx *Cat) {
523
-		c := &Row{}
524
-		c.Init = func(cc *Row) {
519
+func Duration(name string, g ...def.RowGenerator) def.CatGenerator {
520
+	G := def.RowGenerators(g)
521
+	return func(ctx *def.Cat) {
522
+		c := &def.Row{}
523
+		c.Init = func(cc *def.Row) {
525 524
 			cc.Name = name
526 525
 			cc.Type = "duration"
527 526
 			cc.Get = func() interface{} {
@@ -545,11 +544,11 @@ func Duration(name string, g ...RowGenerator) CatGenerator {
545 544
 
546 545
 // Net is the various types of network a blockchain server can connect to - test, main
547 546
 // and so forth
548
-func Net(name string, g ...RowGenerator) CatGenerator {
549
-	G := RowGenerators(g)
550
-	return func(ctx *Cat) {
551
-		c := &Row{}
552
-		c.Init = func(cc *Row) {
547
+func Net(name string, g ...def.RowGenerator) def.CatGenerator {
548
+	G := def.RowGenerators(g)
549
+	return func(ctx *def.Cat) {
550
+		c := &def.Row{}
551
+		c.Init = func(cc *def.Row) {
553 552
 			cc.Name = name
554 553
 			cc.Type = "options"
555 554
 			cc.Opts = Networks
@@ -575,15 +574,15 @@ func Net(name string, g ...RowGenerator) CatGenerator {
575 574
 // which is populated by
576 575
 
577 576
 // Usage populates the usage field for information about a config item
578
-func Usage(usage string) RowGenerator {
579
-	return func(ctx *Row) {
577
+func Usage(usage string) def.RowGenerator {
578
+	return func(ctx *def.Row) {
580 579
 		ctx.Usage = usage + " " + ctx.Usage
581 580
 	}
582 581
 }
583 582
 
584 583
 // Default sets the default value for a config item
585
-func Default(in interface{}) RowGenerator {
586
-	return func(ctx *Row) {
584
+func Default(in interface{}) def.RowGenerator {
585
+	return func(ctx *def.Row) {
587 586
 		ctx.Default = ifc.NewIface()
588 587
 		switch I := in.(type) {
589 588
 		case string:
@@ -645,12 +644,12 @@ func Default(in interface{}) RowGenerator {
645 644
 }
646 645
 
647 646
 // Min attaches to the validator a test that enforces a minimum
648
-func Min(min int) RowGenerator {
649
-	return func(ctx *Row) {
647
+func Min(min int) def.RowGenerator {
648
+	return func(ctx *def.Row) {
650 649
 		ctx.Min = ctx.Min.Put(min)
651 650
 		v := ctx.Validate
652 651
 		var e error
653
-		ctx.Validate = func(r *Row, in interface{}) bool {
652
+		ctx.Validate = func(r *def.Row, in interface{}) bool {
654 653
 			n := min
655 654
 			switch I := in.(type) {
656 655
 			case int:
@@ -679,12 +678,12 @@ func Min(min int) RowGenerator {
679 678
 }
680 679
 
681 680
 // Max attaches to the validator a test that enforces a maximum
682
-func Max(max int) RowGenerator {
683
-	return func(ctx *Row) {
681
+func Max(max int) def.RowGenerator {
682
+	return func(ctx *def.Row) {
684 683
 		ctx.Max = ctx.Max.Put(max)
685 684
 		v := ctx.Validate
686 685
 		var e error
687
-		ctx.Validate = func(r *Row, in interface{}) bool {
686
+		ctx.Validate = func(r *def.Row, in interface{}) bool {
688 687
 			n := max
689 688
 			switch I := in.(type) {
690 689
 			case int:
@@ -714,7 +713,7 @@ func Max(max int) RowGenerator {
714 713
 
715 714
 // RandomString generates a random number and converts to base32 for
716 715
 // a default random password of some number of characters
717
-func RandomString(n int) RowGenerator {
716
+func RandomString(n int) def.RowGenerator {
718 717
 	const (
719 718
 		letterBytes   = "abcdefghijklmnopqrstuvwxyz234567"
720 719
 		letterIdxBits = 6                    // 6 bits to represent a letter index
@@ -722,7 +721,7 @@ func RandomString(n int) RowGenerator {
722 721
 		letterIdxMax  = 63 / letterIdxBits   // # of letter indices fitting in 63 bits
723 722
 	)
724 723
 	var src = rand.NewSource(time.Now().UnixNano())
725
-	return func(ctx *Row) {
724
+	return func(ctx *def.Row) {
726 725
 		b := make([]byte, n)
727 726
 		l := len(letterBytes)
728 727
 		// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
@@ -742,119 +741,3 @@ func RandomString(n int) RowGenerator {
742 741
 		ctx.Value = ctx.Value.Put(sb)
743 742
 	}
744 743
 }
745
-
746
-// SaveConfig writes all the data in Cats the config file at the root of DataDir
747
-func (app *App) SaveConfig() {
748
-	if app == nil {
749
-		return
750
-	}
751
-	datadir, ok := app.Cats["app"]["datadir"].Value.Get().(string)
752
-	if !ok {
753
-		return
754
-	}
755
-	configFile := CleanAndExpandPath(filepath.Join(
756
-		datadir, "config"), "")
757
-	if EnsureDir(configFile) {
758
-	}
759
-	fh, err := os.Create(configFile)
760
-	if err != nil {
761
-		panic(err)
762
-	}
763
-	j, e := json.MarshalIndent(app, "", "\t")
764
-	if e != nil {
765
-		panic(e)
766
-	}
767
-	_, err = fmt.Fprint(fh, string(j))
768
-	if err != nil {
769
-		panic(err)
770
-	}
771
-}
772
-
773
-// MarshalJSON cherrypicks Cats for the values needed to correctly configure it
774
-// and some extra information to make the JSON output friendly to human editors
775
-func (r *App) MarshalJSON() ([]byte, error) {
776
-	out := make(CatsJSON)
777
-	for i, x := range r.Cats {
778
-		out[i] = make(CatJSON)
779
-		for j, y := range x {
780
-			min, _ := y.Min.Get().(int)
781
-			max, _ := y.Max.Get().(int)
782
-			out[i][j] = Line{
783
-				Value:   y.Value.Get(),
784
-				Default: y.Default.Get(),
785
-				Min:     min,
786
-				Max:     max,
787
-				Usage:   y.Usage,
788
-			}
789
-		}
790
-	}
791
-	return json.Marshal(out)
792
-}
793
-
794
-// UnmarshalJSON takes the cherrypicked JSON output of Marshal and puts it back into
795
-// an App
796
-func (r *App) UnmarshalJSON(data []byte) error {
797
-	out := make(CatsJSON)
798
-	e := json.Unmarshal(data, &out)
799
-	if e != nil {
800
-		return e
801
-	}
802
-	for i, x := range out {
803
-		for j, y := range x {
804
-			R := r.Cats[i][j]
805
-			if y.Value != nil {
806
-				switch R.Type {
807
-				case "int", "port":
808
-					y.Value = int(y.Value.(float64))
809
-				case "duration":
810
-					y.Value = time.Duration(int(y.Value.(float64)))
811
-				case "stringslice":
812
-					rt, ok := y.Value.([]string)
813
-					ro := []string{}
814
-					if ok {
815
-						for _, z := range rt {
816
-							R.Validate(R, z)
817
-							ro = append(ro, z)
818
-						}
819
-						// R.Value.Put(ro)
820
-					}
821
-					// break
822
-				case "float":
823
-				}
824
-			}
825
-			R.Validate(R, y.Value)
826
-			// R.Value.Put(y.Value)
827
-		}
828
-	}
829
-	return nil
830
-}
831
-
832
-// RunAll triggers AppGenerators to configure an App
833
-func (r *AppGenerators) RunAll(app *App) {
834
-	for _, x := range *r {
835
-		x(app)
836
-	}
837
-	return
838
-}
839
-
840
-// RunAll runs a collection of CatGenerators on a Cat
841
-func (r *CatGenerators) RunAll(cat Cat) {
842
-	for _, x := range *r {
843
-		x(&cat)
844
-	}
845
-	return
846
-}
847
-
848
-func (r *RowGenerators) RunAll(row *Row) {
849
-	for _, x := range *r {
850
-		x(row)
851
-	}
852
-}
853
-
854
-func (r *CommandGenerators) RunAll() *Command {
855
-	c := &Command{}
856
-	for _, x := range *r {
857
-		x(c)
858
-	}
859
-	return c
860
-}

cmd/conf/handlers.go → cmd/app/handlers.go View File

@@ -1,4 +1,4 @@
1
-package conf
1
+package app
2 2
 
3 3
 import (
4 4
 	"errors"
@@ -6,13 +6,13 @@ import (
6 6
 	"net"
7 7
 	"os"
8 8
 	"path/filepath"
9
-	"runtime"
10 9
 	"sort"
11 10
 	"strings"
12 11
 	"time"
13 12
 
14
-	"git.parallelcoin.io/dev/9/cmd/app"
13
+	"git.parallelcoin.io/dev/9/cmd/conf"
15 14
 	"git.parallelcoin.io/dev/9/cmd/ctl"
15
+	"git.parallelcoin.io/dev/9/cmd/def"
16 16
 	"git.parallelcoin.io/dev/9/cmd/ll"
17 17
 	"git.parallelcoin.io/dev/9/cmd/nine"
18 18
 	"git.parallelcoin.io/dev/9/cmd/node"
@@ -45,7 +45,7 @@ func optTagList(s []string) (ss string) {
45 45
 	return
46 46
 }
47 47
 
48
-func getCommands(cmds app.Commands) (s []string) {
48
+func getCommands(cmds def.Commands) (s []string) {
49 49
 	for i := range cmds {
50 50
 		s = append(s, i)
51 51
 	}
@@ -53,7 +53,7 @@ func getCommands(cmds app.Commands) (s []string) {
53 53
 	return
54 54
 }
55 55
 
56
-func getTokens(cmds app.Tokens) (s []string) {
56
+func getTokens(cmds def.Tokens) (s []string) {
57 57
 	for _, x := range cmds {
58 58
 		s = append(s, x.Value)
59 59
 	}
@@ -62,7 +62,7 @@ func getTokens(cmds app.Tokens) (s []string) {
62 62
 }
63 63
 
64 64
 // Help prints out help information based on the contents of the commandline
65
-func Help(args []string, tokens app.Tokens, ap *app.App) int {
65
+func Help(args []string, tokens def.Tokens, ap *def.App) int {
66 66
 	fmt.Println(ap.Name, ap.Version(), "-", ap.Tagline)
67 67
 	fmt.Println()
68 68
 	fmt.Println("help with", ap.Name)
@@ -110,28 +110,28 @@ func Help(args []string, tokens app.Tokens, ap *app.App) int {
110 110
 }
111 111
 
112 112
 // Conf runs the configuration menu system
113
-func Conf(args []string, tokens app.Tokens, ap *app.App) int {
113
+func Conf(args []string, tokens def.Tokens, ap *def.App) int {
114 114
 	var r int
115 115
 	for r = 2; r == 2; {
116
-		r = Run(args, tokens, ap)
116
+		r = conf.Run(args, tokens, ap)
117 117
 	}
118 118
 	return r
119 119
 }
120 120
 
121 121
 // // New ???
122
-// func New(args []string, tokens app.Tokens, ap *app.App) int {
122
+// func New(args []string, tokens def.Tokens, ap *def.App) int {
123 123
 // 	fmt.Println("running New", args, getTokens(tokens))
124 124
 // 	return 0
125 125
 // }
126 126
 
127 127
 // // Copy duplicates a configuration to create new one(s) based on it
128
-// func Copy(args []string, tokens app.Tokens, ap *app.App) int {
128
+// func Copy(args []string, tokens def.Tokens, ap *def.App) int {
129 129
 // 	fmt.Println("running Copy", args, getTokens(tokens))
130 130
 // 	return 0
131 131
 // }
132 132
 
133 133
 // List prints the available commands for ctl
134
-func List(args []string, tokens app.Tokens, ap *app.App) int {
134
+func List(args []string, tokens def.Tokens, ap *def.App) int {
135 135
 	if j := validateProxyListeners(ap); j != 0 {
136 136
 		return j
137 137
 	}
@@ -144,7 +144,7 @@ func List(args []string, tokens app.Tokens, ap *app.App) int {
144 144
 
145 145
 // Ctl sends RPC commands input in the command line arguments and prints the result
146 146
 // back to stdout
147
-func Ctl(args []string, tokens app.Tokens, ap *app.App) int {
147
+func Ctl(args []string, tokens def.Tokens, ap *def.App) int {
148 148
 	cl.Register.SetAllLevels(*ap.Config.LogLevel)
149 149
 	setAppDataDir(ap, "ctl")
150 150
 	if j := validateProxyListeners(ap); j != 0 {
@@ -166,7 +166,7 @@ func Ctl(args []string, tokens app.Tokens, ap *app.App) int {
166 166
 }
167 167
 
168 168
 // Node launches the full node
169
-func Node(args []string, tokens app.Tokens, ap *app.App) int {
169
+func Node(args []string, tokens def.Tokens, ap *def.App) int {
170 170
 	node.StateCfg = ap.Config.State
171 171
 	node.Cfg = ap.Config
172 172
 	cl.Register.SetAllLevels(*ap.Config.LogLevel)
@@ -192,13 +192,13 @@ func Node(args []string, tokens app.Tokens, ap *app.App) int {
192 192
 }
193 193
 
194 194
 // Wallet launches the wallet server
195
-func Wallet(args []string, tokens app.Tokens, ap *app.App) int {
195
+func Wallet(args []string, tokens def.Tokens, ap *def.App) int {
196 196
 	setAppDataDir(ap, "wallet")
197 197
 	netDir := walletmain.NetworkDir(*ap.Config.AppDataDir,
198 198
 		ap.Config.ActiveNetParams.Params)
199 199
 	wdb := netDir // + "/wallet.db"
200 200
 	log <- cl.Debug{"opening wallet:", wdb}
201
-	if !FileExists(wdb) {
201
+	if !util.FileExists(wdb) {
202 202
 		if e := walletmain.CreateWallet(
203 203
 			ap.Config, ap.Config.ActiveNetParams, wdb); e != nil {
204 204
 			panic("could not create wallet " + e.Error())
@@ -214,14 +214,14 @@ func Wallet(args []string, tokens app.Tokens, ap *app.App) int {
214 214
 
215 215
 // Shell runs a combined full node and wallet server for use in the common standard
216 216
 // configuration provided by many bitcoin and bitcoin fork servers
217
-func Shell(args []string, tokens app.Tokens, ap *app.App) int {
217
+func Shell(args []string, tokens def.Tokens, ap *def.App) int {
218 218
 	setAppDataDir(ap, "node")
219 219
 	netDir := walletmain.NetworkDir(
220 220
 		filepath.Join(*ap.Config.DataDir, "wallet"),
221 221
 		ap.Config.ActiveNetParams.Params)
222 222
 	wdb := netDir // + "/wallet.db"
223 223
 	log <- cl.Debug{"opening wallet:", wdb}
224
-	if !FileExists(wdb) {
224
+	if !util.FileExists(wdb) {
225 225
 		if e := walletmain.CreateWallet(
226 226
 			ap.Config, ap.Config.ActiveNetParams, wdb); e != nil {
227 227
 			panic("could not create wallet " + e.Error())
@@ -236,7 +236,7 @@ func Shell(args []string, tokens app.Tokens, ap *app.App) int {
236 236
 }
237 237
 
238 238
 // Test runs a testnet based on a set of configuration directories
239
-func Test(args []string, tokens app.Tokens, ap *app.App) int {
239
+func Test(args []string, tokens def.Tokens, ap *def.App) int {
240 240
 	cl.Register.SetAllLevels(*ap.Config.LogLevel)
241 241
 	fmt.Println("running Test", args, getTokens(tokens))
242 242
 	return 0
@@ -244,12 +244,12 @@ func Test(args []string, tokens app.Tokens, ap *app.App) int {
244 244
 
245 245
 // Create generates a set of configurations that are set to connect to each other
246 246
 // in a testnet
247
-func Create(args []string, tokens app.Tokens, ap *app.App) int {
247
+func Create(args []string, tokens def.Tokens, ap *def.App) int {
248 248
 	netDir := walletmain.NetworkDir(
249 249
 		filepath.Join(*ap.Config.DataDir, "wallet"),
250 250
 		ap.Config.ActiveNetParams.Params)
251 251
 	wdb := netDir // + "/wallet.db"
252
-	if !FileExists(wdb) {
252
+	if !util.FileExists(wdb) {
253 253
 		if e := walletmain.CreateWallet(
254 254
 			ap.Config, ap.Config.ActiveNetParams, wdb); e != nil {
255 255
 			panic("could not create wallet " + e.Error())
@@ -262,153 +262,40 @@ func Create(args []string, tokens app.Tokens, ap *app.App) int {
262 262
 }
263 263
 
264 264
 // // TestHandler ???
265
-// func TestHandler(args []string, tokens app.Tokens, ap *app.App) int {
265
+// func TestHandler(args []string, tokens def.Tokens, ap *def.App) int {
266 266
 // 	return 0
267 267
 // }
268 268
 
269 269
 // GUI runs a shell in the background and a GUI interface for wallet and node
270
-func GUI(args []string, tokens app.Tokens, ap *app.App) int {
270
+func GUI(args []string, tokens def.Tokens, ap *def.App) int {
271 271
 	return 0
272 272
 }
273 273
 
274 274
 // Mine runs the standalone miner
275
-func Mine(args []string, tokens app.Tokens, ap *app.App) int {
275
+func Mine(args []string, tokens def.Tokens, ap *def.App) int {
276 276
 	return 0
277 277
 }
278 278
 
279 279
 // GenCerts generates TLS certificates
280
-func GenCerts(args []string, tokens app.Tokens, ap *app.App) int {
280
+func GenCerts(args []string, tokens def.Tokens, ap *def.App) int {
281 281
 	return 0
282 282
 }
283 283
 
284 284
 // GenCA creates a signing key that GenCerts will use if present to sign keys that
285 285
 // it can be used to certify for multiple nodes connected to each other
286 286
 // (wallet/node and RPC)
287
-func GenCA(args []string, tokens app.Tokens, ap *app.App) int {
287
+func GenCA(args []string, tokens def.Tokens, ap *def.App) int {
288 288
 	return 0
289 289
 }
290 290
 
291
-// MinUint32 is a helper function to return the minimum of two uint32s. This avoids a math import and the need to cast to floats.
292
-func MinUint32(a, b uint32) uint32 {
293
-	if a < b {
294
-		return a
295
-	}
296
-	return b
297
-}
298
-
299
-func isWindows() bool {
300
-	return runtime.GOOS == "windows"
301
-}
302
-
303
-// EnsureDir checks a file could be written to a path, creates the directories as needed
304
-func EnsureDir(fileName string) bool {
305
-	dirName := filepath.Dir(fileName)
306
-	if _, serr := os.Stat(dirName); serr != nil {
307
-		merr := os.MkdirAll(dirName, os.ModePerm)
308
-		if merr != nil {
309
-			panic(merr)
310
-		}
311
-		return true
312
-	}
313
-	return false
314
-}
315
-
316
-// FileExists reports whether the named file or directory exists.
317
-func FileExists(filePath string) bool {
318
-	_, err := os.Stat(filePath)
319
-	return err == nil
320
-}
321
-
322
-// CleanAndExpandPath expands environment variables and leading ~ in the passed path, cleans the result, and returns it.
323
-func CleanAndExpandPath(path, datadir string) string {
324
-	// Expand initial ~ to OS specific home directory.
325
-	homeDir := filepath.Dir(util.AppDataDir("9", false))
326
-	if strings.HasPrefix(path, "~") {
327
-		return strings.Replace(path, "~", homeDir, 1)
328
-
329
-	}
330
-	if strings.HasPrefix(path, "./") {
331
-		// explicitly prefix is this must be a relative path
332
-		pwd, _ := os.Getwd()
333
-		return filepath.Join(pwd, path)
334
-	} else if !strings.HasPrefix(path, "/") && !strings.HasPrefix(path, "\\") {
335
-		if path != datadir {
336
-			return filepath.Join(datadir, path)
337
-		}
338
-	}
339
-	// NOTE: The os.ExpandEnv doesn't work with Windows-style %VARIABLE%, but they variables can still be expanded via POSIX-style $VARIABLE.
340
-	path = filepath.Clean(os.ExpandEnv(path))
341
-	return path
342
-}
343
-
344
-// NormalizeAddress returns addr with the passed default port appended if there is not already a port specified.
345
-func NormalizeAddress(addr, defaultPort string) string {
346
-	_, _, err := net.SplitHostPort(addr)
347
-	if err != nil {
348
-		return net.JoinHostPort(addr, defaultPort)
349
-	}
350
-	return addr
351
-}
352
-
353
-// NormalizeAddresses returns a new slice with all the passed peer addresses normalized with the given default port, and all duplicates removed.
354
-func NormalizeAddresses(addrs []string, defaultPort string) []string {
355
-	for i, addr := range addrs {
356
-		addrs[i] = NormalizeAddress(addr, defaultPort)
357
-	}
358
-	return RemoveDuplicateAddresses(addrs)
359
-}
360
-
361
-// RemoveDuplicateAddresses returns a new slice with all duplicate entries in addrs removed.
362
-func RemoveDuplicateAddresses(addrs []string) []string {
363
-	result := make([]string, 0, len(addrs))
364
-	seen := map[string]struct{}{}
365
-	for _, val := range addrs {
366
-		if _, ok := seen[val]; !ok {
367
-			result = append(result, val)
368
-			seen[val] = struct{}{}
369
-		}
370
-	}
371
-	return result
372
-}
373
-
374
-func intersection(a, b []string) (out []string) {
375
-	for _, x := range a {
376
-		for _, y := range b {
377
-			if x == y {
378
-				out = append(out, x)
379
-			}
380
-		}
381
-	}
382
-	return
383
-}
384
-
385
-func uniq(elements []string) []string {
386
-	// Use map to record duplicates as we find them.
387
-	encountered := map[string]bool{}
388
-	result := []string{}
389
-
390
-	for v := range elements {
391
-		if encountered[elements[v]] == true {
392
-			// Do not add duplicate.
393
-		} else {
394
-			// Record this element as an encountered element.
395
-			encountered[elements[v]] = true
396
-			// Append to result slice.
397
-			result = append(result, elements[v])
398
-		}
399
-	}
400
-	// Return the new slice.
401
-	return result
402
-}
403
-
404
-func setAppDataDir(ap *app.App, name string) {
291
+func setAppDataDir(ap *def.App, name string) {
405 292
 	if ap != nil {
406 293
 		if ap.Config != nil {
407 294
 			if ap.Config.AppDataDir == nil {
408 295
 				ap.Config.AppDataDir = new(string)
409 296
 				// set AppDataDir for running as node
410 297
 				*ap.Config.AppDataDir =
411
-					CleanAndExpandPath(
298
+					util.CleanAndExpandPath(
412 299
 						filepath.Join(*ap.Config.DataDir, name),
413 300
 						*ap.Config.DataDir)
414 301
 			}
@@ -420,7 +307,7 @@ func setAppDataDir(ap *app.App, name string) {
420 307
 	}
421 308
 }
422 309
 
423
-func validateWhitelists(ap *app.App) int {
310
+func validateWhitelists(ap *def.App) int {
424 311
 	// Validate any given whitelisted IP addresses and networks.
425 312
 	if ap.Config.Whitelists != nil {
426 313
 		var ip net.IP
@@ -456,7 +343,7 @@ func validateWhitelists(ap *app.App) int {
456 343
 	return 0
457 344
 }
458 345
 
459
-func validateProxyListeners(ap *app.App) int {
346
+func validateProxyListeners(ap *def.App) int {
460 347
 	// if proxy is not enabled, empty the proxy field as node sees presence as a
461 348
 	// on switch
462 349
 	if ap.Config.Proxy != nil {
@@ -482,7 +369,7 @@ func validateProxyListeners(ap *app.App) int {
482 369
 	return 0
483 370
 }
484 371
 
485
-func validatePasswords(ap *app.App) int {
372
+func validatePasswords(ap *def.App) int {
486 373
 
487 374
 	// Check to make sure limited and admin users don't have the same username
488 375
 	if *ap.Config.Username != "" && *ap.Config.Username == *ap.Config.LimitUser {
@@ -502,7 +389,7 @@ func validatePasswords(ap *app.App) int {
502 389
 	return 0
503 390
 }
504 391
 
505
-func validateRPCCredentials(ap *app.App) int {
392
+func validateRPCCredentials(ap *def.App) int {
506 393
 	// The RPC server is disabled if no username or password is provided.
507 394
 	if (*ap.Config.Username == "" || *ap.Config.Password == "") &&
508 395
 		(*ap.Config.LimitUser == "" || *ap.Config.LimitPass == "") {
@@ -524,7 +411,7 @@ func validateRPCCredentials(ap *app.App) int {
524 411
 	return 0
525 412
 }
526 413
 
527
-func validateBlockLimits(ap *app.App) int {
414
+func validateBlockLimits(ap *def.App) int {
528 415
 	// Validate the the minrelaytxfee.
529 416
 	// log <- cl.Debug{"checking min relay tx fee"}
530 417
 	var err error
@@ -537,13 +424,13 @@ func validateBlockLimits(ap *app.App) int {
537 424
 		return 1
538 425
 	}
539 426
 	// Limit the block priority and minimum block sizes to max block size.
540
-	*ap.Config.BlockPrioritySize = int(MinUint32(
427
+	*ap.Config.BlockPrioritySize = int(util.MinUint32(
541 428
 		uint32(*ap.Config.BlockPrioritySize),
542 429
 		uint32(*ap.Config.BlockMaxSize)))
543
-	*ap.Config.BlockMinSize = int(MinUint32(
430
+	*ap.Config.BlockMinSize = int(util.MinUint32(
544 431
 		uint32(*ap.Config.BlockMinSize),
545 432
 		uint32(*ap.Config.BlockMaxSize)))
546
-	*ap.Config.BlockMinWeight = int(MinUint32(
433
+	*ap.Config.BlockMinWeight = int(util.MinUint32(
547 434
 		uint32(*ap.Config.BlockMinWeight),
548 435
 		uint32(*ap.Config.BlockMaxWeight)))
549 436
 	switch {
@@ -564,7 +451,7 @@ func validateBlockLimits(ap *app.App) int {
564 451
 	return 0
565 452
 }
566 453
 
567
-func validateUAComments(ap *app.App) int {
454
+func validateUAComments(ap *def.App) int {
568 455
 	// Look for illegal characters in the user agent comments.
569 456
 	// log <- cl.Debug{"checking user agent comments"}
570 457
 	if ap.Config.UserAgentComments != nil {
@@ -581,7 +468,7 @@ func validateUAComments(ap *app.App) int {
581 468
 	return 0
582 469
 }
583 470
 
584
-func validateMiner(ap *app.App) int {
471
+func validateMiner(ap *def.App) int {
585 472
 	// Check mining addresses are valid and saved parsed versions.
586 473
 	// log <- cl.Debug{"checking mining addresses"}
587 474
 	if ap.Config.MiningAddrs != nil {
@@ -628,7 +515,7 @@ func validateMiner(ap *app.App) int {
628 515
 	return 0
629 516
 }
630 517
 
631
-func validateCheckpoints(ap *app.App) int {
518
+func validateCheckpoints(ap *def.App) int {
632 519
 	var err error
633 520
 	// Check the checkpoints for syntax errors.
634 521
 	// log <- cl.Debug{"checking the checkpoints"}
@@ -645,8 +532,8 @@ func validateCheckpoints(ap *app.App) int {
645 532
 	return 0
646 533
 }
647 534
 
648
-func validateDialers(ap *app.App) int {
649
-	// if !*app.Config.Onion && *app.Config.OnionProxy != "" {
535
+func validateDialers(ap *def.App) int {
536
+	// if !*Config.Onion && *Config.OnionProxy != "" {
650 537
 	// 	// log <- cl.Error{"cannot enable tor proxy without an address specified"}
651 538
 	// 	return 1
652 539
 	// }
@@ -742,7 +629,7 @@ func validateDialers(ap *app.App) int {
742 629
 	return 0
743 630
 }
744 631
 
745
-func validateAddresses(ap *app.App) int {
632
+func validateAddresses(ap *def.App) int {
746 633
 	// TODO: simplify this to a boolean and one slice for config fercryinoutloud
747 634
 	if ap.Config.AddPeers != nil && ap.Config.ConnectPeers != nil {
748 635
 		fmt.Println("ERROR:", cl.Ine(),

+ 44
- 43
cmd/app/parse.go View File

@@ -7,6 +7,7 @@ import (
7 7
 	"os"
8 8
 	"path/filepath"
9 9
 
10
+	"git.parallelcoin.io/dev/9/cmd/def"
10 11
 	"git.parallelcoin.io/dev/9/cmd/node"
11 12
 	"git.parallelcoin.io/dev/9/pkg/util"
12 13
 	"git.parallelcoin.io/dev/9/pkg/util/cl"
@@ -14,11 +15,11 @@ import (
14 15
 
15 16
 var datadir = new(string)
16 17
 
17
-func (app *App) Parse(args []string) int {
18
-	// parse commandline
19
-	cmd, tokens := app.ParseCLI(args)
18
+// Parse commandline
19
+func Parse(ap *def.App, args []string) int {
20
+	cmd, tokens := ParseCLI(ap, args)
20 21
 	if cmd == nil {
21
-		cmd = app.Commands["help"]
22
+		cmd = ap.Commands["help"]
22 23
 	}
23 24
 	// get datadir from cli args if given
24 25
 	if dd, ok := tokens["datadir"]; ok {
@@ -26,41 +27,41 @@ func (app *App) Parse(args []string) int {
26 27
 		pwd, _ := os.Getwd()
27 28
 		*datadir = filepath.Join(pwd, *datadir)
28 29
 		dd.Value = *datadir
29
-		app.Cats["app"]["datadir"].Value.Put(*datadir)
30
+		ap.Cats["ap"]["datadir"].Value.Put(*datadir)
30 31
 		DataDir = *datadir
31 32
 	} else {
32 33
 		ddd := util.AppDataDir("9", false)
33
-		app.Cats["app"]["datadir"].Put(ddd)
34
+		ap.Cats["ap"]["datadir"].Put(ddd)
34 35
 		datadir = &ddd
35 36
 		DataDir = *datadir
36 37
 	}
37
-	// for i, x := range app.Cats {
38
+	// for i, x := range ap.Cats {
38 39
 	// 	for j := range x {
39
-	// 		// if i == "app" && j == "datadir" {
40
+	// 		// if i == "ap" && j == "datadir" {
40 41
 	// 		// 	break
41 42
 	// 		// }
42
-	// 		app.Cats[i][j].Init(app.Cats[i][j])
43
+	// 		ap.Cats[i][j].Init(ap.Cats[i][j])
43 44
 	// 	}
44 45
 	// }
45 46
 
46 47
 	// // set AppDataDir for running as node
47
-	// aa := CleanAndExpandPath(filepath.Join(
48
+	// aa := util.CleanAndExpandPath(filepath.Join(
48 49
 	// 	*datadir,
49 50
 	// 	cmd.Name),
50 51
 	// 	*datadir)
51
-	// app.Config.AppDataDir, app.Config.LogDir = &aa, &aa
52
+	// ap.Config.AppDataDir, ap.Config.LogDir = &aa, &aa
52 53
 
53
-	configFile := CleanAndExpandPath(filepath.Join(
54
+	configFile := util.CleanAndExpandPath(filepath.Join(
54 55
 		*datadir, "config"), *datadir)
55
-	// *app.Config.ConfigFile = configFile
56
-	if !FileExists(configFile) {
57
-		if EnsureDir(configFile) {
56
+	// *ap.Config.ConfigFile = configFile
57
+	if !util.FileExists(configFile) {
58
+		if util.EnsureDir(configFile) {
58 59
 		}
59 60
 		fh, err := os.Create(configFile)
60 61
 		if err != nil {
61 62
 			panic(err)
62 63
 		}
63
-		j, e := json.MarshalIndent(app, "", "\t")
64
+		j, e := json.MarshalIndent(ap, "", "\t")
64 65
 		if e != nil {
65 66
 			panic(e)
66 67
 		}
@@ -73,50 +74,50 @@ func (app *App) Parse(args []string) int {
73 74
 	if err != nil {
74 75
 		panic(err)
75 76
 	}
76
-	e := json.Unmarshal(conf, app)
77
+	e := json.Unmarshal(conf, ap)
77 78
 	if e != nil {
78 79
 		panic(e)
79 80
 	}
80 81
 	// now we can initialise the App
81
-	for i, x := range app.Cats {
82
+	for i, x := range ap.Cats {
82 83
 		for j := range x {
83
-			temp := app.Cats[i][j]
84
-			temp.App = app
85
-			app.Cats[i][j] = temp
84
+			temp := ap.Cats[i][j]
85
+			temp.App = ap
86
+			ap.Cats[i][j] = temp
86 87
 		}
87 88
 	}
88
-	app.Config = MakeConfig(app)
89
-	app.Config.ActiveNetParams = node.ActiveNetParams
89
+	ap.Config = MakeConfig(ap)
90
+	ap.Config.ActiveNetParams = node.ActiveNetParams
90 91
 
91
-	if app.Config.LogLevel != nil {
92
-		cl.Register.SetAllLevels(*app.Config.LogLevel)
92
+	if ap.Config.LogLevel != nil {
93
+		cl.Register.SetAllLevels(*ap.Config.LogLevel)
93 94
 	}
94 95
 	// run as configured
95 96
 	r := cmd.Handler(
96 97
 		args,
97 98
 		tokens,
98
-		app)
99
+		ap)
99 100
 	return r
100 101
 }
101 102
 
102
-func (app *App) ParseCLI(args []string) (cmd *Command, tokens Tokens) {
103
-	cmd = new(Command)
103
+func ParseCLI(ap *def.App, args []string) (cmd *def.Command, tokens def.Tokens) {
104
+	cmd = new(def.Command)
104 105
 	// collect set of items in commandline
105 106
 	if len(args) < 2 {
106 107
 		fmt.Print("No args given, printing help:\n\n")
107 108
 		args = append(args, "h")
108 109
 	}
109 110
 	commandsFound := make(map[string]int)
110
-	tokens = make(Tokens)
111
+	tokens = make(def.Tokens)
111 112
 	for _, x := range args[1:] {
112
-		for i, y := range app.Commands {
113
+		for i, y := range ap.Commands {
113 114
 			if y.RE.MatchString(x) {
114 115
 				if _, ok := commandsFound[i]; ok {
115
-					tokens[i] = Token{x, *y}
116
+					tokens[i] = def.Token{x, *y}
116 117
 					commandsFound[i]++
117 118
 					break
118 119
 				} else {
119
-					tokens[i] = Token{x, *y}
120
+					tokens[i] = def.Token{x, *y}
120 121
 					commandsFound[i] = 1
121 122
 					break
122 123
 				}
@@ -124,14 +125,14 @@ func (app *App) ParseCLI(args []string) (cmd *Command, tokens Tokens) {
124 125
 		}
125 126
 	}
126 127
 	var withHandlersNames []string
127
-	withHandlers := make(Commands)
128
+	withHandlers := make(def.Commands)
128 129
 	for i := range commandsFound {
129
-		if app.Commands[i].Handler != nil {
130
-			withHandlers[i] = app.Commands[i]
130
+		if ap.Commands[i].Handler != nil {
131
+			withHandlers[i] = ap.Commands[i]
131 132
 			withHandlersNames = append(withHandlersNames, i)
132 133
 		}
133 134
 	}
134
-	invoked := make(Commands)
135
+	invoked := make(def.Commands)
135 136
 	for i, x := range withHandlers {
136 137
 		invoked[i] = x
137 138
 	}
@@ -143,7 +144,7 @@ func (app *App) ParseCLI(args []string) (cmd *Command, tokens Tokens) {
143 144
 	if len(withHandlersNames) > 1 {
144 145
 		var common [][]string
145 146
 		for _, x := range withHandlersNames {
146
-			i := intersection(withHandlersNames, withHandlers[x].Precedent)
147
+			i := util.Intersection(withHandlersNames, withHandlers[x].Precedent)
147 148
 			common = append(common, i)
148 149
 		}
149 150
 		for _, x := range common {
@@ -153,17 +154,17 @@ func (app *App) ParseCLI(args []string) (cmd *Command, tokens Tokens) {
153 154
 				}
154 155
 			}
155 156
 		}
156
-		resolved = uniq(resolved)
157
+		resolved = util.Uniq(resolved)
157 158
 		if len(resolved) > 1 {
158
-			withHandlers = make(Commands)
159
+			withHandlers = make(def.Commands)
159 160
 			common = [][]string{}
160 161
 			withHandlersNames = resolved
161 162
 			resolved = []string{}
162 163
 			for _, x := range withHandlersNames {
163
-				withHandlers[x] = app.Commands[x]
164
+				withHandlers[x] = ap.Commands[x]
164 165
 			}
165 166
 			for _, x := range withHandlersNames {
166
-				i := intersection(withHandlersNames, withHandlers[x].Precedent)
167
+				i := util.Intersection(withHandlersNames, withHandlers[x].Precedent)
167 168
 				common = append(common, i)
168 169
 			}
169 170
 			for _, x := range common {
@@ -173,7 +174,7 @@ func (app *App) ParseCLI(args []string) (cmd *Command, tokens Tokens) {
173 174
 					}
174 175
 				}
175 176
 			}
176
-			resolved = uniq(resolved)
177
+			resolved = util.Uniq(resolved)
177 178
 		}
178 179
 	} else if len(withHandlersNames) == 1 {
179 180
 		resolved = []string{withHandlersNames[0]}
@@ -186,6 +187,6 @@ func (app *App) ParseCLI(args []string) (cmd *Command, tokens Tokens) {
186 187
 		fmt.Println(err)
187 188
 		return nil, tokens
188 189
 	}
189
-	*cmd = *app.Commands[resolved[0]]
190
+	*cmd = *ap.Commands[resolved[0]]
190 191
 	return cmd, tokens
191 192
 }

+ 0
- 124
cmd/app/util.go View File

@@ -1,124 +0,0 @@
1
-package app
2
-
3
-import (
4
-	"net"
5
-	"os"
6
-	"path/filepath"
7
-	"runtime"
8
-	"strings"
9
-
10
-	"git.parallelcoin.io/dev/9/pkg/util"
11
-)
12
-
13
-// MinUint32 is a helper function to return the minimum of two uint32s. This avoids a math import and the need to cast to floats.
14
-func MinUint32(a, b uint32) uint32 {
15
-	if a < b {
16
-		return a
17
-	}
18
-	return b
19
-}
20
-
21
-func isWindows() bool {
22
-	return runtime.GOOS == "windows"
23
-}
24
-
25
-// EnsureDir checks a file could be written to a path, creates the directories as needed
26
-func EnsureDir(fileName string) bool {
27
-	dirName := filepath.Dir(fileName)
28
-	if _, serr := os.Stat(dirName); serr != nil {
29
-		merr := os.MkdirAll(dirName, os.ModePerm)
30
-		if merr != nil {
31
-			panic(merr)
32
-		}
33
-		return true
34
-	}
35
-	return false
36
-}
37
-
38
-// FileExists reports whether the named file or directory exists.
39
-func FileExists(filePath string) bool {
40
-	_, err := os.Stat(filePath)
41
-	return err == nil
42
-}
43
-
44
-// CleanAndExpandPath expands environment variables and leading ~ in the passed path, cleans the result, and returns it.
45
-func CleanAndExpandPath(path, datadir string) string {
46
-	// Expand initial ~ to OS specific home directory.
47
-	homeDir := filepath.Dir(util.AppDataDir("9", false))
48
-	if strings.HasPrefix(path, "~") {
49
-		return strings.Replace(path, "~", homeDir, 1)
50
-
51
-	}
52
-	if strings.HasPrefix(path, "./") {
53
-		// explicitly prefix is this must be a relative path
54
-		pwd, _ := os.Getwd()
55
-		return filepath.Join(pwd, path)
56
-	} else if !strings.HasPrefix(path, "/") && !strings.HasPrefix(path, "\\") {
57
-		if path != datadir {
58
-			return filepath.Join(datadir, path)
59
-		}
60
-	}
61
-	// NOTE: The os.ExpandEnv doesn't work with Windows-style %VARIABLE%, but they variables can still be expanded via POSIX-style $VARIABLE.
62
-	path = filepath.Clean(os.ExpandEnv(path))
63
-	return path
64
-}
65
-
66
-// NormalizeAddress returns addr with the passed default port appended if there is not already a port specified.
67
-func NormalizeAddress(addr, defaultPort string) string {
68
-	_, _, err := net.SplitHostPort(addr)
69
-	if err != nil {
70
-		return net.JoinHostPort(addr, defaultPort)
71
-	}
72
-	return addr
73
-}
74
-
75
-// NormalizeAddresses returns a new slice with all the passed peer addresses normalized with the given default port, and all duplicates removed.
76
-func NormalizeAddresses(addrs []string, defaultPort string) []string {
77
-	for i, addr := range addrs {
78
-		addrs[i] = NormalizeAddress(addr, defaultPort)
79
-	}
80
-	return RemoveDuplicateAddresses(addrs)
81
-}
82
-
83
-// RemoveDuplicateAddresses returns a new slice with all duplicate entries in addrs removed.
84
-func RemoveDuplicateAddresses(addrs []string) []string {
85
-	result := make([]string, 0, len(addrs))
86
-	seen := map[string]struct{}{}
87
-	for _, val := range addrs {
88
-		if _, ok := seen[val]; !ok {
89
-			result = append(result, val)
90
-			seen[val] = struct{}{}
91
-		}
92
-	}
93
-	return result
94
-}
95
-
96
-func intersection(a, b []string) (out []string) {
97
-	for _, x := range a {
98
-		for _, y := range b {
99
-			if x == y {
100
-				out = append(out, x)
101
-			}
102
-		}
103
-	}
104
-	return
105
-}
106
-
107
-func uniq(elements []string) []string {
108
-	// Use map to record duplicates as we find them.
109
-	encountered := map[string]bool{}
110
-	result := []string{}
111
-
112
-	for v := range elements {
113
-		if encountered[elements[v]] == true {
114
-			// Do not add duplicate.
115
-		} else {
116
-			// Record this element as an encountered element.
117
-			encountered[elements[v]] = true
118
-			// Append to result slice.
119
-			result = append(result, elements[v])
120
-		}
121
-	}
122
-	// Return the new slice.
123
-	return result
124
-}

+ 23
- 22
cmd/app/validators.go View File

@@ -9,15 +9,17 @@ import (
9 9
 	"strings"
10 10
 	"time"
11 11
 
12
+	"git.parallelcoin.io/dev/9/cmd/def"
12 13
 	"git.parallelcoin.io/dev/9/cmd/nine"
13 14
 	"git.parallelcoin.io/dev/9/pkg/chain/fork"
14 15
 	"git.parallelcoin.io/dev/9/pkg/ifc"
16
+	"git.parallelcoin.io/dev/9/pkg/util"
15 17
 	"git.parallelcoin.io/dev/9/pkg/util/cl"
16 18
 )
17 19
 
18 20
 // GenAddr returns a validator with a set default port assumed if one is not present
19
-func GenAddr(name string, port int) func(r *Row, in interface{}) bool {
20
-	return func(r *Row, in interface{}) bool {
21
+func GenAddr(name string, port int) func(r *def.Row, in interface{}) bool {
22
+	return func(r *def.Row, in interface{}) bool {
21 23
 		var s *string
22 24
 		switch I := in.(type) {
23 25
 		case string:
@@ -69,8 +71,8 @@ func GenAddr(name string, port int) func(r *Row, in interface{}) bool {
69 71
 }
70 72
 
71 73
 // GenAddrs returns a validator with a set default port assumed if one is not present
72
-func GenAddrs(name string, port int) func(r *Row, in interface{}) bool {
73
-	return func(r *Row, in interface{}) bool {
74
+func GenAddrs(name string, port int) func(r *def.Row, in interface{}) bool {
75
+	return func(r *def.Row, in interface{}) bool {
74 76
 		var s []string
75 77
 		existing, ok := r.Value.Get().([]string)
76 78
 		if !ok {
@@ -150,13 +152,13 @@ func getAlgoOptions() (options []string) {
150 152
 }
151 153
 
152 154
 // Valid is a collection of validator functions for the different types used
153
-// in a configuration. These functions optionally can accept a *Row and with
155
+// in a configuration. These functions optionally can accept a *def.Row and with
154 156
 // this they assign the validated, parsed value into the Value slot.
155 157
 var Valid = struct {
156 158
 	File, Dir, Port, Bool, Int, Tag, Tags, Algo, Float, Duration, Net,
157
-	Level func(*Row, interface{}) bool
159
+	Level func(*def.Row, interface{}) bool
158 160
 }{
159
-	File: func(r *Row, in interface{}) bool {
161
+	File: func(r *def.Row, in interface{}) bool {
160 162
 		var s *string
161 163
 		switch I := in.(type) {
162 164
 		case string:
@@ -167,7 +169,7 @@ var Valid = struct {
167 169
 			return false
168 170
 		}
169 171
 		if len(*s) > 0 {
170
-			ss := CleanAndExpandPath(*s, *datadir)
172
+			ss := util.CleanAndExpandPath(*s, *datadir)
171 173
 			if r != nil {
172 174
 				r.String = fmt.Sprint(ss)
173 175
 				if r.Value == nil {
@@ -176,13 +178,12 @@ var Valid = struct {
176 178
 				r.Value.Put(ss)
177 179
 				r.App.SaveConfig()
178 180
 				return true
179
-			} else {
180
-				return false
181 181
 			}
182
+			return false
182 183
 		}
183 184
 		return false
184 185
 	},
185
-	Dir: func(r *Row, in interface{}) bool {
186
+	Dir: func(r *def.Row, in interface{}) bool {
186 187
 		var s *string
187 188
 		switch I := in.(type) {
188 189
 		case string:
@@ -193,7 +194,7 @@ var Valid = struct {
193 194
 			return false
194 195
 		}
195 196
 		if len(*s) > 0 {
196
-			ss := CleanAndExpandPath(*s, *datadir)
197
+			ss := util.CleanAndExpandPath(*s, *datadir)
197 198
 			if r != nil {
198 199
 				r.String = fmt.Sprint(ss)
199 200
 				if r.Value == nil {
@@ -208,7 +209,7 @@ var Valid = struct {
208 209
 		}
209 210
 		return false
210 211
 	},
211
-	Port: func(r *Row, in interface{}) bool {
212
+	Port: func(r *def.Row, in interface{}) bool {
212 213
 		var s string
213 214
 		var ii int
214 215
 		isString := false
@@ -243,7 +244,7 @@ var Valid = struct {
243 244
 		}
244 245
 		return true
245 246
 	},
246
-	Bool: func(r *Row, in interface{}) bool {
247
+	Bool: func(r *def.Row, in interface{}) bool {
247 248
 		var sb string
248 249
 		var b bool
249 250
 		switch I := in.(type) {
@@ -282,7 +283,7 @@ var Valid = struct {
282 283
 		}
283 284
 		return true
284 285
 	},
285
-	Int: func(r *Row, in interface{}) bool {
286
+	Int: func(r *def.Row, in interface{}) bool {
286 287
 		var s string
287 288
 		var ii int
288 289
 		isString := false
@@ -315,7 +316,7 @@ var Valid = struct {
315 316
 		}
316 317
 		return true
317 318
 	},
318
-	Tag: func(r *Row, in interface{}) bool {
319
+	Tag: func(r *def.Row, in interface{}) bool {
319 320
 		var s string
320 321
 		switch I := in.(type) {
321 322
 		case string:
@@ -336,7 +337,7 @@ var Valid = struct {
336 337
 		}
337 338
 		return true
338 339
 	},
339
-	Tags: func(r *Row, in interface{}) bool {
340
+	Tags: func(r *def.Row, in interface{}) bool {
340 341
 		var s []string
341 342
 		existing, ok := r.Value.Get().([]string)
342 343
 		if !ok {
@@ -384,7 +385,7 @@ var Valid = struct {
384 385
 		}
385 386
 		return true
386 387
 	},
387
-	Algo: func(r *Row, in interface{}) bool {
388
+	Algo: func(r *def.Row, in interface{}) bool {
388 389
 		var s string
389 390
 		switch I := in.(type) {
390 391
 		case string:
@@ -412,7 +413,7 @@ var Valid = struct {
412 413
 		}
413 414
 		return true
414 415
 	},
415
-	Float: func(r *Row, in interface{}) bool {
416
+	Float: func(r *def.Row, in interface{}) bool {
416 417
 		var s string
417 418
 		var f float64
418 419
 		isString := false
@@ -444,7 +445,7 @@ var Valid = struct {
444 445
 		}
445 446
 		return true
446 447
 	},
447
-	Duration: func(r *Row, in interface{}) bool {
448
+	Duration: func(r *def.Row, in interface{}) bool {
448 449
 		var s string
449 450
 		var t time.Duration
450 451
 		isString := false
@@ -476,7 +477,7 @@ var Valid = struct {
476 477
 		}
477 478
 		return true
478 479
 	},
479
-	Net: func(r *Row, in interface{}) bool {
480
+	Net: func(r *def.Row, in interface{}) bool {
480 481
 		var sn string
481 482
 		switch I := in.(type) {
482 483
 		case string:
@@ -500,7 +501,7 @@ var Valid = struct {
500 501
 		}
501 502
 		return found
502 503
 	},
503
-	Level: func(r *Row, in interface{}) bool {
504
+	Level: func(r *def.Row, in interface{}) bool {
504 505
 		var sl string
505 506
 		switch I := in.(type) {
506 507
 		case string:

+ 0
- 690
cmd/appdecl.go View File

@@ -1,690 +0,0 @@
1
-package cmd
2
-
3
-import (
4
-	"fmt"
5
-	"math/rand"
6
-	"reflect"
7
-	"regexp"
8
-	"strconv"
9
-	"time"
10
-
11
-	"git.parallelcoin.io/dev/9/pkg/util/cl"
12
-)
13
-
14
-func NewApp(name string, g ...AppGenerator) (out *App) {
15
-	gen := AppGenerators(g)
16
-	out = &App{
17
-		Name:     name,
18
-		Cats:     make(Cats),
19
-		Commands: make(Commands),
20
-	}
21
-	gen.RunAll(out)
22
-	// set ref to App in each Row
23
-	for _, x := range out.Cats {
24
-		for _, y := range x {
25
-			y.App = out
26
-		}
27
-	}
28
-	return
29
-}
30
-
31
-// which is made from
32
-
33
-func Version(ver string) AppGenerator {
34
-	return func(ctx *App) {
35
-		ctx.Version = func() string {
36
-			return ver
37
-		}
38
-	}
39
-}
40
-
41
-func Tagline(ver string) AppGenerator {
42
-	return func(ctx *App) {
43
-		ctx.Tagline = ver
44
-	}
45
-}
46
-
47
-func About(ver string) AppGenerator {
48
-	return func(ctx *App) {
49
-		ctx.About = ver
50
-	}
51
-}
52
-
53
-func DefaultRunner(fn func(ctx *App) int) AppGenerator {
54
-	return func(ctx *App) {
55
-		ctx.Default = fn
56
-	}
57
-}
58
-
59
-func Group(name string, g ...CatGenerator) AppGenerator {
60
-	G := CatGenerators(g)
61
-	return func(ctx *App) {
62
-		ctx.Cats[name] = make(Cat)
63
-		G.RunAll(ctx.Cats[name])
64
-	}
65
-}
66
-
67
-func Cmd(name string, g ...CommandGenerator) AppGenerator {
68
-	G := CommandGenerators(g)
69
-	return func(ctx *App) {
70
-		ctx.Commands[name] = G.RunAll()
71
-	}
72
-}
73
-
74
-// Command Item Generators
75
-
76
-func Pattern(patt string) CommandGenerator {
77
-	return func(ctx *Command) {
78
-		ctx.Pattern = patt
79
-		ctx.RE = regexp.MustCompile(ctx.Pattern)
80
-	}
81
-}
82
-
83
-func Short(usage string) CommandGenerator {
84
-	return func(ctx *Command) {
85
-		ctx.Short = usage
86
-	}
87
-}
88
-
89
-func Detail(usage string) CommandGenerator {
90
-	return func(ctx *Command) {
91
-		ctx.Detail = usage
92
-	}
93
-}
94
-
95
-func Opts(opts ...string) CommandGenerator {
96
-	return func(ctx *Command) {
97
-		ctx.Opts = opts
98
-	}
99
-}
100
-
101
-func Precs(precs ...string) CommandGenerator {
102
-	return func(ctx *Command) {
103
-		ctx.Precedent = precs
104
-	}
105
-}
106
-
107
-func Handler(hnd func(args []string, tokens Tokens, app *App) int) CommandGenerator {
108
-	return func(ctx *Command) {
109
-		ctx.Handler = hnd
110
-	}
111
-}
112
-
113
-// Group Item Generators
114
-
115
-func File(name string, g ...RowGenerator) CatGenerator {
116
-	G := RowGenerators(g)
117
-	return func(ctx *Cat) {
118
-		c := &Row{}
119
-		c.Init = func(cc *Row) {
120
-			cc.Name = name
121
-			cc.Type = "string"
122
-			cc.Validate = Valid.File
123
-			cc.Value = NewIface()
124
-			cc.Get = func() interface{} {
125
-				return cc.Value.Get()
126
-			}
127
-			cc.Put = func(in interface{}) bool {
128
-				valid := cc.Validate(cc, in)
129
-				if valid {
130
-					// cc.Value =
131
-					cc.Value.Put(in)
132
-					return true
133
-				}
134
-				return false
135
-			}
136
-			G.RunAll(cc)
137
-		}
138
-		c.Init(c)
139
-		(*ctx)[name] = c
140
-	}
141
-}
142
-
143
-func Dir(name string, g ...RowGenerator) CatGenerator {
144
-	G := RowGenerators(g)
145
-	return func(ctx *Cat) {
146
-		c := &Row{}
147
-		c.Init = func(cc *Row) {
148
-			cc.Name = name
149
-			cc.Type = "string"
150
-			cc.Validate = Valid.Dir
151
-			cc.Value = NewIface()
152
-			cc.Get = func() interface{} {
153
-				return cc.Value.Get()
154
-			}
155
-			cc.Put = func(in interface{}) bool {
156
-				valid := cc.Validate(cc, in)
157
-				if valid {
158
-					// cc.Value =
159
-					cc.Value.Put(in)
160
-					return true
161
-				}
162
-				return false
163
-			}
164
-			G.RunAll(cc)
165
-		}
166
-		c.Init(c)
167
-		(*ctx)[name] = c
168
-	}
169
-}
170
-
171
-func Port(name string, g ...RowGenerator) CatGenerator {
172
-	G := RowGenerators(g)
173
-	return func(ctx *Cat) {
174
-		c := &Row{}
175
-		c.Init = func(cc *Row) {
176
-			cc.Name = name
177
-			cc.Type = "port"
178
-			cc.Validate = Valid.Port
179
-			cc.Value = NewIface()
180
-			cc.Get = func() interface{} {
181
-				return cc.Value.Get()
182
-			}
183
-			cc.Put = func(in interface{}) bool {
184
-				valid := cc.Validate(cc, in)
185
-				if valid {
186
-					cc.Value = cc.Value.Put(in)
187
-					return true
188
-				}
189
-				return false
190
-			}
191
-			G.RunAll(cc)
192
-		}
193
-		c.Init(c)
194
-		(*ctx)[name] = c
195
-	}
196
-}
197
-
198
-func Enable(name string, g ...RowGenerator) CatGenerator {
199
-	G := RowGenerators(g)
200
-	return func(ctx *Cat) {
201
-		c := &Row{}
202
-		c.Init = func(cc *Row) {
203
-			cc.Name = name
204
-			cc.Type = "bool"
205
-			cc.Get = func() interface{} {
206
-				return cc.Value.Get()
207
-			}
208
-			cc.Validate = Valid.Bool
209
-			cc.Value = NewIface().Put(false)
210
-			cc.Default = NewIface().Put(false)
211
-			cc.Put = func(in interface{}) bool {
212
-				valid := cc.Validate(cc, in)
213
-				if valid {
214
-					cc.Value = cc.Value.Put(in)
215
-					return true
216
-				}
217
-				return false
218
-			}
219
-			G.RunAll(cc)
220
-		}
221
-		c.Init(c)
222
-		(*ctx)[name] = c
223
-	}
224
-}
225
-
226
-func Enabled(name string, g ...RowGenerator) CatGenerator {
227
-	G := RowGenerators(g)
228
-	return func(ctx *Cat) {
229
-		c := &Row{}
230
-		c.Init = func(cc *Row) {
231
-			cc.Name = name
232
-			cc.Type = "bool"
233
-			cc.Get = func() interface{} {
234
-				return cc.Value.Get()
235
-			}
236
-			cc.Validate = Valid.Bool
237
-			cc.Value = NewIface().Put(true)
238
-			cc.Default = NewIface().Put(true)
239
-			cc.Put = func(in interface{}) bool {
240
-				valid := cc.Validate(cc, in)
241
-				if valid {
242
-					cc.Value = cc.Value.Put(in)
243
-					return true
244
-				}
245
-				return false
246
-			}
247
-			G.RunAll(cc)
248
-		}
249
-		c.Init(c)
250
-		(*ctx)[name] = c
251
-	}
252
-}
253
-
254
-func Int(name string, g ...RowGenerator) CatGenerator {
255
-	G := RowGenerators(g)
256
-	return func(ctx *Cat) {
257
-		c := &Row{}
258
-		c.Init = func(cc *Row) {
259
-			cc.Name = name
260
-			cc.Type = "int"
261
-			cc.Get = func() interface{} {
262
-				return cc.Value.Get()
263
-			}
264
-			cc.Validate = Valid.Int
265
-			cc.Value = NewIface()
266
-			cc.Put = func(in interface{}) bool {
267
-				valid := cc.Validate(cc, in)
268
-				if valid {
269
-					cc.Value = cc.Value.Put(in)
270
-				}
271
-				return valid
272
-			}
273
-			G.RunAll(cc)
274
-		}
275
-		c.Init(c)
276
-		(*ctx)[name] = c
277
-	}
278
-}
279
-
280
-func Tag(name string, g ...RowGenerator) CatGenerator {
281
-	G := RowGenerators(g)
282
-	return func(ctx *Cat) {
283
-		c := &Row{}
284
-		c.Init = func(cc *Row) {
285
-			cc.Name = name
286
-			cc.Type = "string"
287
-			cc.Get = func() interface{} {
288
-				return cc.Value.Get()
289
-			}
290
-			cc.Validate = Valid.Tag
291
-			cc.Value = NewIface()
292
-			cc.Put = func(in interface{}) bool {
293
-				valid := cc.Validate(cc, in)
294
-				if valid {
295
-					cc.Value = cc.Value.Put(in)
296
-				}
297
-				return valid
298
-			}
299
-			G.RunAll(cc)
300
-		}
301
-		c.Init(c)
302
-		(*ctx)[name] = c
303
-	}
304
-}
305
-
306
-func Tags(name string, g ...RowGenerator) CatGenerator {
307
-	G := RowGenerators(g)
308
-	return func(ctx *Cat) {
309
-		c := &Row{}
310
-		c.Init = func(cc *Row) {
311
-			cc.Name = name
312
-			cc.Type = "stringslice"
313
-			cc.Get = func() interface{} {
314
-				return cc.Value.Get()
315
-			}
316
-			cc.Validate = Valid.Tags
317
-			cc.Value = NewIface()
318
-			cc.Put = func(in interface{}) bool {
319
-				valid := cc.Validate(cc, in)
320
-				if valid {
321
-					cc.Value = cc.Value.Put(in)
322
-				}
323
-				return valid
324
-			}
325
-			G.RunAll(cc)
326
-		}
327
-		c.Init(c)
328
-		(*ctx)[name] = c
329
-	}
330
-}
331
-
332
-func Addr(name string, defPort int, g ...RowGenerator) CatGenerator {
333
-	G := RowGenerators(g)
334
-	return func(ctx *Cat) {
335
-		c := &Row{}
336
-		c.Init = func(cc *Row) {
337
-			cc.Name = name
338
-			cc.Type = "string"
339
-			cc.Get = func() interface{} {
340
-				return cc.Value.Get()
341
-			}
342
-			cc.Validate = GenAddr(name, defPort)
343
-			cc.Value = NewIface()
344
-			cc.Put = func(in interface{}) bool {
345
-				valid := cc.Validate(cc, in)
346
-				if valid {
347
-					cc.Value = cc.Value.Put(in)
348
-				}
349
-				return valid
350
-			}
351
-			cc.Usage = fmt.Sprintf(
352
-				"\n\nNOTE: port must be between 1025-65535, port %d will be assumed if no port is given",
353
-				defPort)
354
-			G.RunAll(cc)
355
-		}
356
-		c.Init(c)
357
-		(*ctx)[name] = c
358
-	}
359
-}
360
-
361
-func Addrs(name string, defPort int, g ...RowGenerator) CatGenerator {
362
-	G := RowGenerators(g)
363
-	return func(ctx *Cat) {
364
-		c := &Row{}
365
-		c.Init = func(cc *Row) {
366
-			cc.Name = name
367
-			cc.Type = "stringslice"
368
-			cc.Get = func() interface{} {
369
-				return cc.Value.Get()
370
-			}
371
-			cc.Validate = GenAddrs(name, defPort)
372
-			cc.Value = NewIface()
373
-			cc.Put = func(in interface{}) bool {
374
-				valid := cc.Validate(cc, in)
375
-				if valid {
376
-					cc.Value = cc.Value.Put(in)
377
-				}
378
-				return valid
379
-			}
380
-			G.RunAll(cc)
381
-		}
382
-		c.Init(c)
383
-		(*ctx)[name] = c
384
-	}
385
-}
386
-
387
-func Level(g ...RowGenerator) CatGenerator {
388
-	G := RowGenerators(g)
389
-	const lvl = "level"
390
-	return func(ctx *Cat) {
391
-		c := &Row{}
392
-		c.Init = func(cc *Row) {
393
-			cc.Name = lvl
394
-			cc.Type = "options"
395
-			cc.Opts = cl.GetLevelOpts()
396
-			cc.Get = func() interface{} {
397
-				return cc.Value.Get()
398
-			}
399
-			cc.Validate = Valid.Level
400
-			cc.Value = NewIface()
401
-			cc.Put = func(in interface{}) bool {
402
-				valid := cc.Validate(cc, in)
403
-				if valid {
404
-					cc.Value = cc.Value.Put(in)
405
-				}
406
-				return valid
407
-			}
408
-			G.RunAll(cc)
409
-		}
410
-		c.Init(c)
411
-		(*ctx)[lvl] = c
412
-	}
413
-}
414
-
415
-func Algo(name string, g ...RowGenerator) CatGenerator {
416
-	G := RowGenerators(g)
417
-	return func(ctx *Cat) {
418
-		c := &Row{}
419
-		c.Init = func(cc *Row) {
420
-			cc.Name = name
421
-			cc.Type = "options"
422
-			cc.Opts = getAlgoOptions()
423
-			cc.Get = func() interface{} {
424
-				return cc.Value.Get()
425
-			}
426
-			cc.Validate = Valid.Algo
427
-			cc.Value = NewIface()
428
-			cc.Put = func(in interface{}) bool {
429
-				valid := cc.Validate(cc, in)
430
-				if valid {
431
-					cc.Value = cc.Value.Put(in)
432
-				}
433
-				return valid
434
-			}
435
-			G.RunAll(cc)
436
-		}
437
-		c.Init(c)
438
-		(*ctx)[name] = c
439
-	}
440
-}
441
-
442
-func Float(name string, g ...RowGenerator) CatGenerator {
443
-	G := RowGenerators(g)
444
-	return func(ctx *Cat) {
445
-		c := &Row{}
446
-		c.Init = func(cc *Row) {
447
-			cc.Name = name
448
-			cc.Type = "float"
449
-			cc.Get = func() interface{} {
450
-				return cc.Value.Get()
451
-			}
452
-			cc.Validate = Valid.Float
453
-			cc.Value = NewIface()
454
-			cc.Put = func(in interface{}) bool {
455
-				valid := cc.Validate(cc, in)
456
-				if valid {
457
-					cc.Value = cc.Value.Put(in)
458
-				}
459
-				return valid
460
-			}
461
-			G.RunAll(cc)
462
-		}
463
-		c.Init(c)
464
-		(*ctx)[name] = c
465
-	}
466
-}
467
-
468
-func Duration(name string, g ...RowGenerator) CatGenerator {
469
-	G := RowGenerators(g)
470
-	return func(ctx *Cat) {
471
-		c := &Row{}
472
-		c.Init = func(cc *Row) {
473
-			cc.Name = name
474
-			cc.Type = "duration"
475
-			cc.Get = func() interface{} {
476
-				return cc.Value.Get()
477
-			}
478
-			cc.Validate = Valid.Duration
479
-			cc.Value = NewIface()
480
-			cc.Put = func(in interface{}) bool {
481
-				valid := cc.Validate(cc, in)
482
-				if valid {
483
-					cc.Value = cc.Value.Put(in)
484
-				}
485
-				return valid
486
-			}
487
-			G.RunAll(cc)
488
-		}
489
-		c.Init(c)
490
-		(*ctx)[name] = c
491
-	}
492
-}
493
-
494
-func Net(name string, g ...RowGenerator) CatGenerator {
495
-	G := RowGenerators(g)
496
-	return func(ctx *Cat) {
497
-		c := &Row{}
498
-		c.Init = func(cc *Row) {
499
-			cc.Name = name
500
-			cc.Type = "options"
501
-			cc.Opts = Networks
502
-			cc.Get = func() interface{} {
503
-				return cc.Value.Get()
504
-			}
505
-			cc.Validate = Valid.Net
506
-			cc.Value = NewIface()
507
-			cc.Put = func(in interface{}) bool {
508
-				valid := cc.Validate(cc, in)
509
-				if valid {
510
-					cc.Value = cc.Value.Put(in)
511
-				}
512
-				return valid
513
-			}
514
-			G.RunAll(cc)
515
-		}
516
-		c.Init(c)
517
-		(*ctx)[name] = c
518
-	}
519
-}
520
-
521
-// which is populated by
522
-
523
-// Usage populates the usage field for information about a config item
524
-func Usage(usage string) RowGenerator {
525
-	return func(ctx *Row) {
526
-		ctx.Usage = usage + " " + ctx.Usage
527
-	}
528
-}
529
-
530
-// Default sets the default value for a config item
531
-func Default(in interface{}) RowGenerator {
532
-	return func(ctx *Row) {
533
-		ctx.Default = NewIface()
534
-		switch I := in.(type) {
535
-		case string:
536
-			if ctx.Validate(ctx, I) {
537
-				ctx.Default.Put(I)
538
-			}
539
-		case []string:
540
-			if ctx.Validate(ctx, I) {
541
-				ctx.Default.Put(I)
542
-			}
543
-		case int:
544
-			if ctx.Validate(ctx, I) {
545
-				ctx.Default.Put(I)
546
-			}
547
-		case float64:
548
-			if ctx.Validate(ctx, I) {
549
-				ctx.Default.Put(I)
550
-			}
551
-		case bool:
552
-			if ctx.Validate(ctx, I) {
553
-				ctx.Default.Put(I)
554
-			}
555
-		case time.Duration:
556
-			if ctx.Validate(ctx, I) {
557
-				ctx.Default.Put(I)
558
-			}
559
-		case *string:
560
-			if ctx.Validate(ctx, I) {
561
-				ctx.Default.Put(I)
562
-			}
563
-		case *[]string:
564
-			if ctx.Validate(ctx, I) {
565
-				ctx.Default.Put(I)
566
-			}
567
-		case *int:
568
-			if ctx.Validate(ctx, I) {
569
-				ctx.Default.Put(I)
570
-			}
571
-		case *float64:
572
-			if ctx.Validate(ctx, I) {
573
-				ctx.Default.Put(I)
574
-			}
575
-		case *bool:
576
-			if ctx.Validate(ctx, I) {
577
-				ctx.Default.Put(I)
578
-			}
579
-		case *time.Duration:
580
-			if ctx.Validate(ctx, I) {
581
-				ctx.Default.Put(I)
582
-			}
583
-		case nil:
584
-
585
-		default:
586
-			fmt.Println("type not found", ctx.Name, reflect.TypeOf(in))
587
-			return
588
-		}
589
-		// ctx.Value.Put(nil)
590
-	}
591
-}
592
-
593
-// Min attaches to the validator a test that enforces a minimum
594
-func Min(min int) RowGenerator {
595
-	return func(ctx *Row) {
596
-		ctx.Min = ctx.Min.Put(min)
597
-		v := ctx.Validate
598
-		var e error
599
-		ctx.Validate = func(r *Row, in interface{}) bool {
600
-			n := min
601
-			switch I := in.(type) {
602
-			case int:
603
-				n = I
604
-			case *int:
605
-				n = *I
606
-			case string:
607
-				n, e = strconv.Atoi(I)
608
-				if e != nil {
609
-					return false
610
-				}
611
-			case *string:
612
-				n, e = strconv.Atoi(*I)
613
-				if e != nil {
614
-					return false
615
-				}
616
-			}
617
-			if n < min {
618
-				return false
619
-				// in = min
620
-			}
621
-			// none of the above will affect if this wasn't an int
622
-			return v(r, in)
623
-		}
624
-	}
625
-}
626
-
627
-// Max attaches to the validator a test that enforces a maximum
628
-func Max(max int) RowGenerator {
629
-	return func(ctx *Row) {
630
-		ctx.Max = ctx.Max.Put(max)
631
-		v := ctx.Validate
632
-		var e error
633
-		ctx.Validate = func(r *Row, in interface{}) bool {
634
-			n := max
635
-			switch I := in.(type) {
636
-			case int:
637
-				n = I
638
-			case *int:
639
-				n = *I
640
-			case string:
641
-				n, e = strconv.Atoi(I)
642
-				if e != nil {
643
-					return false
644
-				}
645
-			case *string:
646
-				n, e = strconv.Atoi(*I)
647
-				if e != nil {
648
-					return false
649
-				}
650
-			}
651
-			if n > max {
652
-				return false
653
-				// in = max
654
-			}
655
-			// none of the above will affect if this wasn't an int
656
-			return v(r, in)
657
-		}
658
-	}
659
-}
660
-
661
-// RandomsString generates a random number and converts to base32 for
662
-// a default random password of some number of characters
663
-func RandomString(n int) RowGenerator {
664
-	const (
665
-		letterBytes   = "abcdefghijklmnopqrstuvwxyz234567"
666
-		letterIdxBits = 6                    // 6 bits to represent a letter index
667
-		letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
668
-		letterIdxMax  = 63 / letterIdxBits   // # of letter indices fitting in 63 bits
669
-	)
670
-	var src = rand.NewSource(time.Now().UnixNano())
671
-	return func(ctx *Row) {
672
-		b := make([]byte, n)
673
-		l := len(letterBytes)
674
-		// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
675
-		for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
676
-			if remain == 0 {
677
-				cache, remain = src.Int63(), letterIdxMax
678
-			}
679
-			if idx := int(cache & letterIdxMask); idx < l {
680
-				b[i] = letterBytes[idx]
681
-				i--
682
-			}
683
-			cache >>= letterIdxBits
684
-			remain--
685
-		}
686
-
687
-		sb := string(b)
688
-		ctx.Value = ctx.Value.Put(sb)
689
-	}
690
-}

+ 0
- 428
cmd/apptypes.go View File

@@ -1,428 +0,0 @@
1
-package cmd
2
-
3
-import (
4
-	"encoding/json"
5
-	"fmt"
6
-	"os"
7
-	"path/filepath"
8
-	"regexp"
9
-	"sort"
10
-	"time"
11
-
12
-	"git.parallelcoin.io/dev/9/cmd/nine"
13
-)
14
-
15
-type App struct {
16
-	Name     string
17
-	Tagline  string
18
-	About    string
19
-	Version  func() string
20
-	Default  func(ctx *App) int
21
-	Cats     Cats
22
-	Commands Commands
23
-	Config   *nine.Config
24
-}
25
-
26
-func (app *App) SaveConfig() {
27
-	if app == nil {
28
-		return
29
-	}
30
-	datadir, ok := app.Cats["app"]["datadir"].Value.Get().(string)
31
-	if !ok {
32
-		return
33
-	}
34
-	configFile := CleanAndExpandPath(filepath.Join(
35
-		datadir, "config"), "")
36
-	if EnsureDir(configFile) {
37
-	}
38
-	fh, err := os.Create(configFile)
39
-	if err != nil {
40
-		panic(err)
41
-	}
42
-	j, e := json.MarshalIndent(app, "", "\t")
43
-	if e != nil {
44
-		panic(e)
45
-	}
46
-	_, err = fmt.Fprint(fh, string(j))
47
-	if err != nil {
48
-		panic(err)
49
-	}
50
-}
51
-
52
-type Line struct {
53
-	Value   interface{} `json:"value"`
54
-	Default interface{} `json:"default,omitempty"`
55
-	Min     int         `json:"min,omitempty"`
56
-	Max     int         `json:"max,omitempty"`
57
-	Usage   string      `json:"usage"`
58
-}
59
-
60
-type CatJSON map[string]Line
61
-
62
-type CatsJSON map[string]CatJSON
63
-
64
-func (r *App) MarshalJSON() ([]byte, error) {
65
-	out := make(CatsJSON)
66
-	for i, x := range r.Cats {
67
-		out[i] = make(CatJSON)
68
-		for j, y := range x {
69
-			min, _ := y.Min.Get().(int)
70
-			max, _ := y.Max.Get().(int)
71
-			out[i][j] = Line{
72
-				Value:   y.Value.Get(),
73
-				Default: y.Default.Get(),
74
-				Min:     min,
75
-				Max:     max,
76
-				Usage:   y.Usage,
77
-			}
78
-		}
79
-	}
80
-	return json.Marshal(out)
81
-}
82
-
83
-func (r *App) UnmarshalJSON(data []byte) error {
84
-	out := make(CatsJSON)
85
-	e := json.Unmarshal(data, &out)
86
-	if e != nil {
87
-		return e
88
-	}
89
-	for i, x := range out {
90
-		for j, y := range x {
91
-			R := r.Cats[i][j]
92
-			if y.Value != nil {
93
-				switch R.Type {
94
-				case "int", "port":
95
-					y.Value = int(y.Value.(float64))
96
-				case "duration":
97
-					y.Value = time.Duration(int(y.Value.(float64)))
98
-				case "stringslice":
99
-					rt, ok := y.Value.([]string)
100
-					ro := []string{}
101
-					if ok {
102
-						for _, z := range rt {
103
-							R.Validate(R, z)
104
-							ro = append(ro, z)
105
-						}
106
-						// R.Value.Put(ro)
107
-					}
108
-					// break
109
-				case "float":
110
-				}
111
-			}
112
-			R.Validate(R, y.Value)
113
-			// R.Value.Put(y.Value)
114
-		}
115
-	}
116
-	return nil
117
-}
118
-
119
-type AppGenerator func(ctx *App)
120
-type AppGenerators []AppGenerator
121
-
122
-func (r *RowGenerators) RunAll(row *Row) {
123
-	for _, x := range *r {
124
-		x(row)
125
-	}
126
-}
127
-
128
-func (r *CommandGenerators) RunAll() *Command {
129
-	c := &Command{}
130
-	for _, x := range *r {
131
-		x(c)
132
-	}
133
-	return c
134
-}
135
-
136
-func (r *AppGenerators) RunAll(app *App) {
137
-	for _, x := range *r {
138
-		x(app)
139
-	}
140
-	return
141
-}
142
-
143
-type Cats map[string]Cat
144
-
145
-func (r *Cats) getValue(cat, item string) (out *interface{}) {
146
-	if r == nil {
147
-		return
148
-	} else if C, ok := (*r)[cat]; !ok {
149
-		return
150
-	} else if cc, ok := C[item]; !ok {
151
-		return
152
-	} else {
153
-		o := cc.Value.Get()
154
-		return &o
155
-	}
156
-}
157
-
158
-// Str returns the pointer to a value in the category map
159
-func (r *Cats) Str(cat, item string) (out *string) {
160
-	cv := r.getValue(cat, item)
161
-	if cv == nil {
162
-		return
163
-	}
164
-	CC := *cv
165
-	if ci, ok := CC.(string); !ok {
166
-		return
167
-	} else {
168
-		return &ci
169
-	}
170
-}
171
-
172
-// Tags returns the pointer to a value in the category map
173
-func (r *Cats) Tags(cat, item string) (out *[]string) {
174
-	cv := r.getValue(cat, item)
175
-	if cv == nil {
176
-		return
177
-	}
178
-	CC := *cv
179
-	if ci, ok := CC.([]string); !ok {
180
-		return
181
-	} else {
182
-		return &ci
183
-	}
184
-}
185
-
186
-// Map returns the pointer to a value in the category map
187
-func (r *Cats) Map(cat, item string) (out *nine.Mapstringstring) {
188
-	cv := r.getValue(cat, item)
189
-	if cv == nil {
190
-		return
191
-	}
192
-	CC := *cv
193
-	if ci, ok := CC.(nine.Mapstringstring); !ok {
194
-		return
195
-	} else {
196
-		return &ci
197
-	}
198
-}
199
-
200
-// Int returns the pointer to a value in the category map
201
-func (r *Cats) Int(cat, item string) (out *int) {
202
-	cv := r.getValue(cat, item)
203
-	if cv == nil {
204
-		return
205
-	}
206
-	CC := *cv
207
-	if ci, ok := CC.(int); !ok {
208
-		return
209
-	} else {
210
-		return &ci
211
-	}
212
-}
213
-
214
-// Bool returns the pointer to a value in the category map
215
-func (r *Cats) Bool(cat, item string) (out *bool) {
216
-	cv := r.getValue(cat, item)
217
-	if cv == nil {
218
-		return
219
-	}
220
-	CC := *cv
221
-	if ci, ok := CC.(bool); !ok {
222
-		return
223
-	} else {
224
-		return &ci
225
-	}
226
-}
227
-
228
-// Float returns the pointer to a value in the category map
229
-func (r *Cats) Float(cat, item string) (out *float64) {
230
-	cv := r.getValue(cat, item)
231
-	if cv == nil {
232
-		return
233
-	}
234
-	CC := *cv
235
-	if ci, ok := CC.(float64); !ok {
236
-		return
237
-	} else {
238
-		return &ci
239
-	}
240
-}
241
-
242
-// Duration returns the pointer to a value in the category map
243
-func (r *Cats) Duration(cat, item string) (out *time.Duration) {
244
-	cv := r.getValue(cat, item)
245
-	if cv == nil {
246
-		return
247
-	}
248
-	CC := *cv
249
-	if ci, ok := CC.(time.Duration); !ok {
250
-		return
251
-	} else {
252
-		return &ci
253
-	}
254
-}
255
-
256
-type Cat map[string]*Row
257
-type CatGenerator func(ctx *Ca