summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2017-11-16 10:08:15 -0500
committerLuke Shumaker <lukeshu@lukeshu.com>2017-11-16 10:08:15 -0500
commitce0f40c125ff838d332c1974c8e505e4be1e409b (patch)
treef78a992881f07421ae9cc5afc259ca5527614df1
parentefc7a5ebc9e10983571c080017100a8b39eee1d0 (diff)
more
-rw-r--r--backend.go70
-rw-r--r--frontend.go123
-rw-r--r--read_fastimport.go63
-rw-r--r--textproto/io.go6
4 files changed, 157 insertions, 105 deletions
diff --git a/backend.go b/backend.go
new file mode 100644
index 0000000..4d03d46
--- /dev/null
+++ b/backend.go
@@ -0,0 +1,70 @@
+package libfastimport
+
+import (
+ "io"
+ "bufio"
+
+ "git.lukeshu.com/go/libfastimport/textproto"
+)
+
+// A Backend is something that consumes a fast-import stream; the
+// Backend object provides methods for writing to it.
+type Backend struct {
+ w *bufio.Writer
+ fiw *textproto.FIWriter
+ cbr *textproto.CatBlobReader
+}
+
+func NewBackend(fastImport io.Writer, catBlob io.Reader) *Backend {
+ ret := Backend{}
+ ret.w = bufio.NewWriter(fastImport)
+ ret.fiw = textproto.NewFIWriter(ret.w)
+ if catBlob != nil {
+ ret.cbr = textproto.NewCatBlobReader(catBlob)
+ }
+ return &ret
+}
+
+func (b *Backend) Do(cmd Cmd) error {
+ err := cmd.fiWriteCmd(b.fiw)
+ if err != nil {
+ return err
+ }
+ return b.w.Flush()
+}
+
+func (b *Backend) GetMark(cmd CmdGetMark) (string, error) {
+ err := b.Do(cmd)
+ if err != nil {
+ return "", err
+ }
+ line, err := b.cbr.ReadLine()
+ if err != nil {
+ return "", err
+ }
+ return cbpGetMark(line)
+}
+
+func (b *Backend) CatBlob(cmd CmdCatBlob) (sha1 string, data string, err error) {
+ err = b.Do(cmd)
+ if err != nil {
+ return "", "", err
+ }
+ line, err := b.cbr.ReadLine()
+ if err != nil {
+ return "", "", err
+ }
+ return cbpCatBlob(line)
+}
+
+func (b *Backend) Ls(cmd CmdLs) (mode textproto.Mode, dataref string, path textproto.Path, err error) {
+ err = b.Do(cmd)
+ if err != nil {
+ return 0, "", "", err
+ }
+ line, err := b.cbr.ReadLine()
+ if err != nil {
+ return 0, "", "", err
+ }
+ return cbpLs(line)
+}
diff --git a/frontend.go b/frontend.go
index 73f6d73..405ead4 100644
--- a/frontend.go
+++ b/frontend.go
@@ -1,68 +1,107 @@
package libfastimport
import (
- "io"
"bufio"
+ "io"
+ "strings"
"git.lukeshu.com/go/libfastimport/textproto"
)
+type UnsupportedCommand string
+
+func (e UnsupportedCommand) Error() string {
+ return "Unsupported command: " + string(e)
+}
+
+type cmderror struct {
+ Cmd
+ error
+}
+
+// A Frontend is something that produces a fast-import stream; the
+// Frontend object provides methods for reading from it.
type Frontend struct {
- w *bufio.Writer
- fiw *textproto.FIWriter
- cbr *textproto.CatBlobReader
+ fir *textproto.FIReader
+ cbw *textproto.CatBlobWriter
+ w *bufio.Writer
+ c chan cmderror
}
-func NewFrontend(w io.Writer, r io.Reader) *Frontend {
+func NewFrontend(fastImport io.Reader, catBlob io.Writer) *Frontend {
ret := Frontend{}
- ret.w = bufio.NewWriter(w)
- ret.fiw = textproto.NewFIWriter(ret.w)
- if r != nil {
- ret.cbr = textproto.NewCatBlobReader(r)
+ ret.fir = textproto.NewFIReader(fastImport)
+ if catBlob != nil {
+ ret.w = bufio.NewWriter(catBlob)
+ ret.cbw = textproto.NewCatBlobWriter(ret.w)
}
return &ret
}
-func (f *Frontend) Do(cmd Cmd) error {
- err := cmd.fiWriteCmd(f.fiw)
+func (f *Frontend) nextLine() (line string, err error) {
+retry:
+ line, err = f.fir.ReadLine()
if err != nil {
- return err
+ return
+ }
+ switch {
+ case strings.HasPrefix(line, "#"):
+ f.c <- cmderror{CmdComment{Comment: line[1:]}, nil}
+ goto retry
+ case strings.HasPrefix(line, "cat-blob "):
+ f.c <- parse_cat_blob(line)
+ goto retry
+ case strings.HasPrefix(line, "get-mark "):
+ f.c <- parse_get_mark(line)
+ goto retry
+ default:
+ return
}
- return f.w.Flush()
}
-func (f *Frontend) GetMark(cmd CmdGetMark) (string, error) {
- err := f.Do(cmd)
- if err != nil {
- return "", err
+func (f *Frontend) parse() {
+ for {
+ line, err := f.nextLine()
+ if err != nil {
+ f.c <- cmderror{nil, err}
+ return
+ }
+ switch {
+ case strings.HasPrefix(line, "blob "):
+ case strings.HasPrefix(line, "commit "):
+ case strings.HasPrefix(line, "checkpoint\n"):
+ case strings.HasPrefix(line, "done\n"):
+ case strings.HasPrefix(line, "feature "):
+ case strings.HasPrefix(line, "ls "):
+ case strings.HasPrefix(line, "option "):
+ case strings.HasPrefix(line, "progress "):
+ case strings.HasPrefix(line, "reset "):
+ case strings.HasPrefix(line, "tag "):
+ default:
+ f.c <- cmderror{nil, UnsupportedCommand(line)}
+ return
+ }
}
- line, err := f.cbr.ReadLine()
- if err != nil {
- return "", err
- }
- return cbpGetMark(line)
}
-func (f *Frontend) CatBlob(cmd CmdCatBlob) (sha1 string, data string, err error) {
- err = f.Do(cmd)
- if err != nil {
- return "", "", err
- }
- line, err := f.cbr.ReadLine()
- if err != nil {
- return "", "", err
- }
- return cbpCatBlob(line)
+func (f *Frontend) ReadCmd() (Cmd, error) {
+ cmderror := <-f.c
+ cmd := cmderror.Cmd
+ err := cmderror.error
+ return cmderror.Cmd, cmderror.error
}
-func (f *Frontend) Ls(cmd CmdLs) (mode textproto.Mode, dataref string, path textproto.Path, err error) {
- err = f.Do(cmd)
- if err != nil {
- return 0, "", "", err
- }
- line, err := f.cbr.ReadLine()
- if err != nil {
- return 0, "", "", err
- }
- return cbpLs(line)
+func (f *Frontend) RespondGetMark(sha1 string) error {
+ // TODO
+ return f.w.Flush()
+}
+
+func (f *Frontend) RespondCatBlob(sha1 string, data string) error {
+ // TODO
+ return f.w.Flush()
+}
+
+func (f *Frontend) RespondLs(mode textproto.Mode, dataref string, path textproto.Path) error {
+ // TODO
+ return f.w.Flush()
}
diff --git a/read_fastimport.go b/read_fastimport.go
deleted file mode 100644
index abafa4b..0000000
--- a/read_fastimport.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package libfastimport
-
-import (
- "git.lukeshu.com/go/libfastimport/textproto"
-)
-
-type UnsupportedCommand string
-
-func (e UnsupportedCommand) Error() string {
- return "Unsupported command: "+string(e)
-}
-
-type Parser struct {
- fir *textproto.FIReader
-
- cmd chan Cmd
-}
-
-func (p *Parser) GetCmd() (Cmd, error) {
- for p.cmd == nil {
- line, err := p.fir.ReadLine()
- if err != nil {
- return nil, err
- }
- err = p.putLine(line)
- if err != nil {
- return nil, err
- }
- }
- return <-p.cmd, nil
-}
-
-func (p *Parser) putLine(line string) error {
- if len(line) < 1 {
- return UnsupportedCommand(line)
- }
- switch line[0] {
- case '#': // comment
- case 'b': // blob
- case 'c':
- if len(line) < 2 {
- return UnsupportedCommand(line)
- }
- switch line[1] {
- case 'o': // commit
- case 'h': // checkpoint
- case 'a': // cat-blob
- default:
- return UnsupportedCommand(line)
- }
- case 'd': // done
- case 'f': // feature
- case 'g': // get-mark
- case 'l': // ls
- case 'o': // option
- case 'p': // progress
- case 'r': // reset
- case 't': // tag
- default:
- return UnsupportedCommand(line)
- }
- return nil // TODO
-}
diff --git a/textproto/io.go b/textproto/io.go
index af2cb19..cb0105b 100644
--- a/textproto/io.go
+++ b/textproto/io.go
@@ -131,6 +131,12 @@ type CatBlobWriter struct {
w io.Writer
}
+func NewCatBlobWriter(w io.Writer) *CatBlobWriter {
+ return &CatBlobWriter {
+ w: w,
+ }
+}
+
func (cbw *CatBlobWriter) WriteLine(a ...interface{}) error {
_, err := fmt.Fprintln(cbw.w, a...)
return err