|
1 | 1 | import 'dart:convert'; |
2 | 2 | import 'dart:io'; |
| 3 | +import 'dart:isolate'; |
3 | 4 |
|
4 | 5 | import 'package:archive/archive_io.dart'; |
5 | 6 | import 'package:args/command_runner.dart'; |
6 | 7 | import 'package:path/path.dart' as path; |
7 | 8 | import 'package:toml/toml.dart'; |
8 | 9 |
|
| 10 | +const junkFileExtensions = [".so", ".py", ".c", ".typed"]; |
| 11 | +const junkFilesAndDirectories = ["__pycache__", "bin"]; |
| 12 | + |
9 | 13 | class PackageCommand extends Command { |
10 | 14 | @override |
11 | 15 | final name = "package"; |
@@ -37,6 +41,17 @@ class PackageCommand extends Command { |
37 | 41 |
|
38 | 42 | try { |
39 | 43 | final currentPath = Directory.current.path; |
| 44 | + final packagePath = (await Isolate.resolvePackageUri( |
| 45 | + Uri.parse('package:serious_python/.'))) |
| 46 | + ?.path; |
| 47 | + |
| 48 | + if (packagePath == null) { |
| 49 | + stdout.writeln("Cannot resolve 'serious_python' package path."); |
| 50 | + exit(1); |
| 51 | + } |
| 52 | + |
| 53 | + final iosDistPath = |
| 54 | + path.join(Directory(packagePath).parent.absolute.path, "ios", "dist"); |
40 | 55 |
|
41 | 56 | // source dir |
42 | 57 | var sourceDirPath = argResults!.rest.first; |
@@ -111,36 +126,28 @@ class PackageCommand extends Command { |
111 | 126 | extraArgs.add("--pre"); |
112 | 127 | } |
113 | 128 |
|
114 | | - final pipProcess = await Process.start( |
115 | | - 'python3', |
116 | | - [ |
117 | | - '-m', |
118 | | - 'pip', |
119 | | - 'install', |
120 | | - '--isolated', |
121 | | - '--upgrade', |
122 | | - ...extraArgs, |
123 | | - '--target', |
124 | | - path.join(tempDir.path, '__pypackages__'), |
125 | | - ...dependencies |
126 | | - ], |
127 | | - environment: { |
128 | | - "CC": "/bin/false", |
129 | | - "CXX": "/bin/false", |
130 | | - "PYTHONPATH": tempDir.path, |
131 | | - "PYTHONOPTIMIZE": "2", |
132 | | - }, |
133 | | - runInShell: true, |
134 | | - includeParentEnvironment: false); |
135 | | - |
136 | | - await for (final line in pipProcess.stdout.transform(utf8.decoder)) { |
137 | | - stdout.write(line); |
138 | | - } |
139 | | - |
140 | | - if (await pipProcess.exitCode != 0) { |
141 | | - stdout.write(await pipProcess.stderr.transform(utf8.decoder).join()); |
142 | | - exit(1); |
143 | | - } |
| 129 | + final pythonPath = |
| 130 | + path.join(iosDistPath, "hostpython3", "bin", "python"); |
| 131 | + |
| 132 | + await runExec(pythonPath, [ |
| 133 | + '-m', |
| 134 | + 'pip', |
| 135 | + 'install', |
| 136 | + '--isolated', |
| 137 | + '--upgrade', |
| 138 | + ...extraArgs, |
| 139 | + '--target', |
| 140 | + path.join(tempDir.path, '__pypackages__'), |
| 141 | + ...dependencies |
| 142 | + ], environment: { |
| 143 | + "CC": "/bin/false", |
| 144 | + "CXX": "/bin/false", |
| 145 | + "PYTHONPATH": tempDir.path, |
| 146 | + "PYTHONOPTIMIZE": "2", |
| 147 | + }); |
| 148 | + |
| 149 | + // compile all python code |
| 150 | + await runExec(pythonPath, ['-m', 'compileall', '-b', tempDir.path]); |
144 | 151 | } |
145 | 152 |
|
146 | 153 | // remove unnecessary files |
@@ -193,17 +200,38 @@ class PackageCommand extends Command { |
193 | 200 | directory.listSync().forEach((entity) { |
194 | 201 | if (entity is Directory) { |
195 | 202 | cleanupPyPackages(entity); |
196 | | - } else if (entity is File && entity.path.endsWith('.so')) { |
| 203 | + } else if (entity is File && |
| 204 | + junkFileExtensions.contains(path.extension(entity.path)) || |
| 205 | + junkFilesAndDirectories.contains(path.basename(entity.path))) { |
| 206 | + stdout.writeln("Deleting ${entity.path}"); |
197 | 207 | entity.deleteSync(); |
198 | 208 | } |
199 | 209 | }); |
200 | 210 |
|
201 | 211 | directory.listSync().forEach((entity) { |
202 | | - if (entity is Directory && entity.path.endsWith('__pycache__')) { |
203 | | - entity.deleteSync(recursive: true); |
204 | | - } else if (entity is Directory && entity.path.endsWith('bin')) { |
| 212 | + if (entity is Directory && |
| 213 | + junkFilesAndDirectories.contains(path.basename(entity.path))) { |
| 214 | + stdout.writeln("Deleting ${entity.path}"); |
205 | 215 | entity.deleteSync(recursive: true); |
206 | 216 | } |
207 | 217 | }); |
208 | 218 | } |
| 219 | + |
| 220 | + Future<int> runExec(String execPath, List<String> args, |
| 221 | + {Map<String, String>? environment}) async { |
| 222 | + final proc = await Process.start(execPath, args, |
| 223 | + environment: environment, |
| 224 | + runInShell: true, |
| 225 | + includeParentEnvironment: false); |
| 226 | + |
| 227 | + await for (final line in proc.stdout.transform(utf8.decoder)) { |
| 228 | + stdout.write(line); |
| 229 | + } |
| 230 | + |
| 231 | + if (await proc.exitCode != 0) { |
| 232 | + stdout.write(await proc.stderr.transform(utf8.decoder).join()); |
| 233 | + exit(1); |
| 234 | + } |
| 235 | + return proc.exitCode; |
| 236 | + } |
209 | 237 | } |
0 commit comments