15 Commits
Author SHA1 Message Date
EnumDev 0fd198d83e Added init system support 2024-08-22 21:54:14 +03:00
EnumDev 673f231c42 Added nushell support 2024-08-22 21:25:46 +03:00
CapCreeperGR e311649a48 Added PopOS ascii 2024-07-18 15:35:14 +03:00
CapCreeperGR 712fd78e21 Updated tide ascii 2024-07-18 14:12:45 +03:00
CapCreeperGR 7d83b0996d Improved GPU and added --time-taken flag 2024-07-17 20:11:30 +03:00
CapCreeperGR f3a016b674 Added Libc information 2024-07-17 13:18:31 +03:00
CapCreeperGR 0e2631d5b0 Added Artix ascii 2024-07-16 20:55:06 +03:00
EnumDev 153758b68e make should now be able to locate the go executable more easily 2024-07-01 13:16:37 +03:00
EnumDev ed45b739a5 Updated BPM package count fetching 2024-07-01 12:44:22 +03:00
EnumDev 8c380dbec4 Stormfetch can now read config files in the directory specified with the Makefile SYSCONFDIR variable 2024-06-20 21:23:50 +03:00
EnumDev 7c493dc9f9 Added filesystem label detection, btrfs subvolumes should now be grouped under one partition and the filesystem type will now be shown if enabled in config.yaml 2024-06-19 18:20:16 +03:00
EnumDev b8d7017299 Fixed bug where xbps packages would be counted on arch systems and not void systems 2024-06-18 07:49:19 +03:00
EnumDev cd08003752 Fixed emerge package count and added VoidLinux/xbps support 2024-06-17 19:41:20 +03:00
EnumDev c4c71fc49a Added hidden_gpus option in the config 2024-06-09 14:45:17 +03:00
EnumDev efdbe94193 Stormfetch will now list all GPUs if multiple of them are connected 2024-06-09 14:39:24 +03:00
12 changed files with 262 additions and 62 deletions
+4 -2
View File
@@ -8,12 +8,12 @@ ifeq ($(SYSCONFDIR),)
SYSCONFDIR := $(PREFIX)/etc SYSCONFDIR := $(PREFIX)/etc
endif endif
ifeq ($(GO),) ifeq ($(GO),)
GO := /usr/bin/go GO := $(shell type -a -P go | head -n 1)
endif endif
build: build:
mkdir -p build mkdir -p build
$(GO) build -ldflags "-w" -o build/stormfetch stormfetch $(GO) build -ldflags "-w -X 'main.systemConfigDir=$(SYSCONFDIR)'" -o build/stormfetch stormfetch
install: build/stormfetch config/ install: build/stormfetch config/
mkdir -p $(DESTDIR)$(BINDIR) mkdir -p $(DESTDIR)$(BINDIR)
@@ -34,3 +34,5 @@ run: build/stormfetch
clean: clean:
rm -r build/ rm -r build/
.PHONY: build
+1 -1
View File
@@ -20,7 +20,7 @@ Stormfetch is still in beta, so distro compatibility is limited. If you would li
- Download `make` from your package manager - Download `make` from your package manager
- Run the following command to compile the project - Run the following command to compile the project
``` ```
make make SYSCONFDIR=/etc
``` ```
- Run the following command to install stormfetch into your system. You may also append a DESTDIR variable at the end of this line if you wish to install in a different location - Run the following command to install stormfetch into your system. You may also append a DESTDIR variable at the end of this line if you wish to install in a different location
``` ```
+20
View File
@@ -0,0 +1,20 @@
#/45;27;45;7
${C1} 'o'
'ooo'
'ooxoo'
'ooxxxoo'
'oookkxxoo'
'oiioxkkxxoo'
':;:iiiioxxxoo'
`'.;::ioxxoo'
'-. `':;jiooo'
'oooio-.. `'i:io'
'ooooxxxxoio:,. `'-;'
'ooooxxxxxkkxoooIi:-. `'
'ooooxxxxxkkkkxoiiiiiji'
'ooooxxxxxkxxoiiii:'` .i'
'ooooxxxxxoi:::'` .;ioxo'
'ooooxooi::'` .:iiixkxxo'
'ooooi:'` `'';ioxxo'
'i:'` '':io'
'` `'
+21
View File
@@ -0,0 +1,21 @@
#/33;7;11;15
${C1} /////////////
/////////////////////
///////${C2}*767${C1}////////////////
//////${C2}7676767676*${C1}//////////////
/////${C2}76767${C1}//${C2}7676767${C1}//////////////
/////${C2}767676${C1}///${C2}*76767${C1}///////////////
///////${C2}767676${C1}///${C2}76767${C1}.///${C2}7676*${C1}///////
/////////${C2}767676${C1}//${C2}76767${C1}///${C2}767676${C1}////////
//////////${C2}76767676767${C1}////${C2}76767${C1}/////////
///////////${C2}76767676${C1}//////${C2}7676${C1}//////////
////////////,${C2}7676${C1},///////${C2}767${C1}///////////
/////////////*${C2}7676${C1}///////${C2}76${C1}////////////
///////////////${C2}7676${C1}////////////////////
///////////////${C2}7676${C1}///${C2}767${C1}////////////
//////////////////////${C2}'${C1}////////////
//////${C2}.7676767676767676767,${C1}//////
/////${C2}767676767676767676767${C1}/////
///////////////////////////
/////////////////////
/////////////
+15 -18
View File
@@ -1,18 +1,15 @@
#/6;10;5;12 #/27;39;5;12
${C1} @@@@@@@@@ ${C1}@@@@ ${C1}@@@${C2}*
@@@~~~~~~~~~@@ ${C1}@@${C2}~~~~${C1}@@ ${C1}@@${C2}~~~
@@~~~ ~~@ ${C1}@@${C2}~~ ${C2}~~${C1}@ ${C1}@@${C2}~~
@~~ @ ${C1}@@${C2}~~ ${C2}~${C1}@ ${C1}@@@${C2}~~
@~ @@@ @ ${C2}*${C1}@@${C2}~~ ${C1}@@@@ ${C2}~${C1}@@@@${C2}~~~ ${C1}@@@${C2}*
@@~ @ @@ ${C2}~~ ${C1}@@${C2}~~~~${C1}@@ ${C2}~~~~ ${C1}@@${C2}~~~
@@~~ @ ${C1}@@${C2}~~ ${C2}~~${C1}@ ${C1}@@${C2}~~
@@@~~ ~@@ @@@ ${C1}@@${C2}~~ ${C2}~${C1}@ ${C1}@@@${C2}~~
~~~ ~~@@@ @@@@~~~ ${C2}*${C1}@@${C2}~~ ${C1}@@@@ ${C2}~${C1}@@@@${C2}~~~ ${C1}@@@${C2}*
~~~@@@@~~~~ ${C2}~~ ${C1}@@${C2}~~~~${C1}@@ ${C2}~~~~ ${C1}@@${C2}~~~
@@@@ @@@@@@@ ~~~~ @@@@ ${C1}@@${C2}~~ ${C2}~~${C1}@ ${C1}@@${C2}~~
~~~~@@@@ @@~~~~~~~@@ @@@@ ${C1}@@${C2}~~ ${C2}~${C1}@ ${C1}@@@${C2}~~
~~~~@@@@~~ ~~@@@@~~~~ ${C2}*${C1}@@${C2}~~ ${C2}~${C1}@@@@${C2}~~~
@@@ ~~~~ @@@@@ ~~~~ @@@ ${C2}~~ ${C2}~~~~
~~~@@@@ @@@@~~~~~@@@@ @@@@~~~
~~~~@@@~~~~ ~~~~@@@~~~
~~~ ~~~
+19
View File
@@ -0,0 +1,19 @@
#/2;36;72;15
${C2}:::::----:::::
${C2}::----------------::=
${C2}:-------------------::
${C1} : ${C2}:::. ..:-------:
${C1} =*=. ${C2}.:-----:
${C1} =****- ${C2}:-----:
${C1}=*****- ${C2}:::::: :-----:
${C1}=****+ ${C2}:--------: :----:
${C1}+****- ${C2}.----------. :----:
${C1}+****- ${C2}.----------. :-----
${C1}=****+ ${C2}:--------: :----:
${C1}=*****- ${C2}:::::: :-----:
${C1} =*****- ${C2}:----:
${C1} =*****+: ${C2}:-:
${C1} =*******=:: ::=-. ${C2}.
${C1} ==*******************-
${C1} ===****************=-
${C1} ===+=****++===
+2
View File
@@ -3,3 +3,5 @@ fetch_script: auto
ansii_colors: [] ansii_colors: []
force_config_ansii: false force_config_ansii: false
dependency_warning: true dependency_warning: true
show_fs_type: true
hidden_gpus: []
+18 -4
View File
@@ -5,19 +5,33 @@ echo -e "${C3}Hostname: ${C4}$(cat /etc/hostname)"
echo -e "${C3}Kernel: ${C4}$(uname -s) $(uname -r)" echo -e "${C3}Kernel: ${C4}$(uname -s) $(uname -r)"
echo -e "${C3}Packages: ${C4}$(get_packages)" echo -e "${C3}Packages: ${C4}$(get_packages)"
echo -e "${C3}Shell: ${C4}${USER_SHELL}" echo -e "${C3}Shell: ${C4}${USER_SHELL}"
echo -e "${C3}Init: ${C4}${INIT_SYSTEM}"
echo -e "${C3}Libc: ${C4}${LIBC}"
if [ ! -z "$CPU_MODEL" ]; then echo -e "${C3}CPU: ${C4}${CPU_MODEL} (${CPU_THREADS} threads)"; fi if [ ! -z "$CPU_MODEL" ]; then echo -e "${C3}CPU: ${C4}${CPU_MODEL} (${CPU_THREADS} threads)"; fi
if [ ! -z "$GPU_MODEL" ]; then echo -e "${C3}GPU: ${C4}${GPU_MODEL}"; fi for i in $(seq ${CONNECTED_GPUS}); do
gpu="GPU$i"
echo -e "${C3}GPU: ${C4}${!gpu}"
done
if [ ! -z "$MEM_TOTAL" ] && [ ! -z "$MEM_USED" ]; then echo -e "${C3}Memory: ${C4}${MEM_USED} MiB / ${MEM_TOTAL} MiB"; fi if [ ! -z "$MEM_TOTAL" ] && [ ! -z "$MEM_USED" ]; then echo -e "${C3}Memory: ${C4}${MEM_USED} MiB / ${MEM_TOTAL} MiB"; fi
for i in $(seq ${MOUNTED_PARTITIONS}); do for i in $(seq ${MOUNTED_PARTITIONS}); do
device="PARTITION${i}_DEVICE" device="PARTITION${i}_DEVICE"
mountpoint="PARTITION${i}_MOUNTPOINT" mountpoint="PARTITION${i}_MOUNTPOINT"
label="PARTITION${i}_LABEL" label="PARTITION${i}_LABEL"
type="PARTITION${i}_TYPE"
total="PARTITION${i}_TOTAL_SIZE" total="PARTITION${i}_TOTAL_SIZE"
used="PARTITION${i}_USED_SIZE" used="PARTITION${i}_USED_SIZE"
if [ -z "${!label}" ]; then if [ -z "${!type}" ]; then
echo -e "${C3}Partition ${!mountpoint}: ${C4}${!used}/${!total}" if [ -z "${!label}" ]; then
echo -e "${C3}Partition ${!mountpoint}: ${C4}${!used}/${!total}"
else
echo -e "${C3}Partition ${!label}: ${C4}${!used}/${!total}"
fi
else else
echo -e "${C3}Partition ${!label}: ${C4}${!used}/${!total}" if [ -z "${!label}" ]; then
echo -e "${C3}Partition ${!mountpoint} (${!type}): ${C4}${!used}/${!total}"
else
echo -e "${C3}Partition ${!label} (${!type}): ${C4}${!used}/${!total}"
fi
fi fi
done done
if [ ! -z "$DISPLAY_PROTOCOL" ]; then if [ ! -z "$DISPLAY_PROTOCOL" ]; then
+5 -2
View File
@@ -20,11 +20,14 @@ get_packages() {
if command_exists rpm; then if command_exists rpm; then
ARRAY+=("$(rpm -qa | wc -l) (rpm)") ARRAY+=("$(rpm -qa | wc -l) (rpm)")
fi fi
if command_exists xbps-query; then
ARRAY+=("$(xbps-query -l | wc -l) (xbps)")
fi
if command_exists bpm; then if command_exists bpm; then
ARRAY+=("$(bpm list -n) (bpm)") ARRAY+=("$(bpm list -c) (bpm)")
fi fi
if command_exists emerge; then if command_exists emerge; then
ARRAY+=("$(ls -l /var/db/pkg/ | wc -l) (emerge)") ARRAY+=("$(ls -l /var/db/pkg/* | wc -l) (emerge)")
fi fi
if command_exists flatpak; then if command_exists flatpak; then
ARRAY+=("$(flatpak list | wc -l) (flatpak)") ARRAY+=("$(flatpak list | wc -l) (flatpak)")
+72 -22
View File
@@ -11,17 +11,24 @@ import (
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
"time"
) )
var systemConfigDir = "/etc/"
var configPath = "" var configPath = ""
var fetchScriptPath = "" var fetchScriptPath = ""
var TimeTaken = false
var config = StormfetchConfig{ var config = StormfetchConfig{
Ascii: "auto", Ascii: "auto",
FetchScript: "auto", FetchScript: "auto",
AnsiiColors: make([]int, 0), AnsiiColors: make([]int, 0),
ForceConfigAnsii: false, ForceConfigAnsii: false,
DependencyWarning: true, DependencyWarning: true,
ShowFSType: false,
HiddenGPUS: make([]int, 0),
} }
type StormfetchConfig struct { type StormfetchConfig struct {
@@ -31,6 +38,8 @@ type StormfetchConfig struct {
AnsiiColors []int `yaml:"ansii_colors"` AnsiiColors []int `yaml:"ansii_colors"`
ForceConfigAnsii bool `yaml:"force_config_ansii"` ForceConfigAnsii bool `yaml:"force_config_ansii"`
DependencyWarning bool `yaml:"dependency_warning"` DependencyWarning bool `yaml:"dependency_warning"`
ShowFSType bool `yaml:"show_fs_type"`
HiddenGPUS []int `yaml:"hidden_gpus"`
} }
func main() { func main() {
@@ -42,12 +51,12 @@ func main() {
func readConfig() { func readConfig() {
// Get home directory // Get home directory
configDir, _ := os.UserConfigDir() userConfigDir, _ := os.UserConfigDir()
// Find valid config directory // Find valid config directory
if _, err := os.Stat(path.Join(configDir, "stormfetch/config.yaml")); err == nil { if _, err := os.Stat(path.Join(userConfigDir, "stormfetch/config.yaml")); err == nil {
configPath = path.Join(configDir, "stormfetch/config.yaml") configPath = path.Join(userConfigDir, "stormfetch/config.yaml")
} else if _, err := os.Stat("/etc/stormfetch/config.yaml"); err == nil { } else if _, err := os.Stat(path.Join(systemConfigDir, "stormfetch/config.yaml")); err == nil {
configPath = "/etc/stormfetch/config.yaml" configPath = path.Join(systemConfigDir, "stormfetch/config.yaml")
} else { } else {
log.Fatalf("Config file not found: %s", err.Error()) log.Fatalf("Config file not found: %s", err.Error())
} }
@@ -70,18 +79,19 @@ func readConfig() {
log.Fatalf("Fetch script path points to a directory") log.Fatalf("Fetch script path points to a directory")
} }
} }
if _, err := os.Stat(path.Join(configDir, "stormfetch/fetch_script.sh")); err == nil { if _, err := os.Stat(path.Join(userConfigDir, "stormfetch/fetch_script.sh")); err == nil {
fetchScriptPath = path.Join(configDir, "stormfetch/fetch_script.sh") fetchScriptPath = path.Join(userConfigDir, "stormfetch/fetch_script.sh")
} else if _, err := os.Stat("/etc/stormfetch/fetch_script.sh"); err == nil { } else if _, err := os.Stat(path.Join(systemConfigDir, "stormfetch/fetch_script.sh")); err == nil {
fetchScriptPath = "/etc/stormfetch/fetch_script.sh" fetchScriptPath = path.Join(systemConfigDir, "stormfetch/fetch_script.sh")
} else { } else {
log.Fatalf("Fetch script file not found: %s", err.Error()) log.Fatalf("Fetch script file not found: %s", err.Error())
} }
} }
func readFlags() { func readFlags() {
flag.StringVar(&config.Ascii, "ascii", config.Ascii, "help message for flagname") flag.StringVar(&config.Ascii, "ascii", config.Ascii, "Set distro ascii")
flag.StringVar(&config.DistroName, "distro-name", config.DistroName, "help message for flagname") flag.StringVar(&config.DistroName, "distro-name", config.DistroName, "Set distro name")
flag.BoolVar(&TimeTaken, "time-taken", false, "Show time taken for fetched information")
flag.Parse() flag.Parse()
} }
@@ -105,19 +115,37 @@ func checkDependencies() {
} }
} }
func SetupFetchEnv() []string { func SetupFetchEnv(showTimeTaken bool) []string {
var env = make(map[string]string) var env = make(map[string]string)
env["DISTRO_LONG_NAME"] = getDistroInfo().LongName setVariable := func(key string, setter func() string) {
env["DISTRO_SHORT_NAME"] = getDistroInfo().ShortName start := time.Now().UnixMilli()
env["CPU_MODEL"] = getCPUName() env[key] = setter()
env["CPU_THREADS"] = strconv.Itoa(getCPUThreads()) end := time.Now().UnixMilli()
if showTimeTaken {
fmt.Println(fmt.Sprintf("Setting '%s' took %d milliseconds", key, end-start))
}
}
setVariable("DISTRO_LONG_NAME", func() string { return getDistroInfo().LongName })
setVariable("DISTRO_SHORT_NAME", func() string { return getDistroInfo().ShortName })
setVariable("CPU_MODEL", func() string { return getCPUName() })
setVariable("CPU_THREADS", func() string { return strconv.Itoa(getCPUThreads()) })
start := time.Now().UnixMilli()
memory := GetMemoryInfo() memory := GetMemoryInfo()
end := time.Now().UnixMilli()
if showTimeTaken {
fmt.Println(fmt.Sprintf("Setting '%s' took %d milliseconds", "MEM_*", end-start))
}
if memory != nil { if memory != nil {
env["MEM_TOTAL"] = strconv.Itoa(memory.MemTotal) env["MEM_TOTAL"] = strconv.Itoa(memory.MemTotal)
env["MEM_USED"] = strconv.Itoa(memory.MemTotal - memory.MemAvailable) env["MEM_USED"] = strconv.Itoa(memory.MemTotal - memory.MemAvailable)
env["MEM_FREE"] = strconv.Itoa(memory.MemAvailable) env["MEM_FREE"] = strconv.Itoa(memory.MemAvailable)
} }
start = time.Now().UnixMilli()
partitions := getMountedPartitions() partitions := getMountedPartitions()
end = time.Now().UnixMilli()
if showTimeTaken {
fmt.Println(fmt.Sprintf("Setting '%s' took %d milliseconds", "PARTITION_*", end-start))
}
if len(partitions) != 0 { if len(partitions) != 0 {
env["MOUNTED_PARTITIONS"] = strconv.Itoa(len(partitions)) env["MOUNTED_PARTITIONS"] = strconv.Itoa(len(partitions))
for i, part := range partitions { for i, part := range partitions {
@@ -126,23 +154,45 @@ func SetupFetchEnv() []string {
if part.Label != "" { if part.Label != "" {
env["PARTITION"+strconv.Itoa(i+1)+"_LABEL"] = part.Label env["PARTITION"+strconv.Itoa(i+1)+"_LABEL"] = part.Label
} }
if part.Type != "" && config.ShowFSType {
env["PARTITION"+strconv.Itoa(i+1)+"_TYPE"] = part.Type
}
env["PARTITION"+strconv.Itoa(i+1)+"_TOTAL_SIZE"] = FormatBytes(part.TotalSize) env["PARTITION"+strconv.Itoa(i+1)+"_TOTAL_SIZE"] = FormatBytes(part.TotalSize)
env["PARTITION"+strconv.Itoa(i+1)+"_USED_SIZE"] = FormatBytes(part.UsedSize) env["PARTITION"+strconv.Itoa(i+1)+"_USED_SIZE"] = FormatBytes(part.UsedSize)
env["PARTITION"+strconv.Itoa(i+1)+"_FREE_SIZE"] = FormatBytes(part.FreeSize) env["PARTITION"+strconv.Itoa(i+1)+"_FREE_SIZE"] = FormatBytes(part.FreeSize)
} }
} }
env["DE_WM"] = GetDEWM() setVariable("DE_WM", func() string { return GetDEWM() })
env["USER_SHELL"] = GetShell() setVariable("USER_SHELL", func() string { return GetShell() })
env["DISPLAY_PROTOCOL"] = GetDisplayProtocol() setVariable("DISPLAY_PROTOCOL", func() string { return GetDisplayProtocol() })
setVariable("LIBC", func() string { return GetLibc() })
setVariable("INIT_SYSTEM", func() string { return GetInitSystem() })
start = time.Now().UnixMilli()
monitors := getMonitorResolution() monitors := getMonitorResolution()
end = time.Now().UnixMilli()
if showTimeTaken {
fmt.Println(fmt.Sprintf("Setting '%s' took %d milliseconds", "MONITOR_*", end-start))
}
if len(monitors) != 0 { if len(monitors) != 0 {
env["CONNECTED_MONITORS"] = strconv.Itoa(len(monitors)) env["CONNECTED_MONITORS"] = strconv.Itoa(len(monitors))
for i, monitor := range monitors { for i, monitor := range monitors {
env["MONITOR"+strconv.Itoa(i+1)] = monitor env["MONITOR"+strconv.Itoa(i+1)] = monitor
} }
} }
if getGPUName() != "" { start = time.Now().UnixMilli()
env["GPU_MODEL"] = getGPUName() gpus := getGPUNames()
end = time.Now().UnixMilli()
if showTimeTaken {
fmt.Println(fmt.Sprintf("Setting '%s' took %d milliseconds", "GPU_*", end-start))
}
if len(gpus) != 0 {
env["CONNECTED_GPUS"] = strconv.Itoa(len(gpus))
for i, gpu := range gpus {
if gpu == "" {
continue
}
env["GPU"+strconv.Itoa(i+1)] = gpu
}
} }
var ret = make([]string, len(env)) var ret = make([]string, len(env))
@@ -201,7 +251,7 @@ func runStormfetch() {
cmd := exec.Command("/bin/bash", fetchScriptPath) cmd := exec.Command("/bin/bash", fetchScriptPath)
cmd.Dir = path.Dir(fetchScriptPath) cmd.Dir = path.Dir(fetchScriptPath)
cmd.Env = os.Environ() cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, SetupFetchEnv()...) cmd.Env = append(cmd.Env, SetupFetchEnv(TimeTaken)...)
cmd.Env = append(cmd.Env, "C0=\033[0m") cmd.Env = append(cmd.Env, "C0=\033[0m")
for key, value := range colorMap { for key, value := range colorMap {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", key, value)) cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", key, value))
Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 121 KiB

+84 -12
View File
@@ -119,22 +119,21 @@ func getCPUThreads() int {
return int(cpu.TotalThreads) return int(cpu.TotalThreads)
} }
func getGPUName() string { func getGPUNames() []string {
null, _ := os.Open(os.DevNull) var ret []string
serr := os.Stderr cmd := exec.Command("/bin/bash", "-c", "lspci -v -m | grep 'VGA' -A6 | grep '^Device:' | sed 's/^Device://' | awk '{$1=$1};1'")
os.Stderr = null bytes, err := cmd.Output()
gpu, err := ghw.GPU()
defer null.Close()
os.Stderr = serr
if err != nil { if err != nil {
return "" return nil
} }
for _, graphics := range gpu.GraphicsCards { for _, name := range strings.Split(string(bytes), "\n") {
if graphics.DeviceInfo != nil { name = strings.TrimSpace(name)
return graphics.DeviceInfo.Product.Name if name == "" {
continue
} }
ret = append(ret, name)
} }
return "" return ret
} }
type Memory struct { type Memory struct {
@@ -227,6 +226,8 @@ func GetShell() string {
return "Zsh " + runCommand("$SHELL --version | awk '{print $2}'") return "Zsh " + runCommand("$SHELL --version | awk '{print $2}'")
case "fish": case "fish":
return "Fish " + runCommand("$SHELL --version | awk '{print $3}'") return "Fish " + runCommand("$SHELL --version | awk '{print $3}'")
case "nu":
return "Nushell " + runCommand("$SHELL --version")
default: default:
return "Unknown" return "Unknown"
} }
@@ -315,6 +316,7 @@ type partition struct {
Device string Device string
MountPoint string MountPoint string
Label string Label string
Type string
TotalSize uint64 TotalSize uint64
UsedSize uint64 UsedSize uint64
FreeSize uint64 FreeSize uint64
@@ -324,6 +326,10 @@ func getMountedPartitions() []partition {
mounts, err := mountinfo.GetMounts(func(info *mountinfo.Info) (skip, stop bool) { mounts, err := mountinfo.GetMounts(func(info *mountinfo.Info) (skip, stop bool) {
return !strings.HasPrefix(info.Source, "/dev/"), false return !strings.HasPrefix(info.Source, "/dev/"), false
}) })
fslabels, err := os.ReadDir("/dev/disk/by-label")
if err != nil && !os.IsNotExist(err) {
return nil
}
partlabels, err := os.ReadDir("/dev/disk/by-partlabel") partlabels, err := os.ReadDir("/dev/disk/by-partlabel")
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
return nil return nil
@@ -336,16 +342,33 @@ func getMountedPartitions() []partition {
} }
labels[link] = entry.Name() labels[link] = entry.Name()
} }
for _, entry := range fslabels {
link, err := filepath.EvalSymlinks(filepath.Join("/dev/disk/by-label/", entry.Name()))
if err != nil {
continue
}
labels[link] = entry.Name()
}
var partitions []partition var partitions []partition
for _, entry := range mounts { for _, entry := range mounts {
p := partition{ p := partition{
entry.Source, entry.Source,
entry.Mountpoint, entry.Mountpoint,
"", "",
entry.FSType,
0, 0,
0, 0,
0, 0,
} }
skip := false
for _, part := range partitions {
if part.Device == p.Device {
skip = true
}
}
if skip {
continue
}
if value, ok := labels[entry.Source]; ok { if value, ok := labels[entry.Source]; ok {
p.Label = value p.Label = value
} }
@@ -368,6 +391,55 @@ func getMountedPartitions() []partition {
return partitions return partitions
} }
func GetInitSystem() string {
runCommand := func(command string) string {
cmd := exec.Command("/bin/bash", "-c", command)
workdir, err := os.Getwd()
if err != nil {
return ""
}
cmd.Dir = workdir
cmd.Env = os.Environ()
out, err := cmd.Output()
if err != nil {
return ""
}
return strings.TrimSpace(string(out))
}
link, err := os.Readlink("/sbin/init")
if err != nil {
return "Unknown"
}
if path.Base(link) == "systemd" {
return "Systemd " + runCommand("systemctl --version | head -1 | awk '{print $2}'")
} else if path.Base(link) == "openrc-init" {
return "OpenRC " + runCommand("openrc --version | awk '{print $3}'")
} else if path.Base(link) == "runit-init" {
return "Runit"
} else {
return "Unknown"
}
}
func GetLibc() string {
cmd := exec.Command("/bin/bash", "-c", "find /usr/lib64/ -maxdepth 1 -name 'ld-*' | grep musl")
if err := cmd.Run(); err != nil {
cmd = exec.Command("/bin/bash", "-c", "ldd --version | head -1 | cut -d' ' -f4")
bytes, err := cmd.Output()
if err != nil {
return "Glibc"
}
return "Glibc " + strings.TrimSpace(string(bytes))
}
cmd = exec.Command("/bin/bash", "-c", "ldd 2>&1 | grep 'Version' | cut -d' ' -f2")
bytes, err := cmd.Output()
if err != nil {
return "Musl"
}
return "Musl " + strings.TrimSpace(string(bytes))
}
func FormatBytes(bytes uint64) string { func FormatBytes(bytes uint64) string {
var suffixes [6]string var suffixes [6]string
suffixes[0] = "B" suffixes[0] = "B"