diff --git a/examples/templates/README.md.tmpl b/examples/templates/README.md.tmpl new file mode 100644 index 0000000000..462481d419 --- /dev/null +++ b/examples/templates/README.md.tmpl @@ -0,0 +1,3 @@ +# [{NAME}] + +Test case for [{NAME}]. diff --git a/examples/templates/go.mod.tmpl b/examples/templates/go.mod.tmpl new file mode 100644 index 0000000000..0641f9e2bf --- /dev/null +++ b/examples/templates/go.mod.tmpl @@ -0,0 +1,8 @@ +module github.com/TrueBlocks/trueblocks-core/examples/[{LOWER}] + +// Go Version +go 1.22 + +replace github.com/TrueBlocks/trueblocks-core/sdk => ../../sdk + +require github.com/TrueBlocks/trueblocks-core v2.5.8-release.0.20240422010715-cf442e547b61+incompatible // indirect diff --git a/examples/templates/main.go.tmpl b/examples/templates/main.go.tmpl new file mode 100644 index 0000000000..122187132b --- /dev/null +++ b/examples/templates/main.go.tmpl @@ -0,0 +1,28 @@ +package main + +import ( + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" +) + +func main() { + opts := sdk.BlocksOptions{ + BlockIds: []string{"latest"}, + } + + blocks, _, err := opts.Blocks() + if err != nil { + fmt.Println(err) + return + } + + fmt.Println("[") + for i, block := range blocks { + if i > 0 { + fmt.Println(",") + } + fmt.Println(block.String()) + } + fmt.Println("]") +} diff --git a/examples/templates/main_test.go.tmpl b/examples/templates/main_test.go.tmpl new file mode 100644 index 0000000000..b9777c3fd0 --- /dev/null +++ b/examples/templates/main_test.go.tmpl @@ -0,0 +1,9 @@ +package main + +import ( + "testing" +) + +func TestMainFunction(t *testing.T) { + main() +} diff --git a/examples/usesSdk/abis.go b/examples/usesSdk/abis.go new file mode 100644 index 0000000000..ae0ae1bc21 --- /dev/null +++ b/examples/usesSdk/abis.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" +) + +// DoAbis tests the When sdk function +func DoAbis() { + logger.Info("DoAbis") + + opts := sdk.AbisOptions{ + Addrs: []string{"uniswap.eth"}, + } + + if functions, _, err := opts.Abis(); err != nil { + logger.Fatal(err) + } else { + SaveToFile[types.Function]("usesSDK/abis.json", functions) + } +} diff --git a/examples/usesSdk/blocks.go b/examples/usesSdk/blocks.go new file mode 100644 index 0000000000..51ff9d6e0f --- /dev/null +++ b/examples/usesSdk/blocks.go @@ -0,0 +1,72 @@ +package main + +import ( + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" +) + +// DoBlocks tests the Blocks sdk function +func DoBlocks() { + logger.Info("DoBlocks") + + opts := sdk.BlocksOptions{ + BlockIds: testBlocks, + Globals: sdk.Globals{ + Cache: true, + }, + } + + if blocks, _, err := opts.Blocks(); err != nil { + logger.Fatal(err) + } else { + SaveToFile[types.Block[types.Transaction]]("usesSDK/blocks.json", blocks) + } + + opts.Hashes = true + if blocks, _, err := opts.BlocksHashes(); err != nil { + logger.Fatal(err) + } else { + SaveToFile[types.Block[string]]("usesSDK/blocks-hashes.json", blocks) + } + + opts.Hashes = false + opts.Traces = true + if traces, _, err := opts.BlocksTraces(); err != nil { + logger.Fatal(err) + } else { + SaveToFile[types.Trace]("usesSDK/blocks-traces.json", traces) + } + + opts.Traces = false + opts.Uniq = true + // if apps, _, err := opts.BlocksUniq(); err != nil { + // logger.Fatal(err) + // } else { + // SaveToFile[types.Appearance]("usesSDK/blocks-uniq.json", apps) + // } + + opts.Uniq = false + opts.Logs = true + if logs, _, err := opts.BlocksLogs(); err != nil { + logger.Fatal(err) + } else { + SaveToFile[types.Log]("usesSDK/blocks-logs.json", logs) + } + + opts.Logs = false + opts.Withdrawals = true + if withdrawals, _, err := opts.BlocksWithdrawals(); err != nil { + logger.Fatal(err) + } else { + SaveToFile[types.Withdrawal]("usesSDK/blocks-withdrawals.json", withdrawals) + } + + opts.Withdrawals = false + opts.Count = false + if counts, _, err := opts.BlocksCount(); err != nil { + logger.Fatal(err) + } else { + SaveToFile[types.BlockCount]("usesSDK/blocks-count.json", counts) + } +} diff --git a/examples/usesSdk/chunks.go b/examples/usesSdk/chunks.go new file mode 100644 index 0000000000..51a0934cd5 --- /dev/null +++ b/examples/usesSdk/chunks.go @@ -0,0 +1,34 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoChunks tests the When sdk function +func DoChunks() { + logger.Info("DoChunks") + + opts := sdk.ChunksOptions{ + Mode: sdk.CMIndex, + } + + buf := bytes.Buffer{} + if err := opts.ChunksBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/chunks.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *ChunksOptions) ChunksManifest() ([]types.ChunkRecord, *types.MetaData, error) { +// func (opts *ChunksOptions) ChunksIndex() ([]types.ChunkIndex, *types.MetaData, error) { +// func (opts *ChunksOptions) ChunksBlooms() ([]types.ChunkBloom, *types.MetaData, error) { +// func (opts *ChunksOptions) ChunksPins() ([]types.ChunkPinReport, *types.MetaData, error) { +// func (opts *ChunksOptions) ChunksAddresses() ([]types.ChunkAddress, *types.MetaData, error) { +// // func (opts *ChunksOptions) ChunksAppearances() ([]types.ChunkAppearance, *types.MetaData, error) { +// func (opts *ChunksOptions) ChunkStats() ([]types.ChunkStats, *types.MetaData, error) { diff --git a/examples/usesSdk/config.go b/examples/usesSdk/config.go new file mode 100644 index 0000000000..0d7f4773fd --- /dev/null +++ b/examples/usesSdk/config.go @@ -0,0 +1,27 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoConfig tests the When sdk function +func DoConfig() { + logger.Info("DoConfig") + + opts := sdk.ConfigOptions{ + Mode: sdk.CMShow, + } + + buf := bytes.Buffer{} + if err := opts.ConfigBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/config.json", buf.String()) + fmt.Println(buf.String()) +} diff --git a/examples/usesSdk/daemon.go b/examples/usesSdk/daemon.go new file mode 100644 index 0000000000..b682d4d35b --- /dev/null +++ b/examples/usesSdk/daemon.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoDaemon tests the When sdk function +func DoDaemon() { + logger.Info("DoDaemon") + + // opts := sdk.DaemonOptions{ + // Mode: sdk.CMIndex, + // } + + // buf := bytes.Buffer{} + // if err := opts.Daemon(&buf); err != nil { + // logger.Fatal(err) + // } + + file.StringToAsciiFile("usesSDK/daemon.json", "daemon is not an sdk option") +} diff --git a/examples/usesSdk/explore.go b/examples/usesSdk/explore.go new file mode 100644 index 0000000000..93a8bb4c34 --- /dev/null +++ b/examples/usesSdk/explore.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoExplore tests the When sdk function +func DoExplore() { + logger.Info("DoExplore") + + // opts := sdk.ExploreOptions{ + // Mode: sdk.CMIndex, + // } + + // buf := bytes.Buffer{} + // if err := opts.Explore(&buf); err != nil { + // logger.Fatal(err) + // } + + file.StringToAsciiFile("usesSDK/explore.json", "explore is not an SDK option") +} diff --git a/examples/usesSdk/export.go b/examples/usesSdk/export.go new file mode 100644 index 0000000000..a9a9052380 --- /dev/null +++ b/examples/usesSdk/export.go @@ -0,0 +1,36 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoExport tests the When sdk function +func DoExport() { + logger.Info("DoExport") + + opts := sdk.ExportOptions{ + Addrs: []string{testAddrs[0]}, + } + + buf := bytes.Buffer{} + if err := opts.ExportBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/export.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *ExportOptions) Export() ([]types.Transaction, *types.MetaData, error) { +// func (opts *ExportOptions) ExportAppearances() ([]types.Appearance, *types.MetaData, error) { +// func (opts *ExportOptions) ExportReceipts() ([]types.Receipt, *types.MetaData, error) { +// func (opts *ExportOptions) ExportLogs() ([]types.Log, *types.MetaData, error) { +// func (opts *ExportOptions) ExportTraces() ([]types.Trace, *types.MetaData, error) { +// func (opts *ExportOptions) ExportStatements() ([]types.Statement, *types.MetaData, error) { +// func (opts *ExportOptions) ExportBalances() ([]types.State, *types.MetaData, error) { +// func (opts *ExportOptions) ExportWithdrawals() ([]types.Withdrawal, *types.MetaData, error) { +// func (opts *ExportOptions) ExportCount() ([]types.AppearanceCount, *types.MetaData, error) { diff --git a/examples/usesSdk/go.mod b/examples/usesSdk/go.mod new file mode 100644 index 0000000000..93df02d7ab --- /dev/null +++ b/examples/usesSdk/go.mod @@ -0,0 +1,8 @@ +module github.com/TrueBlocks/trueblocks-core/examples/usesSdk + +// Go Version +go 1.22 + +replace github.com/TrueBlocks/trueblocks-core/sdk => ../../sdk + +require github.com/TrueBlocks/trueblocks-core v2.5.8-release.0.20240422010715-cf442e547b61+incompatible // indirect diff --git a/examples/usesSdk/init.go b/examples/usesSdk/init.go new file mode 100644 index 0000000000..7511788b61 --- /dev/null +++ b/examples/usesSdk/init.go @@ -0,0 +1,28 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoInit tests the When sdk function +func DoInit() { + logger.Info("DoInit") + + opts := sdk.InitOptions{ + All: true, + } + + buf := bytes.Buffer{} + if err := opts.InitBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/init.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *InitOptions) InitAll() ([]bool, *types.MetaData, error) { diff --git a/examples/usesSdk/list.go b/examples/usesSdk/list.go new file mode 100644 index 0000000000..757868d103 --- /dev/null +++ b/examples/usesSdk/list.go @@ -0,0 +1,30 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoList tests the When sdk function +func DoList() { + logger.Info("DoList") + + opts := sdk.ListOptions{ + Addrs: []string{testAddrs[0]}, + } + + buf := bytes.Buffer{} + if err := opts.ListBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/list.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *ListOptions) List() ([]types.Appearance, *types.MetaData, error) { +// func (opts *ListOptions) ListCount() ([]types.AppearanceCount, *types.MetaData, error) { +// func (opts *ListOptions) ListBounds() ([]types.Bounds, *types.MetaData, error) { diff --git a/examples/usesSdk/logs.go b/examples/usesSdk/logs.go new file mode 100644 index 0000000000..d1f8fd58c1 --- /dev/null +++ b/examples/usesSdk/logs.go @@ -0,0 +1,28 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoLogs tests the When sdk function +func DoLogs() { + logger.Info("DoLogs") + + opts := sdk.LogsOptions{ + TransactionIds: []string{"10001002.0"}, + } + + buf := bytes.Buffer{} + if err := opts.LogsBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/logs.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *LogsOptions) Logs() ([]types.Log, *types.MetaData, error) { diff --git a/examples/usesSdk/main.go b/examples/usesSdk/main.go new file mode 100644 index 0000000000..83b1aa0f00 --- /dev/null +++ b/examples/usesSdk/main.go @@ -0,0 +1,41 @@ +package main + +import "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + +func main() { + // DoSlurp() + // DoNames() + DoBlocks() + // DoTransactions() + // DoReceipts() + // DoLogs() + // DoTraces() + // DoState() + // DoTokens() + DoAbis() + // DoWhen() + // DoList() + // DoExport() + // DoMonitors() + // DoConfig() + // DoStatus() + // // DoDaemon() + // // DoScrape() + // DoChunks() + // // DoInit() + // DoExplore() +} + +var testBlocks = []string{ + "5001001", +} + +var testAddrs = []string{ + "0x054993ab0f2b1acc0fdc65405ee203b4271bebe6", +} + +func init() { + // These test cases drop files in the usesSDK folder. This line + // creates the folder in the cwd. + file.EstablishFolder("usesSDK") +} diff --git a/examples/usesSdk/main_test.go b/examples/usesSdk/main_test.go new file mode 100644 index 0000000000..732d224456 --- /dev/null +++ b/examples/usesSdk/main_test.go @@ -0,0 +1,8 @@ +package main + +import "testing" + +// UsesSDK is a simple function that calls the SDK +func TestUserSDK(t *testing.T) { + main() +} diff --git a/examples/usesSdk/monitors.go b/examples/usesSdk/monitors.go new file mode 100644 index 0000000000..c15921a85a --- /dev/null +++ b/examples/usesSdk/monitors.go @@ -0,0 +1,31 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoMonitors tests the When sdk function +func DoMonitors() { + logger.Info("DoMonitors") + + opts := sdk.MonitorsOptions{ + Addrs: []string{testAddrs[0]}, + List: true, + } + + buf := bytes.Buffer{} + if err := opts.MonitorsBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/monitors.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *MonitorsOptions) Monitors() ([]bool, *types.MetaData, error) { +// func (opts *MonitorsOptions) MonitorsClean() ([]types.MonitorClean, *types.MetaData, error) { +// func (opts *MonitorsOptions) MonitorsList() ([]types.Monitor, *types.MetaData, error) { diff --git a/examples/usesSdk/names.go b/examples/usesSdk/names.go new file mode 100644 index 0000000000..c7822845af --- /dev/null +++ b/examples/usesSdk/names.go @@ -0,0 +1,31 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoNames tests the When sdk function +func DoNames() { + logger.Info("DoNames") + + opts := sdk.NamesOptions{ + Terms: []string{"Giveth"}, + MatchCase: true, + } + + buf := bytes.Buffer{} + if err := opts.NamesBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/names.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *NamesOptions) Names() ([]types.Name, *types.MetaData, error) { +// func (opts *NamesOptions) NamesAddr() ([]base.Address, *types.MetaData, error) { +// func (opts *NamesOptions) NamesTags() ([]string, *types.MetaData, error) { diff --git a/examples/usesSdk/receipts.go b/examples/usesSdk/receipts.go new file mode 100644 index 0000000000..855fb90ed1 --- /dev/null +++ b/examples/usesSdk/receipts.go @@ -0,0 +1,28 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoReceipts tests the When sdk function +func DoReceipts() { + logger.Info("DoReceipts") + + opts := sdk.ReceiptsOptions{ + TransactionIds: []string{"10001002.0"}, + } + + buf := bytes.Buffer{} + if err := opts.ReceiptsBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/receipts.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *ReceiptsOptions) Receipts() ([]types.Receipt, *types.MetaData, error) { diff --git a/examples/usesSdk/save.go b/examples/usesSdk/save.go new file mode 100644 index 0000000000..7e51c624e7 --- /dev/null +++ b/examples/usesSdk/save.go @@ -0,0 +1,41 @@ +package main + +import ( + "bufio" + "fmt" + "os" +) + +// SaveToFile writes the content of the slice to a file specified by fn. +func SaveToFile[T fmt.Stringer](fn string, slice []T) error { + file, err := os.Create(fn) + if err != nil { + return err + } + defer file.Close() + + writer := bufio.NewWriter(file) + if _, err = writer.WriteString("[\n"); err != nil { + return err + } + + for i, item := range slice { + if i > 0 { + if _, err = writer.WriteString(","); err != nil { + return err + } + } + if writer.WriteString(fmt.Sprintf("%s\n", item.String())); err != nil { + return err + } + } + if _, err = writer.WriteString("]\n"); err != nil { + return err + } + + if writer.Flush(); err != nil { + return err + } + + return nil +} diff --git a/examples/usesSdk/slurp.go b/examples/usesSdk/slurp.go new file mode 100644 index 0000000000..feca60daaa --- /dev/null +++ b/examples/usesSdk/slurp.go @@ -0,0 +1,31 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoSlurp tests the When sdk function +func DoSlurp() { + logger.Info("DoSlurp") + + opts := sdk.SlurpOptions{ + Addrs: []string{testAddrs[0]}, + PerPage: 10, + } + + buf := bytes.Buffer{} + if err := opts.SlurpBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/slurp.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *SlurpOptions) Slurp() ([]types.Slurp, *types.MetaData, error) { +// func (opts *SlurpOptions) SlurpAppearances() ([]types.Appearance, *types.MetaData, error) { +// func (opts *SlurpOptions) SlurpCount() ([]types.SlurpCount, *types.MetaData, error) { diff --git a/examples/usesSdk/state.go b/examples/usesSdk/state.go new file mode 100644 index 0000000000..5c0e4ce66d --- /dev/null +++ b/examples/usesSdk/state.go @@ -0,0 +1,34 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoState tests the state sdk function +func DoState() { + logger.Info("DoState") + + opts := sdk.StateOptions{ + Globals: sdk.Globals{ + Verbose: true, + Cache: true, + }, + BlockIds: testBlocks, + Addrs: testAddrs, + } + + buf := bytes.Buffer{} + if err := opts.StateBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/state.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *StateOptions) State() ([]types.State, *types.MetaData, error) { +// func (opts *StateOptions) StateCall() ([]types.Result, *types.MetaData, error) { diff --git a/examples/usesSdk/status.go b/examples/usesSdk/status.go new file mode 100644 index 0000000000..0ed26fcc00 --- /dev/null +++ b/examples/usesSdk/status.go @@ -0,0 +1,27 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoStatus tests the When sdk function +func DoStatus() { + logger.Info("DoStatus") + + opts := sdk.StatusOptions{ + Modes: sdk.SMBlocks, + } + + buf := bytes.Buffer{} + if err := opts.StatusBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/status.json", buf.String()) + fmt.Println(buf.String()) +} diff --git a/examples/usesSdk/tokens.go b/examples/usesSdk/tokens.go new file mode 100644 index 0000000000..0acc59bf64 --- /dev/null +++ b/examples/usesSdk/tokens.go @@ -0,0 +1,28 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoTokens tests the When sdk function +func DoTokens() { + logger.Info("DoTokens") + + opts := sdk.TokensOptions{ + Addrs: []string{"ens.eth", "trueblocks.eth"}, + } + + buf := bytes.Buffer{} + if err := opts.TokensBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/tokens.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *TokensOptions) Tokens() ([]types.Token, *types.MetaData, error) { diff --git a/examples/usesSdk/traces.go b/examples/usesSdk/traces.go new file mode 100644 index 0000000000..4482b042c5 --- /dev/null +++ b/examples/usesSdk/traces.go @@ -0,0 +1,29 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoTraces tests the When sdk function +func DoTraces() { + logger.Info("DoTraces") + + opts := sdk.TracesOptions{ + TransactionIds: []string{"10001002.0"}, + } + + buf := bytes.Buffer{} + if err := opts.TracesBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/traces.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *TracesOptions) Traces() ([]types.Trace, *types.MetaData, error) { +// func (opts *TracesOptions) TracesCount() ([]types.TraceCount, *types.MetaData, error) { diff --git a/examples/usesSdk/transactions.go b/examples/usesSdk/transactions.go new file mode 100644 index 0000000000..c90da834b7 --- /dev/null +++ b/examples/usesSdk/transactions.go @@ -0,0 +1,31 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoTransactions tests the When sdk function +func DoTransactions() { + logger.Info("DoTransactions") + + opts := sdk.TransactionsOptions{ + TransactionIds: []string{"10001002.0"}, + } + + buf := bytes.Buffer{} + if err := opts.TransactionsBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/transactions.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *TransactionsOptions) Transactions() ([]types.Transaction, *types.MetaData, error) { +// func (opts *TransactionsOptions) TransactionsTraces() ([]types.Trace, *types.MetaData, error) { +// func (opts *TransactionsOptions) TransactionsUniq() ([]types.Appearance, *types.MetaData, error) { +// func (opts *TransactionsOptions) TransactionsLogs() ([]types.Log, *types.MetaData, error) { diff --git a/examples/usesSdk/when.go b/examples/usesSdk/when.go new file mode 100644 index 0000000000..6df03c9b58 --- /dev/null +++ b/examples/usesSdk/when.go @@ -0,0 +1,34 @@ +package main + +import ( + "bytes" + "fmt" + + "github.com/TrueBlocks/trueblocks-core/sdk" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +// DoWhen tests the When sdk function +func DoWhen() { + logger.Info("DoWhen") + + opts := sdk.WhenOptions{ + Globals: sdk.Globals{ + Verbose: true, + Cache: true, + }, + BlockIds: testBlocks, + } + + buf := bytes.Buffer{} + if err := opts.WhenBytes(&buf); err != nil { + logger.Fatal(err) + } + + file.StringToAsciiFile("usesSDK/when.json", buf.String()) + fmt.Println(buf.String()) +} +// func (opts *WhenOptions) When() ([]types.NamedBlock, *types.MetaData, error) { +// func (opts *WhenOptions) WhenTimestamps() ([]types.Timestamp, *types.MetaData, error) { +// func (opts *WhenOptions) WhenCount() ([]types.TimestampCount, *types.MetaData, error) { diff --git a/scripts/build-examples.sh b/scripts/build-examples.sh index 958f7f4154..67ab9ff096 100755 --- a/scripts/build-examples.sh +++ b/scripts/build-examples.sh @@ -5,16 +5,27 @@ # Purpose: This script sets up the build environment, # builds the project, and runs the tests. +#------------------------------------------------ +# Determine the directory where the script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + #------------------------------------------------ # Function to build a Go program build_target() { - echo "Building target $1" + echo "Built target examples/$1" (cd "$1" && go build -o "../../bin/examples/$1") } #------------------------------------------------ -# Build each target using the build_target function -cd examples -build_target simple -build_target findFirst -build_target balanceChart +# Begin script execution here +cd "$SCRIPT_DIR/../examples" || exit 1 # Exit if changing directory fails + +# Find directories containing a 'go.mod' file, search only direct children +find . -maxdepth 2 -type f -name 'go.mod' -exec dirname {} \; | while read -r dir; do + # Check for the presence of a '.skip' file in the directory + if [[ ! -f "$dir/.exclude" ]]; then + build_target "$(basename "$dir")" + else + echo "Skipping $dir due to .exclude file" + fi +done diff --git a/scripts/make-go-work.sh b/scripts/make-go-work.sh index 0a155fc82e..32147f14e9 100755 --- a/scripts/make-go-work.sh +++ b/scripts/make-go-work.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #------------------------------------------------ # Name: make-go-work.sh @@ -6,8 +6,11 @@ # to a go.work file, and runs go work sync #------------------------------------------------ +# Get the directory where the script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + # Navigate to the root of the repo -cd "$(dirname "$0")/.." +cd "$SCRIPT_DIR/.." #------------------------------------------------ # Check if the go.work file already exists @@ -37,5 +40,8 @@ done echo ")" >> $GO_WORK_FILE go work sync -cd - +#------------------------------------------------ +echo "Created go.work with these contents." +cat go.work +cd - 2>&1 > /dev/null exit 0 diff --git a/sdk/init.go b/sdk/init.go index 34f1683dae..ea463c239a 100644 --- a/sdk/init.go +++ b/sdk/init.go @@ -25,6 +25,7 @@ import ( type InitOptions struct { All bool `json:"all,omitempty"` + Example string `json:"example,omitempty"` DryRun bool `json:"dryRun,omitempty"` Publisher base.Address `json:"publisher,omitempty"` FirstBlock base.Blknum `json:"firstBlock,omitempty"` diff --git a/src/apps/chifra/.golangci.yml b/src/apps/chifra/.golangci.yml index e4e72de0d7..09493715c0 100644 --- a/src/apps/chifra/.golangci.yml +++ b/src/apps/chifra/.golangci.yml @@ -1,5 +1,5 @@ run: - exlude-files: + exclude-files: - ".*_test.go" linters: disable: diff --git a/src/apps/chifra/cmd/init.go b/src/apps/chifra/cmd/init.go index b29d368c5d..d8062e0f99 100644 --- a/src/apps/chifra/cmd/init.go +++ b/src/apps/chifra/cmd/init.go @@ -58,11 +58,13 @@ func init() { initCmd.Flags().SortFlags = false initCmd.Flags().BoolVarP(&initPkg.GetOptions().All, "all", "a", false, `in addition to Bloom filters, download full index chunks (recommended)`) + initCmd.Flags().StringVarP(&initPkg.GetOptions().Example, "example", "e", "", `create an example for the SDK with the given name (hidden)`) initCmd.Flags().BoolVarP(&initPkg.GetOptions().DryRun, "dry_run", "d", false, `display the results of the download without actually downloading`) initCmd.Flags().StringVarP(&initPkg.GetOptions().Publisher, "publisher", "P", "", `the publisher of the index to download (hidden)`) initCmd.Flags().Uint64VarP(&initPkg.GetOptions().FirstBlock, "first_block", "F", 0, `do not download any chunks earlier than this block`) initCmd.Flags().Float64VarP(&initPkg.GetOptions().Sleep, "sleep", "s", 0.0, `seconds to sleep between downloads`) if os.Getenv("TEST_MODE") != "true" { + _ = initCmd.Flags().MarkHidden("example") _ = initCmd.Flags().MarkHidden("publisher") } globals.InitGlobals("init", initCmd, &initPkg.GetOptions().Globals, capabilities) diff --git a/src/apps/chifra/internal/init/handle_example.go b/src/apps/chifra/internal/init/handle_example.go new file mode 100644 index 0000000000..3f9944f958 --- /dev/null +++ b/src/apps/chifra/internal/init/handle_example.go @@ -0,0 +1,46 @@ +// Copyright 2021 The TrueBlocks Authors. All rights reserved. +// Use of this source code is governed by a license that can +// be found in the LICENSE file. + +package initPkg + +import ( + "os" + "strings" + + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/utils" +) + +// HandleExample populates a subfolder of the ./examples folder with a skeleton +// of the files needed to run an example. This is a convenience function for +// developers to quickly get started with the example. +func (opts *InitOptions) HandleExample() error { + template := "" // will use opts.Template in the future + tmplFolder := "./templates/" + template // will later support opts.Template + + // We already know that the folder does not exist since it passed validation... + _ = os.MkdirAll("./"+opts.Example, 0755) + + logger.Info("Example created in ./" + opts.Example + " from " + tmplFolder) + + for _, fn := range []string{"main.go", "main_test.go", "go.mod", "README.md"} { + copyOne(fn, opts.Example, tmplFolder) + } + + // update the go.work file + os.Remove("../go.work") + utils.System("source ../scripts/make-go-work.sh") + + return nil +} + +func copyOne(fn, exName, tmplFolder string) { + contents := file.AsciiFileToString(tmplFolder + fn + ".tmpl") + contents = strings.ReplaceAll(contents, "[{NAME}]", utils.MakeFirstUpperCase(exName)) + contents = strings.ReplaceAll(contents, "[{LOWER}]", exName) + fn = "./" + exName + "/" + fn + _ = file.StringToAsciiFile(fn, contents) + logger.Info("\t==> " + fn) +} diff --git a/src/apps/chifra/internal/init/options.go b/src/apps/chifra/internal/init/options.go index 5aaa7f0426..0089e80933 100644 --- a/src/apps/chifra/internal/init/options.go +++ b/src/apps/chifra/internal/init/options.go @@ -28,6 +28,7 @@ import ( // InitOptions provides all command options for the chifra init command. type InitOptions struct { All bool `json:"all,omitempty"` // In addition to Bloom filters, download full index chunks (recommended) + Example string `json:"example,omitempty"` // Create an example for the SDK with the given name DryRun bool `json:"dryRun,omitempty"` // Display the results of the download without actually downloading Publisher string `json:"publisher,omitempty"` // The publisher of the index to download FirstBlock uint64 `json:"firstBlock,omitempty"` // Do not download any chunks earlier than this block @@ -45,6 +46,7 @@ var defaultInitOptions = InitOptions{} // testLog is used only during testing to export the options for this test case. func (opts *InitOptions) testLog() { logger.TestLog(opts.All, "All: ", opts.All) + logger.TestLog(len(opts.Example) > 0, "Example: ", opts.Example) logger.TestLog(opts.DryRun, "DryRun: ", opts.DryRun) logger.TestLog(len(opts.Publisher) > 0, "Publisher: ", opts.Publisher) logger.TestLog(opts.FirstBlock != 0, "FirstBlock: ", opts.FirstBlock) @@ -75,6 +77,8 @@ func InitFinishParseInternal(w io.Writer, values url.Values) *InitOptions { switch key { case "all": opts.All = true + case "example": + opts.Example = value[0] case "dryRun": opts.DryRun = true case "publisher": diff --git a/src/apps/chifra/internal/init/output.go b/src/apps/chifra/internal/init/output.go index f3acd9389b..8c405f5761 100644 --- a/src/apps/chifra/internal/init/output.go +++ b/src/apps/chifra/internal/init/output.go @@ -52,6 +52,8 @@ func (opts *InitOptions) InitInternal() error { // EXISTING_CODE if opts.DryRun { err = opts.HandleDryRun() + } else if len(opts.Example) > 0 { + err = opts.HandleExample() } else { err = opts.HandleInit() } diff --git a/src/apps/chifra/internal/init/validate.go b/src/apps/chifra/internal/init/validate.go index 23915f9a43..c48bf0be94 100644 --- a/src/apps/chifra/internal/init/validate.go +++ b/src/apps/chifra/internal/init/validate.go @@ -5,8 +5,14 @@ package initPkg import ( + "fmt" + "os" + "strings" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/history" + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/usage" "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/validate" ) @@ -34,9 +40,27 @@ func (opts *InitOptions) validateInit() error { } } - historyFile := config.PathToCache(chain) + "tmp/history.txt" - if history.FromHistoryBool(historyFile, "init") && !opts.All { - return validate.Usage("You previously called chifra init --all. You must continue to do so.") + if len(opts.Example) > 0 { + cwd, _ := os.Getwd() + if !strings.HasSuffix(cwd, "examples") { + return fmt.Errorf("must be in the ./examples directory to run this command") + } + + if valid, err := file.IsValidFolderName(opts.Example); err != nil { + return usage.Usage("{0} {1}", opts.Example, fmt.Sprintf("%v", err)) + } else if !valid { + return usage.Usage("{0} is not a valid folder name", opts.Example) + } + // if len(opts.Template) > 0 { + // must exist + // } + // } else if len(opts.Template) > 0 { + // return validate.Usage("The {0} option requires the {1} flag.", "--template", "--example") + } else { + historyFile := config.PathToCache(chain) + "tmp/history.txt" + if history.FromHistoryBool(historyFile, "init") && !opts.All { + return validate.Usage("You previously called chifra init --all. You must continue to do so.") + } } return opts.Globals.Validate() diff --git a/src/apps/chifra/pkg/base/address.go b/src/apps/chifra/pkg/base/address.go index 06839a5b35..13254fde1a 100644 --- a/src/apps/chifra/pkg/base/address.go +++ b/src/apps/chifra/pkg/base/address.go @@ -67,6 +67,13 @@ func (a *Address) IsZero() bool { return v == "0x0000000000000000000000000000000000000000" } +func (e *Address) UnmarshalJSON(data []byte) error { + if string(data) == "\"0x0\"" { + return nil + } + return e.Address.UnmarshalJSON(data) +} + func (a *Address) Common() common.Address { return common.BytesToAddress(a.Bytes()) } diff --git a/src/apps/chifra/pkg/base/hash.go b/src/apps/chifra/pkg/base/hash.go index cafe598509..a9bebd4cf1 100644 --- a/src/apps/chifra/pkg/base/hash.go +++ b/src/apps/chifra/pkg/base/hash.go @@ -38,6 +38,13 @@ func (h Hash) MarshalText() ([]byte, error) { return []byte(h.Hex()), nil } +func (h *Hash) UnmarshalJSON(data []byte) error { + if string(data) == "\"0x0\"" { + return nil + } + return h.Hash.UnmarshalJSON(data) +} + // SetHex sets the hash based on the provided string func (h *Hash) SetHex(hexStr string) { h.Hash = common.HexToHash(hexStr) diff --git a/src/apps/chifra/pkg/file/folder.go b/src/apps/chifra/pkg/file/folder.go index 9285430e56..0c18a20fce 100644 --- a/src/apps/chifra/pkg/file/folder.go +++ b/src/apps/chifra/pkg/file/folder.go @@ -5,9 +5,11 @@ package file import ( + "fmt" "io" "os" "path/filepath" + "strings" ) func IsFolderEmpty(folder string) (bool, error) { @@ -38,3 +40,21 @@ func CleanFolder(chain, rootFolder string, subFolders []string) error { return nil } + +// IsValidFolderName checks if the folder name is valid and does not exist in the current directory. +func IsValidFolderName(folderName string) (bool, error) { + // Check for invalid characters (example for a simple Unix-like rule) + // You might need a more specific check depending on your OS requirements. + if strings.ContainsAny(folderName, "/<>:\"\\|?*") { + return false, fmt.Errorf("folder name contains invalid characters") + } + + // Check if folder exists + if _, err := os.Stat(folderName); err == nil { + return false, fmt.Errorf("folder already exists") + } else if !os.IsNotExist(err) { + return false, err // some other error occurred when checking the folder + } + + return true, nil +} diff --git a/src/apps/chifra/pkg/types/types_abi.go b/src/apps/chifra/pkg/types/types_abi.go index 60cf45d8ed..c4f65fda1c 100644 --- a/src/apps/chifra/pkg/types/types_abi.go +++ b/src/apps/chifra/pkg/types/types_abi.go @@ -32,7 +32,7 @@ type Abi struct { // EXISTING_CODE } -func (s *Abi) String() string { +func (s Abi) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_appearance.go b/src/apps/chifra/pkg/types/types_appearance.go index df0a9f937e..6ce7f548ec 100644 --- a/src/apps/chifra/pkg/types/types_appearance.go +++ b/src/apps/chifra/pkg/types/types_appearance.go @@ -52,7 +52,7 @@ type Appearance struct { // EXISTING_CODE } -func (s *Appearance) String() string { +func (s Appearance) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_appearanceTable.go b/src/apps/chifra/pkg/types/types_appearanceTable.go index fa9d720261..d2f2a10933 100644 --- a/src/apps/chifra/pkg/types/types_appearanceTable.go +++ b/src/apps/chifra/pkg/types/types_appearanceTable.go @@ -43,7 +43,7 @@ type AppearanceTable struct { // EXISTING_CODE } -func (s *AppearanceTable) String() string { +func (s AppearanceTable) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_appearancecount.go b/src/apps/chifra/pkg/types/types_appearancecount.go index e7e69a0161..5baba3b8a3 100644 --- a/src/apps/chifra/pkg/types/types_appearancecount.go +++ b/src/apps/chifra/pkg/types/types_appearancecount.go @@ -34,7 +34,7 @@ type AppearanceCount struct { // EXISTING_CODE } -func (s *AppearanceCount) String() string { +func (s AppearanceCount) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_block.go b/src/apps/chifra/pkg/types/types_block.go index 636441a846..523b350eb3 100644 --- a/src/apps/chifra/pkg/types/types_block.go +++ b/src/apps/chifra/pkg/types/types_block.go @@ -69,7 +69,7 @@ type Block[Tx string | Transaction] struct { // EXISTING_CODE } -func (s *Block[Tx]) String() string { +func (s Block[Tx]) String() string { bytes, _ := json.Marshal(s) return string(bytes) } @@ -147,7 +147,7 @@ func (s *Block[Tx]) Model(chain, format string, verbose bool, extraOptions map[s "difficulty": s.Difficulty, "timestamp": s.Timestamp, "date": s.Date(), - "baseFeePerGas": s.BaseFeePerGas.Uint64(), + "baseFeePerGas": base.FormattedValue(&s.BaseFeePerGas, false, 18), } order = []string{ diff --git a/src/apps/chifra/pkg/types/types_blockcount.go b/src/apps/chifra/pkg/types/types_blockcount.go index f77de2db9f..5607d41f65 100644 --- a/src/apps/chifra/pkg/types/types_blockcount.go +++ b/src/apps/chifra/pkg/types/types_blockcount.go @@ -45,7 +45,7 @@ type BlockCount struct { // EXISTING_CODE } -func (s *BlockCount) String() string { +func (s BlockCount) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_bounds.go b/src/apps/chifra/pkg/types/types_bounds.go index fb4b2c6893..e079557106 100644 --- a/src/apps/chifra/pkg/types/types_bounds.go +++ b/src/apps/chifra/pkg/types/types_bounds.go @@ -40,7 +40,7 @@ type Bounds struct { // EXISTING_CODE } -func (s *Bounds) String() string { +func (s Bounds) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_cacheitem.go b/src/apps/chifra/pkg/types/types_cacheitem.go index f113b0bf80..b3c54d448e 100644 --- a/src/apps/chifra/pkg/types/types_cacheitem.go +++ b/src/apps/chifra/pkg/types/types_cacheitem.go @@ -40,7 +40,7 @@ type CacheItem struct { // EXISTING_CODE } -func (s *CacheItem) String() string { +func (s CacheItem) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_chain.go b/src/apps/chifra/pkg/types/types_chain.go index f4f5918151..236a011a14 100644 --- a/src/apps/chifra/pkg/types/types_chain.go +++ b/src/apps/chifra/pkg/types/types_chain.go @@ -38,7 +38,7 @@ type Chain struct { // EXISTING_CODE } -func (s *Chain) String() string { +func (s Chain) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_chunkaddress.go b/src/apps/chifra/pkg/types/types_chunkaddress.go index 56af5fd57d..42da841cfa 100644 --- a/src/apps/chifra/pkg/types/types_chunkaddress.go +++ b/src/apps/chifra/pkg/types/types_chunkaddress.go @@ -36,7 +36,7 @@ type ChunkAddress struct { // EXISTING_CODE } -func (s *ChunkAddress) String() string { +func (s ChunkAddress) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_chunkbloom.go b/src/apps/chifra/pkg/types/types_chunkbloom.go index 3b1c74eb12..4ccabc145e 100644 --- a/src/apps/chifra/pkg/types/types_chunkbloom.go +++ b/src/apps/chifra/pkg/types/types_chunkbloom.go @@ -44,7 +44,7 @@ type ChunkBloom struct { // EXISTING_CODE } -func (s *ChunkBloom) String() string { +func (s ChunkBloom) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_chunkindex.go b/src/apps/chifra/pkg/types/types_chunkindex.go index aa4d0281bd..5ad8f24a90 100644 --- a/src/apps/chifra/pkg/types/types_chunkindex.go +++ b/src/apps/chifra/pkg/types/types_chunkindex.go @@ -40,7 +40,7 @@ type ChunkIndex struct { // EXISTING_CODE } -func (s *ChunkIndex) String() string { +func (s ChunkIndex) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_chunkpinreport.go b/src/apps/chifra/pkg/types/types_chunkpinreport.go index ee03c466c5..2dc89a69a1 100644 --- a/src/apps/chifra/pkg/types/types_chunkpinreport.go +++ b/src/apps/chifra/pkg/types/types_chunkpinreport.go @@ -38,7 +38,7 @@ type ChunkPinReport struct { // EXISTING_CODE } -func (s *ChunkPinReport) String() string { +func (s ChunkPinReport) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_chunkrecord.go b/src/apps/chifra/pkg/types/types_chunkrecord.go index a09d1e8133..f1af5d6f0e 100644 --- a/src/apps/chifra/pkg/types/types_chunkrecord.go +++ b/src/apps/chifra/pkg/types/types_chunkrecord.go @@ -38,7 +38,7 @@ type ChunkRecord struct { // EXISTING_CODE } -func (s *ChunkRecord) String() string { +func (s ChunkRecord) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_chunkstats.go b/src/apps/chifra/pkg/types/types_chunkstats.go index 45af51886e..9eb1bbed3f 100644 --- a/src/apps/chifra/pkg/types/types_chunkstats.go +++ b/src/apps/chifra/pkg/types/types_chunkstats.go @@ -50,7 +50,7 @@ type ChunkStats struct { // EXISTING_CODE } -func (s *ChunkStats) String() string { +func (s ChunkStats) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_function.go b/src/apps/chifra/pkg/types/types_function.go index b4c40db2b0..6990993afc 100644 --- a/src/apps/chifra/pkg/types/types_function.go +++ b/src/apps/chifra/pkg/types/types_function.go @@ -59,7 +59,7 @@ type Function struct { // EXISTING_CODE } -func (s *Function) String() string { +func (s Function) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_ipfspin.go b/src/apps/chifra/pkg/types/types_ipfspin.go index 153ec50ab6..339105333c 100644 --- a/src/apps/chifra/pkg/types/types_ipfspin.go +++ b/src/apps/chifra/pkg/types/types_ipfspin.go @@ -39,7 +39,7 @@ type IpfsPin struct { // EXISTING_CODE } -func (s *IpfsPin) String() string { +func (s IpfsPin) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_log.go b/src/apps/chifra/pkg/types/types_log.go index 6da1114eed..0a5c11f97d 100644 --- a/src/apps/chifra/pkg/types/types_log.go +++ b/src/apps/chifra/pkg/types/types_log.go @@ -54,7 +54,7 @@ type Log struct { // EXISTING_CODE } -func (s *Log) String() string { +func (s Log) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_logfilter.go b/src/apps/chifra/pkg/types/types_logfilter.go index 6c986618f1..2493dce7d1 100644 --- a/src/apps/chifra/pkg/types/types_logfilter.go +++ b/src/apps/chifra/pkg/types/types_logfilter.go @@ -38,7 +38,7 @@ type LogFilter struct { // EXISTING_CODE } -func (s *LogFilter) String() string { +func (s LogFilter) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_manifest.go b/src/apps/chifra/pkg/types/types_manifest.go index 2bb38c97bf..554864e32b 100644 --- a/src/apps/chifra/pkg/types/types_manifest.go +++ b/src/apps/chifra/pkg/types/types_manifest.go @@ -36,7 +36,7 @@ type Manifest struct { // EXISTING_CODE } -func (s *Manifest) String() string { +func (s Manifest) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_monitor.go b/src/apps/chifra/pkg/types/types_monitor.go index 7ff424b444..9a5b9a4caa 100644 --- a/src/apps/chifra/pkg/types/types_monitor.go +++ b/src/apps/chifra/pkg/types/types_monitor.go @@ -33,7 +33,7 @@ type Monitor struct { // EXISTING_CODE } -func (s *Monitor) String() string { +func (s Monitor) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_monitorclean.go b/src/apps/chifra/pkg/types/types_monitorclean.go index 5232e3463a..66d95f9706 100644 --- a/src/apps/chifra/pkg/types/types_monitorclean.go +++ b/src/apps/chifra/pkg/types/types_monitorclean.go @@ -36,7 +36,7 @@ type MonitorClean struct { // EXISTING_CODE } -func (s *MonitorClean) String() string { +func (s MonitorClean) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_name.go b/src/apps/chifra/pkg/types/types_name.go index 4af397a170..722c844a54 100644 --- a/src/apps/chifra/pkg/types/types_name.go +++ b/src/apps/chifra/pkg/types/types_name.go @@ -58,7 +58,7 @@ type Name struct { // EXISTING_CODE } -func (s *Name) String() string { +func (s Name) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_namedblock.go b/src/apps/chifra/pkg/types/types_namedblock.go index ee7155ad81..99c240acab 100644 --- a/src/apps/chifra/pkg/types/types_namedblock.go +++ b/src/apps/chifra/pkg/types/types_namedblock.go @@ -39,7 +39,7 @@ type NamedBlock struct { // EXISTING_CODE } -func (s *NamedBlock) String() string { +func (s NamedBlock) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_parameter.go b/src/apps/chifra/pkg/types/types_parameter.go index 164137f633..e73e2a4ac4 100644 --- a/src/apps/chifra/pkg/types/types_parameter.go +++ b/src/apps/chifra/pkg/types/types_parameter.go @@ -44,7 +44,7 @@ type Parameter struct { // EXISTING_CODE } -func (s *Parameter) String() string { +func (s Parameter) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_receipt.go b/src/apps/chifra/pkg/types/types_receipt.go index 3a056e83be..7be6cb67bc 100644 --- a/src/apps/chifra/pkg/types/types_receipt.go +++ b/src/apps/chifra/pkg/types/types_receipt.go @@ -61,7 +61,7 @@ type Receipt struct { // EXISTING_CODE } -func (s *Receipt) String() string { +func (s Receipt) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_reportcheck.go b/src/apps/chifra/pkg/types/types_reportcheck.go index 01e85618b3..d2672cb290 100644 --- a/src/apps/chifra/pkg/types/types_reportcheck.go +++ b/src/apps/chifra/pkg/types/types_reportcheck.go @@ -42,7 +42,7 @@ type ReportCheck struct { // EXISTING_CODE } -func (s *ReportCheck) String() string { +func (s ReportCheck) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_result.go b/src/apps/chifra/pkg/types/types_result.go index 270c341d63..51d1e8d09d 100644 --- a/src/apps/chifra/pkg/types/types_result.go +++ b/src/apps/chifra/pkg/types/types_result.go @@ -51,7 +51,7 @@ type Result struct { // EXISTING_CODE } -func (s *Result) String() string { +func (s Result) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_slurp.go b/src/apps/chifra/pkg/types/types_slurp.go index dfa80e663b..64f77b03c5 100644 --- a/src/apps/chifra/pkg/types/types_slurp.go +++ b/src/apps/chifra/pkg/types/types_slurp.go @@ -84,7 +84,7 @@ type Slurp struct { // EXISTING_CODE } -func (s *Slurp) String() string { +func (s Slurp) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_slurpcount.go b/src/apps/chifra/pkg/types/types_slurpcount.go index 7f06fe6acd..f9bd3aa042 100644 --- a/src/apps/chifra/pkg/types/types_slurpcount.go +++ b/src/apps/chifra/pkg/types/types_slurpcount.go @@ -32,7 +32,7 @@ type SlurpCount struct { // EXISTING_CODE } -func (s *SlurpCount) String() string { +func (s SlurpCount) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_state.go b/src/apps/chifra/pkg/types/types_state.go index c5180e4c98..3a0e57bd18 100644 --- a/src/apps/chifra/pkg/types/types_state.go +++ b/src/apps/chifra/pkg/types/types_state.go @@ -52,7 +52,7 @@ type State struct { // EXISTING_CODE } -func (s *State) String() string { +func (s State) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_statement.go b/src/apps/chifra/pkg/types/types_statement.go index 287a9d18d2..1c1a11c5b5 100644 --- a/src/apps/chifra/pkg/types/types_statement.go +++ b/src/apps/chifra/pkg/types/types_statement.go @@ -99,7 +99,7 @@ type Statement struct { // EXISTING_CODE } -func (s *Statement) String() string { +func (s Statement) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_status.go b/src/apps/chifra/pkg/types/types_status.go index 465a0ed671..18dbf81ef3 100644 --- a/src/apps/chifra/pkg/types/types_status.go +++ b/src/apps/chifra/pkg/types/types_status.go @@ -72,7 +72,7 @@ type Status struct { // EXISTING_CODE } -func (s *Status) String() string { +func (s Status) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_timestamp.go b/src/apps/chifra/pkg/types/types_timestamp.go index 8bd23ba5b8..34131ef0f9 100644 --- a/src/apps/chifra/pkg/types/types_timestamp.go +++ b/src/apps/chifra/pkg/types/types_timestamp.go @@ -35,7 +35,7 @@ type Timestamp struct { // EXISTING_CODE } -func (s *Timestamp) String() string { +func (s Timestamp) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_timestampcount.go b/src/apps/chifra/pkg/types/types_timestampcount.go index 1b09d4502a..2cc15b06fb 100644 --- a/src/apps/chifra/pkg/types/types_timestampcount.go +++ b/src/apps/chifra/pkg/types/types_timestampcount.go @@ -28,7 +28,7 @@ type TimestampCount struct { // EXISTING_CODE } -func (s *TimestampCount) String() string { +func (s TimestampCount) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_token.go b/src/apps/chifra/pkg/types/types_token.go index 7ad8dfdff8..fc36cf0131 100644 --- a/src/apps/chifra/pkg/types/types_token.go +++ b/src/apps/chifra/pkg/types/types_token.go @@ -55,7 +55,7 @@ type Token struct { // EXISTING_CODE } -func (s *Token) String() string { +func (s Token) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_trace.go b/src/apps/chifra/pkg/types/types_trace.go index 382895208a..8a184d5319 100644 --- a/src/apps/chifra/pkg/types/types_trace.go +++ b/src/apps/chifra/pkg/types/types_trace.go @@ -61,7 +61,7 @@ type Trace struct { // EXISTING_CODE } -func (s *Trace) String() string { +func (s Trace) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_traceaction.go b/src/apps/chifra/pkg/types/types_traceaction.go index e02ef6b9b5..e5dafe0ca0 100644 --- a/src/apps/chifra/pkg/types/types_traceaction.go +++ b/src/apps/chifra/pkg/types/types_traceaction.go @@ -57,7 +57,7 @@ type TraceAction struct { // EXISTING_CODE } -func (s *TraceAction) String() string { +func (s TraceAction) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_tracecount.go b/src/apps/chifra/pkg/types/types_tracecount.go index 69665737d2..2bec6be283 100644 --- a/src/apps/chifra/pkg/types/types_tracecount.go +++ b/src/apps/chifra/pkg/types/types_tracecount.go @@ -39,7 +39,7 @@ type TraceCount struct { // EXISTING_CODE } -func (s *TraceCount) String() string { +func (s TraceCount) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_tracefilter.go b/src/apps/chifra/pkg/types/types_tracefilter.go index e70eeda0c9..d088476724 100644 --- a/src/apps/chifra/pkg/types/types_tracefilter.go +++ b/src/apps/chifra/pkg/types/types_tracefilter.go @@ -43,7 +43,7 @@ type TraceFilter struct { // EXISTING_CODE } -func (s *TraceFilter) String() string { +func (s TraceFilter) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_traceresult.go b/src/apps/chifra/pkg/types/types_traceresult.go index f9b0b6cde4..44ee9858a3 100644 --- a/src/apps/chifra/pkg/types/types_traceresult.go +++ b/src/apps/chifra/pkg/types/types_traceresult.go @@ -40,7 +40,7 @@ type TraceResult struct { // EXISTING_CODE } -func (s *TraceResult) String() string { +func (s TraceResult) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_transaction.go b/src/apps/chifra/pkg/types/types_transaction.go index 1517b8672c..2b5122e5c9 100644 --- a/src/apps/chifra/pkg/types/types_transaction.go +++ b/src/apps/chifra/pkg/types/types_transaction.go @@ -99,7 +99,7 @@ type Transaction struct { // EXISTING_CODE } -func (s *Transaction) String() string { +func (s Transaction) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/apps/chifra/pkg/types/types_withdrawal.go b/src/apps/chifra/pkg/types/types_withdrawal.go index 05dedb94c9..bff54f7406 100644 --- a/src/apps/chifra/pkg/types/types_withdrawal.go +++ b/src/apps/chifra/pkg/types/types_withdrawal.go @@ -46,7 +46,7 @@ type Withdrawal struct { // EXISTING_CODE } -func (s *Withdrawal) String() string { +func (s Withdrawal) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/dev_tools/goMaker/README.md b/src/dev_tools/goMaker/README.md index f2252b1a7f..3f47daaf28 100644 --- a/src/dev_tools/goMaker/README.md +++ b/src/dev_tools/goMaker/README.md @@ -1,15 +1,85 @@ ## goMaker -`goMaker` is development-only tool that aids in various aspects of building TrueBlocks. The program is disabled for most users, -but for core developers it can be used to automatically generate help files, API interface specs, command line options parsers -and many of the test case files. Generally, regular users will not use `goMaker`. +`goMaker` is development-only tool that aids in various aspects of building TrueBlocks. The program is +disabled for most users, but for core developers it can be used to automatically generate help files, +API interface specs, command line options parsers and many of the test case files. Generally, regular +users will not use `goMaker`. ### Usage `Usage:` goMaker -`Purpose:` Automatically writes files various purposes. +`Purpose:` Automatically writes files for various purposes. `Notes:` - You must run this tool from the root of the TrueBlocks repository. -- Template files are stored in ./src/dev_tools/goMaker/templates and ./src/other/data-models/. +- Template files are stored in ./src/dev_tools/goMaker/templates. +- No command line options are accepted. + +### Notes on Commands + +The options, notes, and descriptions for the `chifra` subcommands are stored in a file +called `cmd-line-options.csv` in the folder mentioned above. This file is a CSV file +with the following fields: + +| Name | Description | Notes | +| ------------ | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------ | +| num | internal use | | +| folder | the type of the tool | one of \[`apps` \| `tools`\] | +| group | the group to which the item belongs | one of \[ `Accounts` \| `Admin` \| `Chain Data` \| `Chain State` \| `Other` \] | +| route | the subcommand | also called route in various places | +| tool | internal use | an artifact from previous versions of goMaker | +| longName | the name of option | may be empty for some special types of rows | +| hotKey | hot key for the option | may be empty | +| def_val | default for the option | most likely empty | +| attributes | attributes for the option | any combination of \[ `visible` \| `required` \| `docs` \| `config` \] (see below) | +| option_type | the option's type | \[ `group` \| `command` \| `positional` \| `flag` \| `switch` \| `note` \| `alias` \] (see below) | +| data_type | the option's data type | various combinations of `basic types`, `enums`, `lists`, or `lists of enums` (see below) | +| return_type | the type of structure returned | if present, the type of the structure returned by the associated SDK routine (see below) | +| summary | the summary for the subcommand | displayed by `chifra --help` | +| usage | the format of the arguments | in true Linux fashion | +| capabilities | the command's global capabilities | see [this explaination](https://github.com/TrueBlocks/trueblocks-core/blob/develop/docs/content/chifra/globals.md) | +| description | the subcommand's full description | shown with `chifra cmd --help` | + +- `attributes` is a pipe (`|`) separated list of the following: + - `visible` - the option is visible on the command line, hidden (but available) otherwise + - `required` - the option is required + - `docs` - the option is documented (if present, `visible` must be `true`) + - `config` - the option is a configuration file option (documented in the help file, not available on the command line) + +- `option_type` is one of the following: + - `group` - the broad group the subcommand belongs to in the documentation + - `command` - the subcommand's controling row in the `cmd-line-options.csv` file (used for documentation only) + - `positional` - a positional argument (a command line argument without a leading `--option`) + - `flag` - a flag (a command line argument that requires a trailing value) + - `switch` - a switch (a boolean command line argument) + - `note` - a note (used for documentation only, this appears in the notes section of the READMEs) + - `alias` - an alias (used for the Hugo website only, this aliases old pages) + +### Notes on Data Models + +The `goMaker` program also generates a huge number of source code files and documentation related to the various data models produced or consumed by the various TrueBlocks tools. These data models are stored in `.toml` files in the `./src/dev_tools/goMaker/templates/classDefinitions` folder and the model's fields (in a `.csv`) are stored in a subfolder called `fields`. There are two files for each data model (a `.toml` and a `.csv`) names identically to the data model's name. + +The `.toml` file contains the following fields: + +| Name | Description | Notes | +| ------------ | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | +| class | the name of teh data model in lower case | | +| contained_by | if this data model is contained by other models, the list of other models | | +| doc_group | corresponds the subcommand's group for documentation purposes | | +| doc_route | corresponds to the subsection of the data model documentation for this type | poorly named | +| doc_descr | the short description for this type | see below | +| go_output | if not empty, the destination folder for the generated code. Disabled if empty | | +| go_model | an override for the generic (i.e. somewhat complicated) `Blocks` model only | | +| produced_by | a list of commands that produces this data model | | +| cache_as | if set to `group`, the cache for this type is a slice. A single value otherwise. | | +| cache_by | the fields by which to identify cache items | (one of \[ `address,block` \| `address,block,fourbyte` \| `address,tx` \| `block` \| `tx` \] | +| cache_type | one of \[ `cacheable` \| `marshal_only` \] | | + +### Notes on Templates + +The `./src/dev_tools/goMaker/templates` folder also contains a number of templates used by the `goMaker` program. The names of these templates corresponds to the location in the repo's paths the generated files will be written. For example, the `./sdk_route.go.tmpl` writes files to the `./sdk` folder. The filename of the file is `.go` where `` is the route of the subcommand. The template name may contain the word "route" or the word "type" which is sequentially replaced with either the routes or the data model types. + +### Fin + +Enough already. Experiment if you must. diff --git a/src/dev_tools/goMaker/templates/classDefinitions/appearance.toml b/src/dev_tools/goMaker/templates/classDefinitions/appearance.toml index 63ddecfbba..f141177ac7 100644 --- a/src/dev_tools/goMaker/templates/classDefinitions/appearance.toml +++ b/src/dev_tools/goMaker/templates/classDefinitions/appearance.toml @@ -1,6 +1,6 @@ [settings] class = "Appearance" - contained_by = "Monitor" + contained_by = "monitor" doc_group = "01-Accounts" doc_descr = "an appearance (``) of an address anywhere on the chain (note that in some cases, not all fields will appear depending on the command)" doc_route = "103-appearance" diff --git a/src/dev_tools/goMaker/templates/classDefinitions/appearancetable.toml b/src/dev_tools/goMaker/templates/classDefinitions/appearancetable.toml index 20410cd398..354a13b7c7 100644 --- a/src/dev_tools/goMaker/templates/classDefinitions/appearancetable.toml +++ b/src/dev_tools/goMaker/templates/classDefinitions/appearancetable.toml @@ -1,6 +1,6 @@ [settings] class = "AppearanceTable" - contained_by = "Monitor" + contained_by = "monitor" doc_group = "01-Accounts" doc_descr = "an appearance table for an address" doc_route = "121-appearanceTable" diff --git a/src/dev_tools/goMaker/templates/cmd-line-options.csv b/src/dev_tools/goMaker/templates/cmd-line-options.csv index 55b37bd562..dc40c3d8a4 100644 --- a/src/dev_tools/goMaker/templates/cmd-line-options.csv +++ b/src/dev_tools/goMaker/templates/cmd-line-options.csv @@ -305,6 +305,7 @@ num,folder,group,route,tool,longName,hotKey,def_val,attributes,option_type,data_ # 47000,apps,Admin,init,init,,,,visible|docs,command,,,Initialize index,[flags],verbose|version|noop|noColor|chain|,Initialize the TrueBlocks system by downloading the Unchained Index from IPFS. 47020,apps,Admin,init,init,all,a,,visible|docs,switch,,bool,,,,in addition to Bloom filters, download full index chunks (recommended) +47025,apps,Admin,init,init,example,e,,visible,flag,,,,,,create an example for the SDK with the given name 47030,apps,Admin,init,init,dry_run,d,,visible|docs,switch,,,,,,display the results of the download without actually downloading 47040,apps,Admin,init,init,publisher,P,,,flag,
,,,,,the publisher of the index to download 47050,apps,Admin,init,init,first_block,F,,visible|docs,flag,,,,,,do not download any chunks earlier than this block diff --git a/src/dev_tools/goMaker/templates/src_apps_chifra_pkg_types_type.go.tmpl b/src/dev_tools/goMaker/templates/src_apps_chifra_pkg_types_type.go.tmpl index b2579c480c..191ed0f839 100644 --- a/src/dev_tools/goMaker/templates/src_apps_chifra_pkg_types_type.go.tmpl +++ b/src/dev_tools/goMaker/templates/src_apps_chifra_pkg_types_type.go.tmpl @@ -24,7 +24,7 @@ type {{.ModelName "simple"}} struct { // EXISTING_CODE } -func (s *{{.ModelName ""}}) String() string { +func (s {{.ModelName ""}}) String() string { bytes, _ := json.Marshal(s) return string(bytes) } diff --git a/src/dev_tools/goMaker/types/load.go b/src/dev_tools/goMaker/types/load.go index cda9dbf9f8..2bdaa268ca 100644 --- a/src/dev_tools/goMaker/types/load.go +++ b/src/dev_tools/goMaker/types/load.go @@ -228,5 +228,5 @@ func (cb *CodeBase) FinishLoad(baseTypes []Structure, options []Option, structMa return nil } - return fmt.Errorf("protective measure - not an error, but codebase.json has changed") + return fmt.Errorf("Quitting: codebase.json has changed. Rerun the command to ignore this warning.") } diff --git a/src/dev_tools/testRunner/README.md b/src/dev_tools/testRunner/README.md index 1b994b42db..55ed33ef5b 100644 --- a/src/dev_tools/testRunner/README.md +++ b/src/dev_tools/testRunner/README.md @@ -1,16 +1,24 @@ -# testRunner - new GoLang test runner +# testRunner -This tool runs the core's test cases of which there are nearly 1,500. +The `testRunner` tool runs the core's test cases of which there are nearly 1,500. -All tests will be run (in the order shown below) unless you provide a filter. +All tests are run (in the order shown below) unless you provide a filter. You may provide a filter in two ways: (1) export an environment variable with the name `TB_TEST_FILTER`, or (2) provide as the first argument on the tool's command line. -Provide a filter by running `testRunner` with the environment variable `TB_TEST_FILTER` exported, thus: +The filter takes the following format: ```[bash] -TB_TEST_FILTER=routeList:modeList testRunner +TB_TEST_FILTER=: testRunner ``` -If you provide a filter, the tests will be run in the order you provide. Either of the two lists may be empty in which case all tests of that type will run. Seperate the two lists with a colon (:). +or + +```[bash] +testRunner : +``` + +## Format of the filter + +The filter consists of two lists `` and `` separated by a colon (:). If either of the lists is empty, the given filter is disabled. The tests proceed in the following order, unless you provide a filter, in which case they run in the order you provide. The special `tools` and `apps` routes are used as shorthand for all tests of that type. `routeList` may be empty or one or more (comma seperated) items from: @@ -48,3 +56,35 @@ If you provide a filter, the tests will be run in the order you provide. Either - cmd - sdk ``` + +## Examples + +```[bash] +TB_TEST_FILTER=tools:cmd testRunner +``` + +runs the `cmd` tests for all the `tools`. + +```[bash] +testRunner export:api +``` + +runs the `api` tests for the `export` command. + +```[bash] +testRunner blocks,traces,export:sdk,cmd +``` + +runs the `sdk` and `cmd` tests for the `blocks`, `traces`, and `export` commands as does + +```[bash] +TB_TEST_FILTER=blocks,traces,export:sdk,cmd testRunner +``` + +Finally, + +```[bash] +testRunner +``` + +runs all tests. diff --git a/src/dev_tools/testRunner/filter.go b/src/dev_tools/testRunner/filter.go new file mode 100644 index 0000000000..0d3e00f1dd --- /dev/null +++ b/src/dev_tools/testRunner/filter.go @@ -0,0 +1,178 @@ +package main + +import ( + "fmt" + "os" + "sort" + "strings" + + "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" +) + +type helper struct { + path string + order int + on bool +} + +var routeMap = map[string]helper{ + "slurp": {"tools", 0, os.Getenv("TEST_SLURP") == "true"}, + "names": {"tools", 1, true}, + "blocks": {"tools", 2, true}, + "logs": {"tools", 3, true}, + "receipts": {"tools", 4, true}, + "state": {"tools", 5, true}, + "tokens": {"tools", 6, true}, + "traces": {"tools", 7, true}, + "transactions": {"tools", 8, true}, + "abis": {"tools", 9, true}, + "when": {"tools", 10, true}, + "list": {"apps", 11, true}, + "monitors": {"apps", 12, true}, + "export": {"apps", 13, true}, + "scrape": {"apps", 14, true}, + "status": {"apps", 15, true}, + "chifra": {"apps", 16, true}, + "chunks": {"apps", 17, true}, + "config": {"apps", 18, true}, + "daemon": {"apps", 19, true}, + "explore": {"apps", 20, true}, + "init": {"apps", 21, true}, +} + +var modeMap = map[string]helper{ + "sdk": {"mode", 1, true}, + "api": {"mode", 2, true}, + "cmd": {"mode", 3, true}, +} + +func isValidEnvironment() error { + if os.Getenv("TEST_MODE") != "true" { + return fmt.Errorf("you must run this program with TEST_MODE=true") + } + + filter := os.Getenv("TB_TEST_FILTER") + if len(filter) == 0 && len(os.Args) > 1 { + filter = os.Args[1] + os.Args = []string{os.Args[0]} + } + if len(filter) == 0 { + return nil + } + if !strings.Contains(filter, ":") { + filter += ":" + } + parts := strings.Split(filter, ":") + if len(parts) != 2 || (len(routeMap[parts[0]].path) == 0 && len(modeMap[parts[1]].path) == 0) { + return fmt.Errorf("invalid filter: %s", filter) + } + return nil +} + +func getRoutesAndModes() ([]string, []string) { + filter := os.Getenv("TB_TEST_FILTER") + if len(filter) == 0 && len(os.Args) > 1 { + filter = os.Args[1] + os.Args = []string{os.Args[0]} + } + if len(filter) > 0 { + if !strings.Contains(filter, ":") { + filter += ":" + } + parts := strings.Split(filter, ":") + if len(parts) != 2 { + logger.Error("filter must be in the form of 'route:mode'") + os.Exit(1) + } + + userRoutes, userModes := parts[0], parts[1] + if len(userRoutes) > 0 { + for key, value := range routeMap { + routeMap[key] = helper{value.path, value.order, false} + } + nOn := 0 + routes := strings.Split(userRoutes, ",") + for _, route := range routes { + if route == "tools" || route == "apps" { + for key, value := range routeMap { + if value.path == route { + on := true + if key == "slurp" { + on = os.Getenv("TEST_SLURP") == "true" + } + if key == "status" { + on = false + if strings.Contains(filter, "status") { + fmt.Println("Tests for the status route may not be run seperately.") + os.Exit(1) + } + } + routeMap[key] = helper{routeMap[key].path, routeMap[key].order, on} + } + } + } else { + if len(routeMap[route].path) > 0 { + routeMap[route] = helper{routeMap[route].path, nOn, true} + nOn++ + } + } + } + } + + if len(userModes) > 0 { + for key, value := range modeMap { + modeMap[key] = helper{value.path, value.order, false} + } + nOn := 0 + modes := strings.Split(userModes, ",") + for _, mode := range modes { + if len(modeMap[mode].path) > 0 { + modeMap[mode] = helper{modeMap[mode].path, nOn, true} + nOn++ + } + } + } + } + + // sort the routes and prepare for return... + sorted := []helper{} + for key, value := range routeMap { + if value.on { + sorted = append(sorted, helper{key, value.order, true}) + } + } + sort.Slice(sorted, func(i, j int) bool { + return sorted[i].order < sorted[j].order + }) + order := []string{} + for _, item := range sorted { + order = append(order, item.path) + } + + // sort the modes and prepare for return... + sorted = []helper{} + for key, value := range modeMap { + if value.on { + sorted = append(sorted, helper{key, value.order, true}) + } + } + sort.Slice(sorted, func(i, j int) bool { + return sorted[i].order < sorted[j].order + }) + modes := []string{} + for _, item := range sorted { + modes = append(modes, item.path) + } + + if len(order) == 0 || len(modes) == 0 { + logger.Error("No routes or modes are enabled") + os.Exit(1) + } + + if len(filter) > 0 { + fmt.Println("Order:", order) + fmt.Println("Modes:", modes) + } + + return order, modes +} diff --git a/src/dev_tools/testRunner/go.mod b/src/dev_tools/testRunner/go.mod index 577124424b..b8fd991593 100644 --- a/src/dev_tools/testRunner/go.mod +++ b/src/dev_tools/testRunner/go.mod @@ -2,6 +2,3 @@ module github.com/TrueBlocks/trueblocks-core/testRunner // Go Version go 1.22 - -replace github.com/TrueBlocks/trueblocks-core/sdk => ../../../sdk - diff --git a/src/dev_tools/testRunner/main.go b/src/dev_tools/testRunner/main.go index e4339d2586..6026451334 100644 --- a/src/dev_tools/testRunner/main.go +++ b/src/dev_tools/testRunner/main.go @@ -11,7 +11,6 @@ import ( "os" "path/filepath" "regexp" - "sort" "strings" "text/template" "unicode" @@ -23,10 +22,14 @@ import ( func init() { os.Setenv("NO_USERQUERY", "true") - os.Setenv("TEST_MODE", "true") } func main() { + if err := isValidEnvironment(); err != nil { + logger.Fatal(err) + os.Exit(1) + } + if err := startApiServer(); err != nil { logger.Fatal(err) } @@ -303,147 +306,6 @@ func toJson(structure interface{}) string { return buf.String() } -func getRoutesAndModes() ([]string, []string) { - type helper struct { - path string - order int - on bool - } - - routeMap := map[string]helper{ - "slurp": {"tools", 0, os.Getenv("TEST_SLURP") == "true"}, - "names": {"tools", 1, true}, - "blocks": {"tools", 2, true}, - "logs": {"tools", 3, true}, - "receipts": {"tools", 4, true}, - "state": {"tools", 5, true}, - "tokens": {"tools", 6, true}, - "traces": {"tools", 7, true}, - "transactions": {"tools", 8, true}, - "abis": {"tools", 9, true}, - "when": {"tools", 10, true}, - "list": {"apps", 11, true}, - "monitors": {"apps", 12, true}, - "export": {"apps", 13, true}, - "scrape": {"apps", 14, true}, - "status": {"apps", 15, true}, - "chifra": {"apps", 16, true}, - "chunks": {"apps", 17, true}, - "config": {"apps", 18, true}, - "daemon": {"apps", 19, true}, - "explore": {"apps", 20, true}, - "init": {"apps", 21, true}, - } - - modeMap := map[string]helper{ - "sdk": {"mode", 1, true}, - "api": {"mode", 2, true}, - "cmd": {"mode", 3, true}, - } - - filter := os.Getenv("TB_TEST_FILTER") - if len(filter) > 0 { - if !strings.Contains(filter, ":") { - filter += ":" - } - parts := strings.Split(filter, ":") - if len(parts) != 2 { - logger.Error("TB_TEST_FILTER must be in the form of 'route:mode'") - os.Exit(1) - } - - userRoutes, userModes := parts[0], parts[1] - if len(userRoutes) > 0 { - for key, value := range routeMap { - routeMap[key] = helper{value.path, value.order, false} - } - nOn := 0 - routes := strings.Split(userRoutes, ",") - for _, route := range routes { - if route == "tools" || route == "apps" { - for key, value := range routeMap { - if value.path == route { - on := true - if key == "slurp" { - on = os.Getenv("TEST_SLURP") == "true" - } - if key == "status" { - on = false - if strings.Contains(filter, "status") { - fmt.Println("Tests for the status route may not be run seperately.") - os.Exit(1) - } - } - routeMap[key] = helper{routeMap[key].path, routeMap[key].order, on} - } - } - } else { - if len(routeMap[route].path) > 0 { - routeMap[route] = helper{routeMap[route].path, nOn, true} - nOn++ - } - } - } - } - - if len(userModes) > 0 { - for key, value := range modeMap { - modeMap[key] = helper{value.path, value.order, false} - } - nOn := 0 - modes := strings.Split(userModes, ",") - for _, mode := range modes { - if len(modeMap[mode].path) > 0 { - modeMap[mode] = helper{modeMap[mode].path, nOn, true} - nOn++ - } - } - } - } - - // sort the routes and prepare for return... - sorted := []helper{} - for key, value := range routeMap { - if value.on { - sorted = append(sorted, helper{key, value.order, true}) - } - } - sort.Slice(sorted, func(i, j int) bool { - return sorted[i].order < sorted[j].order - }) - order := []string{} - for _, item := range sorted { - order = append(order, item.path) - } - - // sort the modes and prepare for return... - sorted = []helper{} - for key, value := range modeMap { - if value.on { - sorted = append(sorted, helper{key, value.order, true}) - } - } - sort.Slice(sorted, func(i, j int) bool { - return sorted[i].order < sorted[j].order - }) - modes := []string{} - for _, item := range sorted { - modes = append(modes, item.path) - } - - if len(order) == 0 || len(modes) == 0 { - logger.Error("No routes or modes are enabled") - os.Exit(1) - } - - if len(filter) > 0 { - fmt.Println("Order:", order) - fmt.Println("Modes:", modes) - } - - return order, modes -} - func getRepoRoot() string { wd, _ := os.Getwd() if !strings.HasSuffix(wd, "/build") { diff --git a/src/dev_tools/testRunner/main_test.go b/src/dev_tools/testRunner/main_test.go index 5dad4871bf..653db53bba 100644 --- a/src/dev_tools/testRunner/main_test.go +++ b/src/dev_tools/testRunner/main_test.go @@ -9,7 +9,8 @@ import ( ) func TestMainFunction(t *testing.T) { - os.Setenv("TB_TEST_FILTER", "chifra:cmd") + os.Setenv("TEST_MODE", "true") + os.Setenv("TB_TEST_FILTER", "init") err := os.Chdir("../../../build/") if err != nil { logger.Fatal(fmt.Sprintf("Failed to change directory: %v", err)) diff --git a/src/dev_tools/testRunner/testCases/chifra.csv b/src/dev_tools/testRunner/testCases/chifra.csv index 478c8d55e6..0dfeaf0c50 100644 --- a/src/dev_tools/testRunner/testCases/chifra.csv +++ b/src/dev_tools/testRunner/testCases/chifra.csv @@ -28,7 +28,7 @@ on ,cmd ,fast ,chifra ,apps ,chifra ,help_scrape ,n ,modes = on ,cmd ,fast ,chifra ,apps ,chifra ,help_chunks ,n ,modes = chunks & help on ,cmd ,fast ,chifra ,apps ,chifra ,help_init ,n ,modes = init & help on ,cmd ,fast ,chifra ,apps ,chifra ,help_explore ,n ,modes = explore & help -on ,cmd ,fast ,chifra ,apps ,chifra ,help_slurp ,n ,modes = slurp & help +local ,cmd ,fast ,chifra ,apps ,chifra ,help_slurp ,n ,modes = slurp & help on ,both ,fast ,names ,apps ,chifra ,run_names ,y ,modes = names & terms = 50-Tokens & expand on ,both ,fast ,names ,apps ,chifra ,run_names_tags ,y ,modes = names & tags diff --git a/tests b/tests index 567027866c..ede103d8ee 160000 --- a/tests +++ b/tests @@ -1 +1 @@ -Subproject commit 567027866ca4f5320f517ffe88b7036079c130e6 +Subproject commit ede103d8ee1beac4522ad34087e9012ea5cd0f98