diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | auth.go | 4 | ||||
-rw-r--r-- | bommom.go | 128 | ||||
-rw-r--r-- | formats.go | 158 | ||||
-rw-r--r-- | store.go | 12 |
5 files changed, 187 insertions, 116 deletions
@@ -9,3 +9,4 @@ pkg/ bin/ bommom +filestore/ @@ -1,9 +1,5 @@ package main -// Authentication globals -var auth AuthService -var anonUser = &User{name: "common"} - // Basic registered user account structure, for permissions etc. type User struct { // TODO: more specific types for these @@ -3,18 +3,19 @@ package main // CLI for bommom tools. Also used to launch web interface. import ( - "encoding/csv" - "encoding/json" - "encoding/xml" "flag" "fmt" "io" "log" "os" - "path" - "strings" + "path" ) +// Globals +var bomstore BomStore +var auth AuthService +var anonUser = &User{name: "common"} + // Command line flags var ( templatePath = flag.String("templatepath", "./templates", "path to template directory") @@ -61,16 +62,20 @@ func main() { } } +func openBomStore() { + +} + func initCmd() { - jfbs, err := NewJSONFileBomStore(*fileStorePath) + err := NewJSONFileBomStore(*fileStorePath) if err != nil { log.Fatal(err) } - jfbs, err = OpenJSONFileBomStore(*fileStorePath) + bomstore, err = OpenJSONFileBomStore(*fileStorePath) if err != nil { log.Fatal(err) } - bs, err := jfbs.GetStub(ShortName("common"), ShortName("gizmo")) + bs, err := bomstore.GetStub(ShortName("common"), ShortName("gizmo")) if err == nil { // dummy BomStub already exists? return @@ -83,7 +88,7 @@ func initCmd() { HeadVersion: b.Version, IsPublicView: true, IsPublicEdit: true} - jfbs.Persist(bs, b, "v001") + bomstore.Persist(bs, b, "v001") } func dumpCmd() { @@ -122,14 +127,15 @@ func dumpCmd() { log.Fatal("Error: not valid ShortName: " + userStr + " and/or " + nameStr) } - jfbs, err := OpenJSONFileBomStore(*fileStorePath) + var err error + bomstore, err = OpenJSONFileBomStore(*fileStorePath) if err != nil { log.Fatal(err) } if auth == nil { auth = DummyAuth(true) } - bs, b, err := jfbs.GetHead(ShortName(userStr), ShortName(nameStr)) + bs, b, err := bomstore.GetHead(ShortName(userStr), ShortName(nameStr)) if err != nil { log.Fatal(err) } @@ -140,7 +146,7 @@ func dumpCmd() { case "json": DumpBomAsJSON(bs, b, outFile) case "csv": - DumpBomAsCSV(bs, b, outFile) + DumpBomAsCSV(b, outFile) case "xml": DumpBomAsXML(bs, b, outFile) default: @@ -149,7 +155,7 @@ func dumpCmd() { } func listCmd() { - jfbs, err := OpenJSONFileBomStore(*fileStorePath) + bomstore, err := OpenJSONFileBomStore(*fileStorePath) if err != nil { log.Fatal(err) } @@ -162,14 +168,14 @@ func listCmd() { if !isShortName(name) { log.Fatal("Error: not a possible username: " + name) } - bomStubs, err = jfbs.ListBoms(ShortName(name)) + bomStubs, err = bomstore.ListBoms(ShortName(name)) if err != nil { log.Fatal(err) } } else { // list all boms from all names // TODO: ERROR - bomStubs, err = jfbs.ListBoms("") + bomStubs, err = bomstore.ListBoms("") if err != nil { log.Fatal(err) } @@ -182,8 +188,8 @@ func listCmd() { func printUsage() { fmt.Println("bommom is a tool for managing and publishing electronics BOMs") fmt.Println("") - fmt.Println("Usage:") - fmt.Println("\tbommom command [options]") + fmt.Println("Usage (flags must go first?):") + fmt.Println("\tbommom [options] command [arguments]") fmt.Println("") fmt.Println("Commands:") fmt.Println("") @@ -199,91 +205,3 @@ func printUsage() { flag.PrintDefaults() } -// -------- conversion/dump/load routines - -func DumpBomAsText(bs *BomStub, b *Bom, out io.Writer) { - fmt.Fprintln(out) - fmt.Fprintf(out, "%s (version %s, created %s)\n", bs.Name, b.Version, b.Created) - fmt.Fprintf(out, "Creator: %s\n", bs.Owner) - if bs.Description != "" { - fmt.Fprintf(out, "Description: %s\n", bs.Description) - } - fmt.Println() - // "by line item" - fmt.Fprintf(out, "tag\tqty\tmanufacturer\tmpn\t\tdescription\t\tcomment\n") - for _, li := range b.LineItems { - fmt.Fprintf(out, "%s\t%d\t%s\t%s\t\t%s\t\t%s\n", - li.Tag, - len(li.Elements), - li.Manufacturer, - li.Mpn, - li.Description, - li.Comment) - } - /* // "by circuit element" - fmt.Fprintf(out, "tag\tsymbol\tmanufacturer\tmpn\t\tdescription\t\tcomment\n") - for _, li := range b.LineItems { - for _, elm := range li.Elements { - fmt.Fprintf(out, "%s\t%s\t%s\t%s\t\t%s\t\t%s\n", - li.Tag, - elm, - li.Manufacturer, - li.Mpn, - li.Description, - li.Comment) - } - } - */ -} - -func DumpBomAsCSV(bs *BomStub, b *Bom, out io.Writer) { - dumper := csv.NewWriter(out) - defer dumper.Flush() - // "by line item" - dumper.Write([]string{"qty", - "symbols", - "manufacturer", - "mpn", - "description", - "comment"}) - for _, li := range b.LineItems { - dumper.Write([]string{ - fmt.Sprint(len(li.Elements)), - strings.Join(li.Elements, ","), - li.Manufacturer, - li.Mpn, - li.Description, - li.Comment}) - } -} - -func DumpBomAsJSON(bs *BomStub, b *Bom, out io.Writer) { - - obj := map[string]interface{}{ - "bom_meta": bs, - "bom": b, - } - - enc := json.NewEncoder(out) - if err := enc.Encode(&obj); err != nil { - log.Fatal(err) - } -} - -func DumpBomAsXML(bs *BomStub, b *Bom, out io.Writer) { - - /* - obj := map[string] interface{} { - "BomMeta": bs, - "Bom": b, - } - */ - - enc := xml.NewEncoder(out) - if err := enc.Encode(bs); err != nil { - log.Fatal(err) - } - if err := enc.Encode(b); err != nil { - log.Fatal(err) - } -} diff --git a/formats.go b/formats.go new file mode 100644 index 0000000..6c10a0a --- /dev/null +++ b/formats.go @@ -0,0 +1,158 @@ +package main + +// Bom/BomStub conversion/dump/load routines + +import ( + "encoding/csv" + "encoding/json" + "encoding/xml" + "fmt" + "io" + "log" + "strings" +) + +// --------------------- text (CLI only ) ----------------------- + +func DumpBomAsText(bs *BomStub, b *Bom, out io.Writer) { + fmt.Fprintln(out) + fmt.Fprintf(out, "%s (version %s, created %s)\n", bs.Name, b.Version, b.Created) + fmt.Fprintf(out, "Creator: %s\n", bs.Owner) + if bs.Description != "" { + fmt.Fprintf(out, "Description: %s\n", bs.Description) + } + fmt.Println() + // "by line item" + fmt.Fprintf(out, "tag\tqty\tmanufacturer\tmpn\t\tdescription\t\tcomment\n") + for _, li := range b.LineItems { + fmt.Fprintf(out, "%s\t%d\t%s\t%s\t\t%s\t\t%s\n", + li.Tag, + len(li.Elements), + li.Manufacturer, + li.Mpn, + li.Description, + li.Comment) + } + /* // "by circuit element" + fmt.Fprintf(out, "tag\tsymbol\tmanufacturer\tmpn\t\tdescription\t\tcomment\n") + for _, li := range b.LineItems { + for _, elm := range li.Elements { + fmt.Fprintf(out, "%s\t%s\t%s\t%s\t\t%s\t\t%s\n", + li.Tag, + elm, + li.Manufacturer, + li.Mpn, + li.Description, + li.Comment) + } + } + */ +} + +// --------------------- csv ----------------------- + +func DumpBomAsCSV(b *Bom, out io.Writer) { + dumper := csv.NewWriter(out) + defer dumper.Flush() + // "by line item" + dumper.Write([]string{"qty", + "symbols", + "manufacturer", + "mpn", + "description", + "comment"}) + for _, li := range b.LineItems { + dumper.Write([]string{ + fmt.Sprint(len(li.Elements)), + strings.Join(li.Elements, ","), + li.Manufacturer, + li.Mpn, + li.Description, + li.Comment}) + } +} + +func LoadBomFromCSV(out io.Writer) (*Bom, error) { + + b := Bom{} + + dumper := csv.NewWriter(out) + defer dumper.Flush() + // "by line item" + dumper.Write([]string{"qty", + "symbols", + "manufacturer", + "mpn", + "description", + "comment"}) + for _, li := range b.LineItems { + dumper.Write([]string{ + fmt.Sprint(len(li.Elements)), + strings.Join(li.Elements, ","), + li.Manufacturer, + li.Mpn, + li.Description, + li.Comment}) + } + return &b, nil +} + +// --------------------- JSON ----------------------- + +func DumpBomAsJSON(bs *BomStub, b *Bom, out io.Writer) { + + obj := map[string]interface{}{ + "bom_meta": bs, + "bom": b, + } + + enc := json.NewEncoder(out) + if err := enc.Encode(&obj); err != nil { + log.Fatal(err) + } +} + +func LoadBomFromJSON(input io.Reader) (*BomStub, *Bom, error) { + + bs := BomStub{} + b := Bom{} + + obj := map[string]interface{}{ + "bom_meta": bs, + "bom": b, + } + + enc := json.NewDecoder(input) + if err := enc.Decode(&obj); err != nil { + log.Fatal(err) + } + return &bs, &b, nil +} + +// --------------------- XML ----------------------- + +func DumpBomAsXML(bs *BomStub, b *Bom, out io.Writer) { + + enc := xml.NewEncoder(out) + if err := enc.Encode(bs); err != nil { + log.Fatal(err) + } + if err := enc.Encode(b); err != nil { + log.Fatal(err) + } +} + +func LoadBomFromXML(input io.Reader) (*BomStub, *Bom, error) { + + bs := BomStub{} + b := Bom{} + + enc := xml.NewDecoder(input) + if err := enc.Decode(bs); err != nil { + log.Fatal(err) + } + if err := enc.Decode(b); err != nil { + log.Fatal(err) + } + return &bs, &b, nil +} @@ -7,15 +7,13 @@ import ( "path" ) -var bomstore BomStore - // TODO: who owns returned BOMs? Caller? need "free" methods? type BomStore interface { GetStub(user, name ShortName) (*BomStub, error) - GetHead(user, name ShortName) (*Bom, error) + GetHead(user, name ShortName) (*BomStub, *Bom, error) GetBom(user, name, version ShortName) (*Bom, error) Persist(bs *BomStub, b *Bom, version ShortName) error - ListBoms(user ShortName) (*Bom, error) + ListBoms(user ShortName) ([]BomStub, error) } // Basic BomStore backend using a directory structure of JSON files saved to @@ -24,12 +22,12 @@ type JSONFileBomStore struct { Rootfpath string } -func NewJSONFileBomStore(fpath string) (*JSONFileBomStore, error) { +func NewJSONFileBomStore(fpath string) error { err := os.MkdirAll(fpath, os.ModePerm|os.ModeDir) if err != nil && !os.IsExist(err) { - return nil, err + return err } - return &JSONFileBomStore{Rootfpath: fpath}, nil + return nil } func OpenJSONFileBomStore(fpath string) (*JSONFileBomStore, error) { |