From a3824add71c21cf97a05b9f584f25d08e011f7d7 Mon Sep 17 00:00:00 2001 From: Nicholas Sollazzo Date: Fri, 10 Jul 2026 10:52:50 +0200 Subject: [PATCH] refactor: dedup admin field-flag application into applyStringFieldFlags (POS-187) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The soul/post/feed/profile admin commands each carried a near-identical loop that walked a [][2]string flag→API-key mapping and copied string flags into the request body. feed's version already generalized the two semantics (create = omit empty, update = send changed incl. empty) via a forCreate bool; the other three just hadn't been pointed at it. Extract that loop once as applyStringFieldFlags(cmd, mapping, fields, omitEmpty) and have all four call sites delegate to it. No behavior change: the array (--framework/--tag) and bool handlers are untouched, and the existing e2e/golden wire-body assertions still pass. Net -11 lines, four copies of the loop collapsed to one. Co-Authored-By: Paperclip --- internal/cli/admin.go | 34 +++++++++++++++++++++++++--------- internal/cli/feed.go | 16 +--------------- internal/cli/post.go | 11 ++--------- internal/cli/profile.go | 12 +++--------- 4 files changed, 31 insertions(+), 42 deletions(-) diff --git a/internal/cli/admin.go b/internal/cli/admin.go index c80ad36..033fcba 100644 --- a/internal/cli/admin.go +++ b/internal/cli/admin.go @@ -235,18 +235,34 @@ func addSoulFieldFlags(cmd *cobra.Command) { f.String("license", "", "SPDX license id (overrides frontmatter)") } -// applySoulFieldFlags copies every explicitly set field flag over fields — -// flags always beat frontmatter. -func applySoulFieldFlags(cmd *cobra.Command, fields map[string]any) error { - for _, pair := range soulFieldFlagMap { - if !cmd.Flags().Changed(pair[0]) { - continue - } - v, err := cmd.Flags().GetString(pair[0]) +// applyStringFieldFlags copies the mapped string flags into fields. When +// omitEmpty is true (create) only non-empty values are sent, so empty optionals +// fall through to the server defaults; when false (update) every explicitly set +// flag is sent, so an explicit empty value clears that field. The mapping is an +// ordered slice so the wire body stays deterministic. +func applyStringFieldFlags(cmd *cobra.Command, mapping [][2]string, fields map[string]any, omitEmpty bool) error { + for _, pair := range mapping { + flag, key := pair[0], pair[1] + v, err := cmd.Flags().GetString(flag) if err != nil { return err } - fields[pair[1]] = v + if omitEmpty { + if v != "" { + fields[key] = v + } + } else if cmd.Flags().Changed(flag) { + fields[key] = v + } + } + return nil +} + +// applySoulFieldFlags copies every explicitly set field flag over fields — +// flags always beat frontmatter. +func applySoulFieldFlags(cmd *cobra.Command, fields map[string]any) error { + if err := applyStringFieldFlags(cmd, soulFieldFlagMap, fields, false); err != nil { + return err } if cmd.Flags().Changed("framework") { v, err := cmd.Flags().GetStringArray("framework") diff --git a/internal/cli/feed.go b/internal/cli/feed.go index d71f8a4..5fe84d7 100644 --- a/internal/cli/feed.go +++ b/internal/cli/feed.go @@ -84,21 +84,7 @@ func addFeedFieldFlags(cmd *cobra.Command) { // applies its defaults); on update only the flags explicitly set are sent, so // an explicit empty --author/--listing clears that attribution. func applyFeedStringFlags(cmd *cobra.Command, fields map[string]any, forCreate bool) error { - for _, pair := range feedStringFlagMap { - flag, key := pair[0], pair[1] - v, err := cmd.Flags().GetString(flag) - if err != nil { - return err - } - if forCreate { - if v != "" { - fields[key] = v - } - } else if cmd.Flags().Changed(flag) { - fields[key] = v - } - } - return nil + return applyStringFieldFlags(cmd, feedStringFlagMap, fields, forCreate) } // applyFeedTagsFlag copies --tag into defaultTags when explicitly set. diff --git a/internal/cli/post.go b/internal/cli/post.go index 61286a5..554e6d2 100644 --- a/internal/cli/post.go +++ b/internal/cli/post.go @@ -92,15 +92,8 @@ func addPostFieldFlags(cmd *cobra.Command) { // applyPostFieldFlags copies every explicitly set field flag over fields — // flags always beat frontmatter. func applyPostFieldFlags(cmd *cobra.Command, fields map[string]any) error { - for _, pair := range postFieldFlagMap { - if !cmd.Flags().Changed(pair[0]) { - continue - } - v, err := cmd.Flags().GetString(pair[0]) - if err != nil { - return err - } - fields[pair[1]] = v + if err := applyStringFieldFlags(cmd, postFieldFlagMap, fields, false); err != nil { + return err } if cmd.Flags().Changed("tag") { v, err := cmd.Flags().GetStringArray("tag") diff --git a/internal/cli/profile.go b/internal/cli/profile.go index 0d8b1c6..98f9c9a 100644 --- a/internal/cli/profile.go +++ b/internal/cli/profile.go @@ -61,7 +61,7 @@ func newProfileCreateCmd() *cobra.Command { // omitted so the server applies its defaults (e.g. the GitHub avatar) and // never sees an empty string where it expects a URL. An ordered slice (not // a map) keeps the wire body deterministic, like soulFieldFlagMap. - for _, fk := range [][2]string{ + if err := applyStringFieldFlags(cmd, [][2]string{ {"handle", "handle"}, {"name", "name"}, {"kind", "kind"}, @@ -69,14 +69,8 @@ func newProfileCreateCmd() *cobra.Command { {"github-url", "githubUrl"}, {"website", "website"}, {"bio", "bio"}, - } { - v, gerr := cmd.Flags().GetString(fk[0]) - if gerr != nil { - return gerr - } - if v != "" { - fields[fk[1]] = v - } + }, fields, true); err != nil { + return err } // Bools are always sent (false is meaningful); granting a seal is opt-in. verified, gerr := cmd.Flags().GetBool("verified")