Skip to content

Commit e8713a4

Browse files
committed
git-bundle-server: propagate 'context.Context' through call stack
The 'context.Context' structure is used, among other things, to hold request, command, function, etc. scoped information for throughout the call stack. In particular, this information scoping will be useful for logging (e.g., holding a session ID or a region nesting level) added in future patches. Following Go convention [1], pass the 'ctx' from the 'main()' function of the 'git-bundle-server' into child structures that will implement the initial round of logging in the application (i.e., the arg parser, 'git-bundle-server' commands, and daemon providers). [1] https://pkg.go.dev/context Signed-off-by: Victoria Dye <[email protected]>
1 parent c22c05e commit e8713a4

File tree

17 files changed

+120
-82
lines changed

17 files changed

+120
-82
lines changed

cmd/git-bundle-server/delete.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"context"
45
"os"
56

67
"github.com/github/git-bundle-server/internal/argparse"
@@ -19,10 +20,10 @@ Remove the configuration for the given '<route>' and delete its repository
1920
data.`
2021
}
2122

22-
func (Delete) Run(args []string) error {
23+
func (Delete) Run(ctx context.Context, args []string) error {
2324
parser := argparse.NewArgParser("git-bundle-server delete <route>")
2425
route := parser.PositionalString("route", "the route to delete")
25-
parser.Parse(args)
26+
parser.Parse(ctx, args)
2627

2728
repo, err := core.CreateRepository(*route)
2829
if err != nil {

cmd/git-bundle-server/init.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"context"
45
"fmt"
56

67
"github.com/github/git-bundle-server/internal/argparse"
@@ -21,12 +22,12 @@ Initialize a repository by cloning a bare repo from '<url>', whose bundles
2122
should be hosted at '<route>'.`
2223
}
2324

