Skip to content

Commit ca23190

Browse files
committed
bundle-server: add 'web-server' subcommand
The 'web-server' subcommand is used to start/stop a daemon process running 'git-bundle-web-server', selecting 'launchd' or 'systemd' to manage the process depending on the operating system (Windows support is not yet implemented). Signed-off-by: Victoria Dye <[email protected]>
1 parent 684a295 commit ca23190

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

cmd/git-bundle-server/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ func all() []argparse.Subcommand {
1515
Stop{},
1616
Update{},
1717
UpdateAll{},
18+
NewWebServerCommand(),
1819
}
1920
}
2021

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

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"os"
7+
"os/exec"
8+
"path/filepath"
9+
10+
"github.com/github/git-bundle-server/internal/argparse"
11+
"github.com/github/git-bundle-server/internal/common"
12+
"github.com/github/git-bundle-server/internal/daemon"
13+
)
14+
15+
type webServer struct {
16+
user common.UserProvider
17+
cmdExec common.CommandExecutor
18+
fileSystem common.FileSystem
19+
}
20+
21+
func NewWebServerCommand() *webServer {
22+
// Create dependencies
23+
return &webServer{
24+
user: common.NewUserProvider(),
25+
cmdExec: common.NewCommandExecutor(),
26+
fileSystem: common.NewFileSystem(),
27+
}
28+
}
29+
30+
func (webServer) Name() string {
31+
return "web-server"
32+
}
33+
34+
func (webServer) Description() string {
35+
return `Manage the web server hosting bundle content`
36+
}
37+
38+
func (w *webServer) getDaemonConfig() (*daemon.DaemonConfig, error) {
39+
// Find git-bundle-web-server
40+
// First, search for it on the path
41+
programPath, err := exec.LookPath("git-bundle-web-server")
42+
if err != nil {
43+
if errors.Is(err, exec.ErrDot) {
44+
// Result is a relative path
45+
programPath, err = filepath.Abs(programPath)
46+
if err != nil {
47+
return nil, fmt.Errorf("could not get absolute path to program: %w", err)
48+
}
49+
} else {
50+
// Fall back on looking for it in the same directory as the currently-running executable
51+
exePath, err := os.Executable()
52+
if err != nil {
53+
return nil, fmt.Errorf("failed to get path to current executable: %w", err)
54+
}
55+
exeDir := filepath.Dir(exePath)
56+
if err != nil {
57+
return nil, fmt.Errorf("failed to get parent dir of current executable: %w", err)
58+
}
59+
60+
programPath = filepath.Join(exeDir, "git-bundle-web-server")
61+
programExists, err := w.fileSystem.FileExists(programPath)
62+
if err != nil {
63+
return nil, fmt.Errorf("could not determine whether path to 'git-bundle-web-server' exists: %w", err)
64+
} else if !programExists {
65+
return nil, fmt.Errorf("could not find path to 'git-bundle-web-server'")
66+
}
67+
}
68+
}
69+
70+
return &daemon.DaemonConfig{
71+
Label: "com.github.bundleserver",
72+
Description: "Web server hosting Git Bundle Server content",
73+
Program: programPath,
74+
}, nil
75+
}
76+
77+
func (w *webServer) startServer(args []string) error {
78+
// Parse subcommand arguments
79+
parser := argparse.NewArgParser("git-bundle-server web-server start [-f|--force]")
80+
force := parser.Bool("force", false, "Whether to force reconfiguration of the web server daemon")
81+
parser.BoolVar(force, "f", false, "Alias of --force")
82+
parser.Parse(args)
83+
84+
d, err := daemon.NewDaemonProvider(w.user, w.cmdExec, w.fileSystem)
85+
if err != nil {
86+
return err
87+
}
88+
89+
config, err := w.getDaemonConfig()
90+
if err != nil {
91+
return err
92+
}
93+
94+
err = d.Create(config, *force)
95+
if err != nil {
96+
return err
97+
}
98+
99+
err = d.Start(config.Label)
100+
if err != nil {
101+
return err
102+
}
103+
104+
return nil
105+
}
106+
107+
func (w *webServer) stopServer(args []string) error {
108+
// Parse subcommand arguments
109+
parser := argparse.NewArgParser("git-bundle-server web-server stop")
110+
parser.Parse(args)
111+
112+
d, err := daemon.NewDaemonProvider(w.user, w.cmdExec, w.fileSystem)
113+
if err != nil {
114+
return err
115+
}
116+
117+
config, err := w.getDaemonConfig()
118+
if err != nil {
119+
return err
120+
}
121+
122+
err = d.Stop(config.Label)
123+
if err != nil {
124+
return err
125+
}
126+
127+
return nil
128+
}
129+
130+
func (w *webServer) Run(args []string) error {
131+
// Parse command arguments
132+
parser := argparse.NewArgParser("git-bundle-server web-server (start|stop) <options>")
133+
parser.Subcommand(argparse.NewSubcommand("start", "Start the web server", w.startServer))
134+
parser.Subcommand(argparse.NewSubcommand("stop", "Stop the web server", w.stopServer))
135+
parser.Parse(args)
136+
137+
return parser.InvokeSubcommand()
138+
}

0 commit comments

Comments
 (0)