Skip to content

Commit

Permalink
feat: allow provide dynamic inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
moisespsena committed Apr 16, 2019
1 parent ba47ac0 commit c0c4a9b
Show file tree
Hide file tree
Showing 10 changed files with 493 additions and 148 deletions.
30 changes: 30 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"path/filepath"
"regexp"

"github.com/moisespsena-go/xbindata/walker"

"github.com/gobwas/glob"
)

Expand Down Expand Up @@ -42,6 +44,34 @@ type InputConfig struct {
IgnoreGlob []glob.Glob

Prefix string

NamePrefix string

WalkFunc func(visited *map[string]bool, recursive bool, cb func(info walker.FileInfo) error) error
}

func (i InputConfig) Walk(visited *map[string]bool, cb walker.WalkCallback) (err error) {
if i.WalkFunc != nil {
return i.WalkFunc(visited, i.Recursive, i.prepareCb(cb))
}

return i.DefaultWalk(visited, i.Recursive, cb)
}

func (i InputConfig) DefaultWalk(visited *map[string]bool, recursive bool, cb walker.WalkCallback) (err error) {
var pth = i.Path
w := walker.Walker{Recursive: recursive, VisitedPaths: visited}
return w.Walk(pth, i.prepareCb(cb))
}

func (i InputConfig) prepareCb(cb walker.WalkCallback) walker.WalkCallback {
if i.NamePrefix != "" {
old := cb
cb = func(info walker.FileInfo) error {
return old(info.SetNamePrefix(i.NamePrefix))
}
}
return cb
}

// Config defines a set of options for the asset conversion.
Expand Down
137 changes: 94 additions & 43 deletions config_many.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ package xbindata

import (
"fmt"
"github.com/apex/log"
"os"
"path"
"path/filepath"
"regexp"

"gopkg.in/yaml.v2"

"github.com/moisespsena-go/path-helpers"
"github.com/moisespsena-go/xbindata/ignore"

"github.com/mitchellh/mapstructure"

"github.com/gobwas/glob"
)

