-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathflutter.dart
More file actions
171 lines (151 loc) · 6.01 KB
/
flutter.dart
File metadata and controls
171 lines (151 loc) · 6.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import 'package:snapp_cli/host_runner/host_runner_platform.dart';
import 'package:snapp_cli/service/custom_device_builder/custom_device_builder.dart';
import 'package:snapp_cli/service/setup_device/device_setup.dart';
// ignore: implementation_imports
import 'package:flutter_tools/src/custom_devices/custom_device_config.dart';
class FlutterCustomDeviceBuilder extends CustomDeviceBuilder {
const FlutterCustomDeviceBuilder({
required super.flutterSdkManager,
required super.hostPlatform,
});
@override
Future<CustomDeviceConfig> buildDevice(
final DeviceConfigContext context,
) async {
if (!isContextValid(context)) {
logger.err('Device context: $context');
throw Exception("Device setup did not produce a valid configuration.");
}
/// path to the icu data file on the host machine
final hostIcuDataPath = flutterSdkManager.icuDataPath;
/// path to the build artifacts on the remote machine
const hostBuildClonePath = 'snapp_embedded';
/// path to the icu data file on the remote machine
const hostIcuDataClone = '$hostBuildClonePath/engine';
final ipv6 = context.ipv6!;
final sshTarget = context.sshTarget!;
final formattedLoopbackIp = context.formattedLoopbackIp!;
final remoteAppExecuter = context.appExecuterPath!;
final appArchiveName = '\${appName}.tar.gz';
return CustomDeviceConfig(
id: context.id!,
label: context.formattedLabel,
sdkNameAndVersion: context.sdkName!,
enabled: true,
// host-platform specific, filled out later
pingCommand: hostPlatform.pingCommand(
ipv6: ipv6,
pingTarget: context.targetIp!.address,
),
pingSuccessRegex: hostPlatform.pingSuccessRegex,
postBuildCommand: const <String>[],
/// installing process of the app on the remote machine
///
/// 1. create the necessary directories in the remote machine
/// 2. compress the current project on the host without unnecessary files
/// 3. copy the archive project file to the remote
/// 4. extract the project on the remote
/// 5. copy the build artifacts from host to the remote
/// 6. copy the icu data file from host to the remote
/// 7. remove the archive file on host after sending it to the remote
installCommand: hostPlatform.commandRunner(
<String>[
// create the necessary directories in the remote machine
hostPlatform
.sshCommand(
ipv6: ipv6,
sshTarget: sshTarget,
command: 'mkdir -p /tmp/\${appName}/$hostIcuDataClone',
)
.asString,
// compress the current project on the host
hostPlatform
.compressCurrentProjectCommand(
compressedFileName: appArchiveName,
)
.asString,
// copy the archive project file to the remote
hostPlatform
.scpCommand(
ipv6: ipv6,
source: appArchiveName,
dest: '$sshTarget:/tmp/\${appName}',
)
.asString,
// extract the project on the remote
hostPlatform
.sshCommand(
ipv6: ipv6,
sshTarget: sshTarget,
command:
'tar -xvf /tmp/\${appName}/$appArchiveName -C /tmp/\${appName}',
)
.asString,
// copy the build artifacts from host to the remote
hostPlatform
.scpCommand(
ipv6: ipv6,
source: r'${localPath}',
dest: '$sshTarget:/tmp/\${appName}/$hostBuildClonePath',
)
.asString,
// copy the icu data file from host to the remote
hostPlatform
.scpCommand(
ipv6: ipv6,
source: hostIcuDataPath,
dest: '$sshTarget:/tmp/\${appName}/$hostIcuDataClone',
)
.asString,
// remove the archive file on host after sending it to the remote
hostPlatform
.deleteFile(
target: appArchiveName,
lastCommand: true,
)
.asString,
],
),
// just uninstall app by removing the /tmp/${appName} directory on the remote
uninstallCommand: hostPlatform.sshCommand(
ipv6: ipv6,
sshTarget: sshTarget,
command: r'rm -rf "/tmp/${appName}"',
lastCommand: true,
),
// run the app on the remote
runDebugCommand: hostPlatform.sshMultiCommand(
ipv6: ipv6,
sshTarget: sshTarget,
commands: <String>[
'cd /tmp/\${appName} ;',
'$remoteAppExecuter build linux --debug ;',
// remove remote build artifacts
'rm -rf "/tmp/\${appName}/build/flutter_assets/*" ;',
'rm -rf "/tmp/\${appName}/build/linux/arm64/debug/bundle/data/flutter_assets/*" ;',
'rm -rf "/tmp/\${appName}/build/linux/arm64/debug/bundle/data/icudtl.dat" ;',
// and replace them by host build artifacts
'cp -r /tmp/\${appName}/$hostBuildClonePath/flutter_assets/* /tmp/\${appName}/build/flutter_assets ;',
'cp -r /tmp/\${appName}/$hostBuildClonePath/flutter_assets/* /tmp/\${appName}/build/linux/arm64/debug/bundle/data/flutter_assets ;',
'cp -r /tmp/\${appName}/$hostIcuDataClone/icudtl.dat /tmp/\${appName}/build/linux/arm64/debug/bundle/data ;',
// finally run the app
r'DISPLAY=:0 /tmp/\${appName}/build/linux/arm64/debug/bundle/\${appName} ;'
],
),
forwardPortCommand: <String>[
'ssh',
'-o',
'BatchMode=yes',
'-o',
'ExitOnForwardFailure=yes',
if (ipv6) '-6',
'-L',
'$formattedLoopbackIp:\${hostPort}:$formattedLoopbackIp:\${devicePort}',
sshTarget,
"echo 'Port forwarding success'; read",
],
forwardPortSuccessRegex: RegExp('Port forwarding success'),
screenshotCommand: null,
);
}
}