1package commands
2
3import (
4 "context"
5 "os"
6 "sync"
7 "time"
8
9 "github.com/spf13/cobra"
10
11 "github.com/MichaelMure/git-bug/bridge"
12 "github.com/MichaelMure/git-bug/bridge/core"
13 "github.com/MichaelMure/git-bug/util/interrupt"
14)
15
16func newBridgePushCommand() *cobra.Command {
17 env := newEnv()
18
19 cmd := &cobra.Command{
20 Use: "push [<name>]",
21 Short: "Push updates.",
22 PreRunE: loadBackendEnsureUser(env),
23 PostRunE: closeBackend(env),
24 RunE: func(cmd *cobra.Command, args []string) error {
25 return runBridgePush(env, args)
26 },
27 Args: cobra.MaximumNArgs(1),
28 }
29
30 return cmd
31}
32
33func runBridgePush(env *Env, args []string) error {
34 var b *core.Bridge
35 var err error
36
37 if len(args) == 0 {
38 b, err = bridge.DefaultBridge(env.backend)
39 } else {
40 b, err = bridge.LoadBridge(env.backend, args[0])
41 }
42
43 if err != nil {
44 return err
45 }
46
47 parentCtx := context.Background()
48 ctx, cancel := context.WithCancel(parentCtx)
49 defer cancel()
50
51 done := make(chan struct{}, 1)
52
53 var mu sync.Mutex
54 interruptCount := 0
55 interrupt.RegisterCleaner(func() error {
56 mu.Lock()
57 if interruptCount > 0 {
58 env.err.Println("Received another interrupt before graceful stop, terminating...")
59 os.Exit(0)
60 }
61
62 interruptCount++
63 mu.Unlock()
64
65 env.err.Println("Received interrupt signal, stopping the import...\n(Hit ctrl-c again to kill the process.)")
66
67 // send signal to stop the importer
68 cancel()
69
70 // block until importer gracefully shutdown
71 <-done
72 return nil
73 })
74
75 events, err := b.ExportAll(ctx, time.Time{})
76 if err != nil {
77 return err
78 }
79
80 exportedIssues := 0
81 for result := range events {
82 if result.Event != core.ExportEventNothing {
83 env.out.Println(result.String())
84 }
85
86 switch result.Event {
87 case core.ExportEventBug:
88 exportedIssues++
89 }
90 }
91
92 env.out.Printf("exported %d issues with %s bridge\n", exportedIssues, b.Name)
93
94 // send done signal
95 close(done)
96 return nil
97}