refactor: refactor whole project to based on cobra commands

This commit is contained in:
Theis
2024-10-08 20:00:43 +02:00
parent ded0dc8779
commit 0e57a48f61
11 changed files with 649 additions and 153 deletions
@@ -0,0 +1,44 @@
package utils
import (
"fmt"
"os"
)
// Author file utils is a package that contains functions that are used to read
// check, and potentially write to the author file. The author file is a file
// that contains the names and emails of the users that are allowed to commit
// An example of the author file can be found in the examples folder of the repo
func Find_authorfile() string {
if os.Getenv("author_file") == "" {
authors, err := os.UserConfigDir()
if err != nil {
fmt.Println("Error getting user config directory")
os.Exit(2)
}
return (authors + "/cocommit/authors")
} else {
return os.Getenv("author_file")
}
}
func CheckAuthorFile() string {
authorfile := Find_authorfile()
if _, err := os.Stat(authorfile); os.IsNotExist(err) {
println("Author file not found at: ", authorfile)
println("Would you like to create one? (y/n)")
var response string
_, err := fmt.Scanln(&response)
if err != nil {
println("Error reading response")
}
if response == "y" {
//TODO: Tui response to create author file
//createAuthorFile(authorfile)
} else {
os.Exit(1)
}
}
// This string output is mostly for convenience can mostly be ignored
return authorfile
}
+110
View File
@@ -0,0 +1,110 @@
package utils
import (
"fmt"
"os/exec"
"regexp"
"slices"
"strings"
)
// This util file is used to create a commit message using a string builder
// string builder for the commit message
var sb strings.Builder
// list of excluded authors based on the author file
var excludeMode = []string{}
// Regex pattern used to create temp users to add to the commit message
var reg, _ = regexp.Compile("([^:]+):([^:]+)")
func Commit(message string, authors []string) string {
// write the commit message to the string builder
sb.WriteString(message + "\n")
fst := authors[0]
if fst == "all" || fst == "All" {
add_x_users(excludeMode)
goto skip_loop
} else if Groups[fst] != nil {
excludeMode = group_selection(Groups[fst], excludeMode)
add_x_users(excludeMode)
goto skip_loop
}
// Loop that adds users
for _, committer := range authors {
if _, ok := Users[committer]; ok {
sb_author(committer)
} else if match := reg.MatchString(committer); match {
str := strings.Split(committer, ":")
sb.WriteString("\nCo-authored-by: ")
sb.WriteString(str[0])
sb.WriteString(" <")
sb.WriteString(str[1])
sb.WriteRune('>')
} else if committer[0] == '^' { // Negations
excludeMode = append(excludeMode, Users[committer[1:]].Username)
} else {
println(committer, " was unknown. User either not defined or name typed wrong")
}
}
if len(excludeMode) > 0 {
add_x_users(excludeMode)
}
// Skip label for edge cases at top of function
skip_loop:
return sb.String()
}
func GitWrapper(commit string) {
// commit shell command
cmd := exec.Command("git", "commit", "-m", commit)
// https://stackoverflow.com/questions/18159704/how-to-debug-exit-status-1-error-when-running-exec-command-in-golang
cmd_output, err := cmd.CombinedOutput()
if err != nil {
println(fmt.Sprint(err) + " : " + string(cmd_output))
} else {
println(string(cmd_output))
}
}
// helper function to add an author to the commit message
func sb_author(committer string) {
sb.WriteString("\nCo-authored-by: ")
sb.WriteString(Users[committer].Username)
sb.WriteString(" <")
sb.WriteString(Users[committer].Email)
sb.WriteRune('>')
}
// helper function to add x amount of users to the commit message
func add_x_users(excludeMode []string) {
if len(DefExclude) > 0 {
excludeMode = append(excludeMode, DefExclude...)
}
for key, user := range Users {
if !slices.Contains(excludeMode, user.Username) {
sb_author(key)
excludeMode = append(excludeMode, user.Username)
}
}
}
// helper function to select a group of users to exclude in the commit message
func group_selection(group []User, excludeMode []string) []string {
for _, user := range Users {
if !(slices.Contains(group, user)) {
excludeMode = append(excludeMode, user.Username)
}
}
return excludeMode
}
+69
View File
@@ -0,0 +1,69 @@
package utils
import (
"bufio"
"os"
"strings"
)
// This util file is used to handle users and their information
type User struct {
Username string
Email string
Names string
}
var Users = map[string]User{}
var DefExclude = []string{}
var Groups = map[string][]User{}
func Define_users(author_file string) {
file, err := os.Open(author_file)
if err != nil {
print("File not found")
os.Exit(2)
}
defer file.Close()
scanner := bufio.NewScanner(file)
// eat a single input
scanner.Scan()
// reads the input of authors file and formats accordingly
for scanner.Scan() {
input_str := scanner.Text()
group_info := []string{}
if strings.Contains(input_str, ";;") {
input := strings.Split(input_str, ";;")
input_str = input[0]
group_info = append(group_info, strings.Split(input[1], "|")...)
}
info := strings.Split(input_str, "|")
usr := User{Username: info[2], Email: info[3], Names: info[0] + "/" + info[1]}
Users[info[0]] = usr
Users[info[1]] = usr
// Adds users with the ex tag to the defExclude list
if len(info) == 5 {
if info[4] == "ex" {
DefExclude = append(DefExclude, info[2])
}
} else if len(group_info) > 0 {
// Group assignment
for _, group := range group_info {
if Groups[group] == nil {
Groups[group] = []User{usr}
} else {
//TODO: Try and find a cleaner way of doing this
usr_lst := Groups[group]
usr_lst = append(usr_lst, usr)
Groups[group] = usr_lst
}
}
}
}
if err := scanner.Err(); err != nil {
os.Exit(2)
}
}