const (
Expand All @@ -20,40 +21,21 @@ const (
DefaultDataDir = "assets"
)

type IgnoreSlice []string

func (s IgnoreSlice) Items() (r []*regexp.Regexp, err error) {
for j, pattern := range s {
if regexPattern, err := regexp.Compile(pattern); err != nil {
return nil, fmt.Errorf("invalid regex pattern #%d (%q): %v", j, pattern, err)
} else {
r = append(r, regexPattern)
}
}
return
}

type IgnoreGlobSlice []string

func (s IgnoreGlobSlice) Items() (r []glob.Glob, err error) {
for j, pattern := range s {
if globPattern, err := glob.Compile(pattern); err != nil {
return nil, fmt.Errorf("invalid glob pattern #%d (%q): %v", j, pattern, err)
} else {
r = append(r, globPattern)
}
}
return
}
type (
IgnoreSlice = ignore.IgnoreSlice
IgnoreGlobSlice = ignore.IgnoreGlobSlice

type ManyConfigInputSlice []ManyConfigInput
ManyConfigInputSlice []ManyConfigInput
)

func (s ManyConfigInputSlice) Items() (r []InputConfig, err error) {
for j, input := range s {
if c, err := input.Config(); err != nil {
return nil, fmt.Errorf("get config from input #%d (%q) failed: %v", j, input, err)
} else {
r = append(r, *c)
for _, c := range c {
r = append(r, *c)
}
}
}
return
Expand All @@ -62,28 +44,97 @@ func (s ManyConfigInputSlice) Items() (r []InputConfig, err error) {
type ManyConfigInput struct {
Path string
Prefix string
NamePrefix string `mapstructure:"name_prefix" yaml:"name_prefix"`
Recursive bool
Ignore IgnoreSlice
IgnoreGlob IgnoreGlobSlice `mapstructure:"ignore_glob" yaml:"ignore_glob"`
}

func (i ManyConfigInput) Config() (c *InputConfig, err error) {
c = &InputConfig{
Path: i.Path,
Recursive: i.Recursive,
Prefix: i.Prefix,
func (i ManyConfigInput) Config() (configs []*InputConfig, err error) {
if _, err = os.Stat(i.Path); err != nil {
if os.IsNotExist(err) {
log.Warnf("input %q does not exists", i.Path)
return nil, nil
}
return
}

if i.Prefix == "_" {
c.Prefix = i.Path
}
xbinputFile := filepath.Join(i.Path, ".xbinputs.yml")
if _, err = os.Stat(xbinputFile); err == nil {
if i.Prefix == "_" {
i.Prefix = i.Path
}

if c.IgnoreGlob, err = i.IgnoreGlob.Items(); err != nil {
return nil, err
}
if c.Ignore, err = i.Ignore.Items(); err != nil {
return nil, err
var (
xbinput struct{ Sources []ManyConfigInput }
f *os.File
)
if f, err = os.Open(xbinputFile); err != nil {
return
}

func() {
defer f.Close()
err = yaml.NewDecoder(f).Decode(&xbinput)
}()

if err != nil {
return
}

for _, input := range xbinput.Sources {
input.NamePrefix = path.Join(i.NamePrefix, input.NamePrefix)

if input.Prefix != "" {
if input.Prefix == "_" {
input.Prefix = input.Path
}

input.Prefix = filepath.Join(i.Prefix, input.Prefix)
}

input.Path = filepath.Join(i.Path, input.Path)

if !i.Recursive && input.Recursive {
input.Recursive = false
}

input.IgnoreGlob = append(i.IgnoreGlob, input.IgnoreGlob...)
input.Ignore = append(i.Ignore, input.Ignore...)

var cfgs []*InputConfig
if cfgs, err = input.Config(); err != nil {
return
}

configs = append(configs, cfgs...)
}
} else {
c := &InputConfig{
Path: i.Path,
Recursive: i.Recursive,
Prefix: i.Prefix,
NamePrefix: i.NamePrefix,
}

if i.Prefix == "_" {
c.Prefix = i.Path
}

if c.IgnoreGlob, err = i.IgnoreGlob.Items(); err != nil {
return nil, err
}
if c.Ignore, err = i.Ignore.Items(); err != nil {
return nil, err
}

if _, err := os.Stat(filepath.Join(i.Path, ".xbwalk", "main.go")); err == nil {
c.WalkFunc = i.Walked
}

configs = append(configs, c)
}

return
}

Expand Down
55 changes: 55 additions & 0 deletions config_many_input_walked.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package xbindata

import (
"bufio"
"fmt"
"github.com/moisespsena-go/xbindata/walker"
"os"
"os/exec"
"path/filepath"
)

func (i ManyConfigInput) Walked(visited *map[string]bool, recursive bool, cb walker.WalkCallback) (err error) {
cmd := exec.Command("go", "run", filepath.Join(i.Path, ".xbwalk", "main.go"))
cmd.Dir = i.Path
cmd.Env = os.Environ()
fr, err := cmd.StdoutPipe()
if err != nil {
return fmt.Errorf("pipe stdout failed: %v", err)
}
defer fr.Close()
cmd.Stderr = os.Stderr

var scanner = bufio.NewScanner(fr)

if err = cmd.Start(); err != nil {
return fmt.Errorf("start failed: %v", err)
}

var closed bool
defer func() {
if !closed {
cmd.Process.Kill()
cmd.Wait()
}
}()

go func() {
for scanner.Scan() {
pth := scanner.Text()
pth = filepath.Join(i.Path, pth)
var info os.FileInfo
if info, err = os.Stat(pth); err != nil {
return
}
if err = cb(walker.FileInfo{FileInfo: info, Path: pth}); err != nil {
return
}
}
}()

cmd.Wait()
closed = true

return err
}
11 changes: 5 additions & 6 deletions convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ func Translate(c *Config) error {
// Locate all the assets.
for _, input := range c.Input {
finder := Finder{
input.Recursive,
tocr,
append(c.Ignore, input.Ignore...),
append(c.IgnoreGlob, input.IgnoreGlob...),
Expand All @@ -84,16 +83,16 @@ func Translate(c *Config) error {
prefix = input.Prefix
}

if err := finder.find(input.Path, prefix); err != nil {
if err := finder.find(&input, prefix); err != nil {
return err
}
}

sort.Slice(tocr.toc, func(i, j int) bool {
return tocr.toc[i].Name < tocr.toc[j].Name
})

toc = tocr.toc

sort.Slice(toc, func(i, j int) bool {
return toc[i].Name < toc[j].Name
})
}

// Create output file.
Expand Down
Loading

0 comments on commit c0c4a9b

Please sign in to comment.