24-
func (Init) Run(args []string) error {
25+
func (Init) Run(ctx context.Context, args []string) error {
2526
parser := argparse.NewArgParser("git-bundle-server init <url> <route>")
2627
url := parser.PositionalString("url", "the URL of a repository to clone")
2728
// TODO: allow parsing <route> out of <url>
2829
route := parser.PositionalString("route", "the route to host the specified repo")
29-
parser.Parse(args)
30+
parser.Parse(ctx, args)
3031

3132
repo, err := core.CreateRepository(*route)
3233
if err != nil {

cmd/git-bundle-server/main.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"context"
45
"log"
56
"os"
67

@@ -20,16 +21,18 @@ func all() []argparse.Subcommand {
2021
}
2122

2223
func main() {
24+
ctx := context.Background()
25+
2326
cmds := all()
2427

2528
parser := argparse.NewArgParser("git-bundle-server <command> [<options>]")
2629
parser.SetIsTopLevel(true)
2730
for _, cmd := range cmds {
2831
parser.Subcommand(cmd)
2932
}
30-
parser.Parse(os.Args[1:])
33+
parser.Parse(ctx, os.Args[1:])
3134

32-
err := parser.InvokeSubcommand()
35+
err := parser.InvokeSubcommand(ctx)
3336
if err != nil {
3437
log.Fatal("Failed with error: ", err)
3538
}

cmd/git-bundle-server/start.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"context"
45
"fmt"
56
"os"
67

@@ -20,10 +21,10 @@ Start computing bundles and serving content for the repository at the
2021
specified '<route>'.`
2122
}
2223

23-
func (Start) Run(args []string) error {
24+
func (Start) Run(ctx context.Context, args []string) error {
2425
parser := argparse.NewArgParser("git-bundle-server start <route>")
2526
route := parser.PositionalString("route", "the route for which bundles should be generated")
26-
parser.Parse(args)
27+
parser.Parse(ctx, args)
2728

2829
// CreateRepository registers the route.
2930
repo, err := core.CreateRepository(*route)

cmd/git-bundle-server/stop.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package main
22

33
import (
4+
"context"
5+
46
"github.com/github/git-bundle-server/internal/argparse"
57
"github.com/github/git-bundle-server/internal/core"
68
)
@@ -17,10 +19,10 @@ Stop computing bundles or serving content for the repository at the
1719
specified '<route>'.`
1820
}
1921

20-
func (Stop) Run(args []string) error {
22+
func (Stop) Run(ctx context.Context, args []string) error {
2123
parser := argparse.NewArgParser("git-bundle-server stop <route>")
2224
route := parser.PositionalString("route", "the route for which bundles should stop being generated")
23-
parser.Parse(args)
25+
parser.Parse(ctx, args)
2426

2527
return core.RemoveRoute(*route)
2628
}

cmd/git-bundle-server/update-all.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"context"
45
"fmt"
56
"os"
67
"os/exec"
@@ -21,15 +22,15 @@ func (UpdateAll) Description() string {
2122
For every configured route, run 'git-bundle-server update <options> <route>'.`
2223
}
2324

24-
func (UpdateAll) Run(args []string) error {
25+
func (UpdateAll) Run(ctx context.Context, args []string) error {
2526
user, err := common.NewUserProvider().CurrentUser()
2627
if err != nil {
2728
return err
2829
}
2930
fs := common.NewFileSystem()
3031

3132
parser := argparse.NewArgParser("git-bundle-server update-all")
32-
parser.Parse(args)
33+
parser.Parse(ctx, args)
3334

3435
exe, err := os.Executable()
3536
if err != nil {

cmd/git-bundle-server/update.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"context"
45
"fmt"
56

67
"github.com/github/git-bundle-server/internal/argparse"
@@ -21,10 +22,10 @@ For the repository in the current directory (or the one specified by
2122
bundles, and update the bundle list.`
2223
}
2324

24-
func (Update) Run(args []string) error {
25+
func (Update) Run(ctx context.Context, args []string) error {
2526
parser := argparse.NewArgParser("git-bundle-server update <route>")
2627
route := parser.PositionalString("route", "the route to update")
27-
parser.Parse(args)
28+
parser.Parse(ctx, args)
2829

2930
repo, err := core.CreateRepository(*route)
3031
if err != nil {

cmd/git-bundle-server/web-server.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"context"
45
"errors"
56
"flag"
67
"fmt"
@@ -76,7 +77,7 @@ func (w *webServer) getDaemonConfig() (*daemon.DaemonConfig, error) {
7677
}, nil
7778
}
7879

79-
func (w *webServer) startServer(args []string) error {
80+
func (w *webServer) startServer(ctx context.Context, args []string) error {
8081
// Parse subcommand arguments
8182
parser := argparse.NewArgParser("git-bundle-server web-server start [-f|--force]")
8283

@@ -90,8 +91,8 @@ func (w *webServer) startServer(args []string) error {
9091
parser.Var(f.Value, f.Name, fmt.Sprintf("[Web server] %s", f.Usage))
9192
})
9293

93-
parser.Parse(args)
94-
validate()
94+
parser.Parse(ctx, args)
95+
validate(ctx)
9596

9697
d, err := daemon.NewDaemonProvider(w.user, w.cmdExec, w.fileSystem)
9798
if err != nil {
@@ -130,24 +131,24 @@ func (w *webServer) startServer(args []string) error {
130131
return loopErr
131132
}
132133

133-
err = d.Create(config, *force)
134+
err = d.Create(ctx, config, *force)
134135
if err != nil {
135136
return err
136137
}
137138

138-
err = d.Start(config.Label)
139+
err = d.Start(ctx, config.Label)
139140
if err != nil {
140141
return err
141142
}
142143

143144
return nil
144145
}
145146

146-
func (w *webServer) stopServer(args []string) error {
147+
func (w *webServer) stopServer(ctx context.Context, args []string) error {
147148
// Parse subcommand arguments
148149
parser := argparse.NewArgParser("git-bundle-server web-server stop [--remove]")
149150
remove := parser.Bool("remove", false, "Remove the web server daemon configuration from the system after stopping")
150-
parser.Parse(args)
151+
parser.Parse(ctx, args)
151152

152153
d, err := daemon.NewDaemonProvider(w.user, w.cmdExec, w.fileSystem)
153154
if err != nil {
@@ -159,13 +160,13 @@ func (w *webServer) stopServer(args []string) error {
159160
return err
160161
}
161162

162-
err = d.Stop(config.Label)
163+
err = d.Stop(ctx, config.Label)
163164
if err != nil {
164165
return err
165166
}
166167

167168
if *remove {
168-
err = d.Remove(config.Label)
169+
err = d.Remove(ctx, config.Label)
169170
if err != nil {
170171
return err
171172
}
@@ -174,12 +175,12 @@ func (w *webServer) stopServer(args []string) error {
174175
return nil
175176
}
176177

177-
func (w *webServer) Run(args []string) error {
178+
func (w *webServer) Run(ctx context.Context, args []string) error {
178179
// Parse command arguments
179180
parser := argparse.NewArgParser("git-bundle-server web-server (start|stop) <options>")
180181
parser.Subcommand(argparse.NewSubcommand("start", "Start the web server", w.startServer))
181182
parser.Subcommand(argparse.NewSubcommand("stop", "Stop the web server", w.stopServer))
182-
parser.Parse(args)
183+
parser.Parse(ctx, args)
183184

184-
return parser.InvokeSubcommand()
185+
return parser.InvokeSubcommand(ctx)
185186
}

cmd/git-bundle-web-server/main.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,15 @@ func startServer(server *http.Server,
108108
}
109109

110110
func main() {
111+
ctx := context.Background()
112+
111113
parser := argparse.NewArgParser("git-bundle-web-server [--port <port>] [--cert <filename> --key <filename>]")
112114
flags, validate := utils.WebServerFlags(parser)
113115
flags.VisitAll(func(f *flag.Flag) {
114116
parser.Var(f.Value, f.Name, f.Usage)
115117
})
116-
parser.Parse(os.Args[1:])
117-
validate()
118+
parser.Parse(ctx, os.Args[1:])
119+
validate(ctx)
118120

119121
// Get the flag values
120122
port := utils.GetFlagValue[string](parser, "port")
@@ -139,7 +141,7 @@ func main() {
139141
go func() {
140142
<-c
141143
fmt.Println("Starting graceful server shutdown...")
142-
server.Shutdown(context.Background())
144+
server.Shutdown(ctx)
143145
}()
144146

145147
// Wait for server to shut down

cmd/utils/common-args.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package utils
22

33
import (
4+
"context"
45
"flag"
56
"fmt"
67
"strconv"
@@ -14,7 +15,7 @@ import (
1415
// functions we want to call from the parser.
1516
type argParser interface {
1617
Lookup(name string) *flag.Flag
17-
Usage(errFmt string, args ...any)
18+
Usage(ctx context.Context, errFmt string, args ...any)
1819
}
1920

2021
func GetFlagValue[T any](parser argParser, name string) T {
@@ -38,20 +39,20 @@ func GetFlagValue[T any](parser argParser, name string) T {
3839

3940
// Sets of flags shared between multiple commands/programs
4041

41-
func WebServerFlags(parser argParser) (*flag.FlagSet, func()) {
42+
func WebServerFlags(parser argParser) (*flag.FlagSet, func(context.Context)) {
4243
f := flag.NewFlagSet("", flag.ContinueOnError)
4344
port := f.String("port", "8080", "The port on which the server should be hosted")
4445
cert := f.String("cert", "", "The path to the X.509 SSL certificate file to use in securely hosting the server")
4546
key := f.String("key", "", "The path to the certificate's private key")
4647

4748
// Function to call for additional arg validation (may exit with 'Usage()')
48-
validationFunc := func() {
49+
validationFunc := func(ctx context.Context) {
4950
p, err := strconv.Atoi(*port)
5051
if err != nil || p < 0 || p > 65535 {
51-
parser.Usage("Invalid port '%s'.", *port)
52+
parser.Usage(ctx, "Invalid port '%s'.", *port)
5253
}
5354
if (*cert == "") != (*key == "") {
54-
parser.Usage("Both '--cert' and '--key' are needed to specify SSL configuration.")
55+
parser.Usage(ctx, "Both '--cert' and '--key' are needed to specify SSL configuration.")
5556
}
5657
}
5758

internal/argparse/argparse.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package argparse
22

33
import (
4+
"context"
45
"flag"
56
"fmt"
67
"os"
@@ -117,7 +118,7 @@ func (a *argParser) PositionalList(name string, description string) *[]string {
117118
return arg
118119
}
119120

120-
func (a *argParser) Parse(args []string) {
121+
func (a *argParser) Parse(ctx context.Context, args []string) {
121122
if a.parsed {
122123
// Do nothing if we've already parsed args
123124
return
@@ -147,12 +148,12 @@ func (a *argParser) Parse(args []string) {
147148
if len(a.subcommands) > 0 {
148149
// Parse subcommand, if applicable
149150
if a.FlagSet.NArg() == 0 {
150-
a.Usage("Please specify a subcommand")
151+
a.Usage(ctx, "Please specify a subcommand")
151152
}
152153

153154
subcommand, exists := a.subcommands[a.FlagSet.Arg(0)]
154155
if !exists {
155-
a.Usage("Invalid subcommand '%s'", a.FlagSet.Arg(0))
156+
a.Usage(ctx, "Invalid subcommand '%s'", a.FlagSet.Arg(0))
156157
} else {
157158
a.selectedSubcommand = subcommand
158159
a.argOffset++
@@ -182,7 +183,7 @@ func (a *argParser) Parse(args []string) {
182183
if a.NArg() != 0 {
183184
// If not using subcommands, all args should be accounted for
184185
// Exit with usage if not
185-
a.Usage("Unused arguments specified: %s", strings.Join(a.Args(), " "))
186+
a.Usage(ctx, "Unused arguments specified: %s", strings.Join(a.Args(), " "))
186187
}
187188
}
188189

@@ -205,15 +206,15 @@ func (a *argParser) NArg() int {
205206
}
206207
}
207208

208-
func (a *argParser) InvokeSubcommand() error {
209+
func (a *argParser) InvokeSubcommand(ctx context.Context) error {
209210
if !a.parsed || a.selectedSubcommand == nil {
210211
panic("subcommand has not been parsed")
211212
}
212213

213-
return a.selectedSubcommand.Run(a.Args())
214+
return a.selectedSubcommand.Run(ctx, a.Args())
214215
}
215216

216-
func (a *argParser) Usage(errFmt string, args ...any) {
217+
func (a *argParser) Usage(ctx context.Context, errFmt string, args ...any) {
217218
fmt.Fprintf(a.FlagSet.Output(), errFmt+"\n", args...)
218219
a.FlagSet.Usage()
219220

0 commit comments

Comments
 (0)