コード例 #1
0
ファイル: shared.go プロジェクト: sdboyer/pipeviz
func recordHead(m *ingest.Message, repo *git.Repository) {
	head, err := repo.Head()
	if err != nil {
		log.Fatalf("Could not get repo HEAD")
	}
	oid := head.Target()

	hn, err := os.Hostname()
	if err != nil {
		log.Fatalln("Could not determine hostname for environment")
	}

	// be extra safe about cleaning the path wrt trailing slashes
	p := repo.Path()
	if strings.LastIndex(p, string(os.PathSeparator)) == len(p)-1 {
		p = path.Dir(path.Dir(p))
	} else {
		p = path.Dir(p)
	}

	m.Add(semantic.LogicState{
		Environment: semantic.EnvLink{
			Address: semantic.Address{
				Hostname: hn,
			},
		},
		Path: p,
		ID: semantic.LogicIdentiifer{
			CommitStr: hex.EncodeToString(oid[:]),
		},
	})

	if head.IsBranch() {
		b := head.Branch()
		bn, _ := b.Name()

		m.Add(semantic.CommitMeta{
			Sha1Str:  hex.EncodeToString(oid[:]),
			Tags:     make([]string, 0),
			Branches: []string{bn},
		})
	}
}
コード例 #2
0
ファイル: post_commit.go プロジェクト: sdboyer/pipeviz
func runPostCommit(cmd *cobra.Command, args []string) {
	repo := getRepoOrExit()

	head, err := repo.Head()
	if err != nil {
		log.Fatalf("Could not get repo HEAD")
	}

	commit, err := repo.LookupCommit(head.Target())
	if err != nil {
		log.Fatalf("Could not find commit pointed at by HEAD")
	}

	ident, err := githelp.GetRepoIdent(repo)
	if err != nil {
		log.Fatalln("Failed to retrieve identifier for repository")
	}

	m := new(ingest.Message)
	m.Add(commitToSemanticForm(commit, ident))

	recordHead(m, repo)
	sendMapToPipeviz(m, repo)
}
コード例 #3
0
ファイル: github.go プロジェクト: sdboyer/pipeviz
func (gpe githubPushEvent) ToMessage(token string) *ingest.Message {
	msg := new(ingest.Message)
	client := http.Client{Timeout: 2 * time.Second}

	for _, c := range gpe.Commits {
		// don't include commits we know not to be new - make that someone else's job
		if !c.Distinct {
			continue
		}

		// take up to 50 bytes for subject
		subjlen := len(c.Message)
		if subjlen > 50 {
			subjlen = 50
		}

		// github doesn't include parent commit list in push payload (UGHHHH). so, call out for it.
		// TODO spawn a goroutine per commit to do these in parallel
		url := strings.Replace(gpe.Repository.GitCommitsURL, "{/sha}", "/"+c.Sha, 1)
		req, err := http.NewRequest("GET", url, nil)
		if err != nil {
			logrus.WithFields(logrus.Fields{
				"system": "pvproxy",
				"err":    err,
				"sha1":   c.Sha,
			}).Warn("Error while creating request for additional information from github; skipping commit.")
			continue
		}

		if token != "" {
			req.Header.Set("Authentication", "token "+token)
		}

		resp, err := client.Do(req)
		if err != nil {
			// just drop the problematic commit
			logrus.WithFields(logrus.Fields{
				"system": "pvproxy",
				"err":    err,
				"sha1":   c.Sha,
			}).Warn("Request to github to retrieve commit parent info failed; commit dropped.")
			continue
		}

		if !statusIsOK(resp) {
			logrus.WithFields(logrus.Fields{
				"system": "pvproxy",
				"status": resp.StatusCode,
				"sha1":   c.Sha,
			}).Warn("Github responded with non-2xx response when requesting parent commit data.")
			continue
		}

		// skip err here, it's effectively caught by the json unmarshaler
		bod, _ := ioutil.ReadAll(resp.Body)

		var jmap interface{}
		err = json.Unmarshal(bod, &jmap)
		if err != nil {
			logrus.WithFields(logrus.Fields{
				"system": "pvproxy",
				"err":    err,
				"sha1":   c.Sha,
			}).Warn("Bad JSON response from github when requesting commit parent info; commit dropped.")
			continue
		}

		var parents []string
		for _, iparent := range jmap.(map[string]interface{})["parents"].([]interface{}) {
			parent := iparent.(map[string]interface{})
			parents = append(parents, parent["sha"].(string))
		}

		t, err := time.Parse(time.RFC3339, c.Timestamp)
		if err != nil {
			logrus.WithFields(logrus.Fields{
				"system":     "pvproxy",
				"err":        err,
				"datestring": c.Timestamp,
				"sha1":       c.Sha,
			}).Warn("Error on parsing date field in github payload; commit dropped.")
		}

		msg.Add(semantic.Commit{
			Sha1Str:    c.Sha,
			Subject:    c.Message[:subjlen],
			Author:     fmt.Sprintf("%q <%s>", c.Author.Name, c.Author.Email),
			Date:       t.Format(gitDateFormat),
			Repository: gpe.Repository.Ident,
			ParentsStr: parents,
		})
	}

	if gpe.Ref[:11] == "refs/heads/" {
		msg.Add(semantic.CommitMeta{
			Sha1Str:  gpe.HeadCommit.Sha,
			Branches: []string{gpe.Ref[11:]},
		})
	} else if gpe.Ref[:10] == "refs/tags/" {
		msg.Add(semantic.CommitMeta{
			Sha1Str: gpe.HeadCommit.Sha,
			Tags:    []string{gpe.Ref[10:]},
		})
	}

	return msg
}
コード例 #4
0
ファイル: sync.go プロジェクト: sdboyer/pipeviz
func syncHistory(repo *git.Repository, all bool) {
	var err error
	var ident string

	msg := new(ingest.Message)

	if all {
		ident, err = githelp.GetRepoIdent(repo)
		if err != nil {
			log.Fatalf("Failed to retrieve a stable identifier for this repository; cannot formulate commits correctly. Aborting.")
		}
	}

	cvisited := make(map[git.Oid]struct{})

	iter, err := repo.NewReferenceIterator()
	if err != nil {
		log.Fatalln("Error while creating reference iterator:", err)
	}

	// For simplicity, create a revwalker now even if we don't use it later
	w, err := repo.Walk()
	if err != nil {
		log.Fatalln("Could not create revwalker iterator:", err)
	}

	w.Sorting(git.SortTopological)
	//defer w.Free()

	for ref, err := iter.Next(); err == nil; ref, err = iter.Next() {
		// in func for easy defer of Free()
		func(r *git.Reference, m *ingest.Message) {
			//defer r.Free()
			oid := r.Target()
			if !r.IsBranch() && !r.IsTag() {
				return
			}
			if r.IsBranch() {
				bn, _ := r.Branch().Name()

				w.Push(oid)
				m.Add(semantic.CommitMeta{
					Sha1Str:  hex.EncodeToString(oid[:]),
					Tags:     make([]string, 0),
					Branches: []string{bn},
				})
			} else if r.IsTag() {
				w.Push(oid)
				m.Add(semantic.CommitMeta{
					Sha1Str: hex.EncodeToString(oid[:]),
					// TODO this still emits the refs/tags/<name> form, ugh
					Tags:     []string{r.Name()},
					Branches: make([]string, 0),
				})
			} else {
				log.Fatalf("Ref %s is neither branch nor tag - wtf\n", r.Name())
			}
		}(ref, msg)
	}
	//iter.Free()

	if err != nil {
		if !git.IsErrorCode(err, git.ErrIterOver) {
			//if gerr, ok := err.(*git.GitError); !ok || gerr.Code != git.ErrIterOver {
			gerr := err.(*git.GitError)
			log.Fatalf("Iteration through repository refs terminated with unexpected error (code: %d, message: %q)\n", gerr.Code, gerr.Message)
		}
	}

	if all {
		w.Iterate(func(c *git.Commit) bool {
			//defer c.Free()
			if _, exists := cvisited[*c.Id()]; exists {
				return false
			}

			cvisited[*c.Id()] = struct{}{}
			msg.Add(commitToSemanticForm(c, ident))
			return true
		})
	}
	//w.Free()
	recordHead(msg, repo)

	sendMapToPipeviz(msg, repo)
}