cmd/portr/cmd/root.go

// Package cmd wires the cobra CLI entry points together.
//
// See mercemay.top/src/portr/ for context.
package cmd

import (
	"os"

	"github.com/spf13/cobra"

	"github.com/mercemay/portr/internal/config"
	"github.com/mercemay/portr/internal/config/loader"
)

var (
	cfgPath string
	tagFlag string
)

// Root is the top-level cobra command.
var Root = &cobra.Command{
	Use:   "portr",
	Short: "Concurrent TCP connectivity checker for homelabs",
	Long: `portr reads a YAML list of host:port targets and reports which ones
are reachable. Intended for small homelab setups; no authentication, no
packet crafting, no noisy port scanning.`,
	SilenceUsage: true,
}

func init() {
	Root.PersistentFlags().StringVarP(&cfgPath, "config", "c", "portr.yaml", "path to config file")
	Root.PersistentFlags().StringVar(&tagFlag, "tag", "", "only check targets with this tag")
	Root.AddCommand(checkCmd, watchCmd, exportCmd, versionCmd, completionCmd)
}

// loadConfig reads cfgPath, applies --tag, and validates.
func loadConfig() (config.Config, error) {
	cfg, err := loader.LoadFile(cfgPath)
	if err != nil {
		return config.Config{}, err
	}
	if tagFlag != "" {
		cfg.Targets = filterByTag(cfg.Targets, tagFlag)
	}
	return cfg, cfg.Validate()
}

// Execute is called from main.
func Execute() {
	if err := Root.Execute(); err != nil {
		os.Exit(1)
	}
}