Skip to content

Commit

Permalink
Add zipfile module (#826)
Browse files Browse the repository at this point in the history
- Also required for the MARTA sample app using GTFS protocol buffers as their
- Basically just importing a starlib module, but wrapping slightly to make usage more consistent with other pixlet
- The style that starlib used here is familiar from working with starlark at Google, but my guess is it's not familiar to most users, and it also isn't consistent with other starlib modules ¯\_(ツ)_/¯
  • Loading branch information
dinosaursrarr authored Jul 31, 2023
1 parent e3d5a0e commit d44879b
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ individual modules, please refer to the Starlib documentation.
| Module | Description |
| --- | --- |
| [`compress/gzip.star`](https://github.com/qri-io/starlib/blob/master/compress/gzip) | gzip decompressing |
| [`compress/zipfile.star`](https://github.com/qri-io/starlib/blob/master/zipfile) | zip decompressing |
| [`encoding/base64.star`](https://github.com/qri-io/starlib/tree/master/encoding/base64) | Base 64 encoding and decoding |
| [`encoding/csv.star`](https://github.com/qri-io/starlib/tree/master/encoding/csv) | CSV decoding |
| [`encoding/json.star`](https://github.com/qri-io/starlib/tree/master/encoding/json) | JSON encoding and decoding |
Expand Down
14 changes: 14 additions & 0 deletions runtime/applet.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
starlibhash "github.com/qri-io/starlib/hash"
starlibhtml "github.com/qri-io/starlib/html"
starlibre "github.com/qri-io/starlib/re"
starlibzip "github.com/qri-io/starlib/zipfile"
starlibjson "go.starlark.net/lib/json"
starlibmath "go.starlark.net/lib/math"
starlibtime "go.starlark.net/lib/time"
Expand Down Expand Up @@ -320,6 +321,19 @@ func (a *Applet) loadModule(thread *starlark.Thread, module string) (starlark.St
starlibgzip.Module.Name: starlibgzip.Module,
}, nil

case "compress/zipfile.star":
// Starlib expects you to load the ZipFile function directly, rather than having it be part of a namespace.
// Wraps this to be more consistent with other pixlet modules, as follows:
// load("compress/zipfile.star", "zipfile")
// archive = zipfile.ZipFile("/tmp/foo.zip")
m, _ := starlibzip.LoadModule()
return starlark.StringDict{
"zipfile": &starlarkstruct.Module{
Name: "zipfile",
Members: m,
},
}, nil

case "encoding/base64.star":
return starlibbase64.LoadModule()

Expand Down
56 changes: 55 additions & 1 deletion runtime/applet_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package runtime

import (
"archive/zip"
"bytes"
"fmt"
"testing"

Expand Down Expand Up @@ -263,7 +265,7 @@ def main():
}

func TestTimezoneDatabase(t *testing.T) {
src:= `
src := `
load("render.star", "render")
load("time.star", "time")
def main():
Expand All @@ -279,4 +281,56 @@ def main():
assert.NoError(t, err)
}

func TestZipModule(t *testing.T) {
// Create a new zip file to read from starlark
// https://go.dev/src/archive/zip/example_test.go
buf := new(bytes.Buffer)
w := zip.NewWriter(buf)
var files = []struct {
Name, Body string
}{
{"readme.txt", "This archive contains some text files."},
{"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"},
{"todo.txt", "Get animal handling licence.\nWrite more examples."},
}
for _, file := range files {
f, err := w.Create(file.Name)
assert.NoError(t, err)
_, err = f.Write([]byte(file.Body))
assert.NoError(t, err)
}
err := w.Close()
assert.NoError(t, err)

// override the print function of the thread so we can check we got correct
// values from the zip module.
var printedText []string
initializer := func(thread *starlark.Thread) *starlark.Thread {
thread.Print = func(thread *starlark.Thread, msg string) {
printedText = append(printedText, msg)
}
return thread
}

src := `
load("compress/zipfile.star", "zipfile")
def main(config):
z = zipfile.ZipFile(config.get("ZIP_BYTES"))
print(z.namelist())
zf = z.open("readme.txt")
print(zf.read())
return []
`

app := &Applet{}
err = app.Load("test.star", []byte(src), nil)
_, err = app.Run(map[string]string{"ZIP_BYTES": buf.String()}, initializer)
assert.NoError(t, err)

assert.Equal(t, []string{
"[\"readme.txt\", \"gopher.txt\", \"todo.txt\"]",
"This archive contains some text files.",
}, printedText)
}

// TODO: test Screens, especially Screens.Render()

0 comments on commit d44879b

Please sign in to comment.