main.go

  1package main
  2
  3import (
  4	"context"
  5	"fmt"
  6	"log"
  7	"os"
  8	"os/signal"
  9	"runtime/debug"
 10	"syscall"
 11	"time"
 12
 13	"github.com/charmbracelet/soft-serve/config"
 14	"github.com/charmbracelet/soft-serve/server"
 15	mcobra "github.com/muesli/mango-cobra"
 16	"github.com/muesli/roff"
 17	"github.com/spf13/cobra"
 18)
 19
 20var (
 21	// Version contains the application version number. It's set via ldflags
 22	// when building.
 23	Version = ""
 24
 25	// CommitSHA contains the SHA of the commit that this application was built
 26	// against. It's set via ldflags when building.
 27	CommitSHA = ""
 28
 29	rootCmd = &cobra.Command{
 30		Use:   "soft",
 31		Short: "A self-hostable Git server for the command line",
 32		Long:  "Soft Serve is a self-hostable Git server for the command line.",
 33		RunE: func(cmd *cobra.Command, args []string) error {
 34			return cmd.Help()
 35		},
 36	}
 37
 38	serveCmd = &cobra.Command{
 39		Use:   "serve",
 40		Short: "Start the server",
 41		Long:  "Start the server",
 42		Args:  cobra.NoArgs,
 43		RunE: func(cmd *cobra.Command, args []string) error {
 44			cfg := config.DefaultConfig()
 45			s := server.NewServer(cfg)
 46
 47			done := make(chan os.Signal, 1)
 48			signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
 49
 50			log.Printf("Starting SSH server on %s:%d", cfg.BindAddr, cfg.Port)
 51			go func() {
 52				if err := s.Start(); err != nil {
 53					log.Fatalln(err)
 54				}
 55			}()
 56
 57			<-done
 58
 59			log.Printf("Stopping SSH server on %s:%d", cfg.BindAddr, cfg.Port)
 60			ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
 61			defer func() { cancel() }()
 62			return s.Shutdown(ctx)
 63		},
 64	}
 65
 66	manCmd = &cobra.Command{
 67		Use:    "man",
 68		Short:  "Generate man pages",
 69		Args:   cobra.NoArgs,
 70		Hidden: true,
 71		RunE: func(cmd *cobra.Command, args []string) error {
 72			manPage, err := mcobra.NewManPage(1, rootCmd) //.
 73			if err != nil {
 74				return err
 75			}
 76
 77			manPage = manPage.WithSection("Copyright", "(C) 2021-2022 Charmbracelet, Inc.\n"+
 78				"Released under MIT license.")
 79			fmt.Println(manPage.Build(roff.NewDocument()))
 80			return nil
 81		},
 82	}
 83)
 84
 85func init() {
 86	rootCmd.AddCommand(
 87		serveCmd,
 88		manCmd,
 89	)
 90	rootCmd.CompletionOptions.HiddenDefaultCmd = true
 91
 92	if len(CommitSHA) >= 7 {
 93		vt := rootCmd.VersionTemplate()
 94		rootCmd.SetVersionTemplate(vt[:len(vt)-1] + " (" + CommitSHA[0:7] + ")\n")
 95	}
 96	if Version == "" {
 97		if info, ok := debug.ReadBuildInfo(); ok && info.Main.Sum != "" {
 98			Version = info.Main.Version
 99		} else {
100			Version = "unknown (built from source)"
101		}
102	}
103	rootCmd.Version = Version
104}
105
106func main() {
107	if err := rootCmd.Execute(); err != nil {
108		log.Fatalln(err)
109	}
110}