Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
report.go 3.43 KiB
package libyear

import (
	"context"
	"database/sql"
	"fmt"
	"log/slog"

	"dmd.tanna.dev/internal/libyear/db"
	"github.com/jedib0t/go-pretty/v6/table"
)

func Report(ctx context.Context, logger *slog.Logger, sqlDB *sql.DB, platform string, org string, repo string, owner string) (table.Writer, error) {
	if platform != "" && org != "" && repo != "" {
		return reportSingleRepo(ctx, logger, sqlDB, platform, org, repo)
	}

	return reportAllRepos(ctx, logger, sqlDB, platform, org, repo, owner)
}

func reportSingleRepo(ctx context.Context, logger *slog.Logger, sqlDB *sql.DB, platform, org, repo string) (table.Writer, error) {
	q := db.New(sqlDB)

	rows, err := q.RetrieveLibyearForSpecificRepo(ctx, db.RetrieveLibyearForSpecificRepoParams{
		Platform: platform,
		Org:      org,
		Repo:     repo,
	})

	if err != nil {
		return nil, fmt.Errorf("failed to list libyears for the specified repo (%s/%s/%s): %v", platform, org, repo, err)
	}

	if len(rows) == 0 {
		logger.Warn(fmt.Sprintf("No rows returned when querying Libyears for a specific repo (%s/%s/%s): might be implementation issue. Have you run `dmd db generate libyear`?", platform, org, repo))
		return nil, nil
	}

	total := 0.0
	owner := ""
	for _, row := range rows {
		total += row.Libyear
		if row.Owner.Valid {
			owner = row.Owner.String
		}
	}
	if owner != "" {
		owner = " (owned by " + owner + ") "
	}

	tw := table.NewWriter()
	tw.SetTitle("Libyear data for %s/%s/%s%s: %.2f Libyears", platform, org, repo, owner, total)
	tw.AppendHeader(table.Row{
		"Package Name",
		"Package Manager",
		"Current version (release date)",
		"Latest version version (release date)",
		"Libyears",
		"Owner",
	})

	for _, row := range rows {
		curr := row.Version
		if row.CurrentVersion.Valid {
			curr = row.CurrentVersion.String
		}

		if curr == row.LatestVersion {
			continue
		}

		curr += fmt.Sprintf(" (%s)", row.VersionReleaseDate)
		latest := fmt.Sprintf("%s (%s)", row.LatestVersion, row.LatestVersionReleaseDate)

		tw.AppendRow(table.Row{
			row.PackageName,
			row.PackageManager,
			curr,
			latest,
			fmt.Sprintf("%.2f", row.Libyear),
			row.Owner.String,
		})
	}

	if tw.Length() == 0 {
		logger.Debug(fmt.Sprintf("Skipping rendering of Libyears for a specific repo (%s/%s/%s): although %d rows were returned, none of them have been selected to render", platform, org, repo, len(rows)))
		return nil, nil
	}

	return tw, nil
}

func reportAllRepos(ctx context.Context, logger *slog.Logger, sqlDB *sql.DB, platform, org, repo, owner string) (table.Writer, error) {
	q := db.New(sqlDB)

	rows, err := q.RetrieveAllLibyears(ctx, db.NewRetrieveAllLibyearsParams(platform, org, repo, owner))
	if err != nil {
		return nil, fmt.Errorf("failed to list libyears: %v", err)
	}

	if len(rows) == 0 {
		logger.Warn("No rows returned when querying Libyears - have you run `dmd db generate libyear`?")
		return nil, nil
	}

	tw := table.NewWriter()
	tw.AppendHeader(table.Row{
		"Platform",
		"Organisation",
		"Repo",
		"Owner",
		"Libyears",
	})

	for _, row := range rows {
		if !row.TotalLibyears.Valid {
			logger.Warn(fmt.Sprintf("Skipping row that doesn't have a sum calculated - worth investigating. Row: %v", row))
			continue
		}

		if row.TotalLibyears.Float64 == 0 {
			logger.Debug(fmt.Sprintf("Skipping row that has a Libyear of 0. Row: %v", row))
			continue
		}

		tw.AppendRow(table.Row{
			row.Platform,
			row.Organisation,
			row.Repo,
			row.Owner.String,
			fmt.Sprintf("%.2f", row.TotalLibyears.Float64),
		})
	}

	return tw, nil
}