Files
stormfetch/src/main.go
T

157 lines
3.7 KiB
Go

package main
import (
"flag"
"fmt"
"strconv"
"strings"
"time"
"unicode"
)
// Build-time variables
var StormfetchVersion = "dev"
var SystemConfigDir = "/etc/"
// Flag variables
var ShowVersion = false
var ShowModuleTimeTaken = false
var configPath = ""
func main() {
readConfig()
parseFlags()
initializeModuleMap()
run()
}
func parseFlags() {
flag.BoolVar(&ShowVersion, "version", false, "Show Stormfetch version")
flag.BoolVar(&ShowModuleTimeTaken, "time-taken", false, "Show time taken to execute each module")
flag.StringVar(&config.Ascii, "ascii", config.Ascii, "Set distro ascii")
flag.StringVar(&config.DistroName, "distro-name", config.DistroName, "Set distro name")
flag.Parse()
}
func run() {
if ShowVersion {
fmt.Printf("Stormfetch version %s\n", StormfetchVersion)
return
}
// Fetch ascii art and remove header
asciiArt := GetDistroAsciiArt()
asciiArtHeader := ""
if strings.HasPrefix(asciiArt, "#/") {
asciiArtHeader = strings.SplitN(asciiArt, "\n", 2)[0]
asciiArt = strings.SplitN(asciiArt, "\n", 2)[1]
}
asciiArtNoColor := asciiArt
// Rewrite last color code to the start of the next line
lastColor := "0"
for i := 1; i < len(asciiArt); i++ {
rune := rune(asciiArt[i])
if unicode.IsDigit(rune) && asciiArt[i-1] == '%' {
lastColor = string(rune)
}
if rune == '\n' {
asciiArt = asciiArt[:i+1] + "%" + lastColor + asciiArt[i+1:]
}
}
// Setup color map and replace colors in ascii art
colorMap := setupColorMap(asciiArtHeader)
for key, value := range colorMap {
asciiArt = strings.ReplaceAll(asciiArt, "%"+strconv.Itoa(key), value)
asciiArtNoColor = strings.ReplaceAll(asciiArtNoColor, "%"+strconv.Itoa(key), "")
}
// Execute modules in order
modulesText := make([]string, 0)
for _, moduleConfig := range config.Modules {
module, ok := Modules[moduleConfig.Name]
if !ok {
continue
}
// Set module config options
if moduleConfig.Format != "" {
module.Format = moduleConfig.Format
}
if moduleConfig.Data != nil {
module.Data = moduleConfig.Data
}
// Execute module
start := time.Now().UnixMilli()
text := module.Execute(module)
end := time.Now().UnixMilli()
// Show time taken
if ShowModuleTimeTaken {
fmt.Printf("Module '%s' took %d milliseconds\n", module.Name, end-start)
}
// Replace colors in returned string
textNoColor := text
for key, value := range colorMap {
text = strings.ReplaceAll(text, "%"+strconv.Itoa(key), value)
textNoColor = strings.ReplaceAll(textNoColor, "%"+strconv.Itoa(key), value)
}
// Continue if text length is 0
if len(textNoColor) == 0 {
continue
}
// Add text to slice
for _, line := range strings.Split(strings.TrimSpace(text), "\n") {
modulesText = append(modulesText, line)
}
}
// Get longest line in ascii art
maxWidth := 0
for _, line := range strings.Split(asciiArtNoColor, "\n") {
if len(line) > maxWidth {
maxWidth = len(line)
}
}
// Split ascii art into each line
asciiArtSplit := strings.Split(asciiArt, "\n")
asciiArtNoColorSplit := strings.Split(asciiArtNoColor, "\n")
// Get amount of lines to print
lineCount := max(len(asciiArtSplit), len(modulesText))
// Combine ascii art and module text
final := strings.Builder{}
for i := range lineCount {
// Write ascii art
currentLineLength := 0
if i < len(asciiArtSplit) {
final.WriteString(asciiArtSplit[i])
currentLineLength += len(asciiArtNoColorSplit[i])
}
// Write blank space between ascii art and module text
for i := currentLineLength; i < maxWidth+3; i++ {
final.WriteString(" ")
}
// Write module text
if i < len(modulesText) {
final.WriteString(modulesText[i])
}
final.WriteString("\n")
}
fmt.Println(strings.TrimRight(final.String(), "\n") + "\033[0m")
}