github.com/nemith/go-gitlog@v0.0.2-0.20180205151741-6c79beb2287b/parser.go (about)

     1  package gitlog
     2  
     3  import (
     4  	"errors"
     5  	"regexp"
     6  	"strconv"
     7  	"strings"
     8  	"time"
     9  )
    10  
    11  type parser struct{}
    12  
    13  func (p *parser) parse(str *string) ([]*Commit, error) {
    14  	lines := strings.Split(*str, separator)
    15  	if len(lines) < 1 {
    16  		return nil, errors.New("wip")
    17  	}
    18  
    19  	lines = lines[1:]
    20  	commits := make([]*Commit, len(lines))
    21  
    22  	for i, line := range lines {
    23  		commits[i] = p.parseCommit(&line)
    24  	}
    25  
    26  	return commits, nil
    27  }
    28  
    29  func (p *parser) parseCommit(str *string) *Commit {
    30  	segments := strings.Split(*str, delimiter)
    31  	commit := &Commit{}
    32  
    33  	for _, segment := range segments {
    34  		endFieldType := strings.Index(segment, ":")
    35  		fieldType := segment[0:endFieldType]
    36  		content := segment[endFieldType+1:]
    37  
    38  		switch fieldType {
    39  		case hashField:
    40  			commit.Hash = p.parseHash(&content)
    41  		case treeField:
    42  			commit.Tree = p.parseTree(&content)
    43  		case authorField:
    44  			commit.Author = p.parseAuthor(&content)
    45  		case committerField:
    46  			commit.Committer = p.parseCommitter(&content)
    47  		case tagField:
    48  			commit.Tag = p.parseTag(&content)
    49  		case subjectField:
    50  			commit.Subject = p.parseSubject(&content)
    51  		case bodyField:
    52  			commit.Body = p.parseBody(&content)
    53  		}
    54  	}
    55  
    56  	commit.Tag.Date = commit.Author.Date
    57  
    58  	return commit
    59  }
    60  
    61  func (p *parser) parseHash(str *string) *Hash {
    62  	parts := strings.Split(*str, " ")
    63  	return &Hash{
    64  		Long:  parts[0],
    65  		Short: parts[1],
    66  	}
    67  }
    68  
    69  func (p *parser) parseTree(str *string) *Tree {
    70  	hash := p.parseHash(str)
    71  
    72  	return &Tree{
    73  		hash.Long,
    74  		hash.Short,
    75  	}
    76  }
    77  
    78  func (p *parser) parseAuthor(str *string) *Author {
    79  	s := *str
    80  
    81  	beginEmail := strings.Index(s, "<")
    82  	endEmail := strings.Index(s, ">")
    83  
    84  	beginDate := strings.LastIndex(s, "[")
    85  	endDate := strings.LastIndex(s, "]")
    86  
    87  	name := s[:beginEmail]
    88  	email := s[beginEmail+1 : endEmail]
    89  	timestamp, _ := strconv.Atoi(s[beginDate+1 : endDate])
    90  
    91  	return &Author{
    92  		name,
    93  		email,
    94  		time.Unix(int64(timestamp), 0),
    95  	}
    96  }
    97  
    98  func (p *parser) parseCommitter(str *string) *Committer {
    99  	author := p.parseAuthor(str)
   100  
   101  	return &Committer{
   102  		author.Name,
   103  		author.Email,
   104  		author.Date,
   105  	}
   106  }
   107  
   108  var tagRegex = regexp.MustCompile("tag:\\s([\\w\\.\\-_/]+)")
   109  
   110  func (p *parser) parseTag(str *string) *Tag {
   111  	res := tagRegex.FindAllStringSubmatch(*str, -1)
   112  	tag := &Tag{
   113  		Name: "",
   114  	}
   115  
   116  	if len(res) > 0 {
   117  		tag.Name = res[0][1]
   118  	}
   119  
   120  	return tag
   121  }
   122  
   123  func (*parser) convNewline(str *string) string {
   124  	nl := "\n"
   125  
   126  	return strings.NewReplacer(
   127  		"\r\n", nl,
   128  		"\r", nl,
   129  		"\n", nl,
   130  	).Replace(*str)
   131  }
   132  
   133  func (p *parser) parseSubject(str *string) string {
   134  	return strings.TrimSpace(p.convNewline(str))
   135  }
   136  
   137  func (p *parser) parseBody(str *string) string {
   138  	s := p.convNewline(str)
   139  	s = strings.TrimSpace(s)
   140  	s = strings.Trim(s, "\"")
   141  	s = strings.TrimSpace(s)
   142  	s = strings.Trim(s, "\"")
   143  	s = strings.TrimSpace(s)
   144  	return s
   145  }