Skip to content

Instantly share code, notes, and snippets.

@lainq
Last active November 28, 2021 16:26
Show Gist options
  • Save lainq/a621acecb174eee7372c89231ee1fbc1 to your computer and use it in GitHub Desktop.
Save lainq/a621acecb174eee7372c89231ee1fbc1 to your computer and use it in GitHub Desktop.
Count the lines and files in ur directory
package main
import (
"fmt"
gitignore "github.com/sabhiram/go-gitignore"
"io/ioutil"
"os"
"path"
"strings"
)
// Create an error message
func CreateErrorMessage(message string, exit bool) {
fmt.Printf("[ERROR]: %s\n", message)
if exit {
os.Exit(1)
}
}
// Checks if the path is a directory
func IsDirectory(directory string) bool {
data, err := os.Stat(directory)
if err != nil {
return false
}
return data.IsDir()
}
func GetLanguageData(files []string) (map[string]int, map[string]int) {
var _lines map[string]int = map[string]int{}
var _files map[string]int = map[string]int{}
for _, filename := range files {
// Get the extension of the file
slices := strings.Split(path.Base(string(filename)), ".")
extension := slices[len(slices)-1]
content, err := ioutil.ReadFile(filename)
if err != nil {
CreateErrorMessage(err.Error(), false)
continue
}
_lines[extension] += len(strings.Split(string(content), "\n"))
_files[extension] += 1
}
return _files, _lines
}
func GetTotalCount(element map[string]int) int {
total := 0
for _, count := range element {
total += count
}
return total
}
func GenerateOutput(files map[string]int, lines map[string]int) {
fmt.Printf("%s [%d]\n", "Files", GetTotalCount(files))
for extension, count := range files {
fmt.Printf("%s: %d \n", extension, count)
}
fmt.Println("-----")
fmt.Printf("%s [%d]\n", "Lines", GetTotalCount(lines))
for extension, count := range lines {
fmt.Printf("%s: %d \n", extension, count)
}
}
// Walk through a directory
func Walk(directory string, ignore *gitignore.GitIgnore) []string {
if !IsDirectory(directory) {
// If the file isn't a directory, exit out of the program
CreateErrorMessage(fmt.Sprintf("%s is not a directory", directory), true)
}
var files []string = []string{}
content, err := ioutil.ReadDir(directory)
if err != nil {
CreateErrorMessage(fmt.Sprintf("Failed to read %s", directory), false)
} else {
for _, filename := range content {
_path := path.Join(directory, filename.Name())
// If the file pattern is in .gitignore
// ignore the file and skip to the next one
if ignore.MatchesPath(path.Base(_path)) {
continue
}
if IsDirectory(_path) {
for _, file := range Walk(_path, ignore) {
files = append(files, file)
}
} else {
files = append(files, _path)
}
}
}
return files
}
func main() {
var directory string
if len(os.Args) > 1 {
directory = os.Args[1]
} else {
_directory, err := os.Getwd()
directory = _directory
if err != nil {
fmt.Printf("Usage: pg <directory>")
os.Exit(1)
}
}
ignore, _err := gitignore.CompileIgnoreFile(path.Join(directory, ".gitignore"))
if _err != nil {
CreateErrorMessage(_err.Error(), false)
}
files := Walk(directory, ignore)
GenerateOutput(GetLanguageData(files))
}
@lainq
Copy link
Author

lainq commented Nov 28, 2021

Pg stands for polyglot

Building

mkdir pg
wget https://gist.githubusercontent.com/pranavbaburaj/a621acecb174eee7372c89231ee1fbc1/raw/d8a06acd69d7c6bd201f2d42a26dc44646e7b64a/pg.go
go mod init pg
go get github.com/sabhiram/go-gitignore

go build pg.go

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment