func TestMain(m *testing.M) { if err := core.LoadEnvVars(); err != nil { log.Info("failed to load env vars", err) } if err := os.Setenv("ABOT_ENV", "test"); err != nil { log.Fatal(err) } os.Exit(m.Run()) }
func main() { rand.Seed(time.Now().UnixNano()) log.SetDebug(os.Getenv("ABOT_DEBUG") == "true") if err := core.LoadEnvVars(); err != nil { log.Fatal(err) } app := cli.NewApp() app.Commands = []cli.Command{ { Name: "new", Usage: "generate a new abot", Action: func(c *cli.Context) error { l := log.New("") l.SetFlags(0) if len(c.Args()) != 1 { l.Fatal("usage: abot new {name}") } if strings.Contains(c.Args().First(), " ") { l.Fatal("name cannot include a space. use camelCase") } err := newAbot(l, c.Args().First(), c.Args().Get(1)) if err != nil { l.Fatalf("could not build new abot. %s", err) } l.Info("Success. Created " + c.Args().First()) return nil }, }, { Name: "server", Aliases: []string{"s"}, Usage: "run server", Action: func(c *cli.Context) error { l := log.New("") l.SetFlags(0) cmd := exec.Command("/bin/sh", "-c", "go build") out, err := cmd.CombinedOutput() if err != nil { l.Info(string(out)) return err } dir, err := os.Getwd() if err != nil { return err } _, file := filepath.Split(dir) cmd = exec.Command("/bin/sh", "-c", "./"+file) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err = cmd.Start(); err != nil { return err } return cmd.Wait() }, }, { Name: "install", Aliases: []string{"i"}, Usage: "download and install plugins listed in plugins.json", Action: func(c *cli.Context) error { errChan := make(chan errMsg) l := log.New("") l.SetFlags(0) l.SetDebug(os.Getenv("ABOT_DEBUG") == "true") go func() { select { case errC := <-errChan: if errC.err == nil { // Success l.Info(errC.msg) os.Exit(0) } // Plugins install failed, so remove incomplete plugins.go file errR := os.Remove("plugins.go") if errR != nil && !os.IsNotExist(errR) { l.Info("could not remove plugins.go file.", errR) } if len(errC.msg) > 0 { l.Fatalf("could not install plugins.\n%s\n%s", errC.msg, errC.err) } l.Fatalf("could not install plugins.\n%s", errC.err) } }() installPlugins(l, errChan) for { // Keep process running until a message is received } }, }, { Name: "search", Usage: "search plugins indexed on itsabot.org", Action: func(c *cli.Context) error { l := log.New("") l.SetFlags(0) args := c.Args() if len(args) == 0 || len(args) > 2 { l.Fatal(errors.New(`usage: abot plugin search {term}`)) } if err := searchPlugins(args.First()); err != nil { l.Fatalf("could not start console\n%s", err) } return nil }, }, { Name: "update", Aliases: []string{"u", "upgrade"}, Usage: "update and install plugins listed in plugins.json", Action: func(c *cli.Context) error { updatePlugins() return nil }, }, { Name: "publish", Aliases: []string{"p"}, Usage: "publish a plugin to itsabot.org", Action: func(c *cli.Context) error { publishPlugin(c) return nil }, }, { Name: "test", Aliases: []string{"t"}, Usage: "tests plugins", Action: func(c *cli.Context) error { lg.SetFlags(0) count, err := testPlugin() if err != nil { return err } if count == 0 { lg.Println("No tests found. Did you run \"abot install\"?") return nil } lg.Printf("Success (%d tests).\n", count) return nil }, }, { Name: "generate", Aliases: []string{"g"}, Usage: "generate plugin scaffolding", Action: func(c *cli.Context) error { l := log.New("") l.SetFlags(0) args := c.Args() if len(args) != 1 { l.Fatal(errors.New(`usage: abot generate {name}`)) } generatePlugin(l, args.First()) l.Info("Created", args.First(), "in", filepath.Join(os.Getenv("PWD"), args.First())) return nil }, }, { Name: "login", Aliases: []string{"l"}, Usage: "log into itsabot.org to enable publishing plugins", Action: func(c *cli.Context) error { login() return nil }, }, { Name: "console", Aliases: []string{"c"}, Usage: "communicate with a running abot server", Action: func(c *cli.Context) error { if err := startConsole(c); err != nil { l := log.New("") l.SetFlags(0) l.Fatalf("could not start console\n%s", err) } return nil }, }, { Name: "dbconsole", Aliases: []string{"dbc"}, Usage: "communicate with a running abot server", Action: func(c *cli.Context) error { cmd := exec.Command("/bin/sh", "-c", "psql "+os.Getenv("ABOT_DATABASE_URL")) cmd.Stdout = os.Stdout cmd.Stdin = os.Stdin if err := cmd.Start(); err != nil { return err } return cmd.Wait() }, }, } app.Action = func(c *cli.Context) error { cli.ShowAppHelp(c) return nil } if err := app.Run(os.Args); err != nil { log.Fatal(err) } }
// New builds a Plugin with its trigger, RPC, and configuration settings from // its plugin.json. func New(url string) (*dt.Plugin, error) { if err := core.LoadEnvVars(); err != nil { log.Fatal(err) } db, err := core.ConnectDB("") if err != nil { return nil, err } // Read plugin.json data from within plugins.go, unmarshal into struct c := dt.PluginConfig{} if len(os.Getenv("ABOT_PATH")) > 0 { p := filepath.Join(os.Getenv("ABOT_PATH"), "plugins.go") var scn *bufio.Scanner fi, err := os.OpenFile(p, os.O_RDONLY, 0666) if os.IsNotExist(err) { goto makePlugin } if err != nil { return nil, err } defer func() { if err = fi.Close(); err != nil { log.Info("failed to close file", fi.Name()) return } }() var found bool var data string scn = bufio.NewScanner(fi) for scn.Scan() { t := scn.Text() if !found && t != url { continue } else if t == url { found = true continue } else if len(t) >= 1 && t[0] == '}' { data += t break } data += t } if err = scn.Err(); err != nil { return nil, err } if len(data) > 0 { if err = json.Unmarshal([]byte(data), &c); err != nil { return nil, err } if len(c.Name) == 0 { return nil, ErrMissingPluginName } } } makePlugin: l := log.New(c.Name) l.SetDebug(os.Getenv("ABOT_DEBUG") == "true") plg := &dt.Plugin{ Trigger: &dt.StructuredInput{}, SetBranches: func(in *dt.Msg) [][]dt.State { return nil }, Events: &dt.PluginEvents{ PostReceive: func(cmd *string) {}, PreProcessing: func(cmd *string, u *dt.User) {}, PostProcessing: func(in *dt.Msg) {}, PreResponse: func(in *dt.Msg, resp *string) {}, }, Config: c, DB: db, Log: l, } plg.SM = dt.NewStateMachine(plg) return plg, nil }