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 }