Skip to content

Commit

Permalink
use go's internal flag library to reduce binary size
Browse files Browse the repository at this point in the history
  • Loading branch information
Mic92 committed Sep 24, 2024
1 parent 5aee6f2 commit 5616ab6
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 123 deletions.
180 changes: 77 additions & 103 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,141 +2,115 @@ package cmd

import (
"encoding/json"
"flag"
"fmt"
"log/slog"
"log"
"os"
"slices"
"strings"

"github.com/numtide/nixos-facter/pkg/hwinfo"

"github.com/numtide/nixos-facter/pkg/facter"

"github.com/spf13/cobra"
"github.com/numtide/nixos-facter/pkg/hwinfo"
)

var (
cfgFile string
outputPath string
logLevel string
hardwareFeatures []string

scanner = facter.Scanner{}
)

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "nixos-facter",
Short: "Hardware report generator",
// todo Long description
// todo add Long description
RunE: func(cmd *cobra.Command, args []string) error {
// check the effective user id is 0 e.g. root
if os.Geteuid() != 0 {
cmd.SilenceUsage = true
return fmt.Errorf("you must run this program as root")
}
const usage = `nixos-facter [flags]
Hardware report generator
// convert the hardware features into probe features
for _, str := range hardwareFeatures {
probe, err := hwinfo.ProbeFeatureString(str)
if err != nil {
return fmt.Errorf("invalid hardware feature: %w", err)
}
scanner.Features = append(scanner.Features, probe)
}
Usage:
nixos-facter [flags]
// set the log level
if logLevel != "" {
if logLevel == "debug" {
slog.SetLogLoggerLevel(slog.LevelDebug)
} else if logLevel == "info" {
slog.SetLogLoggerLevel(slog.LevelInfo)
} else if logLevel == "warn" {
slog.SetLogLoggerLevel(slog.LevelWarn)
} else if logLevel == "error" {
slog.SetLogLoggerLevel(slog.LevelError)
} else {
return fmt.Errorf("invalid log level: %s", logLevel)
}
}
Flags:
-e, --ephemeral capture all ephemeral properties e.g. swap, filesystems and so on
-f, --hardware strings Hardware items to probe. Possible values are memory,pci,isapnp,net,floppy,misc,misc_serial,misc_par,misc_floppy,serial,cpu,bios,monitor,mouse,scsi,usb,usb_mods,adb,modem,modem_usb,parallel,parallel_lp,parallel_zip,isa,isa_isdn,isdn,kbd,prom,sbus,braille,braille_alva,braille_fhp,braille_ht,ignx11,sys,bios_vbe,isapnp_old,isapnp_new,isapnp_mod,braille_baum,manual,fb,veth,pppoe,scan,pcmcia,fork,parallel_imm,s390,cpuemu,sysfs,s390disks,udev,block,block_cdrom,block_part,edd,edd_mod,bios_ddc,bios_fb,bios_mode,input,block_mods,bios_vesa,cpuemu_debug,scsi_noserial,wlan,bios_crc,hal,bios_vram,bios_acpi,bios_ddc_ports,modules_pata,net_eeprom,x86emu,max,lxrc,all,, (default [memory,pci,net,serial,cpu,bios,monitor,scsi,usb,prom,sbus,sys,sysfs,udev,block,wlan])
-h, --help help for nixos-facter
-o, --output string path to write the report
-s, --swap capture swap entries
report, err := scanner.Scan()
if err != nil {
return err
}
`

bytes, err := json.MarshalIndent(report, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal report to json: %w", err)
}
func init() {
// Define flags
flag.StringVar(&outputPath, "output", "", "path to write the report")
flag.BoolVar(&scanner.Swap, "swap", false, "capture swap entries")
flag.BoolVar(&scanner.Ephemeral, "ephemeral", false, "capture all ephemeral properties e.g. swap, filesystems and so on")
flag.StringVar(&logLevel, "log-level", "info", "log level")

defaultFeatures := []string{
"memory", "pci", "net", "serial", "cpu", "bios", "monitor", "scsi", "usb", "prom", "sbus", "sys", "sysfs",
"udev", "block", "wlan",
}

// if a file path is provided write the report to it, otherwise output the report on stdout
if outputPath == "" {
if _, err = os.Stdout.Write(bytes); err != nil {
return fmt.Errorf("failed to write report to stdout: %w", err)
}
fmt.Println()
} else if err = os.WriteFile(outputPath, bytes, 0o644); err != nil {
return fmt.Errorf("failed to write report to output path: %w", err)
probeFeatures := hwinfo.ProbeFeatureStrings()
filteredFeatures := []string{}
for _, feature := range probeFeatures {
if feature != "default" && feature != "int" {
filteredFeatures = append(filteredFeatures, feature)
}
}

hardwareFeatures = defaultFeatures
flag.Func("hardware", fmt.Sprintf("Hardware items to probe. Possible values are %s", strings.Join(filteredFeatures, ",")), func(flagValue string) error {
hardwareFeatures = strings.Split(flagValue, ",")
return nil
},
})

// Custom usage function
flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s\n", usage) }
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}
flag.Parse()

func init() {
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.s
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.nixos-facter.yaml)")
// Check if the effective user id is 0 e.g. root
if os.Geteuid() != 0 {
log.Fatalf("you must run this program as root")
}

// Cobra also supports local flags, which will only run when this action is called directly.
f := rootCmd.Flags()
f.StringVarP(&outputPath, "output", "o", "", "path to write the report")
// Convert the hardware features into probe features
for _, str := range hardwareFeatures {
probe, err := hwinfo.ProbeFeatureString(str)
if err != nil {
log.Fatalf("invalid hardware feature: %v", err)
}
scanner.Features = append(scanner.Features, probe)
}

// Options for optional ephemeral system properties.
f.BoolVarP(&scanner.Swap, "swap", "s", false, "capture swap entries")
f.BoolVarP(&scanner.Ephemeral, "ephemeral", "e", false, "capture all ephemeral properties e.g. swap, filesystems and so on")
f.StringVarP(&logLevel, "log-level", "l", "info", "log level")
// Set the log level
switch logLevel {
case "debug":
log.SetFlags(log.LstdFlags | log.Lshortfile)
case "info":
log.SetFlags(log.LstdFlags)
case "warn", "error":
log.SetFlags(0)
default:
log.Fatalf("invalid log level: %s", logLevel)
}

// We currently support all probe features at a high level as they share some generic information,
// but we do not have mappings for all of their detail sections.
// These will be added on a priority / need basis.
report, err := scanner.Scan()
if err != nil {
log.Fatalf("failed to scan: %v", err)
}

defaultFeatures := []string{
"memory", "pci", "net", "serial", "cpu", "bios", "monitor", "scsi", "usb", "prom", "sbus", "sys", "sysfs",
"udev", "block", "wlan",
bytes, err := json.MarshalIndent(report, "", " ")
if err != nil {
log.Fatalf("failed to marshal report to json: %v", err)
}

// we strip default and int from the feature list
probeFeatures := hwinfo.ProbeFeatureStrings()
slices.DeleteFunc(probeFeatures, func(str string) bool {
switch str {
case "default", "int":
return true
default:
return false
// If a file path is provided write the report to it, otherwise output the report on stdout
if outputPath == "" {
if _, err = os.Stdout.Write(bytes); err != nil {
log.Fatalf("failed to write report to stdout: %v", err)
}
})

f.StringSliceVarP(
&hardwareFeatures,
"hardware",
"f",
defaultFeatures,
fmt.Sprintf(
"Hardware items to probe. Possible values are %s",
strings.Join(probeFeatures, ","),
),
)
fmt.Println()
} else if err = os.WriteFile(outputPath, bytes, 0o644); err != nil {
log.Fatalf("failed to write report to output path: %v", err)
}
}
3 changes: 0 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ go 1.22.3

require (
github.com/klauspost/cpuid/v2 v2.2.9-0.20240805145549-92d5326f011e
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
)

require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.22.0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
8 changes: 0 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/klauspost/cpuid/v2 v2.2.9-0.20240805145549-92d5326f011e h1:XLeT7xVis8xyC0F4CqQ2fAcuBar61PMI7GhrUEBBKas=
github.com/klauspost/cpuid/v2 v2.2.9-0.20240805145549-92d5326f011e/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
Expand All @@ -15,11 +12,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
Expand Down
9 changes: 0 additions & 9 deletions nix/packages/nixos-facter/gomod2nix.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ schema = 3
[mod."github.com/davecgh/go-spew"]
version = "v1.1.2-0.20180830191138-d8f796af33cc"
hash = "sha256-fV9oI51xjHdOmEx6+dlq7Ku2Ag+m/bmbzPo6A4Y74qc="
[mod."github.com/inconshreveable/mousetrap"]
version = "v1.1.0"
hash = "sha256-XWlYH0c8IcxAwQTnIi6WYqq44nOKUylSWxWO/vi+8pE="
[mod."github.com/klauspost/cpuid/v2"]
version = "v2.2.9-0.20240805145549-92d5326f011e"
hash = "sha256-yCZS40L97G7WZHhy/A6I8ArEkyHi86DGAW43SziYPek="
Expand All @@ -16,12 +13,6 @@ schema = 3
[mod."github.com/pmezard/go-difflib"]
version = "v1.0.1-0.20181226105442-5d4384ee4fb2"
hash = "sha256-XA4Oj1gdmdV/F/+8kMI+DBxKPthZ768hbKsO3d9Gx90="
[mod."github.com/spf13/cobra"]
version = "v1.8.1"
hash = "sha256-yDF6yAHycV1IZOrt3/hofR+QINe+B2yqkcIaVov3Ky8="
[mod."github.com/spf13/pflag"]
version = "v1.0.5"
hash = "sha256-w9LLYzxxP74WHT4ouBspH/iQZXjuAh2WQCHsuvyEjAw="
[mod."github.com/stretchr/testify"]
version = "v1.9.0"
hash = "sha256-uUp/On+1nK+lARkTVtb5RxlW15zxtw2kaAFuIASA+J0="
Expand Down

0 comments on commit 5616ab6

Please sign in to comment.