Skip to content

Commit

Permalink
feat: display files per language on table
Browse files Browse the repository at this point in the history
  • Loading branch information
ramirezfernando committed Apr 9, 2024
1 parent 04c2e01 commit 204d2c8
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 38 deletions.
45 changes: 30 additions & 15 deletions src/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ import (
"github.com/charmbracelet/log"
)

type languageDetails struct {
// TODO: Change to uint
lines int
files int
}

func main() {
if len(os.Args) != 2 {
log.Fatal(`Usage: cloc <folder>`)
Expand Down Expand Up @@ -59,20 +65,20 @@ func getMessage(path string) tea.Msg {
return terminal.ClocCompleted{Table: t, Help: h}
}

func countLinesOfCode(path string) (map[string]int, error) {
func countLinesOfCode(path string) (map[string]languageDetails, error) {
var wg sync.WaitGroup
var mu sync.Mutex
lineCount := make(map[string]int)

lineCount := make(map[string]languageDetails)

err := filepath.WalkDir(path, func(currPath string, info fs.DirEntry, err error) error {
if err != nil {
return err
}
if info.IsDir() || !info.Type().IsRegular(){
if info.IsDir() || !info.Type().IsRegular() {
return nil
}
language, exists := language.Exts[filepath.Ext(currPath)];
language, exists := language.Exts[filepath.Ext(currPath)]
if !exists {
return nil
}
Expand All @@ -83,12 +89,18 @@ func countLinesOfCode(path string) (map[string]int, error) {

lines, err := countLinesOfFile(currPath)
if err != nil {
log.Error("Error counting lines in %s: %v\n", currPath, err)
log.Error(err)
return
}

mu.Lock()
lineCount[language] += lines
ld, exists := lineCount[language]
if !exists {
ld = languageDetails{}
}
ld.lines += lines
ld.files++
lineCount[language] = ld
mu.Unlock()
}()

Expand Down Expand Up @@ -133,26 +145,29 @@ func countLinesOfFile(filePath string) (int, error) {
return count, err
}

func generateTable(lineCount map[string]int) table.Model {
func generateTable(lineCount map[string]languageDetails) table.Model {
columns := []table.Column{
{Title: "Language", Width: 16},
{Title: "Lines of Code", Width: 16},
{Title: "Lines", Width: 16},
{Title: "Files", Width: 10},
}

rows := []table.Row{}
total := 0
for language, count := range lineCount {
rows = append(rows, table.Row{language, strconv.Itoa(count)})
total += count
lineTotal := 0
fileTotal := 0
for language, details := range lineCount {
rows = append(rows, table.Row{language, strconv.Itoa(details.lines), strconv.Itoa(details.files)})
lineTotal += details.lines
fileTotal += details.files
}
sort.Slice(rows, func(i, j int) bool {
li1, _ := strconv.Atoi(rows[i][1])
li2, _ := strconv.Atoi(rows[j][1])
return li1 > li2
})

rows = append(rows, table.Row{"", ""})
rows = append(rows, table.Row{"Total", strconv.Itoa(total)})
rows = append(rows, table.Row{"", "", ""})
rows = append(rows, table.Row{"Total", strconv.Itoa(lineTotal), strconv.Itoa(fileTotal)})

t := table.New(
table.WithColumns(columns),
Expand Down
47 changes: 25 additions & 22 deletions src/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import (
)

func TestGetMessage(t *testing.T) {
llc := map[string]int{
"Go": 4,
"OCaml": 28,
"Plain Text": 0,
"JavaScript": 24,
llc := map[string]languageDetails{
"Go": {4, 1},
"OCaml": {28, 1},
"Plain Text": {0, 1},
"JavaScript": {24, 1},
}

_, err := countLinesOfCode("../tests/data/nonexistent.txt")
Expand All @@ -41,14 +41,16 @@ func TestCountLinesOfCode(t *testing.T) {

tests := []struct {
path string
expectedClocMap map[string]int
expectedClocMap map[string]languageDetails
}{
{"../tests/data/hello.go", map[string]int{"Go": 4}},
{"../tests/data/stack.ml", map[string]int{"OCaml": 28}},
{"../tests/data/empty.txt", map[string]int{"Plain Text": 0}},
{"../tests/data/person.js", map[string]int{"JavaScript": 24}},
{"../tests/data", map[string]int{"Go": 4, "OCaml": 28, "Plain Text": 0, "JavaScript": 24}}, // Directory
{"../tests/data/nonexistent.txt", map[string]int{}}, // Non-existent file
{"../tests/data/hello.go", map[string]languageDetails{"Go": {4, 1}}},
{"../tests/data/stack.ml", map[string]languageDetails{"OCaml": {28, 1}}},
{"../tests/data/empty.txt", map[string]languageDetails{"Plain Text": {0, 1}}},
{"../tests/data/person.js", map[string]languageDetails{"JavaScript": {24, 1}}},
{"../tests/data", map[string]languageDetails{"Go": {4, 1}, "OCaml": {28, 1}, "Plain Text": {0, 1}, "JavaScript": {24, 1}}}, // Directory
{"../tests/data/nonexistent.txt", map[string]languageDetails{}}, // Non-existent file
{"../tests/data/unsupported.xyz", map[string]languageDetails{}}, // Unsupported file extension

}

for _, tt := range tests {
Expand Down Expand Up @@ -82,23 +84,24 @@ func TestCountLinesOfFile(t *testing.T) {
}

func TestGenerateTable(t *testing.T) {
llc := map[string]int{
"Go": 100,
"Python": 200,
"Java": 150,
llc := map[string]languageDetails{
"Go": {100, 1},
"Python": {200, 1},
"Java": {150, 1},
}

expectedColumns := []table.Column{
{Title: "Language", Width: 16},
{Title: "Lines of Code", Width: 16},
{Title: "Lines", Width: 16},
{Title: "Files", Width: 10},
}

expectedRows := []table.Row{
{"Python", "200"},
{"Java", "150"},
{"Go", "100"},
{"", ""},
{"Total", "450"},
{"Python", "200", "1"},
{"Java", "150", "1"},
{"Go", "100", "1"},
{"", "", ""},
{"Total", "450", "3"},
}

expectedTable := table.New(
Expand Down
2 changes: 1 addition & 1 deletion src/terminal/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ var baseStyle = lipgloss.NewStyle().
BorderForeground(lipgloss.Color("240"))

func (m Model) View() string {
out := m.ExecutionTime.View()
out := "Elapsed: " + m.ExecutionTime.View()

if !m.IsRunning {
out += "\n" + baseStyle.Render(m.Table.View())
Expand Down
1 change: 1 addition & 0 deletions tests/data/unsupported.xyz
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Unsupported file extension: .xyz

0 comments on commit 204d2c8

Please sign in to comment.