Fix golangci-lint issues: resolve range copy, naming, and whitespace violations

- Fix range copy issues in cmd_network.go (use indexing instead of copying 168-byte structs)
- Rename DiscoveryService to Service to avoid package name stuttering
- Update all references to use new Service constructor names
- Apply automatic whitespace fixes using golangci-lint --fix
- Reduce linting issues from 32 to 7 (only cyclomatic complexity remains)

Remaining issues are architectural complexity violations that require manual refactoring.
This commit is contained in:
Tobias Gesellchen
2026-01-10 00:02:59 +01:00
parent 433368788b
commit 62a67818d2
15 changed files with 149 additions and 45 deletions
+6
View File
@@ -62,6 +62,7 @@ func setBalance(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Balance level set to %d", level))
return nil
}
@@ -85,6 +86,7 @@ func balanceLeft(c *cli.Context) error {
}
newLevel := currentBalance.ActualBalance - amount
err = client.SetBalanceSafe(newLevel)
if err != nil {
PrintError(fmt.Sprintf("Failed to shift balance left: %v", err))
@@ -92,6 +94,7 @@ func balanceLeft(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Balance shifted from %d to %d (left)", currentBalance.ActualBalance, newLevel))
return nil
}
@@ -115,6 +118,7 @@ func balanceRight(c *cli.Context) error {
}
newLevel := currentBalance.ActualBalance + amount
err = client.SetBalanceSafe(newLevel)
if err != nil {
PrintError(fmt.Sprintf("Failed to shift balance right: %v", err))
@@ -122,6 +126,7 @@ func balanceRight(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Balance shifted from %d to %d (right)", currentBalance.ActualBalance, newLevel))
return nil
}
@@ -143,5 +148,6 @@ func balanceCenter(c *cli.Context) error {
}
PrintSuccess("Balance centered")
return nil
}
+5
View File
@@ -51,6 +51,7 @@ func setBass(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Bass level set to %d", level))
return nil
}
@@ -74,6 +75,7 @@ func bassUp(c *cli.Context) error {
}
newLevel := currentBass.ActualBass + amount
err = client.SetBassSafe(newLevel)
if err != nil {
PrintError(fmt.Sprintf("Failed to increase bass: %v", err))
@@ -81,6 +83,7 @@ func bassUp(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Bass increased from %d to %d", currentBass.ActualBass, newLevel))
return nil
}
@@ -104,6 +107,7 @@ func bassDown(c *cli.Context) error {
}
newLevel := currentBass.ActualBass - amount
err = client.SetBassSafe(newLevel)
if err != nil {
PrintError(fmt.Sprintf("Failed to decrease bass: %v", err))
@@ -111,6 +115,7 @@ func bassDown(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Bass decreased from %d to %d", currentBass.ActualBass, newLevel))
return nil
}
+11
View File
@@ -53,6 +53,7 @@ func setClockTime(c *cli.Context) error {
// Parse time string (HH:MM format)
var hour, minute int
var err error
if timeStr == "now" {
@@ -74,6 +75,7 @@ func setClockTime(c *cli.Context) error {
PrintError(fmt.Sprintf("Invalid time format. Use HH:MM, Unix timestamp, or 'now': %v", err))
return err
}
PrintDeviceHeader(fmt.Sprintf("Setting clock time to %02d:%02d", hour, minute), clientConfig.Host, clientConfig.Port)
}
}
@@ -89,6 +91,7 @@ func setClockTime(c *cli.Context) error {
targetTime := time.Date(now.Year(), now.Month(), now.Day(), hour, minute, 0, 0, now.Location())
clockTimeRequest := models.NewClockTimeRequest(targetTime)
err = client.SetClockTime(clockTimeRequest)
if err != nil {
PrintError(fmt.Sprintf("Failed to set clock time: %v", err))
@@ -96,6 +99,7 @@ func setClockTime(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Clock time set to %02d:%02d", hour, minute))
return nil
}
@@ -118,6 +122,7 @@ func setClockTimeNow(c *cli.Context) error {
now := time.Now()
PrintSuccess(fmt.Sprintf("Clock time set to current time (%02d:%02d)", now.Hour(), now.Minute()))
return nil
}
@@ -172,6 +177,7 @@ func enableClockDisplay(c *cli.Context) error {
}
PrintSuccess("Clock display enabled")
return nil
}
@@ -193,6 +199,7 @@ func disableClockDisplay(c *cli.Context) error {
}
PrintSuccess("Clock display disabled")
return nil
}
@@ -210,6 +217,7 @@ func setClockDisplayBrightness(c *cli.Context) error {
// Convert brightness string to numeric value
var brightnessLevel int
switch brightness {
case "low", "LOW":
brightnessLevel = 25
@@ -231,6 +239,7 @@ func setClockDisplayBrightness(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Clock display brightness set to %s", brightness))
return nil
}
@@ -248,6 +257,7 @@ func setClockDisplayFormat(c *cli.Context) error {
// Validate and normalize format value
var formatSetting models.ClockFormat
switch format {
case "12", "12h", "12hour":
formatSetting = models.ClockFormat12Hour
@@ -267,6 +277,7 @@ func setClockDisplayFormat(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Clock display format set to %s", format))
return nil
}
+4
View File
@@ -16,10 +16,12 @@ func discoverDevices(c *cli.Context) error {
showAll := c.Bool("all")
fmt.Printf("Discovering SoundTouch devices...\n")
if showAll {
fmt.Printf("Timeout: %v\n", timeout)
fmt.Printf("Mode: Detailed information\n")
}
fmt.Println()
// Load configuration
@@ -35,6 +37,7 @@ func discoverDevices(c *cli.Context) error {
// Create discovery service
discoveryService := discovery.NewUnifiedDiscoveryService(cfg)
ctx, cancel := context.WithTimeout(context.Background(), cfg.DiscoveryTimeout+5*time.Second)
defer cancel()
@@ -52,6 +55,7 @@ func discoverDevices(c *cli.Context) error {
fmt.Println("- Devices are on a different network segment")
fmt.Println("- Network blocks multicast traffic")
fmt.Println("- Firewall is blocking discovery ports")
return nil
}
+14
View File
@@ -10,6 +10,7 @@ import (
// getDeviceInfo handles the device info command
func getDeviceInfo(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -27,6 +28,7 @@ func getDeviceInfo(c *cli.Context) error {
fmt.Printf(" Name: %s\n", deviceInfo.Name)
fmt.Printf(" Type: %s\n", deviceInfo.Type)
fmt.Printf(" Device ID: %s\n", deviceInfo.DeviceID)
if deviceInfo.MargeAccountUUID != "" {
fmt.Printf(" Account UUID: %s\n", deviceInfo.MargeAccountUUID)
}
@@ -46,9 +48,11 @@ func getDeviceInfo(c *cli.Context) error {
for _, component := range deviceInfo.Components {
fmt.Printf(" - Category: %s\n", component.ComponentCategory)
if component.SoftwareVersion != "" {
fmt.Printf(" Software Version: %s\n", component.SoftwareVersion)
}
if component.SerialNumber != "" {
fmt.Printf(" Serial Number: %s\n", component.SerialNumber)
}
@@ -61,6 +65,7 @@ func getDeviceInfo(c *cli.Context) error {
// getDeviceName handles getting the device name
func getDeviceName(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -74,12 +79,14 @@ func getDeviceName(c *cli.Context) error {
}
fmt.Printf("Device Name: %s\n", name)
return nil
}
// setDeviceName handles setting the device name
func setDeviceName(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -98,12 +105,14 @@ func setDeviceName(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Device name set to '%s'", newName))
return nil
}
// getCapabilities handles getting device capabilities
func getCapabilities(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -137,9 +146,11 @@ func getCapabilities(c *cli.Context) error {
for _, capName := range capNames {
capability := capabilities.GetCapabilityByName(capName)
fmt.Printf(" - %s", capName)
if capability.URL != "" {
fmt.Printf(" (%s)", capability.URL)
}
fmt.Println()
}
}
@@ -150,6 +161,7 @@ func getCapabilities(c *cli.Context) error {
// getPresets handles getting device presets
func getPresets(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -170,6 +182,7 @@ func getPresets(c *cli.Context) error {
}
fmt.Printf(" Configured Presets:\n")
for _, preset := range presets.Preset {
fmt.Printf(" %d. %s\n", preset.ID, preset.GetDisplayName())
fmt.Printf(" Source: %s\n", preset.ContentItem.Source)
@@ -213,6 +226,7 @@ func selectPreset(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Preset %d selected", presetNum))
return nil
}
+8 -2
View File
@@ -36,7 +36,9 @@ func getNetworkInfo(c *cli.Context) error {
}
fmt.Printf(" Interfaces (%d):\n", len(interfaces))
for i, iface := range interfaces {
for i := range interfaces {
iface := &interfaces[i]
fmt.Printf("\n Interface %d:\n", i+1)
fmt.Printf(" Type: %s\n", iface.GetType())
@@ -77,7 +79,9 @@ func getNetworkInfo(c *cli.Context) error {
activeInterfaces := networkInfo.GetActiveInterfaces()
if len(activeInterfaces) > 0 {
fmt.Println("\n Active Connections:")
for _, iface := range activeInterfaces {
for i := range activeInterfaces {
iface := &activeInterfaces[i]
fmt.Printf(" - %s: %s\n", iface.GetType(), iface.GetNetworkSummary())
}
}
@@ -103,6 +107,7 @@ func pingDevice(c *cli.Context) error {
}
PrintSuccess("Device is reachable")
return nil
}
@@ -118,5 +123,6 @@ func getDeviceURL(c *cli.Context) error {
baseURL := client.BaseURL()
fmt.Printf("Device URL: %s\n", baseURL)
return nil
}
+19
View File
@@ -11,6 +11,7 @@ import (
// getNowPlaying handles getting the current playback status
func getNowPlaying(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -48,6 +49,7 @@ func getNowPlaying(c *cli.Context) error {
if nowPlaying.HasTimeInfo() {
fmt.Printf(" Duration: %s\n", nowPlaying.FormatDuration())
if nowPlaying.Position != nil {
fmt.Printf(" Position: %s\n", nowPlaying.FormatPosition())
}
@@ -67,6 +69,7 @@ func getNowPlaying(c *cli.Context) error {
// playCommand handles play command
func playCommand(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -80,12 +83,14 @@ func playCommand(c *cli.Context) error {
}
PrintSuccess("Play command sent")
return nil
}
// pauseCommand handles pause command
func pauseCommand(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -99,12 +104,14 @@ func pauseCommand(c *cli.Context) error {
}
PrintSuccess("Pause command sent")
return nil
}
// stopCommand handles stop command
func stopCommand(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -118,12 +125,14 @@ func stopCommand(c *cli.Context) error {
}
PrintSuccess("Stop command sent")
return nil
}
// nextCommand handles next track command
func nextCommand(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -137,12 +146,14 @@ func nextCommand(c *cli.Context) error {
}
PrintSuccess("Next track command sent")
return nil
}
// prevCommand handles previous track command
func prevCommand(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -156,6 +167,7 @@ func prevCommand(c *cli.Context) error {
}
PrintSuccess("Previous track command sent")
return nil
}
@@ -178,6 +190,7 @@ func sendKey(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("%s key command sent", key))
return nil
}
@@ -199,6 +212,7 @@ func powerCommand(c *cli.Context) error {
}
PrintSuccess("Power command sent")
return nil
}
@@ -220,6 +234,7 @@ func muteCommand(c *cli.Context) error {
}
PrintSuccess("Mute command sent")
return nil
}
@@ -241,6 +256,7 @@ func thumbsUpCommand(c *cli.Context) error {
}
PrintSuccess("Thumbs up command sent")
return nil
}
@@ -262,6 +278,7 @@ func thumbsDownCommand(c *cli.Context) error {
}
PrintSuccess("Thumbs down command sent")
return nil
}
@@ -283,6 +300,7 @@ func volumeUpKey(c *cli.Context) error {
}
PrintSuccess("Volume up command sent")
return nil
}
@@ -304,5 +322,6 @@ func volumeDownKey(c *cli.Context) error {
}
PrintSuccess("Volume down command sent")
return nil
}
+17
View File
@@ -10,6 +10,7 @@ import (
// listSources handles listing available audio sources
func listSources(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -32,6 +33,7 @@ func listSources(c *cli.Context) error {
for _, source := range availableSources {
fmt.Printf(" • %s", source.GetDisplayName())
if source.SourceAccount != "" && source.SourceAccount != source.Source {
fmt.Printf(" (%s)", source.SourceAccount)
}
@@ -40,18 +42,22 @@ func listSources(c *cli.Context) error {
if source.IsLocalSource() {
attributes = append(attributes, "Local")
}
if source.IsLocalSource() {
attributes = append(attributes, "Available")
}
if len(attributes) > 0 {
fmt.Printf(" [%s]", strings.Join(attributes, ", "))
}
fmt.Println()
}
}
// Show all configured sources
fmt.Printf(" All Sources:\n")
for _, source := range sources.SourceItem {
status := "Available"
if !source.IsLocalSource() {
@@ -59,6 +65,7 @@ func listSources(c *cli.Context) error {
}
fmt.Printf(" • %s (%s)\n", source.GetDisplayName(), status)
if source.SourceAccount != "" && source.SourceAccount != source.Source {
fmt.Printf(" Account: %s\n", source.SourceAccount)
}
@@ -68,11 +75,14 @@ func listSources(c *cli.Context) error {
streamingSources := sources.GetStreamingSources()
if len(streamingSources) > 0 {
fmt.Printf(" Streaming Services:\n")
for _, source := range streamingSources {
fmt.Printf(" • %s", source.GetDisplayName())
if source.SourceAccount != "" {
fmt.Printf(" (%s)", source.SourceAccount)
}
fmt.Println()
}
}
@@ -83,6 +93,7 @@ func listSources(c *cli.Context) error {
// selectSource handles selecting an audio source
func selectSource(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -110,6 +121,7 @@ func selectSource(c *cli.Context) error {
// selectSpotify handles selecting Spotify source
func selectSpotify(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -123,12 +135,14 @@ func selectSpotify(c *cli.Context) error {
}
PrintSuccess("Spotify source selected")
return nil
}
// selectBluetooth handles selecting Bluetooth source
func selectBluetooth(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -142,12 +156,14 @@ func selectBluetooth(c *cli.Context) error {
}
PrintSuccess("Bluetooth source selected")
return nil
}
// selectAux handles selecting AUX input source
func selectAux(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -161,5 +177,6 @@ func selectAux(c *cli.Context) error {
}
PrintSuccess("AUX input source selected")
return nil
}
+6
View File
@@ -11,6 +11,7 @@ import (
// getVolume handles getting the current volume level
func getVolume(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -39,6 +40,7 @@ func getVolume(c *cli.Context) error {
// setVolume handles setting the volume level
func setVolume(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -77,6 +79,7 @@ func setVolume(c *cli.Context) error {
// volumeUp handles increasing the volume
func volumeUp(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -95,12 +98,14 @@ func volumeUp(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Volume increased to %d (%s)", volume.GetLevel(), models.GetVolumeLevelName(volume.GetLevel())))
return nil
}
// volumeDown handles decreasing the volume
func volumeDown(c *cli.Context) error {
clientConfig := GetClientConfig(c)
client, err := CreateSoundTouchClient(clientConfig)
if err != nil {
return err
@@ -119,5 +124,6 @@ func volumeDown(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Volume decreased to %d (%s)", volume.GetLevel(), models.GetVolumeLevelName(volume.GetLevel())))
return nil
}
+15
View File
@@ -36,11 +36,14 @@ func getZone(c *cli.Context) error {
if len(zone.Members) > 0 {
fmt.Printf(" Members (%d):\n", len(zone.Members))
for _, member := range zone.Members {
fmt.Printf(" - %s", member.DeviceID)
if member.IP != "" {
fmt.Printf(" (IP: %s)", member.IP)
}
fmt.Println()
}
} else {
@@ -102,11 +105,14 @@ func getZoneMembers(c *cli.Context) error {
}
fmt.Printf("Zone Members (%d):\n", len(members))
for i, member := range members {
fmt.Printf(" %d. %s", i+1, member)
if member == clientConfig.Host {
fmt.Print(" (this device)")
}
fmt.Println()
}
@@ -133,12 +139,14 @@ func createZone(c *cli.Context) error {
// Parse and validate member IPs
var memberIPs []net.IP
for _, member := range members {
ip := net.ParseIP(member)
if ip == nil {
PrintError(fmt.Sprintf("Invalid IP address: %s", member))
return fmt.Errorf("invalid IP address: %s", member)
}
memberIPs = append(memberIPs, ip)
}
@@ -146,6 +154,7 @@ func createZone(c *cli.Context) error {
// In a real scenario, you might want to specify the master separately
masterDeviceID := "master" // This would need to be a real device ID
memberMap := make(map[string]string)
for i, ip := range memberIPs {
deviceID := fmt.Sprintf("device_%d", i+1)
memberMap[deviceID] = ip.String()
@@ -158,6 +167,7 @@ func createZone(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Zone created with members: %s", strings.Join(members, ", ")))
return nil
}
@@ -189,6 +199,7 @@ func addToZone(c *cli.Context) error {
// For this example, we'll use the IP as the device ID
// In practice, you'd need the actual device ID
deviceID := memberIP
err = client.AddToZone(deviceID, memberIP)
if err != nil {
PrintError(fmt.Sprintf("Failed to add to zone: %v", err))
@@ -196,6 +207,7 @@ func addToZone(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Added %s to zone", memberIP))
return nil
}
@@ -227,6 +239,7 @@ func removeFromZone(c *cli.Context) error {
// For this example, we'll use the IP as the device ID
// In practice, you'd need the actual device ID
deviceID := memberIP
err = client.RemoveFromZone(deviceID)
if err != nil {
PrintError(fmt.Sprintf("Failed to remove from zone: %v", err))
@@ -234,6 +247,7 @@ func removeFromZone(c *cli.Context) error {
}
PrintSuccess(fmt.Sprintf("Removed %s from zone", memberIP))
return nil
}
@@ -255,6 +269,7 @@ func dissolveZone(c *cli.Context) error {
}
PrintSuccess("Zone dissolved")
return nil
}
+1
View File
@@ -66,6 +66,7 @@ func RequireHost(c *cli.Context) error {
if c.String("host") == "" {
return fmt.Errorf("host is required. Use --host flag or set SOUNDTOUCH_HOST environment variable")
}
return nil
}