Skip to content

Commit

Permalink
Refactor workflow APIs: support workflow builder based on Go template.
Browse files Browse the repository at this point in the history
  • Loading branch information
jellyterra committed Sep 24, 2024
1 parent 73d7a22 commit d8b9f9d
Show file tree
Hide file tree
Showing 21 changed files with 295 additions and 206 deletions.
4 changes: 2 additions & 2 deletions cmd/pagine/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"time"
)

func GenerateAll(root, dest *vfs.DirFS, isServing bool) error {
func GenerateAll(root, dest *vfs.DirFS, jobBuilderRoot string, isServing bool) error {

env, err := config.LoadEnv(root)
if err != nil {
Expand Down Expand Up @@ -54,7 +54,7 @@ func GenerateAll(root, dest *vfs.DirFS, isServing bool) error {
return err
}

err = CollectAndRunWorkflows(root, dest)
err = CollectAndRunWorkflows(root, dest, os.DirFS(jobBuilderRoot).(fs.StatFS))
if err != nil {
return err
}
Expand Down
4 changes: 3 additions & 1 deletion cmd/pagine/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ var (
optPublicDir = flag.String("public", "/tmp/"+filepath.Base(wd)+".public", "Location of public directory.")

optAddr = flag.String("serve", "", "Listen and Serve as HTTP.")

jobBuilderRoot = os.Getenv("PAGINE_JOB_BUILDER_ROOT")
)

func main() {
Expand All @@ -41,7 +43,7 @@ func _main() error {
return err
}
} else {
err := GenerateAll(root, dest, false)
err := GenerateAll(root, dest, jobBuilderRoot, false)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/pagine/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func Serve(root, dest *vfs.DirFS) error {
for {
if !updated.Load() {
updated.Store(true)
err := GenerateAll(root, dest, true)
err := GenerateAll(root, dest, jobBuilderRoot, true)
if err != nil {
fmt.Println(err)
}
Expand Down
24 changes: 15 additions & 9 deletions cmd/pagine/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"sync"
)

func CollectAndRunWorkflows(root, dest *vfs.DirFS) error {
func CollectAndRunWorkflows(root, dest *vfs.DirFS, jobBuilderRoot fs.StatFS) error {
bases, err := CollectWorkflows(root, dest)
if err != nil {
return err
Expand All @@ -24,15 +24,26 @@ func CollectAndRunWorkflows(root, dest *vfs.DirFS) error {
return nil
}

var wg sync.WaitGroup
var workflows []*workflow.Workflow

for _, base := range bases {
wf, err := config.LoadWorkflow(base, jobBuilderRoot)
if err != nil {
return err
}

workflows = append(workflows, wf)
}

var wg sync.WaitGroup

for _, wf := range workflows {
wg.Add(1)

go func() {
defer wg.Done()

err := RunWorkflow(base)
err := RunWorkflow(wf)
if err != nil {
fmt.Println(err)
}
Expand Down Expand Up @@ -67,14 +78,9 @@ func CollectWorkflows(root, dest *vfs.DirFS) (dirs []*vfs.DirFS, _ error) {
})
}

func RunWorkflow(root *vfs.DirFS) error {
func RunWorkflow(wf *workflow.Workflow) error {
var stageReports collection.Vector[*workflow.StageReport]

wf, err := config.LoadWorkflow(root)
if err != nil {
return err
}

for _, stage := range wf.Stages {
stageReport, err := stage.Run()
if err != nil {
Expand Down
12 changes: 7 additions & 5 deletions structure/v1_cast.go → common/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0
// that can be found in the LICENSE file and https://mozilla.org/MPL/2.0/.

package structure
package common

var v1Cast = map[string]any{
"Any": func(v any) any { return v },
"Int": func(v any) int { return v.(int) },
"Str": func(v any) string { return v.(string) },
func PanicOnError(err error) {
if err != nil {
panic(err)
}
}

func WrapObject(v any) func() any { return func() any { return v } }
13 changes: 13 additions & 0 deletions common/v1_arithmetic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2024 Jelly Terra
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0
// that can be found in the LICENSE file and https://mozilla.org/MPL/2.0/.

package common

var V1Arithmetic = map[string]any{
"add": func(aInt, bInt int) int { return aInt + bInt },
"sub": func(aInt, bInt int) int { return aInt - bInt },
"mul": func(aInt, bInt int) int { return aInt * bInt },
"div": func(aInt, bInt int) int { return aInt / bInt },
"mod": func(aInt, bInt int) int { return aInt % bInt },
}
44 changes: 44 additions & 0 deletions common/v1_builtin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2024 Jelly Terra
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0
// that can be found in the LICENSE file and https://mozilla.org/MPL/2.0/.

package common

import "errors"

type Slice struct {
Raw []any
}

func (s *Slice) Len() int { return len(s.Raw) }
func (s *Slice) Index(i int) any { return s.Raw[i] }
func (s *Slice) Slice(start, end int) *Slice { return &Slice{s.Raw[start:end]} }
func (s *Slice) Push(e ...any) (_ Void) { s.Raw = append(s.Raw, e...); return }
func (s *Slice) StringSlice() []string {
slice := make([]string, len(s.Raw))
for i, e := range s.Raw {
slice[i], _ = e.(string)
}
return slice
}

type Map struct {
Raw map[string]any
}

type Void string

func (m *Map) Set(key string, value any) (_ Void) { m.Raw[key] = value; return }
func (m *Map) Get(key string) any { return m.Raw[key] }
func (m *Map) Has(key string) bool { return m.Raw[key] != nil }
func (m *Map) Delete(key string) (_ Void) { delete(m.Raw, key); return }

var V1Builtin = map[string]any{
"panic": func(v string) (_ Void) { panic(errors.New(v)); return },

"Any": func(v any) any { return v },
"Int": func(v any) int { return v.(int) },
"Str": func(v any) string { return v.(string) },

"makeSlice": func() *Slice { return new(Slice) },
}
34 changes: 34 additions & 0 deletions common/v1_path.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2024 Jelly Terra
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0
// that can be found in the LICENSE file and https://mozilla.org/MPL/2.0/.

package common

import (
. "path"
)

type V1Path struct{}

func (V1Path) Base(path string) string { return Base(path) }

func (V1Path) Clean(path string) string { return Clean(path) }

func (V1Path) Dir(path string) string { return Dir(path) }

func (V1Path) Ext(path string) string { return Ext(path) }

func (V1Path) IsAbs(path string) bool { return IsAbs(path) }

func (V1Path) Join(paths ...string) string { return Join(paths...) }

func (V1Path) Match(pattern, name string) (matched bool, valid bool) {
matched, err := Match(pattern, name)
if err != nil {
return false, false
}

return matched, true
}

func (V1Path) Split(path string) (dir, file string) { return Split(path) }
55 changes: 55 additions & 0 deletions common/v1_strings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2024 Jelly Terra
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0
// that can be found in the LICENSE file and https://mozilla.org/MPL/2.0/.

package common

import "strings"

type V1Strings struct{}

func (V1Strings) Contains(s, substr string) bool { return strings.Contains(s, substr) }
func (V1Strings) ContainsAny(s, chars string) bool { return strings.Contains(s, chars) }
func (V1Strings) ContainsRune(s string, r rune) bool { return strings.ContainsRune(s, r) }

func (V1Strings) Count(s, substr string) int { return strings.Count(s, substr) }

func (V1Strings) HasPrefix(str, prefix string) bool { return strings.HasPrefix(str, prefix) }
func (V1Strings) HasSuffix(str, suffix string) bool { return strings.HasSuffix(str, suffix) }

func (V1Strings) Index(s, substr string) int { return strings.Index(s, substr) }
func (V1Strings) IndexAny(s, chars string) int { return strings.IndexAny(s, chars) }
func (V1Strings) IndexByte(s string, c byte) int { return strings.IndexByte(s, c) }
func (V1Strings) IndexRune(s string, r rune) int { return strings.IndexRune(s, r) }

func (V1Strings) Join(sep string, elems ...string) string { return strings.Join(elems, sep) }

func (V1Strings) LastIndex(s, substr string) int { return strings.LastIndex(s, substr) }
func (V1Strings) LastIndexAny(s, chars string) int { return strings.LastIndexAny(s, chars) }
func (V1Strings) LastIndexByte(s string, c byte) int { return strings.LastIndexByte(s, c) }

func (V1Strings) Repeat(s string, count int) string { return strings.Repeat(s, count) }

func (V1Strings) Replace(s, old, new string, n int) string { return strings.Replace(s, old, new, n) }
func (V1Strings) ReplaceAll(s, old, new string) string { return strings.ReplaceAll(s, old, new) }

func (V1Strings) Split(s, substr string) []string { return strings.Split(s, substr) }
func (V1Strings) SplitAfter(s, substr string) []string { return strings.SplitAfter(s, substr) }
func (V1Strings) SplitAfterN(s, substr string, n int) []string {
return strings.SplitAfterN(s, substr, n)
}
func (V1Strings) SplitN(s, substr string, n int) []string { return strings.SplitN(s, substr, n) }

func (V1Strings) ToLower(s string) string { return strings.ToLower(s) }
func (V1Strings) ToTitle(s string) string { return strings.ToTitle(s) }
func (V1Strings) ToUpper(s string) string { return strings.ToUpper(s) }
func (V1Strings) ToValidUTF8(s, replacement string) string {
return strings.ToValidUTF8(s, replacement)
}

func (V1Strings) Trim(s, cutset string) string { return strings.Trim(s, cutset) }
func (V1Strings) TrimLeft(s, cutset string) string { return strings.TrimLeft(s, cutset) }
func (V1Strings) TrimPrefix(str, prefix string) string { return strings.TrimPrefix(str, prefix) }
func (V1Strings) TrimRight(s, cutset string) string { return strings.TrimRight(s, cutset) }
func (V1Strings) TrimSpace(s string) string { return strings.TrimSpace(s) }
func (V1Strings) TrimSuffix(str, suffix string) string { return strings.TrimSuffix(str, suffix) }
52 changes: 17 additions & 35 deletions config/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import (
"github.com/jellyterra/collection-go"
"github.com/webpagine/pagine/v2/vfs"
"github.com/webpagine/pagine/v2/workflow"
"github.com/webpagine/pagine/v2/workflow/builtin/tsc"
"github.com/webpagine/pagine/v2/workflow/builtin"
"io/fs"
"os"
)

type TscJobConfig struct {
Expand All @@ -23,21 +25,25 @@ type Workflow struct {
} `yaml:"stage"`
}

func LoadJob(root *vfs.DirFS, m map[string]any) (*workflow.Job, error) {
gen, ok := jobGens[m["type"].(string)]
if !ok {
return nil, fmt.Errorf("unknown job type: %s", m["type"])
func LoadJob(root *vfs.DirFS, m map[string]any, jobBuilderRoot fs.StatFS) (*workflow.Job, error) {
if m["type"] == nil {
return nil, fmt.Errorf("job type is not specified")
}

job, err := gen(root, m)
if err != nil {
jobBuilderFile := m["type"].(string) + ".tmpl"

_, err := jobBuilderRoot.Stat(jobBuilderFile)
switch {
case err == nil:
case os.IsNotExist(err):
return workflow.BuildJob(builtin.BuiltinBuilders, jobBuilderFile, root, m)
default:
return nil, err
}

return job, nil
return workflow.BuildJob(jobBuilderRoot, jobBuilderFile, root, m)
}

func LoadWorkflow(root *vfs.DirFS) (*workflow.Workflow, error) {
func LoadWorkflow(root *vfs.DirFS, jobBuilderRoot fs.StatFS) (*workflow.Workflow, error) {

var (
rawWorkflow Workflow
Expand All @@ -54,7 +60,7 @@ func LoadWorkflow(root *vfs.DirFS) (*workflow.Workflow, error) {
var jobs collection.Vector[*workflow.Job]

for _, job := range stage.Job {
job, err := LoadJob(root, job)
job, err := LoadJob(root, job, jobBuilderRoot)
if err != nil {
return nil, err
}
Expand All @@ -69,27 +75,3 @@ func LoadWorkflow(root *vfs.DirFS) (*workflow.Workflow, error) {
Stages: stages.Raw,
}, nil
}

type TscJob struct {
Path string `json:"path"`
}

func generateTscJob(root *vfs.DirFS, m map[string]any) (*workflow.Job, error) {
var tscJob TscJob

err := UnmarshalMap(m, &tscJob)
if err != nil {
return nil, err
}

cmd, err := tsc.BuildTS(root, tscJob.Path)

return &workflow.Job{
Title: m["title"].(string),
Commands: []*workflow.Command{cmd},
}, nil
}

var jobGens = map[string]func(root *vfs.DirFS, m map[string]any) (*workflow.Job, error){
"tsc/v1": generateTscJob,
}
12 changes: 0 additions & 12 deletions structure/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@ import (
"github.com/webpagine/pagine/v2/vfs"
)

func WrapObject(v any) func() any { return func() any { return v } }

func WrapMap(funcMap map[string]any) func() map[string]any {
return func() map[string]any { return funcMap }
}

type GetFuncMap func(b *Context) map[string]any

type Context struct {
Expand All @@ -26,10 +20,4 @@ type Context struct {
DataSet MetadataSet
}

func panicOnError(err error) {
if err != nil {
panic(err)
}
}

var Versions = map[string]GetFuncMap{}
Loading

0 comments on commit d8b9f9d

Please sign in to comment.