maddy

Fork https://github.com/foxcpp/maddy

git clone git://git.lin.moe/go/maddy.git

  1package maddycli
  2
  3import (
  4	"fmt"
  5	"os"
  6	"strings"
  7
  8	"github.com/foxcpp/maddy/framework/log"
  9	"github.com/urfave/cli/v2"
 10)
 11
 12var app *cli.App
 13
 14func init() {
 15	app = cli.NewApp()
 16	app.Usage = "composable all-in-one mail server"
 17	app.Description = `Maddy is Mail Transfer agent (MTA), Mail Delivery Agent (MDA), Mail Submission
 18Agent (MSA), IMAP server and a set of other essential protocols/schemes
 19necessary to run secure email server implemented in one executable.
 20
 21This executable can be used to start the server ('run') and to manipulate
 22databases used by it (all other subcommands).
 23`
 24	app.Authors = []*cli.Author{
 25		{
 26			Name:  "Maddy Mail Server maintainers & contributors",
 27			Email: "~foxcpp/maddy@lists.sr.ht",
 28		},
 29	}
 30	app.ExitErrHandler = func(c *cli.Context, err error) {
 31		cli.HandleExitCoder(err)
 32	}
 33	app.EnableBashCompletion = true
 34	app.Commands = []*cli.Command{
 35		{
 36			Name:   "generate-man",
 37			Hidden: true,
 38			Action: func(c *cli.Context) error {
 39				man, err := app.ToMan()
 40				if err != nil {
 41					return err
 42				}
 43				fmt.Println(man)
 44				return nil
 45			},
 46		},
 47		{
 48			Name:   "generate-fish-completion",
 49			Hidden: true,
 50			Action: func(c *cli.Context) error {
 51				cp, err := app.ToFishCompletion()
 52				if err != nil {
 53					return err
 54				}
 55				fmt.Println(cp)
 56				return nil
 57			},
 58		},
 59	}
 60}
 61
 62func AddGlobalFlag(f cli.Flag) {
 63	app.Flags = append(app.Flags, f)
 64}
 65
 66func AddSubcommand(cmd *cli.Command) {
 67	app.Commands = append(app.Commands, cmd)
 68
 69	if cmd.Name == "run" {
 70		// Backward compatibility hack to start the server as just ./maddy
 71		// Needs to be done here so we will register all known flags with
 72		// stdlib before Run is called.
 73		app.Action = func(c *cli.Context) error {
 74			log.Println("WARNING: Starting server not via 'maddy run' is deprecated and will stop working in the next version")
 75			return cmd.Action(c)
 76		}
 77		app.Flags = append(app.Flags, cmd.Flags...)
 78	}
 79}
 80
 81// RunWithoutExit is like Run but returns exit code instead of calling os.Exit
 82// To be used in maddy.cover.
 83func RunWithoutExit() int {
 84	code := 0
 85
 86	cli.OsExiter = func(c int) { code = c }
 87	defer func() {
 88		cli.OsExiter = os.Exit
 89	}()
 90
 91	Run()
 92
 93	return code
 94}
 95
 96func Run() {
 97	mapStdlibFlags(app)
 98
 99	// Actual entry point is registered in maddy.go.
100
101	// Print help when called via maddyctl executable. To be removed
102	// once backward compatibility hack for 'maddy run' is removed too.
103	if strings.Contains(os.Args[0], "maddyctl") && len(os.Args) == 1 {
104		if err := app.Run([]string{os.Args[0], "help"}); err != nil {
105			log.DefaultLogger.Error("app.Run failed", err)
106		}
107		return
108	}
109
110	if err := app.Run(os.Args); err != nil {
111		log.DefaultLogger.Error("app.Run failed", err)
112	}
113}