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