Beispiel #1
0
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())
}
Beispiel #2
0
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)
	}
}
Beispiel #3
0
// 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
}