Skip to content

Commit

Permalink
refactor: remove parser builder
Browse files Browse the repository at this point in the history
  • Loading branch information
gabotechs committed Feb 10, 2024
1 parent 87be321 commit 8283462
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 107 deletions.
8 changes: 5 additions & 3 deletions cmd/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,17 @@ func CheckCmd() *cobra.Command {
if len(cfg.Check.Entrypoints) == 0 {
return fmt.Errorf(`config file "%s" has no entrypoints`, configPath)
}
parserBuilder, err := makeParserBuilder(cfg.Check.Entrypoints, cfg)
lang, err := inferLang(cfg.Check.Entrypoints, cfg)
if err != nil {
return err
}
parser, err := parserBuilder(args)
parser := language.NewParser(lang)
parser.UnwrapProxyExports = cfg.UnwrapExports
parser.Exclude = cfg.Exclude
if err != nil {
return err
}
return check.Check(parser, &cfg.Check, graph.NewStdErrCallbacks[*language.FileInfo]())
return check.Check[*language.FileInfo](parser, &cfg.Check, graph.NewStdErrCallbacks[*language.FileInfo]())
},
}
}
9 changes: 4 additions & 5 deletions cmd/entropy.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,13 @@ func EntropyCmd() *cobra.Command {
if err != nil {
return err
}
parserBuilder, err := makeParserBuilder(files, cfg)
if err != nil {
return err
}
parser, err := parserBuilder(files)
lang, err := inferLang(files, cfg)
if err != nil {
return err
}
parser := language.NewParser(lang)
parser.UnwrapProxyExports = cfg.UnwrapExports
parser.Exclude = cfg.Exclude
err = entropy.Render(files, parser, entropy.RenderConfig{
NoOpen: noBrowserOpen,
EnableGui: enableGui,
Expand Down
22 changes: 8 additions & 14 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ import (
"os"
"path/filepath"

"github.com/gabotechs/dep-tree/internal/graph"
"github.com/spf13/cobra"
"github.com/spf13/pflag"

"github.com/gabotechs/dep-tree/internal/config"
"github.com/gabotechs/dep-tree/internal/js"
"github.com/gabotechs/dep-tree/internal/language"
"github.com/gabotechs/dep-tree/internal/python"
"github.com/gabotechs/dep-tree/internal/rust"
"github.com/gabotechs/dep-tree/internal/utils"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

const renderGroupId = "render"
Expand Down Expand Up @@ -94,7 +92,7 @@ $ dep-tree check`,
return root
}

func inferLang(files []string) string {
func inferLang(files []string, cfg *config.Config) (language.Language, error) {
score := struct {
js int
python int
Expand Down Expand Up @@ -126,20 +124,16 @@ func inferLang(files []string) string {
}
}
}
return top.lang
}

func makeParserBuilder(files []string, cfg *config.Config) (graph.NodeParserBuilder[*language.FileInfo], error) {
if len(files) == 0 {
if top.lang == "" {
return nil, errors.New("at least one file must be provided")
}
switch inferLang(files) {
switch top.lang {
case "js":
return language.ParserBuilder(js.MakeJsLanguage, &cfg.Js, cfg), nil
return js.MakeJsLanguage(&cfg.Js)
case "rust":
return language.ParserBuilder(rust.MakeRustLanguage, &cfg.Rust, cfg), nil
return rust.MakeRustLanguage(&cfg.Rust)
case "python":
return language.ParserBuilder(python.MakePythonLanguage, &cfg.Python, cfg), nil
return python.MakePythonLanguage(&cfg.Python)
default:
return nil, fmt.Errorf("file \"%s\" not supported", files[0])
}
Expand Down
28 changes: 20 additions & 8 deletions cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import (
"strings"
"testing"

"github.com/gabotechs/dep-tree/internal/config"
"github.com/gabotechs/dep-tree/internal/js"
"github.com/gabotechs/dep-tree/internal/language"
"github.com/gabotechs/dep-tree/internal/python"
"github.com/gabotechs/dep-tree/internal/rust"
"github.com/stretchr/testify/require"

"github.com/gabotechs/dep-tree/internal/utils"
Expand Down Expand Up @@ -107,34 +112,41 @@ func TestInferLang(t *testing.T) {
tests := []struct {
Name string
Files []string
Expected string
Expected language.Language
Error string
}{
{
Name: "only 1 file",
Files: []string{"foo.js"},
Expected: "js",
Expected: &js.Language{},
},
{
Name: "majority of files",
Files: []string{"foo.js", "bar.rs", "foo.rs", "foo.py"},
Expected: "rust",
Expected: &rust.Language{},
},
{
Name: "unrelated files",
Files: []string{"foo.py", "foo.pdf"},
Expected: "python",
Expected: &python.Language{},
},
{
Name: "no match",
Files: []string{"foo.pdf", "bar.docx"},
Expected: "",
Name: "no match",
Files: []string{"foo.pdf", "bar.docx"},
Error: "at least one file must be provided",
},
}

for _, tt := range tests {
t.Run(tt.Name, func(t *testing.T) {
a := require.New(t)
a.Equal(tt.Expected, inferLang(tt.Files))
lang, err := inferLang(tt.Files, &config.Config{})
if tt.Error != "" {
a.ErrorContains(err, tt.Error)
} else {
a.NoError(err)
a.IsType(tt.Expected, lang)
}
})
}
}
23 changes: 14 additions & 9 deletions cmd/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,32 @@ func TreeCmd() *cobra.Command {
return err
}

parserBuilder, err := makeParserBuilder(files, cfg)
lang, err := inferLang(files, cfg)
if err != nil {
return err
}

if jsonFormat {
parser, err := parserBuilder(files)
if err != nil {
return err
}
parser := language.NewParser(lang)
parser.UnwrapProxyExports = cfg.UnwrapExports
parser.Exclude = cfg.Exclude

depTree, err := tree.NewTree(files, parser, graph.NewStdErrCallbacks[*language.FileInfo]())
if jsonFormat {
t, err := tree.NewTree[*language.FileInfo](files, parser, graph.NewStdErrCallbacks[*language.FileInfo]())
if err != nil {
return err
}

rendered, err := depTree.RenderStructured()
rendered, err := t.RenderStructured()
fmt.Println(rendered)
return err
} else {
return tui.Loop(files, parserBuilder, nil, true, nil, graph.NewStdErrCallbacks[*language.FileInfo]())
return tui.Loop[*language.FileInfo](
files,
parser,
nil,
true,
nil,
graph.NewStdErrCallbacks[*language.FileInfo]())
}
},
}
Expand Down
6 changes: 3 additions & 3 deletions internal/language/exports.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (p *Parser) parseExports(
}
defer stack.Pop()
cacheKey := fmt.Sprintf("%s-%t", id, unwrappedExports)
if cached, ok := p.exportsCache[cacheKey]; ok {
if cached, ok := p.ExportsCache[cacheKey]; ok {
return cached, nil
}

Expand All @@ -69,7 +69,7 @@ func (p *Parser) parseExports(
return nil, err
}

wrapped, err := p.lang.ParseExports(file)
wrapped, err := p.Lang.ParseExports(file)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -119,6 +119,6 @@ func (p *Parser) parseExports(
}

result := ExportsResult{Exports: exports, Errors: exportErrors}
p.exportsCache[cacheKey] = &result
p.ExportsCache[cacheKey] = &result
return &result, nil
}
6 changes: 3 additions & 3 deletions internal/language/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package language
type FileCacheKey string

func (p *Parser) parseFile(absPath string) (*FileInfo, error) {
if cached, ok := p.fileCache[absPath]; ok {
if cached, ok := p.FileCache[absPath]; ok {
return cached, nil
}
result, err := p.lang.ParseFile(absPath)
result, err := p.Lang.ParseFile(absPath)
if err != nil {
return nil, err
}
p.fileCache[absPath] = result
p.FileCache[absPath] = result
return result, err
}
6 changes: 3 additions & 3 deletions internal/language/imports.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ type ImportsResult struct {
type ImportsCacheKey string

func (p *Parser) gatherImportsFromFile(id string) (*ImportsResult, error) {
if cached, ok := p.importsCache[id]; ok {
if cached, ok := p.ImportsCache[id]; ok {
return cached, nil
}
file, err := p.parseFile(id)
if err != nil {
return nil, err
}
result, err := p.lang.ParseImports(file)
result, err := p.Lang.ParseImports(file)
if err != nil {
return nil, err
}
p.importsCache[id] = result
p.ImportsCache[id] = result
return result, err
}
62 changes: 21 additions & 41 deletions internal/language/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,24 @@ type Language interface {
}

type Parser struct {
lang Language
unwrapProxyExports bool
exclude []string
Lang Language
UnwrapProxyExports bool
Exclude []string
// cache
fileCache map[string]*FileInfo
importsCache map[string]*ImportsResult
exportsCache map[string]*ExportsResult
FileCache map[string]*FileInfo
ImportsCache map[string]*ImportsResult
ExportsCache map[string]*ExportsResult
}

func NewParser(lang Language) *Parser {
return &Parser{
Lang: lang,
UnwrapProxyExports: false,
Exclude: nil,
FileCache: make(map[string]*FileInfo),
ImportsCache: make(map[string]*ImportsResult),
ExportsCache: make(map[string]*ExportsResult),
}
}

var _ graph.NodeParser[*FileInfo] = &Parser{}
Expand All @@ -44,39 +55,8 @@ type Config interface {
IgnoreFiles() []string
}

type Builder[C any] func(C) (Language, error)

func ParserBuilder[C any](
languageBuilder Builder[C],
langCfg C,
generalCfg Config,
) graph.NodeParserBuilder[*FileInfo] {
fileCache := map[string]*FileInfo{}
importsCache := map[string]*ImportsResult{}
exportsCache := map[string]*ExportsResult{}
return func(files []string) (graph.NodeParser[*FileInfo], error) {
lang, err := languageBuilder(langCfg)
if err != nil {
return nil, err
}

parser := &Parser{
lang: lang,
unwrapProxyExports: true,
fileCache: fileCache,
importsCache: importsCache,
exportsCache: exportsCache,
}
if generalCfg != nil {
parser.unwrapProxyExports = generalCfg.UnwrapProxyExports()
parser.exclude = generalCfg.IgnoreFiles()
}
return parser, err
}
}

func (p *Parser) shouldExclude(path string) bool {
for _, exclusion := range p.exclude {
for _, exclusion := range p.Exclude {
if ok, _ := utils.GlobstarMatch(exclusion, path); ok {
return true
}
Expand Down Expand Up @@ -132,13 +112,13 @@ func (p *Parser) Deps(n *graph.Node[*FileInfo]) ([]*graph.Node[*FileInfo], error
// a different file, we want that file. Ex: foo.ts -> utils/index.ts -> utils/sum.ts. If unwrapProxyExports is
// set to true, we must trace those exports back.
for _, importEntry := range imports.Imports {
if !p.unwrapProxyExports {
if !p.UnwrapProxyExports {
resolvedImports.Set(importEntry.Path, true)
continue
}

// NOTE: at this point p.unwrapProxyExports is always true.
exports, err = p.parseExports(importEntry.Path, p.unwrapProxyExports, nil)
exports, err = p.parseExports(importEntry.Path, p.UnwrapProxyExports, nil)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -178,5 +158,5 @@ func (p *Parser) Deps(n *graph.Node[*FileInfo]) ([]*graph.Node[*FileInfo], error
}

func (p *Parser) Display(n *graph.Node[*FileInfo]) graph.DisplayResult {
return p.lang.Display(n.Id)
return p.Lang.Display(n.Id)
}
4 changes: 2 additions & 2 deletions internal/language/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func TestParser_Deps(t *testing.T) {
exports: tt.Exports,
}
parser := lang.testParser()
parser.unwrapProxyExports = true
parser.UnwrapProxyExports = true
node, err := parser.Node(tt.Path)
a.NoError(err)
deps, err := parser.Deps(node)
Expand All @@ -214,7 +214,7 @@ func TestParser_Deps(t *testing.T) {
}
a.Equal(tt.ExpectedUnwrapped, result)

parser.unwrapProxyExports = false
parser.UnwrapProxyExports = false

deps, err = parser.Deps(node)
a.NoError(err)
Expand Down
8 changes: 4 additions & 4 deletions internal/language/test_language.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ type TestLanguage struct {

func (t *TestLanguage) testParser() *Parser {
return &Parser{
lang: t,
fileCache: map[string]*FileInfo{},
importsCache: map[string]*ImportsResult{},
exportsCache: map[string]*ExportsResult{},
Lang: t,
FileCache: map[string]*FileInfo{},
ImportsCache: map[string]*ImportsResult{},
ExportsCache: map[string]*ExportsResult{},
}
}

Expand Down

0 comments on commit 8283462

Please sign in to comment.