Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/classifier/classifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ func TestClassifier(t *testing.T) {
t.Parallel()

mocks := newTestClassifierMocks(t)
source, sourceErr := coreSourceProvider{}.provider().source()

source, sourceErr := yamlSourceProvider{rawSourceProvider: coreSourceProvider{}}.source()
if sourceErr != nil {
t.Fatal(sourceErr)
return
Expand Down
2 changes: 1 addition & 1 deletion internal/classifier/json_schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestJSONSchema(t *testing.T) {
require.NoError(t, err)
assert.True(t, metaResult.Valid())

coreClassifier, err := yamlSourceProvider{rawSourceProvider: coreSourceProvider{}}.source()
coreClassifier, err := coreSourceProvider{}.provider().source()
require.NoError(t, err)
coreClassifierJSON, err := json.Marshal(coreClassifier)
require.NoError(t, err)
Expand Down
108 changes: 71 additions & 37 deletions internal/classifier/source_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,26 @@ package classifier

import (
"os"
"path/filepath"
"strings"

"github.com/adrg/xdg"
"github.com/bitmagnet-io/bitmagnet/internal/tmdb"
"gopkg.in/yaml.v3"
)

func newSourceProvider(config Config, tmdbConfig tmdb.Config) sourceProvider {
return mergeSourceProvider{
providers: []sourceProvider{
yamlSourceProvider{rawSourceProvider: coreSourceProvider{}},
yamlSourceProvider{rawSourceProvider: xdgSourceProvider{}},
yamlSourceProvider{rawSourceProvider: cwdSourceProvider{}},
configSourceProvider{
config: config,
tmdbEnabled: tmdbConfig.Enabled,
},
},
}
var providers []sourceProvider
providers = append(providers, coreSourceProvider{}.provider())
providers = append(providers, xdgSourceProvider{}.providers()...)
providers = append(providers, cwdSourceProvider{}.providers()...)
providers = append(providers, extraSourceProvider{}.providers()...)
providers = append(providers, configSourceProvider{
config: config,
tmdbEnabled: tmdbConfig.Enabled,
})

return mergeSourceProvider{providers: providers}
}

type sourceProvider interface {
Expand Down Expand Up @@ -49,23 +51,19 @@ func (m mergeSourceProvider) source() (Source, error) {
return source, nil
}

type rawSourceProvider interface {
source() ([]byte, error)
}

type yamlSourceProvider struct {
rawSourceProvider
raw []byte
err error
}

func (y yamlSourceProvider) source() (Source, error) {
raw, err := y.rawSourceProvider.source()
if err != nil {
return Source{}, err
if y.err != nil {
return Source{}, y.err
}

rawWorkflow := make(map[string]interface{})

parseErr := yaml.Unmarshal(raw, &rawWorkflow)
parseErr := yaml.Unmarshal(y.raw, &rawWorkflow)
if parseErr != nil {
return Source{}, parseErr
}
Expand All @@ -86,34 +84,68 @@ func (y yamlSourceProvider) source() (Source, error) {

type coreSourceProvider struct{}

func (coreSourceProvider) source() ([]byte, error) {
return classifierCoreYaml, nil
func (coreSourceProvider) provider() sourceProvider {
return yamlSourceProvider{raw: classifierCoreYaml}
}

type xdgSourceProvider struct{}

func (xdgSourceProvider) source() ([]byte, error) {
if path, pathErr := xdg.ConfigFile("bitmagnet/classifier.yml"); pathErr == nil {
if bytes, readErr := os.ReadFile(path); readErr == nil {
return bytes, nil
} else if !os.IsNotExist(readErr) {
return nil, readErr
}
func (yamlSourceProvider) providers(path string, wildcard bool) []sourceProvider {
glob := path

if wildcard {
dir, fname := filepath.Split(path)
glob = dir + "classifier*" + filepath.Ext(fname)
}

paths, err := filepath.Glob(glob)
if err != nil {
return []sourceProvider{yamlSourceProvider{err: err}}
}

return []byte{'{', '}'}, nil
providers := make([]sourceProvider, len(paths))

for i, path := range paths {
bytes, readErr := os.ReadFile(path)
providers[i] = yamlSourceProvider{raw: bytes, err: readErr}
}

return providers
}

type cwdSourceProvider struct{}
func (xdgSourceProvider) providers() []sourceProvider {
path, err := xdg.ConfigFile("bitmagnet/classifier.yml")
if err != nil {
return []sourceProvider{yamlSourceProvider{err: err}}
}

return yamlSourceProvider{}.providers(path, true)
}

type extraSourceProvider struct{}

func (cwdSourceProvider) source() ([]byte, error) {
if bytes, readErr := os.ReadFile("./classifier.yml"); readErr == nil {
return bytes, nil
} else if !os.IsNotExist(readErr) {
return nil, readErr
func (extraSourceProvider) providers() []sourceProvider {
var extraConfigFiles []string

for _, rawEnvEntry := range os.Environ() {
parts := strings.SplitN(rawEnvEntry, "=", 2)
if parts[0] == extraFilesKey {
extraConfigFiles = strings.Split(parts[1], ",")
}
}

return []byte{'{', '}'}, nil
var providers []sourceProvider
for _, path := range extraConfigFiles {
providers = append(providers, yamlSourceProvider{}.providers(path, false)...)
}

return providers
}

type cwdSourceProvider struct{}

func (cwdSourceProvider) providers() []sourceProvider {
return yamlSourceProvider{}.providers("./classifier.yml", true)
}

type configSourceProvider struct {
Expand Down Expand Up @@ -141,3 +173,5 @@ func (c configSourceProvider) source() (Source, error) {
Flags: fs,
}, nil
}

const extraFilesKey = "EXTRA_CLASSIFIER_FILES"