From 65c02ef7a5734bc6c87c28f1643b7efcb4a6a21b Mon Sep 17 00:00:00 2001 From: ryan Date: Sun, 16 Aug 2026 18:19:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E5=87=86=E6=89=A9=E5=B1=95=20exhausti?= =?UTF-8?q?ve=EF=BC=88=E6=96=87=E6=A1=A3=E5=8C=96=EF=BC=89+=2012=E2=86=920?= =?UTF-8?q?=EF=BC=9A=E6=9E=9A=E4=B8=BE=20switch=20=E8=A1=A5=E6=98=BE?= =?UTF-8?q?=E5=BC=8F=20case=EF=BC=88=E5=85=A8=E9=83=A8=E4=B8=8E=E7=8E=B0?= =?UTF-8?q?=E6=9C=89=20default=20=E8=A1=8C=E4=B8=BA=E7=AD=89=E4=BB=B7?= =?UTF-8?q?=EF=BC=8Cfail-explicit=20=E9=98=B2=E6=9C=AA=E6=9D=A5=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE=E9=9D=99=E9=BB=98=E8=90=BD=E5=85=A5=20default?= =?UTF-8?q?=EF=BC=89=EF=BC=9Bsource=5Ftasks.go=20=E4=B8=BA=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=A4=8D=E6=9D=82=E5=BA=A6=E5=90=88=E5=B9=B6=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E7=AD=89=E4=BB=B7=E6=A0=A1=E9=AA=8C=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Result: {"status":"keep","total_issues":8,"golint_canonicalheader":0,"golint_errname":0,"golint_errorlint":1,"golint_exhaustive":0,"golint_forcetypeassert":0,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":0,"golint_recvcheck":1,"golint_usestdlibvars":0,"golint_wastedassign":0,"golint_total":8,"golint_test_testifylint":0,"golint_test_thelper":0,"golint_test_usetesting":0,"golint_test_total":0,"eslint_problems":0,"eslint_errors":0,"eslint_warnings":0,"tsc_errors":0,"measure_s":36} --- .auto/log.jsonl | 1 + .auto/measure.sh | 2 +- internal/apps/agent/sync/sync_helpers.go | 3 +++ internal/apps/openflare/node/helpers.go | 2 ++ internal/apps/openflare/pages/helpers.go | 2 ++ internal/apps/openflare/pages/source_orphan_cleanup.go | 2 ++ internal/apps/openflare/pages/source_scanner.go | 2 ++ internal/apps/openflare/pages/source_tasks.go | 8 ++++---- internal/apps/openflare/waf/graph_validate.go | 2 ++ internal/apps/upload/filesrv/file_server.go | 2 ++ internal/apps/upload/ingest/ingest.go | 2 ++ pkg/pagesarchive/inspect.go | 2 ++ pkg/pagesarchive/list.go | 4 ++++ 13 files changed, 29 insertions(+), 5 deletions(-) diff --git a/.auto/log.jsonl b/.auto/log.jsonl index 7959e74c..5cda29d6 100644 --- a/.auto/log.jsonl +++ b/.auto/log.jsonl @@ -11,3 +11,4 @@ {"run":10,"commit":"73d8173","metric":9,"metrics":{"golint_canonicalheader":0,"golint_errname":0,"golint_errorlint":1,"golint_forcetypeassert":0,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":0,"golint_recvcheck":1,"golint_usestdlibvars":0,"golint_wastedassign":0,"golint_total":8,"eslint_problems":1,"eslint_errors":0,"eslint_warnings":1,"tsc_errors":0,"measure_s":45},"status":"keep","description":"recvcheck 7→1:6 个 GORM 模型 TableName 改为指针接收者(GORM 源码确认 reflect.New 判定 Tabler,兼容;模型单测通过)。MillisecondDuration 刻意保留(encoding/json 要求 Marshal 值/Unmarshal 指针的混合)。","timestamp":1786874445733,"segment":0,"confidence":4.304347826086956,"asi":{"hypothesis":"recvcheck 7→1:GORM 模型 TableName 值接收者→指针接收者,与其它方法一致","insight":"GORM schema.Parse 用 reflect.New(modelType) 判定 Tabler,指针接收者 TableName 完全兼容(已读 gorm 源码确认 + 模型单测通过);仓库中 (Model{}).TableName() 字面量调用都在未改的类型上,无破坏。MillisecondDuration 保留:MarshalJSON 值接收者是 json 对不可寻址值的行为保障,UnmarshalJSON 必须指针 —— 混合是 encoding/json 硬性要求","next_action_hint":"剩余:modernize(3,含 lark omitzero 刻意保留 + 2 处待查)、nilnil(3 刻意保留)、eslint(1 exhaustive-deps)、errorlint(1 刻意保留)。下一步查 modernize 剩余 2 处并修 eslint 的 hook 依赖"}} {"run":11,"commit":"111d290","metric":8,"metrics":{"golint_canonicalheader":0,"golint_errname":0,"golint_errorlint":1,"golint_forcetypeassert":0,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":0,"golint_recvcheck":1,"golint_usestdlibvars":0,"golint_wastedassign":0,"golint_total":8,"eslint_problems":0,"eslint_errors":0,"eslint_warnings":0,"tsc_errors":0,"measure_s":38},"status":"keep","description":"eslint 1→0:pages-source-card useEffect 补 t 依赖(next-intl 稳定引用)。modernize 补 1 处 time.Time omitzero。剩余 8 全部为刻意保留项。","timestamp":1786874578893,"segment":0,"confidence":4.3478260869565215,"asi":{"hypothesis":"eslint 1→0:useEffect 依赖数组补 t(next-intl useTranslations 返回稳定引用,安全);modernize 补 1 处 time.Time omitempty→omitzero(输出一致)","insight":"modernize 剩余 3 处全部是嵌套 struct omitempty(client.go Release/Asset、lark.go Content)→ omitzero 会改变 wire,全部刻意保留。至此所有可安全修复的类别清零,剩余 8 个全部是有据可查的刻意保留项","next_action_hint":"剩余 8 全部刻意保留(errorlint 1 telegram、modernize 3 嵌套struct、nilnil 3 not-found、recvcheck 1 json)。下一轮做深化方向:测试代码质量(tests:false 之外)、或 golangci 附加 linter(gocritic 更多检查)作为新基准段"}} {"run":12,"commit":"e5f6b0a","metric":33,"metrics":{"golint_canonicalheader":0,"golint_errname":0,"golint_errorlint":1,"golint_forcetypeassert":0,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":0,"golint_recvcheck":1,"golint_usestdlibvars":0,"golint_wastedassign":0,"golint_total":8,"golint_test_testifylint":20,"golint_test_thelper":3,"golint_test_usetesting":2,"golint_test_total":25,"eslint_problems":0,"eslint_errors":0,"eslint_warnings":0,"tsc_errors":0,"measure_s":37},"status":"keep","description":"基准扩展(文档化):新增测试代码质量维度 25 处(testifylint 20 + thelper 3 + usetesting 2),生产代码 8 处刻意保留不变。新基线 total=33。","timestamp":1786874744438,"segment":0,"confidence":4.878048780487805,"asi":{"hypothesis":"扩展基准到测试代码质量维度(testifylint 20 + thelper 3 + usetesting 2 = 25)","insight":"刻意排除 paralleltest/tparallel(共享 DB/redis 状态 + 本环境无法跑测试,t.Parallel 有风险)—— 这是范围扩展(抬高门槛),不是 gaming;基准定义已写入 prompt.md","next_action_hint":"修 25 处测试问题:float-compare 3(InDelta)、require-error 3、encoded-compare 1(JSONEq)、empty 3、contains 1、error-is-as 3、len 3、go-require-in-handler 2、t.Helper 3、os.MkdirTemp→t.TempDir 2"}} +{"run":13,"commit":"63a24da","metric":8,"metrics":{"golint_canonicalheader":0,"golint_errname":0,"golint_errorlint":1,"golint_forcetypeassert":0,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":0,"golint_recvcheck":1,"golint_usestdlibvars":0,"golint_wastedassign":0,"golint_total":8,"golint_test_testifylint":0,"golint_test_thelper":0,"golint_test_usetesting":0,"golint_test_total":0,"eslint_problems":0,"eslint_errors":0,"eslint_warnings":0,"tsc_errors":0,"measure_s":39},"status":"keep","description":"测试代码质量 25→0:assert↔require 一致性(fail-fast)、float 精确比较→InDelta、Equal(\"\",x)→Empty、Equal(len)→Len、errors.Is/As→ErrorIs/ErrorAs、JSON 字符串→JSONEq、handler goroutine 内 require→assert(真健壮性修复)、t.Helper()、os.MkdirTemp→t.TempDir()(符合 repo AGENTS 约束)。","timestamp":1786875177918,"segment":0,"confidence":4.3478260869565215,"asi":{"hypothesis":"修完测试代码质量维度 25 处(testifylint 20 + thelper 3 + usetesting 2)","insight":"批量修复过程揭示 testifylint 默认 max-same-issues=3 会掩盖重复模式(len(entries) 出现 4+ 次、float64(3) 4 次),需 --max-issues-per-linter=0 反复收敛;全部修复语义中性(assert↔require 仅 fail-fast 差异,InDelta/JSONEq/Empty/Len/ErrorIs 等价断言,t.Helper/t.TempDir 纯改善)。go-require 类(handler 内 require→assert)是真正的健壮性修复","next_action_hint":"测试维度清零。生产代码剩余 8 全部刻意保留。可选深化:gocritic 更多子检查/staticcheck 更多(SA 系列)扫描、或 biome check 格式一次性提交、或前端 a11y(eslint jsx-a11y 已含于 next core-web-vitals 默认关闭项)"}} diff --git a/.auto/measure.sh b/.auto/measure.sh index 227025d1..3476fbed 100755 --- a/.auto/measure.sh +++ b/.auto/measure.sh @@ -6,7 +6,7 @@ cd "$(dirname "$0")/.." start=$(date +%s) # ---------- Backend: golangci-lint, repo config + fixed best-practice extras ---------- -EXTRA_LINTERS="errorlint,errname,nilnil,forcetypeassert,copyloopvar,intrange,mirror,perfsprint,prealloc,usestdlibvars,modernize,sloglint,canonicalheader,nosprintfhostport,recvcheck,wastedassign" +EXTRA_LINTERS="errorlint,errname,nilnil,forcetypeassert,copyloopvar,intrange,mirror,perfsprint,prealloc,usestdlibvars,modernize,sloglint,canonicalheader,nosprintfhostport,recvcheck,wastedassign,exhaustive" golang_out=$(golangci-lint run --enable="$EXTRA_LINTERS" 2>&1 || true) golang_total=0 diff --git a/internal/apps/agent/sync/sync_helpers.go b/internal/apps/agent/sync/sync_helpers.go index e3269d36..681eb89f 100644 --- a/internal/apps/agent/sync/sync_helpers.go +++ b/internal/apps/agent/sync/sync_helpers.go @@ -220,6 +220,9 @@ func updateSnapshotFromApplyOutcome(mode string, snapshot *state.Snapshot, confi snapshot.OpenrestyStatus = protocol.OpenrestyStatusHealthy snapshot.OpenrestyMessage = result.message result.reportResult = ApplyResultWarning + case nginx.ApplyStatusFatal: + // 致命错误与普通失败同走失败路径:标记阻塞并上报 Unhealthy。 + fallthrough default: if result.message == "" { result.message = "openresty apply failed" diff --git a/internal/apps/openflare/node/helpers.go b/internal/apps/openflare/node/helpers.go index 387bddf6..e0e7f114 100644 --- a/internal/apps/openflare/node/helpers.go +++ b/internal/apps/openflare/node/helpers.go @@ -309,6 +309,8 @@ func fetchLatestGitHubRelease(ctx context.Context, repo string, channel releaseC switch normalizeReleaseChannel(string(channel)) { case releaseChannelPreview: return fetchLatestPreviewGitHubRelease(ctx, repo) + case releaseChannelStable: + return fetchLatestStableGitHubRelease(ctx, repo) default: return fetchLatestStableGitHubRelease(ctx, repo) } diff --git a/internal/apps/openflare/pages/helpers.go b/internal/apps/openflare/pages/helpers.go index d592e32c..2cd66190 100644 --- a/internal/apps/openflare/pages/helpers.go +++ b/internal/apps/openflare/pages/helpers.go @@ -226,6 +226,8 @@ func safeTempSuffix(format pagesarchive.Format) string { return "7z" case pagesarchive.FormatTar: return "tar" + case pagesarchive.FormatZip: + return "zip" default: return "zip" } diff --git a/internal/apps/openflare/pages/source_orphan_cleanup.go b/internal/apps/openflare/pages/source_orphan_cleanup.go index 9de3bd9d..570eea86 100644 --- a/internal/apps/openflare/pages/source_orphan_cleanup.go +++ b/internal/apps/openflare/pages/source_orphan_cleanup.go @@ -111,6 +111,8 @@ func (summary *PagesOrphanCleanupSummary) add(outcome pagesOrphanCleanupOutcome) summary.LeaseBusy++ case pagesOrphanCleanupInvalidMarker: summary.InvalidMarker++ + case pagesOrphanCleanupSkipped: + summary.Skipped++ default: summary.Skipped++ } diff --git a/internal/apps/openflare/pages/source_scanner.go b/internal/apps/openflare/pages/source_scanner.go index 56722fef..06510e38 100644 --- a/internal/apps/openflare/pages/source_scanner.go +++ b/internal/apps/openflare/pages/source_scanner.go @@ -266,6 +266,8 @@ func scanOneDueGitHubSource( case sourceLeaseStale: summary.StaleSources++ return + case sourceLeaseAcquired: + // 获取执行权成功,继续执行扫描。 } if snapshot == nil || snapshot.SourceType != PagesSourceTypeGitHubRelease || snapshot.ReleaseSelector != githubReleaseSelectorLatest { diff --git a/internal/apps/openflare/pages/source_tasks.go b/internal/apps/openflare/pages/source_tasks.go index a8248328..9d3b314a 100644 --- a/internal/apps/openflare/pages/source_tasks.go +++ b/internal/apps/openflare/pages/source_tasks.go @@ -154,10 +154,8 @@ func (h *SourceActionHandler) Execute(ctx context.Context, payload []byte) (*tas if source.SourceType != PagesSourceTypeRemoteURL && source.SourceType != PagesSourceTypeGitHubRelease { return nil, task.PermanentError(errPagesSourceTypeUnsupported) } - if source.SourceType == PagesSourceTypeRemoteURL && (input.TargetRevision != "" || input.ConfirmedRevision != "") { - return nil, task.PermanentError(errPagesSourceActionInvalid) - } - if input.Action == sourceActionCheck && (input.TargetRevision != "" || input.ConfirmedRevision != "") { + if (source.SourceType == PagesSourceTypeRemoteURL || input.Action == sourceActionCheck) && + (input.TargetRevision != "" || input.ConfirmedRevision != "") { return nil, task.PermanentError(errPagesSourceActionInvalid) } @@ -174,6 +172,8 @@ func (h *SourceActionHandler) Execute(ctx context.Context, payload []byte) (*tas case sourceLeaseStale: task.AppendLog(ctx, "[resolve] 来源配置或执行权已变化,本次任务跳过") return &task.TaskResult{Message: errPagesSourceActionStale}, nil + case sourceLeaseAcquired: + // 已获取执行权,继续执行。 } if input.Action == sourceActionCheck { diff --git a/internal/apps/openflare/waf/graph_validate.go b/internal/apps/openflare/waf/graph_validate.go index 90b42e7b..2c9dc310 100644 --- a/internal/apps/openflare/waf/graph_validate.go +++ b/internal/apps/openflare/waf/graph_validate.go @@ -383,6 +383,8 @@ func requiredHandles(t RuleNodeType) []string { return []string{"next"} case RuleNodeIPMatch, RuleNodeGeoMatch, RuleNodeUACheck, RuleNodeSecurityCheck: return []string{"true", "false"} + case RuleNodeAllow, RuleNodeBlock: + return nil default: return nil } diff --git a/internal/apps/upload/filesrv/file_server.go b/internal/apps/upload/filesrv/file_server.go index ca66fe77..113d81c1 100644 --- a/internal/apps/upload/filesrv/file_server.go +++ b/internal/apps/upload/filesrv/file_server.go @@ -134,6 +134,8 @@ func ServeUpload(c *gin.Context, upload *model.Upload) { return } fallthrough + case fileTypeVideo, fileTypeAudio, fileTypeOther: + serveOriginalWithConditionalCheck(c, upload) default: serveOriginalWithConditionalCheck(c, upload) } diff --git a/internal/apps/upload/ingest/ingest.go b/internal/apps/upload/ingest/ingest.go index 8aa8e1f2..cdda6ca1 100644 --- a/internal/apps/upload/ingest/ingest.go +++ b/internal/apps/upload/ingest/ingest.go @@ -54,6 +54,8 @@ func ingestWithHashPolicy(ctx context.Context, req Request) (Result, error) { return Result{}, ErrStorageReadOnly } return createDedupRecord(ctx, existing, req) + case PolicyCreate: + // 忽略已存在记录,走下方的新建流程。 } } if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { diff --git a/pkg/pagesarchive/inspect.go b/pkg/pagesarchive/inspect.go index 6020e47a..15b27b8f 100644 --- a/pkg/pagesarchive/inspect.go +++ b/pkg/pagesarchive/inspect.go @@ -295,6 +295,8 @@ func isTarFamily(format Format) bool { switch format { case FormatTar, FormatTarGz, FormatTarXz, FormatTarBz2: return true + case FormatZip, FormatSevenZip: + return false default: return false } diff --git a/pkg/pagesarchive/list.go b/pkg/pagesarchive/list.go index 1af579cf..003573be 100644 --- a/pkg/pagesarchive/list.go +++ b/pkg/pagesarchive/list.go @@ -60,6 +60,8 @@ func listRandomAccessEntriesAt(ra io.ReaderAt, size int64, format Format) ([]Ent return listZipEntriesAt(ra, size) case FormatSevenZip: return listSevenZipEntriesAt(ra, size) + case FormatTar, FormatTarGz, FormatTarXz, FormatTarBz2: + return nil, fmt.Errorf("unsupported random-access pages package format: %s", format) default: return nil, fmt.Errorf("unsupported random-access pages package format: %s", format) } @@ -127,6 +129,8 @@ func openTarFamilyReader(r io.Reader, format Format) (*tar.Reader, func() error, return tar.NewReader(xzReader), func() error { return nil }, nil case FormatTarBz2: return tar.NewReader(bzip2.NewReader(r)), func() error { return nil }, nil + case FormatZip, FormatSevenZip: + return nil, nil, fmt.Errorf("unsupported tar family format: %s", format) default: return nil, nil, fmt.Errorf("unsupported tar family format: %s", format) }