// ScanContributions takes a Configuration containing a list of emails
// and a list of projects and returns a list of Contributions
// which contain of a project, how often a user contributed to it and
// description of the project.
func ScanContributions(configuration Configuration) []Contribution {
	contributions := []Contribution{}

	os.Mkdir("repos", 0755)

	for _, project := range configuration.Projects {
		var sumCount int
		for _, repo := range project.Gitrepos {
			util.PrintInfo("Working on " + repo)
			vcs.GetLatestGitRepo(repo, false)
			for _, email := range configuration.Emails {
				count, err := vcs.CountCommits(repo, email)
				if err != nil {
					fmt.Println(err)
				}

				s := fmt.Sprintf("%s: %d commits", email, count)
				util.PrintInfo(s)

				sumCount += count
			}
		}
		if sumCount > 0 {
			c := Contribution{project.Name, sumCount, project.Description}
			contributions = append(contributions, c)
		}
	}
	return contributions
}
Beispiel #2
0
// scanWiki is a helper function for ScanContributions which takes care of the MediaWiki part
func scanWiki(project Project, emails []string, contributions []Contribution) int {
	var sum int
	for _, wiki := range project.MediaWikis {
		util.PrintInfoF("Working on MediaWiki %s as %s", util.PI_TASK, wiki.BaseUrl, wiki.User)

		wikiCount, err := mediawiki.GetUserEdits(wiki.BaseUrl, wiki.User)
		if err != nil {
			switch err.Error() {
			case "Not a valid URL":
				util.PrintInfo(err.Error(), util.PI_MILD_ERROR)
				break
			case "Not able to HTTP Get",
				"Not able to decode JSON",
				"Did not get a 'user' returned":
				util.PrintInfo(err.Error(), util.PI_ERROR)
				break
			}
		}

		if wikiCount != 0 {
			util.PrintInfoF("%d edits", util.PI_RESULT, wikiCount)
			sum += wikiCount
		}
	}
	return sum
}
Beispiel #3
0
// scanHg is a helper function for ScanContributions which takes care of the git part
func scanHg(project Project, emails []string, contributions []Contribution) (int, error) {
	var sum int
	for _, repo := range project.Hgrepos {
		util.PrintInfo("Working on "+repo, util.PI_TASK)
		if PullSources {
			err := hg.GetLatestRepo(repo)
			if err != nil {
				util.PrintInfo("Problem loading repo", util.PI_MILD_ERROR)
				return 0, err
			}
		}
		for _, email := range emails {
			path := filepath.Join("repos-hg", util.LocalRepoName(repo))
			hgCount, err := hg.CountCommits(path, email)
			if err != nil {
				return 0, err
			}

			if hgCount != 0 {
				util.PrintInfoF("%s: %d commits", util.PI_RESULT, email, hgCount)
				sum += hgCount
			}
		}
	}
	return sum, nil
}
Beispiel #4
0
// scanOBS is a helper function for ScanContributions which takes care of the OBS part
func scanOBS(project Project, emails []string, contributions []Contribution) (int, error) {
	var sum int
Loop_obs:
	for _, obsEntry := range project.Obs {
		util.PrintInfo("Working on "+obsEntry.Repo, util.PI_TASK)

		if PullSources {
			err := obs.GetLatestRepo(obsEntry)
			if err != nil {
				return 0, err
			}
		}
		for _, email := range emails {
			obsCount, err := obs.CountCommits("repos-obs"+"/"+obsEntry.Repo, email)
			if err != nil {
				if err == obs.ErrNoChangesFileFound {
					util.PrintInfo("No .changes file found", util.PI_MILD_ERROR)
					break Loop_obs
				}
				util.PrintInfo(err.Error(), util.PI_ERROR) // TODO: return?
			}

			if obsCount != 0 {
				util.PrintInfoF("%s: %d changes", util.PI_RESULT, email, obsCount)
				sum += obsCount
			}
		}
	}
	return sum, nil
}
Beispiel #5
0
func printBinaryInfos(binary map[string]bool) {
	if binary["git"] == false {
		util.PrintInfo("git is not installed. git repositories will be skipped", util.PI_MILD_ERROR)
	}
	if binary["hg"] == false {
		util.PrintInfo("hg is not installed. Mercurial repositories will be skipped", util.PI_MILD_ERROR)
	}
	if binary["osc"] == false {
		util.PrintInfo("osc is not installed. osc repositories will be skipped", util.PI_MILD_ERROR)
	}
}
Beispiel #6
0
// Run will handle the functionallity.
func run(ctx *cli.Context) error {
	// Load specified json configuration file
	configPath := ctx.GlobalString("config")
	configuration, err := loadConfig(configPath)
	if err != nil {
		// if config cant be loaded because default one is used
		// (set in StringFlag) and is not available, then show the usage.
		if !ctx.IsSet("config") {
			cli.ShowAppHelp(ctx)
			return nil
		}
		return cli.NewExitError(err.Error(), 1)
	}

	// Get users template selection
	templateName := ctx.GlobalString("template")

	var templateData string

	// Get Template as templateData string
	templatesPath := os.Getenv(templatesFolderEnv)
	if templatesPath == "" {
		// Use asset
		data, err := Asset(filepath.Join(templateFolderName, templateName))
		if err != nil {
			return cli.NewExitError(err.Error(), 1)
		}
		templateData = string(data)
	} else {
		// Use template from user defined folder
		absoluteTemplatePath := filepath.Join(templatesPath, templateName)
		if !util.FileExists(absoluteTemplatePath) {
			var s string
			fmt.Sprintf(s, "Template file %s does not exist\n", absoluteTemplatePath)
			return cli.NewExitError(s, 1)
		}
		data, err := ioutil.ReadFile(absoluteTemplatePath)
		if err != nil {
			return cli.NewExitError(err.Error(), 1)
		}
		templateData = string(data)
	}

	gontrib.PullSources = !ctx.GlobalBool("no-pull")

	contributions, err := gontrib.ScanContributions(configuration)
	if err != nil {
		util.PrintInfo(err.Error(), util.PI_ERROR)
		return cli.NewExitError(err.Error(), 1)
	}

	outputPath := ctx.GlobalString("output")
	f, err := os.Create(outputPath)
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	defer f.Close()

	writer := bufio.NewWriter(f)
	fillTemplate(contributions, templateData, writer)
	if err := writer.Flush(); err != nil {
		return cli.NewExitError(err.Error(), 1)
	}

	util.PrintInfoF("\nReport saved in: %s", util.PI_INFO, outputPath)
	return nil
}