@@ -16,8 +16,14 @@ import (
1616var DefaultRules = []ValidateRule {
1717 func (c CommitEntry ) (vr ValidateResult ) {
1818 vr .CommitEntry = c
19+ if len (strings .Split (c ["parent" ], " " )) > 1 {
20+ vr .Pass = true
21+ vr .Msg = "merge commits do not require DCO"
22+ return vr
23+ }
24+
1925 hasValid := false
20- for _ , line := range strings .Split (c . Body , "\n " ) {
26+ for _ , line := range strings .Split (c [ "body" ] , "\n " ) {
2127 if validDCO .MatchString (line ) {
2228 hasValid = true
2329 }
@@ -63,14 +69,14 @@ func main() {
6369
6470 results := ValidateResults {}
6571 for _ , commit := range c {
66- fmt .Printf (" * %s %s ... " , commit . AbbreviatedCommit , commit . Subject )
72+ fmt .Printf (" * %s %s ... " , commit [ "abbreviated_commit" ] , commit [ "subject" ] )
6773 vr := ValidateCommit (commit , DefaultRules )
6874 results = append (results , vr ... )
6975 if _ , fail := vr .PassFail (); fail == 0 {
7076 fmt .Println ("PASS" )
7177 if * flVerbose {
7278 for _ , r := range vr {
73- if ! r .Pass {
79+ if r .Pass {
7480 fmt .Printf (" - %s\n " , r .Msg )
7581 }
7682 }
@@ -127,51 +133,26 @@ func (vr ValidateResults) PassFail() (pass int, fail int) {
127133}
128134
129135// CommitEntry represents a single commit's information from `git`
130- type CommitEntry struct {
131- Commit string
132- AbbreviatedCommit string `json:"abbreviated_commit"`
133- Tree string
134- AbbreviatedTree string `json:"abbreviated_tree"`
135- Parent string
136- AbbreviatedParent string `json:"abbreviated_parent"`
137- Refs string
138- Encoding string
139- Subject string
140- SanitizedSubjectLine string `json:"sanitized_subject_line"`
141- Body string
142- CommitNotes string `json:"commit_notes"`
143- VerificationFlag string `json:"verification_flag"`
144- ShortMsg string
145- Signer string
146- SignerKey string `json:"signer_key"`
147- Author PersonAction `json:"author,omitempty"`
148- Committer PersonAction `json:"committer,omitempty"`
149- }
150-
151- // PersonAction is a time and identity of an action on a git commit
152- type PersonAction struct {
153- Name string `json:"name"`
154- Email string `json:"email"`
155- Date string `json:"date"` // this could maybe be an actual time.Time
156- }
136+ type CommitEntry map [string ]string
157137
158138var (
159- prettyLogSubject = `--pretty=format:%s`
160- prettyLogBody = `--pretty=format:%b`
161- prettyLogCommit = `--pretty=format:%H`
162- prettyLogAuthorName = `--pretty=format:%aN`
163- prettyLogAuthorEmail = `--pretty=format:%aE`
164- prettyLogCommitterName = `--pretty=format:%cN`
165- prettyLogCommitterEmail = `--pretty=format:%cE`
166- prettyLogSigner = `--pretty=format:%GS`
167- prettyLogCommitNotes = `--pretty=format:%N`
168- prettyLogFormat = `--pretty=format:{"commit": "%H", "abbreviated_commit": "%h", "tree": "%T", "abbreviated_tree": "%t", "parent": "%P", "abbreviated_parent": "%p", "refs": "%D", "encoding": "%e", "sanitized_subject_line": "%f", "verification_flag": "%G?", "signer_key": "%GK", "author": { "date": "%aD" }, "committer": { "date": "%cD" }}`
139+ prettyFormat = `--pretty=format:`
140+ formatSubject = `%s`
141+ formatBody = `%b`
142+ formatCommit = `%H`
143+ formatAuthorName = `%aN`
144+ formatAuthorEmail = `%aE`
145+ formatCommitterName = `%cN`
146+ formatCommitterEmail = `%cE`
147+ formatSigner = `%GS`
148+ formatCommitNotes = `%N`
149+ formatMap = `{"commit": "%H", "abbreviated_commit": "%h", "tree": "%T", "abbreviated_tree": "%t", "parent": "%P", "abbreviated_parent": "%p", "refs": "%D", "encoding": "%e", "sanitized_subject_line": "%f", "verification_flag": "%G?", "signer_key": "%GK", "author_date": "%aD" , "committer_date": "%cD" }`
169150)
170151
171152// GitLogCommit assembles the full information on a commit from its commit hash
172153func GitLogCommit (commit string ) (* CommitEntry , error ) {
173154 buf := bytes .NewBuffer ([]byte {})
174- cmd := exec .Command ("git" , "log" , "-1" , prettyLogFormat , commit )
155+ cmd := exec .Command ("git" , "log" , "-1" , prettyFormat + formatMap , commit )
175156 cmd .Stdout = buf
176157 cmd .Stderr = os .Stderr
177158
@@ -186,53 +167,23 @@ func GitLogCommit(commit string) (*CommitEntry, error) {
186167 return nil , err
187168 }
188169
189- output , err := exec .Command ("git" , "log" , "-1" , prettyLogSubject , commit ).Output ()
190- if err != nil {
191- return nil , err
192- }
193- c .Subject = strings .TrimSpace (string (output ))
194-
195- output , err = exec .Command ("git" , "log" , "-1" , prettyLogBody , commit ).Output ()
196- if err != nil {
197- return nil , err
198- }
199- c .Body = strings .TrimSpace (string (output ))
200-
201- output , err = exec .Command ("git" , "log" , "-1" , prettyLogAuthorName , commit ).Output ()
202- if err != nil {
203- return nil , err
204- }
205- c .Author .Name = strings .TrimSpace (string (output ))
206-
207- output , err = exec .Command ("git" , "log" , "-1" , prettyLogAuthorEmail , commit ).Output ()
208- if err != nil {
209- return nil , err
210- }
211- c .Author .Email = strings .TrimSpace (string (output ))
212-
213- output , err = exec .Command ("git" , "log" , "-1" , prettyLogCommitterName , commit ).Output ()
214- if err != nil {
215- return nil , err
216- }
217- c .Committer .Name = strings .TrimSpace (string (output ))
218-
219- output , err = exec .Command ("git" , "log" , "-1" , prettyLogCommitterEmail , commit ).Output ()
220- if err != nil {
221- return nil , err
222- }
223- c .Committer .Email = strings .TrimSpace (string (output ))
224-
225- output , err = exec .Command ("git" , "log" , "-1" , prettyLogCommitNotes , commit ).Output ()
226- if err != nil {
227- return nil , err
228- }
229- c .CommitNotes = strings .TrimSpace (string (output ))
230-
231- output , err = exec .Command ("git" , "log" , "-1" , prettyLogSigner , commit ).Output ()
232- if err != nil {
233- return nil , err
170+ // any user provided fields can't be sanitized for the mock-json marshal above
171+ for k , v := range map [string ]string {
172+ "subject" : formatSubject ,
173+ "body" : formatBody ,
174+ "author_name" : formatAuthorName ,
175+ "author_email" : formatAuthorEmail ,
176+ "committer_name" : formatCommitterName ,
177+ "committer_email" : formatCommitterEmail ,
178+ "commit_notes" : formatCommitNotes ,
179+ "signer" : formatSigner ,
180+ } {
181+ output , err := exec .Command ("git" , "log" , "-1" , prettyFormat + v , commit ).Output ()
182+ if err != nil {
183+ return nil , err
184+ }
185+ c [k ] = strings .TrimSpace (string (output ))
234186 }
235- c .Signer = strings .TrimSpace (string (output ))
236187
237188 return & c , nil
238189}
@@ -241,7 +192,7 @@ func GitLogCommit(commit string) (*CommitEntry, error) {
241192// If commitrange is a git still range 12345...54321, then it will be isolated set of commits.
242193// If commitrange is a single commit, all ancestor commits up through the hash provided.
243194func GitCommits (commitrange string ) ([]CommitEntry , error ) {
244- output , err := exec .Command ("git" , "log" , prettyLogCommit , commitrange ).Output ()
195+ output , err := exec .Command ("git" , "log" , prettyFormat + formatCommit , commitrange ).Output ()
245196 if err != nil {
246197 return nil , err
247198 }
0 commit comments