summaryrefslogtreecommitdiff
path: root/model
diff options
context:
space:
mode:
Diffstat (limited to 'model')
-rw-r--r--model/multi.go73
-rw-r--r--model/new.go98
-rw-r--r--model/source.go10
3 files changed, 142 insertions, 39 deletions
diff --git a/model/multi.go b/model/multi.go
new file mode 100644
index 0000000..35b792f
--- /dev/null
+++ b/model/multi.go
@@ -0,0 +1,73 @@
+package model
+
+import (
+ "errors"
+ "io/fs"
+ "path/filepath"
+ "slices"
+ "strings"
+)
+
+func Include(root fs.FS, st *State, data map[string]*SourceData, indexers []Indexer, runners []Runner) error {
+ for _, s := range st.Sources {
+ if data[s.Path] == nil || data[s.Path].Includes == nil {
+ continue
+ }
+ for _, w := range data[s.Path].Includes {
+ if IsRelative(w) {
+ p, err := filepath.Abs(filepath.Join(s.Path, w))
+ if err != nil {
+ return err
+ }
+
+ // check if source is already included
+ for _, maybeSource := range st.Sources {
+ if maybeSource.Path == p {
+ continue
+ }
+ }
+
+ src, errs := NewSource(root, p, indexers, runners)
+ if len(errs) > 0 {
+ return errors.Join(errs...)
+ }
+ s.Targets = append(s.Targets, src.Targets...)
+ }
+ }
+ }
+ return nil
+}
+
+func Wants(root fs.FS, st *State, data map[string]*SourceData, indexers []Indexer, runners []Runner) error {
+ for i, s := range st.Sources {
+ if data[s.Path] == nil || data[s.Path].Wants == nil {
+ continue
+ }
+ for _, w := range data[s.Path].Wants {
+ if IsRelative(w) {
+ p, err := filepath.Abs(filepath.Join(s.Path, w))
+ if err != nil {
+ return err
+ }
+
+ // check if source is already included
+ for _, maybeSource := range st.Sources {
+ if maybeSource.Path == p {
+ continue
+ }
+ }
+
+ src, errs := NewSource(root, p, indexers, runners)
+ if len(errs) > 0 {
+ return errors.Join(errs...)
+ }
+ st.Sources = slices.Insert(st.Sources, i+1, src)
+ }
+ }
+ }
+ return nil
+}
+
+func IsRelative(path string) bool {
+ return strings.HasPrefix(path, ".")
+}
diff --git a/model/new.go b/model/new.go
index 94e19a8..fc57ad0 100644
--- a/model/new.go
+++ b/model/new.go
@@ -4,13 +4,58 @@ import (
"errors"
"github.com/ewy1/pik/flags"
"github.com/ewy1/pik/identity"
+ "github.com/ewy1/pik/spool"
"io/fs"
"path/filepath"
"strings"
"sync"
)
-func NewState(rootFs fs.FS, locations []string, indexers []Indexer, runners []Runner) (*State, []error) {
+func NewSource(rootFs fs.FS, loc string, indexers []Indexer, runners []Runner) (*Source, []error) {
+ var errs []error
+ _, dirName := filepath.Split(strings.TrimSuffix(loc, "/"))
+ src := &Source{
+ Path: loc,
+ Identity: identity.New(dirName),
+ Whitelists: make(map[string][]string),
+ }
+ loc = strings.TrimSuffix(loc, "/")
+ loc = strings.TrimPrefix(loc, "/")
+
+ if loc == "" {
+ return nil, nil
+ }
+
+ locationWg := sync.WaitGroup{}
+ var targets = make([][]Target, len(indexers), len(indexers))
+ for ti, indexer := range indexers {
+ locationWg.Go(func() {
+ subFs, err := fs.Sub(rootFs, loc)
+ if err != nil && !errors.Is(err, fs.ErrNotExist) {
+ errs = append(errs, err)
+ return
+ }
+ result, err := indexer.Index("/"+loc, subFs, runners)
+ if err != nil && !errors.Is(err, fs.ErrNotExist) {
+ errs = append(errs, err)
+ return
+ }
+ targets[ti] = result
+ })
+ }
+ locationWg.Wait()
+
+ for _, t := range targets {
+ if t == nil {
+ continue
+ }
+ src.Targets = append(src.Targets, t...)
+ }
+
+ return src, errs
+}
+
+func NewState(rootFs fs.FS, locations []string, data map[string]*SourceData, indexers []Indexer, runners []Runner) (*State, []error) {
var errs []error
st := &State{
All: *flags.All,
@@ -19,46 +64,12 @@ func NewState(rootFs fs.FS, locations []string, indexers []Indexer, runners []Ru
var sources = make([]*Source, len(locations), len(locations))
for i, loc := range locations {
wg.Go(func() {
- _, dirName := filepath.Split(strings.TrimSuffix(loc, "/"))
- src := &Source{
- Path: loc,
- Identity: identity.New(dirName),
- Whitelists: make(map[string][]string),
+ src, err := NewSource(rootFs, loc, indexers, runners)
+ errs = append(errs, err...)
+ for _, e := range err {
+ _, _ = spool.Warn("%v\n", e)
}
sources[i] = src
- loc = strings.TrimSuffix(loc, "/")
- loc = strings.TrimPrefix(loc, "/")
-
- if loc == "" {
- return
- }
-
- locationWg := sync.WaitGroup{}
- var targets = make([][]Target, len(indexers), len(indexers))
- for ti, indexer := range indexers {
- locationWg.Go(func() {
- subFs, err := fs.Sub(rootFs, loc)
- if err != nil && !errors.Is(err, fs.ErrNotExist) {
- errs = append(errs, err)
- return
- }
- result, err := indexer.Index("/"+loc, subFs, runners)
- if err != nil && !errors.Is(err, fs.ErrNotExist) {
- errs = append(errs, err)
- return
- }
- targets[ti] = result
- })
- }
- locationWg.Wait()
-
- for _, t := range targets {
- if t == nil {
- continue
- }
- sources[i].Targets = append(sources[i].Targets, t...)
- }
-
})
}
@@ -71,5 +82,14 @@ func NewState(rootFs fs.FS, locations []string, indexers []Indexer, runners []Ru
st.Sources = append(st.Sources, s)
}
+ err := Wants(rootFs, st, data, indexers, runners)
+ if err != nil {
+ errs = append(errs, err)
+ }
+ err = Include(rootFs, st, data, indexers, runners)
+ if err != nil {
+ errs = append(errs, err)
+ }
+
return st, errs
}
diff --git a/model/source.go b/model/source.go
index 246929e..2844d23 100644
--- a/model/source.go
+++ b/model/source.go
@@ -6,10 +6,20 @@ import (
"github.com/ewy1/pik/spool"
)
+// SourceData is data we want to save from a Source before it has been properly instantiated
+type SourceData struct {
+ Aliases []string
+ Icon string
+ Path string
+ Wants []string
+ Includes []string
+}
+
// Source is a location containing stuff we can run
// these get created when we find a makefile, .pik folder, etc.
type Source struct {
identity.Identity
+ SourceData
Tags
Path string
Targets []Target