BharatKalluri
1/31/2018 - 6:25 PM

LicenseR - A recursive license checker for R packages

LicenseR - A recursive license checker for R packages

package main

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

import "github.com/PuerkitoBio/goquery"
import "github.com/fatih/color"

var inititalList []string
var finalList []string

func main() {
	fmt.Println("R Package to analyse: ", os.Args[1])
	fmt.Println("Please wait to retrive data from CRAN.....")
	aggregateDeps(os.Args[1])
	for len(inititalList) != 0 {
		temp := inititalList[0]
		aggregateDeps(temp)
		if !stringInSlice(temp, finalList) {
			finalList = append(finalList, temp)
		}
		inititalList = RemoveIndex(inititalList, 0)
	}
	fmt.Println("All deps after recursion are==>")
	fmt.Println(finalList)
	fmt.Println("_________________________________________________________________________________________________________________________________")
	for _, pkg := range finalList {
		printLicense(pkg)
		fmt.Println("______________________________________________________________________________________________________________________________")
	}
}

func stringInSlice(a string, list []string) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}

func RemoveIndex(s []string, index int) []string {
	return append(s[:index], s[index+1:]...)
}

func aggregateDeps(pkgName string) {
	url := "https://cran.r-project.org/web/packages/" + pkgName
	doc, err := goquery.NewDocument(url)
	checkErr(err)
	// Get the first set of deps
	for i := 0; i <= 10; i++ {
		rowOne := doc.Find("body > table:nth-child(3) > tbody:nth-child(1) > tr:nth-child(" + strconv.Itoa(i) + ") > td:nth-child(1)")
		if rowOne.Text() == "Imports:" {
			rowTwo := doc.Find("body > table:nth-child(3) > tbody:nth-child(1) > tr:nth-child(" + strconv.Itoa(i) + ") > td:nth-child(2)")
			rowTwo.Find("a").Each(func(index int, item *goquery.Selection) {
				inititalList = append(inititalList, item.Text())
			})
		}
	}
}

func printLicense(pkgName string) {
	// Print package name here
	url := "https://cran.r-project.org/web/packages/" + pkgName
	fmt.Println("License of ==>", pkgName, " at ", url)

	// Print License here
	doc, err := goquery.NewDocument(url)
	checkErr(err)
	// Append all tr elem to an array
	for i := 0; i <= 10; i++ {
		rowOne := doc.Find("body > table:nth-child(3) > tbody:nth-child(1) > tr:nth-child(" + strconv.Itoa(i) + ") > td:nth-child(1)")
		if rowOne.Text() == "License:" {
			License := doc.Find("body > table:nth-child(3) > tbody:nth-child(1) > tr:nth-child(" + strconv.Itoa(i) + ") > td:nth-child(2)")
			if strings.Contains(License.Text(), "MIT") || strings.Contains(License.Text(), "GPL-3") {
				color.Blue(License.Text())
			} else {
				color.Red(License.Text())
			}
		}
	}
	// Get the elem with imports and store the next elem in global array
}

func checkErr(err error) {
	if err != nil {
		log.Fatal(err)
	}
}