/* Copyright © 2022 Sameer Rahmani 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 . */ 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[A-Z]+):`) state.EndBlockTypePattern = regexp.MustCompile(`/(?P[A-Z]+)$`) state.TagPattern = regexp.MustCompile(`\[([^]]+)\]`) state.FirstLineContent = regexp.MustCompile(`[A-Z]+:\s+(?:\[[^]]+\])*\s?(?P.*)`) 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 }