From dbd183ee004a35770b9737015a8be15200977b9b Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Thu, 25 Jun 2026 07:39:14 +0800 Subject: [PATCH] =?UTF-8?q?fix(ci):=20=E4=BF=AE=20flutter=20analyze=20?= =?UTF-8?q?=E9=97=B8=E9=95=BF=E6=9C=9F=20exit=201(=E5=BD=A2=E5=90=8C?= =?UTF-8?q?=E8=99=9A=E8=AE=BE)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 发现:CI flutter analyze 退出码 1(1204 个 info,0 error/warning),其中 1191 来自 第三方 vendored 包 lucide_icons_patched —— 这道闸一直红/无效。 - analysis_options.yaml:exclude packages/lucide_icons_patched/**(去 1191 噪音) - ci.yml:flutter analyze --no-fatal-infos(info 是建议级不该硬挡 merge; error/warning 仍致命)→ analyze EXIT 0、闸真正可用 - 顺手清 11 个 clean 文件 info:auth_api 删 >>>AUTHLOG 调试 print 残留(+unused sw)、 account_page/plan_card withOpacity→withValues、vpn_bridge where(is Map)→whereType、 测试文件删多余 import + final→const - 剩 2 个 info 在 stats-overhaul dirty 文件(stats_page/device_stat_row),留其合并清 - 验证:flutter analyze --no-fatal-infos EXIT 0(1204→2)、flutter test 48 全过 Co-Authored-By: Claude Opus 4.8 --- .gitea/workflows/ci.yml | 2 +- client/analysis_options.yaml | 6 ++++++ client/lib/bridge/vpn_bridge.dart | 4 ++-- client/lib/screens/account_page.dart | 4 ++-- client/lib/services/auth_api.dart | 4 ---- client/lib/widgets/plan_card.dart | 4 ++-- client/test/bridge/vpn_bridge_mock_test.dart | 3 +-- client/test/flutter_test_config.dart | 1 - 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 78672e9..5973e2d 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -77,7 +77,7 @@ jobs: docker run --rm \ -v "$PWD/client:/app" -w /app \ ghcr.io/cirruslabs/flutter:stable \ - bash -c "flutter pub get && flutter analyze && flutter test test/unit test/widget test/contract" + bash -c "flutter pub get && flutter analyze --no-fatal-infos && flutter test test/unit test/widget test/contract" # ── Job 5: Portable SQL Scan (支柱 3:双库可移植)───────────────────────── # server Go 运行时查询不得含 MySQL 专属构造(同一份 SQL 要跑 mysql 与 sqlite)。 diff --git a/client/analysis_options.yaml b/client/analysis_options.yaml index 24520d0..42005a3 100644 --- a/client/analysis_options.yaml +++ b/client/analysis_options.yaml @@ -1,5 +1,11 @@ include: package:flutter_lints/flutter.yaml +analyzer: + # 第三方 vendored path 依赖不该被项目 lint 评判(否则 ~1191 条 unnecessary_const + # 噪音淹没自身 issue,让 analyze 闸形同虚设)。 + exclude: + - packages/lucide_icons_patched/** + linter: rules: prefer_const_constructors: false diff --git a/client/lib/bridge/vpn_bridge.dart b/client/lib/bridge/vpn_bridge.dart index ce3366d..480c588 100644 --- a/client/lib/bridge/vpn_bridge.dart +++ b/client/lib/bridge/vpn_bridge.dart @@ -110,9 +110,9 @@ class VpnStatsEvent { uploadSpeed: (m['uploadSpeed'] as num?)?.toDouble() ?? 0.0, downloadSpeed: (m['downloadSpeed'] as num?)?.toDouble() ?? 0.0, urltestResults: ((m['urltestResults'] as List?) - ?.where((e) => e is Map) + ?.whereType() .map((e) => UrltestResult.fromMap( - Map.from(e as Map), + Map.from(e), )) .toList()) ?? const [], diff --git a/client/lib/screens/account_page.dart b/client/lib/screens/account_page.dart index 37358a5..fc365d2 100644 --- a/client/lib/screens/account_page.dart +++ b/client/lib/screens/account_page.dart @@ -179,7 +179,7 @@ class _PlanBanner extends StatelessWidget { child: Row(children: [ Container( width: 44, height: 44, - decoration: BoxDecoration(color: PangolinColors.white.withOpacity(0.18), shape: BoxShape.circle), + decoration: BoxDecoration(color: PangolinColors.white.withValues(alpha: 0.18), shape: BoxShape.circle), child: const Icon(PangolinIcons.crown, size: 22, color: PangolinColors.white), ), const SizedBox(width: 12), @@ -187,7 +187,7 @@ class _PlanBanner extends StatelessWidget { Text(email, style: const TextStyle(color: PangolinColors.white, fontWeight: FontWeight.w700, fontSize: 16)), const SizedBox(height: 4), Text(expiresLabel.isEmpty ? t.proMember : '${t.proMember} · $expiresLabel', - style: TextStyle(color: PangolinColors.white.withOpacity(0.85), fontSize: 12)), + style: TextStyle(color: PangolinColors.white.withValues(alpha: 0.85), fontSize: 12)), ])), FilledButton( onPressed: onUpgrade, diff --git a/client/lib/services/auth_api.dart b/client/lib/services/auth_api.dart index 8201f86..77a63d1 100644 --- a/client/lib/services/auth_api.dart +++ b/client/lib/services/auth_api.dart @@ -99,8 +99,6 @@ class AuthApi { Future _post(String path, Map body) async { final uri = Uri.parse('$baseUrl$path'); - print('>>>AUTHLOG POST $uri (baseUrl=$baseUrl) 发起...'); - final sw = Stopwatch()..start(); try { final resp = await _client .post( @@ -109,10 +107,8 @@ class AuthApi { body: jsonEncode(body), ) .timeout(const Duration(seconds: 15)); - print('>>>AUTHLOG POST $uri -> HTTP ${resp.statusCode} (${sw.elapsedMilliseconds}ms)'); return resp; } on Exception catch (e) { - print('>>>AUTHLOG POST $uri 失败 (${sw.elapsedMilliseconds}ms): ${e.runtimeType}: $e'); throw AuthApiException( statusCode: -1, messageZh: '网络请求失败,请检查连接后重试', diff --git a/client/lib/widgets/plan_card.dart b/client/lib/widgets/plan_card.dart index e987fb5..016164a 100644 --- a/client/lib/widgets/plan_card.dart +++ b/client/lib/widgets/plan_card.dart @@ -27,7 +27,7 @@ class PlanCard extends StatelessWidget { Widget build(BuildContext context) { final c = context.pangolin; final onCard = featured ? PangolinColors.white : c.fg1; - final subColor = featured ? PangolinColors.white.withOpacity(0.92) : c.fg2; + final subColor = featured ? PangolinColors.white.withValues(alpha: 0.92) : c.fg2; final card = Container( padding: const EdgeInsets.fromLTRB(20, 22, 20, 20), @@ -44,7 +44,7 @@ class PlanCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - Text(name, style: PangolinText.sm.copyWith(color: featured ? PangolinColors.white.withOpacity(0.85) : c.fg2, fontWeight: FontWeight.w600)), + Text(name, style: PangolinText.sm.copyWith(color: featured ? PangolinColors.white.withValues(alpha: 0.85) : c.fg2, fontWeight: FontWeight.w600)), const SizedBox(height: 6), Row( crossAxisAlignment: CrossAxisAlignment.baseline, diff --git a/client/test/bridge/vpn_bridge_mock_test.dart b/client/test/bridge/vpn_bridge_mock_test.dart index 41bc8f6..d980dc5 100644 --- a/client/test/bridge/vpn_bridge_mock_test.dart +++ b/client/test/bridge/vpn_bridge_mock_test.dart @@ -7,7 +7,6 @@ // 4. selectOutbound 切换时产生 connecting → on 重连序列 // 5. getStatus / getActiveOutbound / setKillSwitch 返回正确值 -import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:pangolin_vpn/bridge/vpn_bridge.dart'; import 'package:pangolin_vpn/bridge/vpn_bridge_mock.dart'; @@ -225,7 +224,7 @@ void main() { // ── 5. VpnStatsEvent schema round-trip ─────────────────────── group('VpnStatsEvent schema', () { test('fromMap / toMap round-trip', () { - final original = const VpnStatsEvent( + const original = VpnStatsEvent( uploadBytes: 1024, downloadBytes: 4096, uploadSpeed: 512.0, diff --git a/client/test/flutter_test_config.dart b/client/test/flutter_test_config.dart index e33d336..04070c7 100644 --- a/client/test/flutter_test_config.dart +++ b/client/test/flutter_test_config.dart @@ -4,7 +4,6 @@ // 让 widget/golden 测试用真字体渲染、且不触发 google_fonts 运行时拉取(避免抛异常)。 import 'dart:async'; import 'dart:io'; -import 'dart:typed_data'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart';