• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

foomo / contentserver / 19671331757

25 Nov 2025 01:33PM UTC coverage: 42.455% (+0.8%) from 41.662%
19671331757

Pull #67

github

web-flow
Merge 12430bd68 into e7e5d09f5
Pull Request #67: Add GCS Storage Backend Support

166 of 331 new or added lines in 11 files covered. (50.15%)

3 existing lines in 2 files now uncovered.

875 of 2061 relevant lines covered (42.46%)

26984.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/cmd/socket.go
1
package cmd
2

3
import (
4
        "context"
5
        "fmt"
6
        "net"
7

8
        "github.com/foomo/contentserver/pkg/handler"
9
        "github.com/foomo/contentserver/pkg/repo"
10
        "github.com/foomo/keel/log"
11
        keelhttp "github.com/foomo/keel/net/http"
12
        "github.com/spf13/cobra"
13
        "github.com/spf13/viper"
14
        "go.uber.org/zap"
15
)
16

17
func NewSocketCommand() *cobra.Command {
×
18
        v := viper.New()
×
19
        cmd := &cobra.Command{
×
20
                Use:   "socket <url>",
×
21
                Short: "Start socket server",
×
22
                Args:  cobra.ExactArgs(1),
×
23
                ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
×
24
                        var comps []string
×
25
                        if len(args) == 0 {
×
26
                                comps = cobra.AppendActiveHelp(comps, "You must specify the URL for the repository you are adding")
×
27
                        } else {
×
28
                                comps = cobra.AppendActiveHelp(comps, "This command does not take any more arguments")
×
29
                        }
×
30
                        return comps, cobra.ShellCompDirectiveNoFileComp
×
31
                },
32
                RunE: func(cmd *cobra.Command, args []string) error {
×
33
                        l := log.Logger()
×
34

×
NEW
35
                        // Create storage based on configuration
×
NEW
36
                        storage, err := createStorage(cmd.Context(), v, l)
×
NEW
37
                        if err != nil {
×
NEW
38
                                return fmt.Errorf("failed to create storage: %w", err)
×
NEW
39
                        }
×
40

NEW
41
                        history, err := repo.NewHistory(l,
×
NEW
42
                                repo.HistoryWithStorage(storage),
×
NEW
43
                                repo.HistoryWithHistoryDir(historyDirFlag(v)),
×
NEW
44
                                repo.HistoryWithHistoryLimit(historyLimitFlag(v)),
×
NEW
45
                        )
×
NEW
46
                        if err != nil {
×
NEW
47
                                return fmt.Errorf("failed to create history: %w", err)
×
NEW
48
                        }
×
NEW
49
                        defer func() {
×
NEW
50
                                if closeErr := history.Close(); closeErr != nil {
×
NEW
51
                                        l.Error("failed to close history storage", zap.Error(closeErr))
×
NEW
52
                                }
×
53
                        }()
54

55
                        r := repo.New(l,
×
56
                                args[0],
×
NEW
57
                                history,
×
58
                                repo.WithHTTPClient(
×
59
                                        keelhttp.NewHTTPClient(
×
60
                                                keelhttp.HTTPClientWithTelemetry(),
×
61
                                        ),
×
62
                                ),
×
63
                                repo.WithPoll(pollFlag(v)),
×
64
                                repo.WithPollInterval(pollIntevalFlag(v)),
×
65
                        )
×
66

×
67
                        // create socket server
×
68
                        handle := handler.NewSocket(l, r)
×
69

×
70
                        // listen on socket
×
NEW
71
                        var lc net.ListenConfig
×
NEW
72
                        ln, err := lc.Listen(cmd.Context(), "tcp", addressFlag(v))
×
73
                        if err != nil {
×
74
                                return err
×
75
                        }
×
76

77
                        // start repo
78
                        up := make(chan bool, 1)
×
79
                        r.OnLoaded(func() {
×
80
                                up <- true
×
81
                        })
×
82
                        go r.Start(context.Background()) //nolint:errcheck
×
83
                        <-up
×
84

×
85
                        l.Info("started listening", zap.String("address", addressFlag(v)))
×
86

×
87
                        for {
×
88
                                // this blocks until connection or error
×
89
                                conn, err := ln.Accept()
×
90
                                if err != nil {
×
91
                                        l.Error("runSocketServer: could not accept connection", zap.Error(err))
×
92
                                        continue
×
93
                                }
94

95
                                // a goroutine handles conn so that the loop can accept other connections
96
                                go func() {
×
97
                                        l.Debug("accepted connection", zap.String("source", conn.RemoteAddr().String()))
×
98
                                        handle.Serve(conn)
×
99
                                        if err := conn.Close(); err != nil {
×
100
                                                l.Warn("failed to close connection", zap.Error(err))
×
101
                                        }
×
102
                                }()
103
                        }
104
                },
105
        }
106

107
        flags := cmd.Flags()
×
108
        addAddressFlag(flags, v)
×
109
        addPollFlag(flags, v)
×
110
        addPollIntervalFlag(flags, v)
×
111
        addHistoryDirFlag(flags, v)
×
112
        addHistoryLimitFlag(flags, v)
×
NEW
113
        addStorageTypeFlag(flags, v)
×
NEW
114
        addStorageGCSBucketFlag(flags, v)
×
NEW
115
        addStorageGCSPrefixFlag(flags, v)
×
116

×
117
        return cmd
×
118
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc