Skip to content

Commit 9cfa840

Browse files
authored
CHORE: 0.3.0 pre-release (#32)
1 parent 85e3de3 commit 9cfa840

File tree

5 files changed

+81
-31
lines changed

5 files changed

+81
-31
lines changed

internal/tree/retriever.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,19 @@ import (
55
"errors"
66
"fmt"
77
"os"
8+
"path/filepath"
89
)
910

10-
func List(path string) (Nodes, error) {
11-
response, err := os.ReadDir(path)
11+
type Tree struct {
12+
WorkDir string
13+
}
14+
15+
func (t *Tree) Copy() Tree {
16+
return Tree{WorkDir: t.WorkDir}
17+
}
18+
19+
func (t *Tree) List(path string) (Nodes, error) {
20+
response, err := os.ReadDir(filepath.Join(t.WorkDir, path))
1221

1322
var pathError *os.PathError
1423
if errors.As(err, &pathError) {
@@ -29,19 +38,27 @@ func List(path string) (Nodes, error) {
2938
return entries, nil
3039
}
3140

32-
func Chdir(path string) error {
33-
err := os.Chdir(path)
41+
func (t *Tree) Chdir(path string) error {
42+
fullPath := filepath.Join(t.WorkDir, path)
43+
dir, err := os.Open(fullPath)
3444

3545
var pathError *os.PathError
3646
if errors.As(err, &pathError) {
47+
return &PathError{Message: fmt.Sprintf("\"%s\": no such file or directory", path)}
48+
}
49+
50+
stat, _ := dir.Stat()
51+
52+
if !stat.IsDir() {
3753
return &PathError{Message: fmt.Sprintf("\"%s\" is not a directory", path)}
3854
}
3955

56+
t.WorkDir = fullPath
4057
return nil
4158
}
4259

43-
func ReadNodeLineByLine(path string, hook LineHook, counter *uint64) {
44-
file, _ := os.Open(path)
60+
func (t *Tree) ReadNodeLineByLine(path string, hook LineHook, counter *uint64) {
61+
file, _ := os.Open(filepath.Join(t.WorkDir, path))
4562
defer file.Close() // nolint:errcheck
4663

4764
scanner := bufio.NewScanner(file)

internal/tree/tree_test.go

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,15 @@ import (
88
"github.com/stretchr/testify/assert"
99
"github.com/stretchr/testify/suite"
1010

11-
"github.com/statloc/core/internal/tree"
11+
t "github.com/statloc/core/internal/tree"
1212
)
1313

1414
type (
1515
TreeSuite struct {
1616
suite.Suite
17+
tree t.Tree
1718
dir string
1819
nonExistingPath string
19-
file string
20-
fileText string
2120
hook func (
2221
text string,
2322
counter *uint64,
@@ -28,40 +27,38 @@ type (
2827
func (s *TreeSuite) SetupSuite() {
2928
s.dir = filepath.Join("..", "..", "testdata")
3029
s.nonExistingPath = "non_existing_path"
31-
s.file = ""
3230
s.hook = func(text string, counter *uint64) {
3331
*counter++
3432
}
35-
36-
file, _ := os.ReadFile(s.file)
37-
s.fileText = string(file)
33+
workdir, _ := os.Getwd()
34+
s.tree = t.Tree{WorkDir: workdir}
3835
}
3936

4037
func (s *TreeSuite) TestList() {
41-
response, err := tree.List(s.dir)
38+
response, err := s.tree.List(s.dir)
4239
assert.Nil(s.T(), err)
43-
assert.IsType(s.T(), response, tree.Nodes{})
40+
assert.IsType(s.T(), response, t.Nodes{})
4441
assert.Len(s.T(), response, 5)
4542

46-
_, err = tree.List(s.nonExistingPath)
43+
_, err = s.tree.List(s.nonExistingPath)
4744
assert.NotNil(s.T(), err)
4845
}
4946

5047
func (s *TreeSuite) TestChdir() {
51-
err := tree.Chdir("non_existing_dir")
48+
err := s.tree.Chdir("non_existing_dir")
5249
assert.NotNil(s.T(), err)
5350

54-
err = tree.Chdir(filepath.Join("..", "..", "testdata"))
51+
err = s.tree.Chdir(filepath.Join("..", "..", "testdata"))
5552
assert.Nil(s.T(), err)
5653

57-
err = tree.Chdir(filepath.Join("..", "internal", "tree"))
54+
err = s.tree.Chdir(filepath.Join("..", "internal", "tree"))
5855
assert.Nil(s.T(), err)
5956
}
6057

6158
func (s *TreeSuite) TestReadNodeLineByLine() {
6259
counter := new(uint64)
6360

64-
tree.ReadNodeLineByLine(filepath.Join(s.dir, "main.go"), s.hook, counter)
61+
s.tree.ReadNodeLineByLine(filepath.Join(s.dir, "main.go"), s.hook, counter)
6562

6663
assert.Equal(s.T(), uint64(7), *counter)
6764
}

main.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ package statloc
33
import (
44
_ "embed"
55
"errors"
6+
"os"
67
"path/filepath"
8+
"sync"
79

810
"github.com/statloc/core/internal/mapping"
911
"github.com/statloc/core/internal/matching"
10-
"github.com/statloc/core/internal/tree"
12+
t "github.com/statloc/core/internal/tree"
1113
)
1214

1315
var (
@@ -21,9 +23,12 @@ var (
2123
func GetStatistics(path string) (statistics Statistics, err error) {
2224
mapping.Load(rawComponentsMapping, rawLanguagesMapping)
2325

26+
workdir, _ := os.Getwd()
27+
tree := t.Tree{WorkDir: workdir}
28+
2429
list, err := tree.List(path)
2530

26-
var treePathError *tree.PathError
31+
var treePathError *t.PathError
2732
if errors.As(err, &treePathError) {
2833
err = &PathError{Path: path}
2934
return
@@ -37,14 +42,20 @@ func GetStatistics(path string) (statistics Statistics, err error) {
3742

3843
err = nil
3944

40-
componentsSet := &componentSet{
45+
componentsSet := componentSet{
4146
Elements: make(map[string]struct{}),
4247
Tail: nil,
4348
}
4449

50+
var waitGroup sync.WaitGroup
51+
var mutex sync.Mutex
52+
53+
54+
waitGroup.Add(1)
4555
tree.Chdir(path) //nolint:errcheck
46-
goAroundCalculating(list, &statistics, nil, componentsSet)
56+
goAroundCalculating(&waitGroup, &mutex, tree, list, &statistics, componentsSet)
4757
tree.Chdir("..") //nolint:errcheck
58+
waitGroup.Wait()
4859

4960
cleanStatistics(statistics.Languages)
5061
cleanStatistics(statistics.Components)
@@ -53,24 +64,28 @@ func GetStatistics(path string) (statistics Statistics, err error) {
5364
}
5465

5566
func goAroundCalculating(
56-
list tree.Nodes,
67+
waitGroup *sync.WaitGroup,
68+
mutex *sync.Mutex,
69+
tree t.Tree,
70+
list t.Nodes,
5771
statistics *Statistics,
58-
tailComponent *component,
59-
componentsSet *componentSet,
72+
componentsSet componentSet,
6073
) {
74+
defer waitGroup.Done()
6175
for _, node := range list {
6276
if node.IsDir {
6377
newComponentTitle, exists := matching.FindMatch(filepath.Base(node.Name), mapping.Components)
6478

6579
exists = exists && !componentsSet.In(newComponentTitle)
6680
if exists {
67-
tailComponent = componentsSet.Add(newComponentTitle)
81+
componentsSet.Tail = componentsSet.Add(newComponentTitle)
6882
}
6983

70-
list, _ = tree.List(node.Name)
84+
newList, _ := tree.List(node.Name)
7185

86+
waitGroup.Add(1)
7287
tree.Chdir(node.Name) //nolint:errcheck
73-
goAroundCalculating(list, statistics, tailComponent, componentsSet)
88+
go goAroundCalculating(waitGroup, mutex, tree.Copy(), newList, statistics, componentsSet.Copy())
7489
tree.Chdir("..") //nolint:errcheck
7590

7691
if exists {
@@ -83,6 +98,7 @@ func goAroundCalculating(
8398
LOC := uint64(1)
8499
tree.ReadNodeLineByLine(node.Name, proceedLine, &LOC)
85100

101+
mutex.Lock()
86102
statistics.Total.Append(LOC, 1)
87103
statistics.Languages[language].Append(LOC, 1)
88104

@@ -95,6 +111,7 @@ func goAroundCalculating(
95111
for componentTitle := range componentsSet.Elements {
96112
statistics.Components[componentTitle].Append(LOC, 1)
97113
}
114+
mutex.Unlock()
98115
}
99116
}
100117
}

main_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ func (s *MainSuite) TestGetStatistics() {
2929
assert.NotPanics(s.T(), func() {core.GetStatistics("testdata")}) //nolint:errcheck
3030

3131
for title, item := range s.results.Components {
32-
println(title)
3332
assert.Equal(s.T(), item.LOC, response.Components[title].LOC)
3433
assert.Equal(s.T(), item.Files, response.Components[title].Files)
3534
}

types.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,26 @@ func (s *componentSet) In(title string) bool {
4141
return exists
4242
}
4343

44+
func (s *componentSet) Copy() componentSet {
45+
elements := make(map[string]struct{})
46+
tail := s.Tail.Copy(elements)
47+
return componentSet{
48+
Tail: tail,
49+
Elements: elements,
50+
}
51+
}
52+
53+
func (c *component) Copy(elements map[string]struct{}) *component {
54+
if c == nil {
55+
return nil
56+
}
57+
elements[c.Title] = struct{}{}
58+
return &component{
59+
Title: c.Title,
60+
Prev: c.Prev.Copy(elements),
61+
}
62+
}
63+
4464
func (t *TableItem) Append(LOC uint64, files uint64) {
4565
t.LOC += LOC
4666
t.Files += files

0 commit comments

Comments
 (0)