168 lines
4.8 KiB
Go
168 lines
4.8 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.gostacks.org/iwasforcedtobehere/fastestmirror/internal/distro"
|
|
"git.gostacks.org/iwasforcedtobehere/fastestmirror/internal/mirror"
|
|
"github.com/fatih/color"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var (
|
|
verbose bool
|
|
timeout int
|
|
topCount int
|
|
)
|
|
|
|
var findCmd = &cobra.Command{
|
|
Use: "find",
|
|
Short: "Find the fastest mirrors for your distribution",
|
|
Long: `Find and test mirrors to determine which ones will make your package
|
|
manager fly faster than a caffinated developer on Monday morning.
|
|
|
|
This command will:
|
|
• Auto-detect your Linux distribution
|
|
• Test multiple mirrors concurrently
|
|
• Rank them by speed and reliability
|
|
• Show you the results in glorious color`,
|
|
RunE: runFind,
|
|
}
|
|
|
|
func runFind(cmd *cobra.Command, args []string) error {
|
|
// Detect distribution
|
|
fmt.Println(color.CyanString("Detecting your Linux distribution..."))
|
|
|
|
distroInfo, err := distro.DetectDistribution()
|
|
if err != nil {
|
|
return fmt.Errorf("fuck me, couldn't detect your distro: %w", err)
|
|
}
|
|
|
|
fmt.Printf("Found: %s\n", color.GreenString(distroInfo.String()))
|
|
|
|
if !distroInfo.IsSupported() {
|
|
return fmt.Errorf("sorry, %s isn't supported yet - but hey, you're using something exotic! 🦄", distroInfo.ID)
|
|
}
|
|
|
|
// Get mirrors for this distribution family
|
|
fmt.Printf("Loading mirrors for %s family...\n", color.YellowString(distroInfo.Family))
|
|
|
|
mirrorList := mirror.NewMirrorList(distroInfo.Family)
|
|
|
|
// Load mirrors from official sources
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second*5)
|
|
defer cancel()
|
|
|
|
err = mirrorList.LoadMirrors(ctx, distroInfo.Family)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to load mirrors: %w", err)
|
|
}
|
|
|
|
fmt.Printf("Testing mirrors (timeout: %ds each)...\n", timeout)
|
|
|
|
err = mirrorList.TestMirrors(ctx, time.Duration(timeout)*time.Second)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("mirror testing failed: %w", err)
|
|
}
|
|
|
|
// Display results
|
|
fmt.Println("\n" + color.GreenString("Testing complete! Here are your results:"))
|
|
fmt.Println()
|
|
|
|
topMirrors := mirrorList.GetTop(topCount)
|
|
allMirrors := mirrorList.GetAll()
|
|
|
|
// Show summary of all tests
|
|
successCount := 0
|
|
for _, mirror := range allMirrors {
|
|
if mirror.Error == nil {
|
|
successCount++
|
|
}
|
|
}
|
|
|
|
if verbose {
|
|
fmt.Printf("Test Summary: %d/%d mirrors responded successfully\n", successCount, len(allMirrors))
|
|
fmt.Println()
|
|
}
|
|
if len(topMirrors) == 0 {
|
|
fmt.Println(color.RedString("No working mirrors found. Your internet might be fucked, or all mirrors are down."))
|
|
return nil
|
|
}
|
|
|
|
// Display top mirrors in a nice table format
|
|
fmt.Printf("%-4s %-50s %-12s %-10s %-8s\n",
|
|
color.CyanString("Rank"),
|
|
color.CyanString("Mirror URL"),
|
|
color.CyanString("Latency"),
|
|
color.CyanString("Speed"),
|
|
color.CyanString("Score"))
|
|
fmt.Println(color.HiBlackString("─────────────────────────────────────────────────────────────────────────────────"))
|
|
|
|
for i, m := range topMirrors {
|
|
rank := color.YellowString("#%d", i+1)
|
|
url := m.URL
|
|
if len(url) > 48 {
|
|
url = url[:45] + "..."
|
|
}
|
|
|
|
latencyStr := color.GreenString("%dms", m.Latency.Milliseconds())
|
|
if m.Latency > 500*time.Millisecond {
|
|
latencyStr = color.RedString("%dms", m.Latency.Milliseconds())
|
|
} else if m.Latency > 200*time.Millisecond {
|
|
latencyStr = color.YellowString("%dms", m.Latency.Milliseconds())
|
|
}
|
|
|
|
speedStr := color.GreenString("%.1f MB/s", m.Speed)
|
|
if m.Speed < 1.0 {
|
|
speedStr = color.RedString("%.1f MB/s", m.Speed)
|
|
} else if m.Speed < 5.0 {
|
|
speedStr = color.YellowString("%.1f MB/s", m.Speed)
|
|
}
|
|
|
|
scoreStr := color.CyanString("%.1f", m.Score)
|
|
|
|
fmt.Printf("%-4s %-50s %-12s %-10s %-8s\n",
|
|
rank, url, latencyStr, speedStr, scoreStr)
|
|
}
|
|
|
|
fmt.Println()
|
|
best := mirrorList.GetBest()
|
|
if best != nil {
|
|
fmt.Printf("Winner: %s\n", color.GreenString(best.URL))
|
|
fmt.Printf("This bad boy clocks in at %.1f MB/s with %dms latency\n",
|
|
best.Speed, best.Latency.Milliseconds())
|
|
}
|
|
|
|
// Show failed mirror count in verbose mode (no detailed errors)
|
|
if verbose {
|
|
failedCount := 0
|
|
for _, m := range allMirrors {
|
|
if m.Error != nil {
|
|
failedCount++
|
|
}
|
|
}
|
|
|
|
if failedCount > 0 {
|
|
fmt.Println()
|
|
fmt.Printf("Failed mirrors: %d (errors hidden for cleaner output)\n", failedCount)
|
|
}
|
|
}
|
|
|
|
fmt.Println()
|
|
fmt.Printf("To apply the fastest mirror, run: %s\n",
|
|
color.CyanString("fastestmirror apply"))
|
|
|
|
return nil
|
|
}
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(findCmd)
|
|
|
|
findCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Show verbose output")
|
|
findCmd.Flags().IntVarP(&timeout, "timeout", "t", 10, "Timeout for each mirror test in seconds")
|
|
findCmd.Flags().IntVarP(&topCount, "top", "n", 5, "Number of top mirrors to display")
|
|
}
|