Skip to content

Commit d313a4e

Browse files
committed
Add some more comments
1 parent 7138650 commit d313a4e

File tree

5 files changed

+79
-16
lines changed

5 files changed

+79
-16
lines changed

integrations/notification_helper_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2019 The Gitea Authors. All rights reserved.
1+
// Copyright 2020 The Gitea Authors. All rights reserved.
22
// Use of this source code is governed by a MIT-style
33
// license that can be found in the LICENSE file.
44

modules/notification/base/main.go

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2019 The Gitea Authors. All rights reserved.
1+
// Copyright 2020 The Gitea Authors. All rights reserved.
22
// Use of this source code is governed by a MIT-style
33
// license that can be found in the LICENSE file.
44

@@ -19,64 +19,114 @@ import (
1919
"time"
2020
)
2121

22+
// funcDef are a semi-generic function definitions
2223
type funcDef struct {
2324
Name string
2425
Args []funcDefArg
2526
}
2627

28+
// funcDefArg describe an argument to a function
2729
type funcDefArg struct {
2830
Name string
2931
Type string
3032
}
3133

34+
// main will generate two files that implement the Notifier interface
35+
// defined in notifier.go
36+
//
37+
// * the NullNotifier which is a basic Notifier that does nothing
38+
// when each of its methods is called
39+
//
40+
// * the QueueNotifier which is a notifier that sends its commands down
41+
// a queue.
42+
//
43+
// The main benefit of this generation is that we never need to keep these
44+
// up to date again. Add a new function to Notifier and the NullNotifier and
45+
// the NotifierQueue will gain these functions automatically.
46+
//
47+
// There are two caveat:
48+
// * All notifier functions must not return anything.
49+
// * If you add a new import you will need to add it to the templates below
3250
func main() {
51+
52+
// OK build the AST from the notifier.go file
3353
fset := token.NewFileSet() // positions are relative to fset
3454
f, err := parser.ParseFile(fset, "notifier.go", nil, 0)
3555
if err != nil {
3656
panic(err)
3757
}
58+
59+
// func will collect all the function definitions from the Notifier interface
3860
funcs := make([]funcDef, 0)
39-
//currentFunc := funcDef{}
61+
4062
ast.Inspect(f, func(n ast.Node) bool {
4163
spec, ok := n.(*ast.TypeSpec)
42-
if !ok || spec.Name.Name != "Notifier" {
43-
return true
64+
if !ok || spec.Name.Name != "Notifier" { // We only care about the Notifier interface declaration
65+
return true // If we are not a type decl or aren't looking at the Notifier decl keep looking
4466
}
67+
68+
// We're at: `type Notifier ...` so now we need check that it's an interface
4569
child, ok := spec.Type.(*ast.InterfaceType)
4670
if !ok {
47-
return false
71+
return false // There's no point looking in non interface types.
4872
}
73+
74+
// OK we're in the declaration of the Notifier, e.g.
75+
// type Notifier interface { ... }
76+
77+
// Let's look at each Method in turn, but first we redefine
78+
// funcs now we know how big it's supposed to be
4979
funcs = make([]funcDef, len(child.Methods.List))
5080
for i, method := range child.Methods.List {
51-
methodFuncDef := method.Type.(*ast.FuncType)
81+
// example: NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits)
82+
83+
// method here is looking at the NotifyPushCommits...
84+
85+
// We know that interfaces have FuncType for the method
86+
methodFuncDef := method.Type.(*ast.FuncType) // eg. (...)
87+
88+
// Extract the function definition from the method
5289
def := funcDef{}
53-
def.Name = method.Names[0].Name
90+
def.Name = method.Names[0].Name // methods only have one name in interfaces <- NotifyPushCommits
91+
92+
// Now construct the args
5493
def.Args = make([]funcDefArg, 0, len(methodFuncDef.Params.List))
5594
for j, param := range methodFuncDef.Params.List {
95+
96+
// interfaces don't have to name their arguments e.g. NotifyNewIssue(*models.Issue)
97+
// but we need a name to make a function call
5698
defaultName := fmt.Sprintf("unknown%d", j)
99+
100+
// Now get the type - here we will just use what is used in source file. (See caveat 2.)
57101
sb := strings.Builder{}
58102
format.Node(&sb, fset, param.Type)
59103

104+
// If our parameter is unnamed
60105
if len(param.Names) == 0 {
61106
def.Args = append(def.Args, funcDefArg{
62107
Name: defaultName,
63108
Type: sb.String(),
64109
})
65110
} else {
111+
// Now in the example NotifyPushCommits we see that refname, oldCommitID etc don't have type following them
112+
// The AST creates these as a single param with mulitple names
113+
// Therefore iterate through the param.Names
66114
for _, ident := range param.Names {
67-
def.Args = append(def.Args, funcDefArg{
68-
Name: ident.Name,
69-
Type: sb.String(),
70-
})
115+
def.Args = append(def.Args, funcDefArg{
116+
Name: ident.Name,
117+
Type: sb.String(),
118+
})
119+
}
71120
}
72-
}
73121
}
74122
funcs[i] = def
75123
}
76124

77-
return true
125+
// We're done so stop walking
126+
return false
78127
})
79128

129+
// First lets create the NullNotifier
80130
buf := bytes.Buffer{}
81131
nullTemplate.Execute(&buf, struct {
82132
Timestamp time.Time
@@ -96,6 +146,7 @@ func main() {
96146
panic(err)
97147
}
98148

149+
// Then create the NotifierQueue
99150
buf = bytes.Buffer{}
100151
queueTemplate.Execute(&buf, struct {
101152
Timestamp time.Time
@@ -132,22 +183,25 @@ import (
132183
"code.gitea.io/gitea/modules/queue"
133184
)
134185
135-
// FunctionCall represents is function call with json.Marshaled arguments
186+
// FunctionCall represents a function call with json.Marshaled arguments
136187
type FunctionCall struct {
137188
Name string
138189
Args [][]byte
139190
}
140191
192+
// QueueNotifier is a notifier queue
141193
type QueueNotifier struct {
142194
name string
143195
notifiers []Notifier
144196
internal queue.Queue
145197
}
146198
199+
// Ensure that QueueNotifier fulfils the Notifier interface
147200
var (
148201
_ Notifier = &QueueNotifier{}
149202
)
150203
204+
// NewQueueNotifier creates a notifier that queues notifications and on dequeueing sends them to the provided notifiers
151205
func NewQueueNotifier(name string, notifiers []Notifier) Notifier {
152206
q := &QueueNotifier{
153207
name: name,
@@ -157,6 +211,7 @@ func NewQueueNotifier(name string, notifiers []Notifier) Notifier {
157211
return q
158212
}
159213
214+
// NewQueueNotifierWithHandle creates a notifier queue with a specific handler function
160215
func NewQueueNotifierWithHandle(name string, handle queue.HandlerFunc) Notifier {
161216
q := &QueueNotifier{
162217
name: name,
@@ -235,6 +290,7 @@ import (
235290
type NullNotifier struct {
236291
}
237292
293+
// Ensure that NullNotifier fulfils the Notifier interface
238294
var (
239295
_ Notifier = &NullNotifier{}
240296
)

modules/notification/base/notifier.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111

1212
//go:generate go run -mod=vendor main.go
1313

14+
// If you change the below definition you must run go generate - see main.go
15+
1416
// Notifier defines an interface to notify receiver
1517
type Notifier interface {
1618
Run()

modules/notification/base/null.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

modules/notification/base/queue.go

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)