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 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 ```bash
# list the files in the root directory # list the files in the root directory
@ -60,7 +60,7 @@ makeshift list profiles
makeshift list profiles default 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 ```bash
# download all data (notice --host and --port are not set here) # 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) Name() string { return "example" }
func (p *Example) Version() string { return "v0.0.1-alpha" } func (p *Example) Version() string { return "v0.0.1-alpha" }
func (p *Example) Description() string { return "An example plugin" } 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{ return makeshift.Metadata{
"author": map[string]any{ "author": map[string]any{
"name": "John Smith", "name": "John Smith",

View file

@ -9,11 +9,16 @@ import (
"strings" "strings"
"git.towk2.me/towk/makeshift/internal/archive" "git.towk2.me/towk/makeshift/internal/archive"
"git.towk2.me/towk/makeshift/internal/kwargs"
"git.towk2.me/towk/makeshift/pkg/client" "git.towk2.me/towk/makeshift/pkg/client"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var (
pluginArgs []string
pluginKWArgs kwargs.KWArgs = kwargs.KWArgs{}
)
var downloadCmd = cobra.Command{ var downloadCmd = cobra.Command{
Use: "download", Use: "download",
Example: ` Example: `
@ -64,6 +69,12 @@ var downloadCmd = cobra.Command{
if len(profileIDs) > 0 { if len(profileIDs) > 0 {
query += "&profiles=" + url.QueryEscape(strings.Join(profileIDs, ",")) 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(). log.Debug().
Str("host", host). 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().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("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("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("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)") 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" 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. // If a marshalling error occurs or outFormat is unknown, an error is returned.
// //
// Supported values are: json, list, yaml // Supported values are: json, list, yaml
func Marshal(data interface{}, outFormat DataFormat) ([]byte, error) { func Marshal(data any, outFormat DataFormat) ([]byte, error) {
switch outFormat { switch outFormat {
case JSON: case JSON:
if bytes, err := json.MarshalIndent(data, "", " "); err != nil { 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 // v. If an unmarshalling error occurs or inFormat is unknown, an error is
// returned. // returned.
// //
// Supported values are: json, list, yaml // 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 { switch inFormat {
case JSON: case JSON:
if err := json.Unmarshal(data, v); err != nil { 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 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{} type Mapper struct{}
func (p *Mapper) Name() string { return "jinja2" } func (p *Mapper) Name() string { return "mapper" }
func (p *Mapper) Version() string { return "test" } func (p *Mapper) Version() string { return "v0.0.1-alpha" }
func (p *Mapper) Description() string { return "Renders Jinja 2 templates" } func (p *Mapper) Description() string { return "Directly maps data to store" }
func (p *Mapper) Metadata() map[string]string { func (p *Mapper) Metadata() makeshift.Metadata {
return map[string]string{ return makeshift.Metadata{
"author.name": "David J. Allen", "author": map[string]any{
"author.email": "davidallendj@gmail.com", "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,18 +11,23 @@ import (
"strings" "strings"
"git.towk2.me/towk/makeshift/internal/archive" "git.towk2.me/towk/makeshift/internal/archive"
"git.towk2.me/towk/makeshift/internal/kwargs"
makeshift "git.towk2.me/towk/makeshift/pkg" makeshift "git.towk2.me/towk/makeshift/pkg"
"git.towk2.me/towk/makeshift/pkg/storage" "git.towk2.me/towk/makeshift/pkg/storage"
"github.com/go-chi/chi/v5"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
func (s *Service) Download() http.HandlerFunc { func (s *Service) Download() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
var ( var (
path = s.PathForData() + strings.TrimPrefix(r.URL.Path, "/download") path = s.PathForData() + strings.TrimPrefix(r.URL.Path, "/download")
pluginNames = strings.Split(r.URL.Query().Get("plugins"), ",") pluginKWArgs = chi.URLParam(r, "kwargs")
profileIDs = strings.Split(r.URL.Query().Get("profiles"), ",") 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 fileInfo os.FileInfo
out *os.File out *os.File
store *storage.MemoryStorage = new(storage.MemoryStorage) store *storage.MemoryStorage = new(storage.MemoryStorage)
@ -32,8 +37,12 @@ func (s *Service) Download() http.HandlerFunc {
err error err error
) )
// parse the KWArgs from request
kw.Set(pluginKWArgs)
// initialize storage // initialize storage
store.Init() store.Init()
store.SetKWArgs(kw)
log.Debug(). log.Debug().
Str("path", path). Str("path", path).
@ -78,7 +87,7 @@ func (s *Service) Download() http.HandlerFunc {
log.Debug().Strs("files", filenamesToArchive).Send() log.Debug().Strs("files", filenamesToArchive).Send()
// prepare plugins // prepare plugins
hooks, errs = s.loadPlugins(pluginNames, store, nil, errs) hooks, errs = s.loadPlugins(pluginNames, store, pluginArgs, errs)
if len(errs) > 0 { if len(errs) > 0 {
log.Error().Errs("errs", errs).Msg("errors occurred loading plugins") log.Error().Errs("errs", errs).Msg("errors occurred loading plugins")
errs = []error{} errs = []error{}

View file

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

View file

@ -1,6 +1,10 @@
package storage package storage
import "fmt" import (
"fmt"
"git.towk2.me/towk/makeshift/internal/kwargs"
)
type MemoryStorage struct { type MemoryStorage struct {
Data map[string]any `json:"data"` Data map[string]any `json:"data"`
@ -15,6 +19,15 @@ func (ms *MemoryStorage) Cleanup() error {
return nil 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) { func (ms *MemoryStorage) Get(k string) (any, error) {
v, ok := ms.Data[k] v, ok := ms.Data[k]
if ok { if ok {
@ -24,6 +37,9 @@ func (ms *MemoryStorage) Get(k string) (any, error) {
} }
func (ms *MemoryStorage) Set(k string, v 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 ms.Data[k] = v
return nil return nil
} }

View file

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