Skip to content

Commit 5fa03e7

Browse files
authored
fix: 增强 Dart SDK 路径检测 (#2)
1 parent 7efcb25 commit 5fa03e7

1 file changed

Lines changed: 99 additions & 7 deletions

File tree

lib/smart_create.dart

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,113 @@ class SmartCreator {
6464
print(pen('输入的文件夹路径不对: $fullPath'));
6565
}
6666
}
67-
int startTime = DateTime.now().microsecondsSinceEpoch;
67+
int startTime = DateTime.now().microsecondsSinceEpoch;
6868
// print('${DateTime.now().toLocal()} AnalysisContextCollection');]
6969
var sb = StringBuffer();
7070
files.forEach((element) {
7171
sb.write("path:$element \n");
7272
});
73-
AnalysisContextCollection analysisContextCollection = AnalysisContextCollection(
74-
includedPaths: files,
75-
excludedPaths: [],
76-
resourceProvider: PhysicalResourceProvider.INSTANCE,
77-
);
73+
// try to detect Dart SDK robustly (async): prefer env, flutter cache, 'where'/'which', then walk up from resolvedExecutable
74+
String? sdkPath = await _detectSdkPath();
75+
if (sdkPath != null && sdkPath.isNotEmpty) {
76+
AnsiPen pen = AnsiPen()..green(bold: true);
77+
print(pen('Detected Dart SDK: $sdkPath'));
78+
} else {
79+
AnsiPen pen = AnsiPen()..yellow(bold: true);
80+
print(pen('Warning: Could not auto-detect Dart SDK. Analyzer may fail in compiled binary.'));
81+
}
82+
83+
// If sdkPath is not found, omit sdkPath and let the analyzer attempt default discovery (may fail for compiled exe).
84+
AnalysisContextCollection analysisContextCollection = (sdkPath != null && sdkPath.isNotEmpty)
85+
? AnalysisContextCollection(
86+
includedPaths: files,
87+
excludedPaths: [],
88+
resourceProvider: PhysicalResourceProvider.INSTANCE,
89+
sdkPath: sdkPath,
90+
)
91+
: AnalysisContextCollection(
92+
includedPaths: files,
93+
excludedPaths: [],
94+
resourceProvider: PhysicalResourceProvider.INSTANCE,
95+
);
7896
return analyseFile(analysisContextCollection, files, startTime);
7997
}
8098

99+
// Attempt to detect Dart SDK path using multiple strategies:
100+
// 1) DART_SDK env
101+
// 2) FLUTTER_ROOT/FLUTTER_HOME -> bin/cache/dart-sdk
102+
// 3) run 'where dart' (Windows) or 'which dart' (posix) and inspect parent dirs
103+
// 4) walk up from Platform.resolvedExecutable looking for 'lib/_internal'
104+
Future<String?> _detectSdkPath() async {
105+
// 1) env
106+
String? sdkPath = Platform.environment['DART_SDK'];
107+
if (sdkPath != null && sdkPath.isNotEmpty) {
108+
return normalize(sdkPath);
109+
}
110+
111+
// 2) flutter env
112+
final flutterRoot = Platform.environment['FLUTTER_ROOT'] ?? Platform.environment['FLUTTER_HOME'];
113+
if (flutterRoot != null && flutterRoot.isNotEmpty) {
114+
final candidate = normalize(join(flutterRoot, 'bin', 'cache', 'dart-sdk'));
115+
if (Directory(candidate).existsSync()) return candidate;
116+
}
117+
118+
// 3) find 'dart' executable using platform tools
119+
try {
120+
if (Platform.isWindows) {
121+
var result = await Process.run('where.exe', ['dart']);
122+
if (result.exitCode == 0) {
123+
final lines = result.stdout.toString().trim().split(RegExp(r"\r?\n"));
124+
if (lines.isNotEmpty) {
125+
final dartExe = lines.first.trim();
126+
final binDir = dirname(dartExe);
127+
final parent = dirname(binDir);
128+
// check for flutter cached sdk
129+
final flutterCache = normalize(join(parent, 'bin', 'cache', 'dart-sdk'));
130+
if (Directory(flutterCache).existsSync()) return flutterCache;
131+
// check for lib/_internal
132+
final internal = normalize(join(parent, 'lib', '_internal'));
133+
if (Directory(internal).existsSync()) return parent;
134+
return parent;
135+
}
136+
}
137+
} else {
138+
var result = await Process.run('which', ['dart']);
139+
if (result.exitCode == 0) {
140+
final dartExe = result.stdout.toString().trim();
141+
if (dartExe.isNotEmpty) {
142+
final binDir = dirname(dartExe);
143+
final parent = dirname(binDir);
144+
final internal = normalize(join(parent, 'lib', '_internal'));
145+
if (Directory(internal).existsSync()) return parent;
146+
return parent;
147+
}
148+
}
149+
}
150+
} catch (e) {
151+
// ignore failures
152+
}
153+
154+
// 4) walk up from resolvedExecutable
155+
try {
156+
String exec = Platform.resolvedExecutable;
157+
String dir = normalize(dirname(exec));
158+
for (int i = 0; i < 8; i++) {
159+
final candidate = normalize(join(dir, 'lib', '_internal'));
160+
if (Directory(candidate).existsSync()) {
161+
return normalize(dirname(candidate));
162+
}
163+
final parent = dirname(dir);
164+
if (parent == dir) break;
165+
dir = parent;
166+
}
167+
} catch (e) {
168+
// ignore
169+
}
170+
171+
return null;
172+
}
173+
81174
Future<void> analyseFile(AnalysisContextCollection analysisContextCollection, List<String> paths, int startTime) async {
82175
// print('${DateTime.now().toLocal()} analyseFile');
83176
List<ParsedComponentInfoInfo> parsedComponentInfoList = [];
@@ -286,7 +379,6 @@ class ${componentInfo!.name}Demo1 extends StatelessWidget {
286379

287380
// 拷贝默认的组件封面图
288381
Future<void> copyCoverFile(ComponentInfo? componentInfo) async {
289-
int startTime = DateTime.now().microsecondsSinceEpoch;
290382
String? destName = getDestFolderName(componentInfo);
291383
String relativePath = getWidgetDirPath(destName);
292384
String path = join(basePath!, relativePath);

0 commit comments

Comments
 (0)