Example #1
0
File: abot.go Project: itsabot/abot
func installPlugins(l *log.Logger, errChan chan errMsg) {
	if err := core.LoadConf(); err != nil {
		errChan <- errMsg{msg: "", err: err}
		return
	}
	plugins := buildPluginFile(l)

	// Fetch all plugins
	if len(plugins.Dependencies) == 1 {
		l.Infof("Fetching 1 plugin...\n")
	} else {
		l.Infof("Fetching %d plugins...\n", len(plugins.Dependencies))
	}
	outC, err := exec.
		Command("/bin/sh", "-c", "go get ./...").
		CombinedOutput()
	if err == nil {
		syncDependencies(plugins, l, errChan)
		return
	}

	// Show errors only when it's not a private repo issue
	if !strings.Contains(string(outC), "fatal: could not read Username for") {
		errChan <- errMsg{msg: string(outC), err: err}
		return
	}

	// TODO enable versioning for private repos
	l.Infof("Fetching private repos...\n\n")
	l.Info("*** This will delete your local plugins to fetch remote copies.")
	_, err = fmt.Print("Continue? [n]: ")
	if err != nil {
		errChan <- errMsg{msg: "", err: err}
		return
	}
	reader := bufio.NewReader(os.Stdin)
	text, err := reader.ReadString('\n')
	if err != nil {
		errChan <- errMsg{msg: "", err: errors.New("failed to read from stdin")}
		return
	}
	if text[0] != 'y' && text[0] != 'Y' {
		errChan <- errMsg{msg: "Canceled", err: nil}
		return
	}
	wg := &sync.WaitGroup{}
	for name, _ := range plugins.Dependencies {
		go clonePrivateRepo(name, errChan, wg)
	}
	wg.Wait()
	syncDependencies(plugins, l, errChan)
}
Example #2
0
File: abot.go Project: itsabot/abot
func updateGlockfileAndInstall(l *log.Logger) {
	outC, err := exec.
		Command("/bin/sh", "-c", `pwd | sed "s|$GOPATH/src/||"`).
		CombinedOutput()
	if err != nil {
		l.Info(string(outC))
		l.Fatal(err)
	}

	// Update plugin dependency versions in GLOCKFILE
	p := string(outC)
	outC, err = exec.
		Command("/bin/sh", "-c", "glock save "+p).
		CombinedOutput()
	if err != nil {
		l.Info(string(outC))
		l.Fatal(err)
	}

	outC, err = exec.
		Command("/bin/sh", "-c", "go install").
		CombinedOutput()
	if err != nil {
		l.Info(string(outC))
		l.Fatal(err)
	}
}
Example #3
0
File: abot.go Project: itsabot/abot
func syncDependencies(plugins *core.PluginJSON, l *log.Logger,
	errChan chan errMsg) {

	// Sync each of them to get dependencies
	wg := &sync.WaitGroup{}
	rand.Seed(time.Now().UTC().UnixNano())
	for url, version := range plugins.Dependencies {
		wg.Add(1)
		go func(url, version string) {
			defer wg.Done()
			// Check out specific commit
			var outB []byte
			var errB error
			if version != "*" {
				l.Debug("checking out", url, "at", version)
				p := filepath.Join(os.Getenv("GOPATH"), "src",
					url)
				c := fmt.Sprintf("git -C %s checkout %s", p, version)
				outB, errB = exec.
					Command("/bin/sh", "-c", c).
					CombinedOutput()
				if errB != nil {
					l.Debug(string(outB))
					errChan <- errMsg{msg: "", err: errB}
					return
				}
			}

			// Anonymously increment the plugin's download count
			// at itsabot.org
			l.Debug("incrementing download count", url)
			p := struct{ Path string }{Path: url}
			outB, errB = json.Marshal(p)
			if errB != nil {
				errChan <- errMsg{msg: "failed to build itsabot.org JSON.", err: errB}
				return
			}
			var u string
			u = os.Getenv("ITSABOT_URL") + "/api/plugins.json"
			req, errB := http.NewRequest("PUT", u, bytes.NewBuffer(outB))
			if errB != nil {
				errChan <- errMsg{msg: "failed to build request to itsabot.org.", err: errB}
				return
			}
			client := &http.Client{Timeout: 10 * time.Second}
			resp, errB := client.Do(req)
			if errB != nil {
				errChan <- errMsg{msg: "failed to update itsabot.org.", err: errB}
				return
			}
			defer func() {
				if errB = resp.Body.Close(); errB != nil {
					errChan <- errMsg{msg: "", err: errB}
				}
			}()
			if resp.StatusCode != 200 {
				l.Infof("WARN: %d - %s\n", resp.StatusCode,
					resp.Status)
			}
		}(url, version)
	}
	wg.Wait()

	// Ensure dependencies are still there with the latest checked out
	// versions, and install the plugins
	l.Info("Installing plugins...")
	outC, err := exec.
		Command("/bin/sh", "-c", "go get ./...").
		CombinedOutput()
	if err != nil {
		errChan <- errMsg{msg: string(outC), err: err}
		return
	}
	embedPluginConfs(plugins, l)
	updateGlockfileAndInstall(l)
	errChan <- errMsg{msg: "Success!"}
}
Example #4
0
File: abot.go Project: itsabot/abot
// newAbot creates a new directory for a new Abot project. It's similar to
// `rails new`.
func newAbot(l *log.Logger, name, dbconnstr string) error {
	// Create a new directory for the project
	if err := os.Mkdir(name, 0777); err != nil {
		return err
	}
	if err := os.Chdir(name); err != nil {
		return err
	}

	// Generate abot.env
	fi, err := os.Create("abot.env")
	if err != nil {
		return err
	}
	defer func() {
		if err = fi.Close(); err != nil {
			l.Info("failed to close abot.env.", err)
		}
	}()
	dir, err := os.Getwd()
	if err != nil {
		return err
	}
	_, err = fi.WriteString(serverAbotEnv(name, dir))
	if err != nil {
		return err
	}

	// Copy and modify base files
	p := filepath.Join(os.Getenv("ABOT_PATH"), "base", "plugins.json")
	if err = core.CopyFileContents(p, "plugins.json"); err != nil {
		return err
	}
	p = filepath.Join(os.Getenv("ABOT_PATH"), "base", "server.go.x")
	if err = core.CopyFileContents(p, "server.go"); err != nil {
		return err
	}
	p = filepath.Join(os.Getenv("ABOT_PATH"), "base", ".gitignore")
	if err = core.CopyFileContents(p, ".gitignore"); err != nil {
		return err
	}
	fi2, err := os.OpenFile(".gitignore", os.O_APPEND|os.O_WRONLY, 0666)
	if err != nil {
		return err
	}
	defer func() {
		if err = fi2.Close(); err != nil {
			l.Info("failed to close .gitignore.", err)
		}
	}()
	_, err = fi2.WriteString(name)
	if err != nil {
		l.Fatal("failed to write to .gitignore.", err)
	}

	// Walk the base/assets dir, copying all files
	p = filepath.Join(os.Getenv("ABOT_PATH"), "base", "assets")
	if err = filepath.Walk(p, recursiveCopy); err != nil {
		return err
	}
	p = filepath.Join(os.Getenv("ABOT_PATH"), "base", "cmd")
	if err = filepath.Walk(p, recursiveCopy); err != nil {
		return err
	}
	p = filepath.Join(os.Getenv("ABOT_PATH"), "base", "data")
	if err = filepath.Walk(p, recursiveCopy); err != nil {
		return err
	}
	p = filepath.Join(os.Getenv("ABOT_PATH"), "base", "db")
	if err = filepath.Walk(p, recursiveCopy); err != nil {
		return err
	}

	// Run cmd/dbsetup.sh
	cmd := exec.Command("/bin/sh", "-c", "cmd/dbsetup.sh "+dbconnstr)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err = cmd.Run(); err != nil {
		l.Info("Fix the errors above, then re-run cmd/dbsetup.sh")
		return err
	}

	// TODO analytics on a new Abot project
	return nil
}