mirror of
https://github.com/larksuite/cli.git
synced 2026-08-03 08:32:46 +08:00
fix(output): canonicalize shortcut format and align pretty scan window
Further review fixes: - Normalize the framework-injected --format to its canonical lowercase and write it back to the runtime context and the cobra flag, so shortcuts that branch on the exact value (e.g. Format == "pretty") behave correctly for mixed-case input like --format Pretty, which previously slipped past those checks and produced empty output. - Size the pretty rendered-text scan window to the content-safety scanner's native 128 KiB per-string capacity (was 64 KiB) so the windowing is no more restrictive than scanning the raw value; keep the 4 KiB overlap for matches crossing a window boundary.
This commit is contained in:
@@ -12,10 +12,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// Keep each pretty-output scan window comfortably below the content-safety
|
||||
// scanner's per-string limit. The overlap covers rule matches that cross a
|
||||
// window boundary without coupling this package to that private limit.
|
||||
prettySafetyScanWindowBytes = 64 << 10
|
||||
// Match the native content-safety scanner's 128 KiB per-string capacity so
|
||||
// rendered-output scanning does not impose a smaller regex match window.
|
||||
// The overlap keeps realistic rule matches visible across window boundaries.
|
||||
prettySafetyScanWindowBytes = 128 << 10
|
||||
prettySafetyScanOverlapBytes = 4 << 10
|
||||
)
|
||||
|
||||
|
||||
@@ -45,9 +45,8 @@ func (p *truncatingContractSafetyProvider) Name() string {
|
||||
}
|
||||
|
||||
func (p *truncatingContractSafetyProvider) Scan(_ context.Context, req extcs.ScanRequest) (*extcs.Alert, error) {
|
||||
// This deliberately differs from the production scanner's private limit; it
|
||||
// models any provider that bounds work independently for each string.
|
||||
const perStringCap = 160 << 10
|
||||
// Model the production scanner's native per-string capacity.
|
||||
const perStringCap = 128 << 10
|
||||
var containsMatch func(any) bool
|
||||
containsMatch = func(data any) bool {
|
||||
switch value := data.(type) {
|
||||
@@ -231,13 +230,13 @@ func TestEmitterPrettyBlockScansRenderedTextBeforeWriting(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmitterPrettyBlockScansLargeRenderedTextPastPerStringCap(t *testing.T) {
|
||||
func TestEmitterPrettyBlockDetectsLongMatchPastFirstScanWindow(t *testing.T) {
|
||||
t.Setenv("LARKSUITE_CLI_CONTENT_SAFETY_MODE", "block")
|
||||
const match = "blocked phrase"
|
||||
// Place the match beyond the scanner's per-string cap and across a scan
|
||||
// window boundary. A single-string scan misses it; overlapping windows keep
|
||||
// the complete match visible to the provider.
|
||||
rendered := strings.Repeat("a", 188410) + match + "\n"
|
||||
const nativePerStringCap = 128 << 10
|
||||
// The match starts after the first native-capacity window and is longer than
|
||||
// the old 64 KiB window. A native-capacity later window must retain it whole.
|
||||
match := strings.Repeat("blocked", 10<<10)
|
||||
rendered := strings.Repeat("a", nativePerStringCap+1) + match + "\n"
|
||||
provider := &truncatingContractSafetyProvider{
|
||||
alert: &extcs.Alert{
|
||||
Provider: "truncating-emitter-contract",
|
||||
|
||||
@@ -944,9 +944,18 @@ func runShortcut(cmd *cobra.Command, f *cmdutil.Factory, s *Shortcut, botOnly bo
|
||||
// own format flag (e.g. base +record-list's markdown|json, mail +watch's
|
||||
// json|data) owns a different enum, already validated by validateEnumFlags.
|
||||
if !shortcutDeclaresFormatFlag(s) {
|
||||
if _, err := output.ParseFormatStrict(rctx.Format); err != nil {
|
||||
format, err := output.ParseFormatStrict(rctx.Format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
canonicalFormat := format.String()
|
||||
if rctx.Str("format") != canonicalFormat {
|
||||
if err := rctx.Cmd.Flags().Set("format", canonicalFormat); err != nil {
|
||||
return errs.NewInternalError(errs.SubtypeUnknown,
|
||||
"failed to canonicalize the framework --format value").WithCause(err)
|
||||
}
|
||||
}
|
||||
rctx.Format = canonicalFormat
|
||||
}
|
||||
if s.Validate != nil {
|
||||
if err := s.Validate(rctx.ctx, rctx); err != nil {
|
||||
|
||||
@@ -367,6 +367,40 @@ func TestRunShortcut_DryRunMixedCasePrettyUsesPlainTextPreview(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunShortcut_MixedCaseFrameworkFormatIsCanonicalized(t *testing.T) {
|
||||
var runtimeFormat string
|
||||
var flagFormat string
|
||||
prettyBranchFired := false
|
||||
s := &Shortcut{
|
||||
Service: "test",
|
||||
Command: "test-shortcut",
|
||||
AuthTypes: []string{"bot"},
|
||||
Execute: func(_ context.Context, rctx *RuntimeContext) error {
|
||||
runtimeFormat = rctx.Format
|
||||
flagFormat = rctx.Str("format")
|
||||
prettyBranchFired = rctx.Format == "pretty"
|
||||
return nil
|
||||
},
|
||||
}
|
||||
f := newTestFactory()
|
||||
cmd := newTestShortcutCmd(s, f)
|
||||
cmd.Flags().Set("format", "PRETTY")
|
||||
cmd.Flags().Set("as", "bot")
|
||||
|
||||
if err := runShortcut(cmd, f, s, false); err != nil {
|
||||
t.Fatalf("runShortcut() error = %v", err)
|
||||
}
|
||||
if runtimeFormat != "pretty" {
|
||||
t.Fatalf("RuntimeContext.Format = %q, want pretty", runtimeFormat)
|
||||
}
|
||||
if flagFormat != "pretty" {
|
||||
t.Fatalf("RuntimeContext.Str(\"format\") = %q, want pretty", flagFormat)
|
||||
}
|
||||
if !prettyBranchFired {
|
||||
t.Fatal("downstream RuntimeContext.Format == \"pretty\" branch did not fire")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunShortcut_UnknownFormatErrorIncludesPretty(t *testing.T) {
|
||||
s := &Shortcut{
|
||||
Service: "test",
|
||||
|
||||
Reference in New Issue
Block a user