ThanksGOd


thanksGOd đŸ’– is a simple funny program to star your Go project dependencies on GitHub.

You can check source code here: https://github.com/maratgaliev/thanksgod

How it works

Let’s describe a Repository struct first.

package models

type Repository struct {
	Username string
	Name     string
	Domain   string
}

Next let’s try to parse Gopkg.lock file and get dependencies list. Godep uses toml file format to store data, so we can use toml parser to retrieve data.

package decoder

import (
	"fmt"
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/maratgaliev/thanksgod/models"
)

type tomlConfig struct {
	SolveMeta solveMeta `toml:"solve-meta"`
}

type solveMeta struct {
	InputImports []string `toml:"input-imports"`
}

func GetUsername(domain, username string) string {
	domainName := strings.Split(domain, ".")[0]
	if domain == "golang.org" {
		return domainName
	} else {
		return username
	}
}

func BuildRepo(url string) models.Repository {
	parsed := strings.Split(url, "/")
	domain, username, reponame := parsed[0], parsed[1], parsed[2]
	return models.Repository{Username: GetUsername(domain, username), Name: reponame, Domain: domain}
}

func GetReposList() []models.Repository {
	var config tomlConfig

	if _, err := toml.DecodeFile("Gopkg.lock", &config); err != nil {
		fmt.Println(err)
	}

	var repos []models.Repository
	data := config.SolveMeta.InputImports

	for _, element := range data {
		item := BuildRepo(element)
		repos = append(repos, item)
	}
	return repos
}

Currently only GitHub based repos are supported, each connector should implement Connector interface with Star function.

package core

type Connector interface {
	Star(username, reponame string)
}

So, let’s move to the next step and implement GitHub connector.

Here we are trying to authorize on GitHub with oauth2 package, and call a Star method from GitHub API wrapper.

package github

import (
	"context"
	"fmt"
	"os"

	"github.com/google/go-github/github"
	"golang.org/x/oauth2"
)

var client = GetClient()
var ctx = context.Background()

func Star(username, reponame string) {
	_, err := client.Activity.Star(ctx, username, reponame)

	if err != nil {
		fmt.Printf("Problem in getting repository information %v\n", err)
		os.Exit(1)
	}
}

func GetClient() *github.Client {
	ts := oauth2.StaticTokenSource(
		&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
	)
	tc := oauth2.NewClient(ctx, ts)
	client := github.NewClient(tc)
	return client
}

Last step - our main.go file, here we are getting list of repos and calling Star function on each repo.

package main

import (
	"github.com/kyokomi/emoji"
	"github.com/maratgaliev/thanksgod/connectors/github"
	"github.com/maratgaliev/thanksgod/decoder"
)

func main() {
	data := decoder.GetReposList()
	for _, element := range data {
		github.Star(element.Username, element.Name)
		emoji.Println(":sparkling_heart:", element.Name)
	}
}

Compile, update your PATH variable and run it from your godep based project root derectory.

thanks.png