From 276837caae94720dfac835bf5e90fc98e6df67ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=89=E6=BE=9C?= Date: Tue, 4 Aug 2026 08:56:42 +0800 Subject: [PATCH] refactor(cli): move test-only schema helpers out of production files Relocate seven functions with zero production callers (schemaProductToolCount, normalizeRuntimeSchemaGroups, runtimeFlagRequiredState, deliverySchemaCatalogAvailable, exactSchemaCommand, schemaMap, schemaToolSpecFromPayload) into a _test.go helper file, shrinking the shipped binary surface. --- internal/cli/runtime_schema.go | 54 --------- internal/cli/schema_catalog.go | 47 ------- internal/cli/schema_orphan_helpers_test.go | 135 +++++++++++++++++++++ internal/cli/schema_snapshot_adapter.go | 8 -- 4 files changed, 135 insertions(+), 109 deletions(-) create mode 100644 internal/cli/schema_orphan_helpers_test.go diff --git a/internal/cli/runtime_schema.go b/internal/cli/runtime_schema.go index f99709b0..c7c2ebdb 100644 --- a/internal/cli/runtime_schema.go +++ b/internal/cli/runtime_schema.go @@ -310,24 +310,6 @@ func topLevelCommand(cmd *cobra.Command) *cobra.Command { return top } -func schemaProductToolCount(product map[string]any) int { - switch value := product["tool_count"].(type) { - case int: - return value - case int64: - return int(value) - case float64: - return int(value) - } - if tools, ok := product["tools"].([]map[string]any); ok { - return len(tools) - } - if tools, ok := product["tools"].([]any); ok { - return len(tools) - } - return 0 -} - type runtimeSchemaFieldCandidate struct { Value any Present bool @@ -1027,22 +1009,6 @@ func normalizeRuntimeSchemaConstraints(constraints RuntimeSchemaConstraints) Run return runtimeannotate.NormalizeConstraints(constraints) } -func normalizeRuntimeSchemaGroups(groups [][]string, minimum int) [][]string { - // Test-facing thin wrapper over NormalizeConstraints group rules. - c := RuntimeSchemaConstraints{} - switch minimum { - case 1: - c.RequireOneOf = groups - default: - c.MutuallyExclusive = groups - } - out := runtimeannotate.NormalizeConstraints(c) - if minimum == 1 { - return out.RequireOneOf - } - return out.MutuallyExclusive -} - func runtimeSchemaConstraintsEmpty(constraints RuntimeSchemaConstraints) bool { return runtimeannotate.ConstraintsEmpty(constraints) } @@ -1091,26 +1057,6 @@ func runtimeFlagCLIType(flag *pflag.Flag) string { } } -func runtimeFlagRequiredState(flag *pflag.Flag) (bool, bool) { - // This helper reports the projected Schema annotation first. Cobra's - // executable marker is retained as a lower-priority observation; the typed - // contract exposes both candidates when an explicit overlay lowers it. - if raw := firstFlagAnnotation(flag, runtimeSchemaFlagRequiredAnnotation); raw != "" { - required, err := strconv.ParseBool(raw) - if err == nil { - return required, true - } - } - if runtimeFlagCobraHardRequired(flag) { - return true, true - } - usage := strings.ToLower(strings.TrimSpace(flag.Usage)) - if usageImpliesRequired(usage) { - return true, true - } - return false, false -} - func usageImpliesRequired(usage string) bool { usage = strings.ToLower(strings.TrimSpace(usage)) if usage == "" { diff --git a/internal/cli/schema_catalog.go b/internal/cli/schema_catalog.go index ecd2cac2..850b8d26 100644 --- a/internal/cli/schema_catalog.go +++ b/internal/cli/schema_catalog.go @@ -21,7 +21,6 @@ import ( "strings" apperrors "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/errors" - "github.com/spf13/cobra" ) const SchemaCatalogSnapshotVersion = 1 @@ -205,10 +204,6 @@ func loadSchemaCatalogSnapshot(snapshot SchemaCatalogSnapshot) (loadedSchemaCata return loadedSchemaCatalog{Snapshot: snapshot, Registry: registry, Index: index}, nil } -func deliverySchemaCatalogAvailable() bool { - return deliverySchemaCatalogError() == nil && len(deliverySchemaCatalog().Index.CanonicalPaths()) > 0 -} - func deliverySchemaAllPayload() (map[string]any, error) { if err := deliverySchemaCatalogError(); err != nil { return nil, err @@ -247,34 +242,6 @@ func schemaOverviewPayloadFromLoaded(loaded loadedSchemaCatalog) (map[string]any return payload, nil } -func exactSchemaCommand(root *cobra.Command, rawPath string) *cobra.Command { - if root == nil { - return nil - } - parts := strings.Fields(strings.TrimSpace(rawPath)) - if len(parts) > 0 && parts[0] == root.Name() { - parts = parts[1:] - } - current := root - for _, part := range parts { - var next *cobra.Command - for _, child := range current.Commands() { - if child.Name() == part { - next = child - break - } - } - if next == nil { - return nil - } - current = next - } - if current == root { - return nil - } - return current -} - // queryDeliverySchemaPayload serves dws schema queries through the production // delivery loader. Completeness / invariant gates must call // schemaPayloadFromLoadedCatalog (or the deliverySchemaPayload var alias) with @@ -388,20 +355,6 @@ func schemaMapSlice(value any) []map[string]any { } } -func schemaMap(value any) map[string]map[string]any { - input, ok := value.(map[string]any) - if !ok { - return nil - } - out := make(map[string]map[string]any, len(input)) - for key, value := range input { - if item, ok := value.(map[string]any); ok { - out[key] = item - } - } - return out -} - func schemaString(value any) string { valueString, _ := value.(string) return valueString diff --git a/internal/cli/schema_orphan_helpers_test.go b/internal/cli/schema_orphan_helpers_test.go new file mode 100644 index 00000000..c0a9a16c --- /dev/null +++ b/internal/cli/schema_orphan_helpers_test.go @@ -0,0 +1,135 @@ +// Copyright 2026 Alibaba Group +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cli + +// Test-only helpers relocated from production schema files; none of these +// functions has a production caller. + +import ( + "strconv" + "strings" + + "github.com/spf13/cobra" + "github.com/spf13/pflag" + + "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd/runtimeannotate" +) + +func schemaProductToolCount(product map[string]any) int { + switch value := product["tool_count"].(type) { + case int: + return value + case int64: + return int(value) + case float64: + return int(value) + } + if tools, ok := product["tools"].([]map[string]any); ok { + return len(tools) + } + if tools, ok := product["tools"].([]any); ok { + return len(tools) + } + return 0 +} + +func normalizeRuntimeSchemaGroups(groups [][]string, minimum int) [][]string { + // Test-facing thin wrapper over NormalizeConstraints group rules. + c := RuntimeSchemaConstraints{} + switch minimum { + case 1: + c.RequireOneOf = groups + default: + c.MutuallyExclusive = groups + } + out := runtimeannotate.NormalizeConstraints(c) + if minimum == 1 { + return out.RequireOneOf + } + return out.MutuallyExclusive +} + +func runtimeFlagRequiredState(flag *pflag.Flag) (bool, bool) { + // This helper reports the projected Schema annotation first. Cobra's + // executable marker is retained as a lower-priority observation; the typed + // contract exposes both candidates when an explicit overlay lowers it. + if raw := firstFlagAnnotation(flag, runtimeSchemaFlagRequiredAnnotation); raw != "" { + required, err := strconv.ParseBool(raw) + if err == nil { + return required, true + } + } + if runtimeFlagCobraHardRequired(flag) { + return true, true + } + usage := strings.ToLower(strings.TrimSpace(flag.Usage)) + if usageImpliesRequired(usage) { + return true, true + } + return false, false +} + +func deliverySchemaCatalogAvailable() bool { + return deliverySchemaCatalogError() == nil && len(deliverySchemaCatalog().Index.CanonicalPaths()) > 0 +} + +func exactSchemaCommand(root *cobra.Command, rawPath string) *cobra.Command { + if root == nil { + return nil + } + parts := strings.Fields(strings.TrimSpace(rawPath)) + if len(parts) > 0 && parts[0] == root.Name() { + parts = parts[1:] + } + current := root + for _, part := range parts { + var next *cobra.Command + for _, child := range current.Commands() { + if child.Name() == part { + next = child + break + } + } + if next == nil { + return nil + } + current = next + } + if current == root { + return nil + } + return current +} + +func schemaMap(value any) map[string]map[string]any { + input, ok := value.(map[string]any) + if !ok { + return nil + } + out := make(map[string]map[string]any, len(input)) + for key, value := range input { + if item, ok := value.(map[string]any); ok { + out[key] = item + } + } + return out +} + +func schemaToolSpecFromPayload(payload map[string]any) (ToolSpec, error) { + wire, err := schemaToolWireFromPayload(payload) + if err != nil { + return ToolSpec{}, err + } + return schemaToolSpecFromWire(wire) +} diff --git a/internal/cli/schema_snapshot_adapter.go b/internal/cli/schema_snapshot_adapter.go index 64ab7592..ea69fe36 100644 --- a/internal/cli/schema_snapshot_adapter.go +++ b/internal/cli/schema_snapshot_adapter.go @@ -217,14 +217,6 @@ func schemaToolWireFromPayload(payload map[string]any) (schemaToolWire, error) { return wire, nil } -func schemaToolSpecFromPayload(payload map[string]any) (ToolSpec, error) { - wire, err := schemaToolWireFromPayload(payload) - if err != nil { - return ToolSpec{}, err - } - return schemaToolSpecFromWire(wire) -} - func schemaToolSpecFromWire(wire schemaToolWire) (ToolSpec, error) { parameterNames := make([]string, 0, len(wire.Parameters)) for name := range wire.Parameters {