Compare commits

..

4 commits

10 changed files with 155 additions and 22 deletions

View file

@ -38,7 +38,7 @@ Start the server. The `--init` flag with create the default files and directory
makeshift serve --root $HOME/apps/makeshift/server --init
```
From here, you might want to see what files are available by default.
From here, you might want to see what files, plugins, and profiles that are available by default.
```bash
# list the files in the root directory
@ -60,7 +60,7 @@ makeshift list profiles
makeshift list profiles default
```
Then, we can start downloading some files or directories (as archives).
Then, we can start downloading some files or directories (as archives) both with and without running plugins.
```bash
# download all data (notice --host and --port are not set here)
@ -158,7 +158,7 @@ type Example struct{}
func (p *Example) Name() string { return "example" }
func (p *Example) Version() string { return "v0.0.1-alpha" }
func (p *Example) Description() string { return "An example plugin" }
func (p *Example) Metadata() map[string]string {
func (p *Example) Metadata() map[string]any {
return makeshift.Metadata{
"author": map[string]any{
"name": "John Smith",

View file

@ -9,11 +9,16 @@ import (
"strings"
"git.towk2.me/towk/makeshift/internal/archive"
"git.towk2.me/towk/makeshift/internal/kwargs"
"git.towk2.me/towk/makeshift/pkg/client"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)
var (
pluginArgs []string
pluginKWArgs kwargs.KWArgs = kwargs.KWArgs{}
)
var downloadCmd = cobra.Command{
Use: "download",
Example: `
@ -64,6 +69,12 @@ var downloadCmd = cobra.Command{
if len(profileIDs) > 0 {
query += "&profiles=" + url.QueryEscape(strings.Join(profileIDs, ","))
}
if len(pluginArgs) > 0 {
query += "&args=" + url.QueryEscape(strings.Join(pluginArgs, ","))
}
if len(pluginKWArgs) > 0 {
query += "&kwargs=" + url.QueryEscape(pluginKWArgs.String())
}
log.Debug().
Str("host", host).
@ -287,6 +298,8 @@ func init() {
downloadCmd.Flags().StringP("path", "p", ".", "Set the path to list files (can be set with MAKESHIFT_PATH)")
downloadCmd.Flags().StringSlice("profiles", []string{}, "Set the profile(s) to use to populate data store")
downloadCmd.Flags().StringSlice("plugins", []string{}, "Set the plugin(s) to run before downloading files")
downloadCmd.Flags().StringSlice("plugin-args", []string{}, "Set the argument list to pass to plugin(s)")
downloadCmd.Flags().Var(&pluginKWArgs, "plugin-kwargs", "Set the argument map to pass to plugin(s)")
downloadCmd.Flags().BoolP("extract", "x", false, "Set whether to extract archive locally after downloading")
downloadCmd.Flags().BoolP("remove-archive", "r", false, "Set whether to remove the archive after extracting (used with '--extract' flag)")

View file

@ -36,11 +36,11 @@ func (df DataFormat) Type() string {
return "DataFormat"
}
// MarshalData marshals arbitrary data into a byte slice formatted as outFormat.
// Marshal marshals arbitrary data into a byte slice formatted as outFormat.
// If a marshalling error occurs or outFormat is unknown, an error is returned.
//
// Supported values are: json, list, yaml
func Marshal(data interface{}, outFormat DataFormat) ([]byte, error) {
func Marshal(data any, outFormat DataFormat) ([]byte, error) {
switch outFormat {
case JSON:
if bytes, err := json.MarshalIndent(data, "", " "); err != nil {
@ -61,12 +61,12 @@ func Marshal(data interface{}, outFormat DataFormat) ([]byte, error) {
}
}
// UnmarshalData unmarshals a byte slice formatted as inFormat into an interface
// Unmarshal unmarshals a byte slice formatted as inFormat into an interface
// v. If an unmarshalling error occurs or inFormat is unknown, an error is
// returned.
//
// Supported values are: json, list, yaml
func Unmarshal(data []byte, v interface{}, inFormat DataFormat) error {
func Unmarshal(data []byte, v any, inFormat DataFormat) error {
switch inFormat {
case JSON:
if err := json.Unmarshal(data, v); err != nil {

34
internal/kwargs/kwargs.go Normal file
View file

@ -0,0 +1,34 @@
package kwargs
import (
"encoding/json"
"fmt"
"git.towk2.me/towk/makeshift/internal/format"
)
const RESERVED_KEY = "kwargs"
type KWArgs map[string]any
func (kw KWArgs) String() string {
b, _ := json.Marshal(kw)
return string(b)
}
func (kw *KWArgs) Set(v string /* should be JSON object*/) error {
var (
newArgs KWArgs
err error
)
err = format.Unmarshal([]byte(v), &newArgs, format.JSON)
if err != nil {
return fmt.Errorf("failed to unmarshal value for %s: %w", kw.Type(), err)
}
*kw = newArgs
return nil
}
func (kw *KWArgs) Type() string {
return "KWArgs"
}

View file

@ -1,16 +1,25 @@
package main
import "git.towk2.me/towk/makeshift/pkg/storage"
import (
makeshift "git.towk2.me/towk/makeshift/pkg"
"git.towk2.me/towk/makeshift/pkg/storage"
)
type Mapper struct{}
func (p *Mapper) Name() string { return "jinja2" }
func (p *Mapper) Version() string { return "test" }
func (p *Mapper) Description() string { return "Renders Jinja 2 templates" }
func (p *Mapper) Metadata() map[string]string {
return map[string]string{
"author.name": "David J. Allen",
"author.email": "davidallendj@gmail.com",
func (p *Mapper) Name() string { return "mapper" }
func (p *Mapper) Version() string { return "v0.0.1-alpha" }
func (p *Mapper) Description() string { return "Directly maps data to store" }
func (p *Mapper) Metadata() makeshift.Metadata {
return makeshift.Metadata{
"author": map[string]any{
"name": "David J. Allen",
"email": "davidallendj@gmail.com",
"links": []string{
"https://github.com/davidallendj",
"https://git.towk2.me/towk",
},
},
}
}

36
pkg/plugins/user/user.go Normal file
View file

@ -0,0 +1,36 @@
package main
import (
makeshift "git.towk2.me/towk/makeshift/pkg"
"git.towk2.me/towk/makeshift/pkg/storage"
)
type User struct{}
func (p *User) Name() string { return "user" }
func (p *User) Version() string { return "v0.0.1-alpha" }
func (p *User) Description() string { return "Get user information" }
func (p *User) Metadata() makeshift.Metadata {
return makeshift.Metadata{
"author": map[string]any{
"name": "David J. Allen",
"email": "davidallendj@gmail.com",
"links": []string{
"https://github.com/davidallendj",
"https://git.towk2.me/towk",
},
},
}
}
func (p *User) Init() error {
return nil
}
func (p *User) Run(store storage.KVStore, args []string) error {
return nil
}
func (p *User) Cleanup() error {
return nil
}

View file

@ -11,8 +11,10 @@ import (
"strings"
"git.towk2.me/towk/makeshift/internal/archive"
"git.towk2.me/towk/makeshift/internal/kwargs"
makeshift "git.towk2.me/towk/makeshift/pkg"
"git.towk2.me/towk/makeshift/pkg/storage"
"github.com/go-chi/chi/v5"
"github.com/rs/zerolog/log"
)
@ -20,9 +22,12 @@ func (s *Service) Download() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var (
path = s.PathForData() + strings.TrimPrefix(r.URL.Path, "/download")
pluginKWArgs = chi.URLParam(r, "kwargs")
pluginArgs = strings.Split(r.URL.Query().Get("args"), ",")
pluginNames = strings.Split(r.URL.Query().Get("plugins"), ",")
profileIDs = strings.Split(r.URL.Query().Get("profiles"), ",")
kw *kwargs.KWArgs
fileInfo os.FileInfo
out *os.File
store *storage.MemoryStorage = new(storage.MemoryStorage)
@ -32,8 +37,12 @@ func (s *Service) Download() http.HandlerFunc {
err error
)
// parse the KWArgs from request
kw.Set(pluginKWArgs)
// initialize storage
store.Init()
store.SetKWArgs(kw)
log.Debug().
Str("path", path).
@ -78,7 +87,7 @@ func (s *Service) Download() http.HandlerFunc {
log.Debug().Strs("files", filenamesToArchive).Send()
// prepare plugins
hooks, errs = s.loadPlugins(pluginNames, store, nil, errs)
hooks, errs = s.loadPlugins(pluginNames, store, pluginArgs, errs)
if len(errs) > 0 {
log.Error().Errs("errs", errs).Msg("errors occurred loading plugins")
errs = []error{}

View file

@ -1,5 +1,7 @@
package storage
import "git.towk2.me/towk/makeshift/internal/kwargs"
type DiskStorage struct{}
func (ds DiskStorage) Init() error {
@ -10,8 +12,17 @@ func (ds DiskStorage) Cleanup() error {
return nil
}
func (ds DiskStorage) Get(k string) error {
return nil
func (ds *DiskStorage) SetKWArgs(kw *kwargs.KWArgs) error {
return ds.Set(kwargs.RESERVED_KEY, kw)
}
func (ds *DiskStorage) GetKWArgs() (*kwargs.KWArgs, error) {
kw, err := ds.Get(kwargs.RESERVED_KEY)
return kw.(*kwargs.KWArgs), err
}
func (ds DiskStorage) Get(k string) (any, error) {
return nil, nil
}
func (ds DiskStorage) Set(k string, v any) error {

View file

@ -1,6 +1,10 @@
package storage
import "fmt"
import (
"fmt"
"git.towk2.me/towk/makeshift/internal/kwargs"
)
type MemoryStorage struct {
Data map[string]any `json:"data"`
@ -15,6 +19,15 @@ func (ms *MemoryStorage) Cleanup() error {
return nil
}
func (ms *MemoryStorage) SetKWArgs(kw *kwargs.KWArgs) error {
return ms.Set(kwargs.RESERVED_KEY, kw)
}
func (ms *MemoryStorage) GetKWArgs() (*kwargs.KWArgs, error) {
kw, err := ms.Get(kwargs.RESERVED_KEY)
return kw.(*kwargs.KWArgs), err
}
func (ms *MemoryStorage) Get(k string) (any, error) {
v, ok := ms.Data[k]
if ok {
@ -24,6 +37,9 @@ func (ms *MemoryStorage) Get(k string) (any, error) {
}
func (ms *MemoryStorage) Set(k string, v any) error {
if k == "kwargs" {
return fmt.Errorf("cannot set reserved key '%s' (use SetKWArgs() instead)", k)
}
ms.Data[k] = v
return nil
}

View file

@ -1,9 +1,14 @@
package storage
import "git.towk2.me/towk/makeshift/internal/kwargs"
type KVStore interface {
Init() error
Cleanup() error
SetKWArgs(kwargs *kwargs.KWArgs) error
GetKWArgs() (*kwargs.KWArgs, error)
Get(k string) (any, error)
Set(k string, v any) error
GetData() any