aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--auth.go4
-rw-r--r--bommom.go128
-rw-r--r--formats.go158
-rw-r--r--store.go12
5 files changed, 187 insertions, 116 deletions
diff --git a/.gitignore b/.gitignore
index b71cac3..d4d9d8f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@
pkg/
bin/
bommom
+filestore/
diff --git a/auth.go b/auth.go
index d8e881e..f0ef530 100644
--- a/auth.go
+++ b/auth.go
@@ -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
diff --git a/bommom.go b/bommom.go
index f7ea966..99fc3ae 100644
--- a/bommom.go
+++ b/bommom.go
@@ -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
+}
diff --git a/store.go b/store.go
index 182f97d..d08deaa 100644
--- a/store.go
+++ b/store.go
@@ -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) {