Leavitt/pkg/core/state.go

133 lines
3.1 KiB
Go

/*
Copyright © 2022 Sameer Rahmani <lxsameer@gnu.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package core
import (
"regexp"
"strings"
git "github.com/go-git/go-git/v5"
)
type State struct {
ProjectRoot string
Repo *git.Repository
// A mapping of file extensions to the language
// e.g '.h' -> 'C/C++'
EnabledLangs map[string]*Lang
BlockTypePattern *regexp.Regexp
EndBlockTypePattern *regexp.Regexp
TagPattern *regexp.Regexp
FirstLineContent *regexp.Regexp
}
func CreateState(projectRoot string) (*State, error) {
state := State{}
var err error
state.ProjectRoot = strings.TrimSpace(projectRoot)
state.Repo, err = git.PlainOpen(state.ProjectRoot)
if err != nil {
return nil, err
}
// Read the pattern from the global or project wide config file
// using viper
state.BlockTypePattern = regexp.MustCompile(`^(?P<type>[A-Z]+):`)
state.EndBlockTypePattern = regexp.MustCompile(`/(?P<end>[A-Z]+)$`)
state.TagPattern = regexp.MustCompile(`\[([^]]+)\]`)
state.FirstLineContent = regexp.MustCompile(`[A-Z]+:\s+(?:\[[^]]+\])*\s?(?P<text>.*)`)
state.EnabledLangs = ExtsToLang
return &state, nil
}
func (s *State) GetLangForExt(ext string) *Lang {
// If the extension is the filename itself.
// like: LICENSE
key := ext
if strings.Contains(key, ".") {
// dotless extension
key = ext[1:]
}
lang, exists := s.EnabledLangs[key]
if exists {
return lang
}
return nil
}
func (s *State) getCommentType(comment string) *string {
match := s.BlockTypePattern.FindAllStringSubmatch(comment, -1)
if len(match) > 0 {
if len(match[0]) == 2 {
// Return the group of regex which is the tag group
return &match[0][1]
} else {
panic("bad regex")
}
}
return nil
}
func (s *State) getTags(comment string) []string {
match := s.TagPattern.FindAllStringSubmatch(comment, -1)
var tags []string
if len(match) > 0 {
for _, tag := range match {
tags = append(tags, tag[1])
}
return tags
}
return nil
}
func (s *State) detectClosingBlock(comment *string) (*string, bool) {
match := s.EndBlockTypePattern.FindAllStringSubmatch(*comment, -1)
if len(match) > 0 {
if len(match[0]) == 2 {
// Return the group of regex which is the type group
return &match[0][1], true
}
}
return nil, false
}
func (s *State) TrimTypeAndTags(comment *string) *string {
match := s.FirstLineContent.FindAllStringSubmatch(*comment, -1)
if len(match) > 0 {
if len(match[0]) == 2 {
// Return the group of regex which is the text group
return &match[0][1]
} else {
panic("bad regex")
}
}
return nil
}