diff --git a/Dockerfile.moth b/Dockerfile.moth
index ac5b9d9..0e8b7e9 100644
--- a/Dockerfile.moth
+++ b/Dockerfile.moth
@@ -1,6 +1,6 @@
FROM neale/eris
-RUN apk --no-cache add lua5.2 lua5.3
+RUN apk --no-cache add lua5.1 lua5.2 lua5.3
RUN ln -s lua5.2 /usr/bin/lua
# Install MOTH. This could be less obtuse.
diff --git a/mothball.go b/mothball.go
deleted file mode 100644
index 845d861..0000000
--- a/mothball.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package mothball
-
-import (
- "archive/zip"
- "os"
- "time"
-)
-
-type Mothball struct {
- zf *zipfile.File,
- filename string,
- mtime time.Time,
-}
-
-func Open(filename string) (*Mothball, error) {
- var m Mothball
-
- m.filename = filename
-
- err := m.Refresh()
- if err != nil {
- return err
- }
-
- return &m
-}
-
-func (m Mothball) Close() (error) {
- return m.zf.Close()
-}
-
-func (m Mothball) Refresh() (error) {
- mtime, err := os.Stat(m.filename)
- if err != nil {
- return err
- }
-
- if mtime == m.mtime {
- return nil
- }
-
- zf, err := zip.OpenReader(m.filename)
- if err != nil {
- return err
- }
-
- m.zf.Close()
- m.zf = zf
- m.mtime = mtime
-}
-
-func (m Mothball)
\ No newline at end of file
diff --git a/src/mothball/mothball.go b/src/mothball/mothball.go
new file mode 100644
index 0000000..1f63776
--- /dev/null
+++ b/src/mothball/mothball.go
@@ -0,0 +1,67 @@
+package mothball
+
+import (
+ "archive/zip"
+ "fmt"
+ "io"
+ "os"
+ "time"
+)
+
+type Mothball struct {
+ zf *zip.ReadCloser
+ filename string
+ mtime time.Time
+}
+
+func Open(filename string) (*Mothball, error) {
+ var m Mothball
+
+ m.filename = filename
+
+ err := m.Refresh()
+ if err != nil {
+ return nil, err
+ }
+
+ return &m, nil
+}
+
+func (m *Mothball) Close() (error) {
+ return m.zf.Close()
+}
+
+func (m *Mothball) Refresh() (error) {
+ info, err := os.Stat(m.filename)
+ if err != nil {
+ return err
+ }
+ mtime := info.ModTime()
+
+ if mtime == m.mtime {
+ return nil
+ }
+
+ zf, err := zip.OpenReader(m.filename)
+ if err != nil {
+ return err
+ }
+
+ if m.zf != nil {
+ m.zf.Close()
+ }
+ m.zf = zf
+ m.mtime = mtime
+
+ return nil
+}
+
+func (m *Mothball) Open(filename string) (io.ReadCloser, error) {
+ for _, f := range m.zf.File {
+ if filename == f.Name {
+ ret, err := f.Open()
+ return ret, err
+ }
+ }
+ return nil, fmt.Errorf("File not found: %s in %s", filename, m.filename)
+}
diff --git a/src/mothball/mothball_test.go b/src/mothball/mothball_test.go
new file mode 100644
index 0000000..f740e27
--- /dev/null
+++ b/src/mothball/mothball_test.go
@@ -0,0 +1,63 @@
+package mothball
+
+import (
+ "archive/zip"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "testing"
+)
+
+func TestMothball(t *testing.T) {
+ tf, err := ioutil.TempFile("", "mothball")
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ defer os.Remove(tf.Name())
+
+ w := zip.NewWriter(tf)
+ f, err := w.Create("moo.txt")
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ // no Close method
+
+ _, err = fmt.Fprintln(f, "The cow goes moo")
+ //.Write([]byte("The cow goes moo"))
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ w.Close()
+ tf.Close()
+
+ // Now read it in
+ mb, err := Open(tf.Name())
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ cow, err := mb.Open("moo.txt")
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ line := make([]byte, 200)
+ n, err := cow.Read(line)
+ if (err != nil) && (err != io.EOF) {
+ t.Error(err)
+ return
+ }
+
+ if string(line[:n]) != "The cow goes moo\n" {
+ t.Log(line)
+ t.Error("Contents didn't match")
+ return
+ }
+
+}
diff --git a/www/credits.html b/www/credits.html
index b6be5ec..ec3367f 100644
--- a/www/credits.html
+++ b/www/credits.html
@@ -92,6 +92,7 @@ window.addEventListener("load", init);
+