1
- /// Dart has no way to install native libraries during package installation
1
+ /// Install the `libpact` dependency.
2
2
///
3
- /// Something to keep an eye on: https://github.com/dart-lang/pub/issues/39
3
+ /// Currently, this is not managed by `pub` due to limitations:
4
+ /// - https://github.com/dart-lang/pub/issues/39
5
+ /// - https://github.com/dart-lang/pub/issues/3693
6
+
7
+ import 'dart:ffi' ;
4
8
import 'dart:io' ;
5
9
import 'package:http/http.dart' as http;
6
10
import 'package:path/path.dart' as path;
@@ -18,7 +22,7 @@ String getPlatformFileType() {
18
22
19
23
default :
20
24
throw UnsupportedError (
21
- 'Sorry! ${Platform .operatingSystem } is unsupported by pact_dart.' );
25
+ '${Platform .operatingSystem } is unsupported by pact_dart.' );
22
26
}
23
27
}
24
28
@@ -28,15 +32,55 @@ String getLibDirectory() {
28
32
return env;
29
33
}
30
34
31
- return '/usr/local/lib' ;
35
+ switch (Platform .operatingSystem) {
36
+ case 'windows' :
37
+ final programFiles =
38
+ Platform .environment['ProgramFiles' ] ?? 'C:\\ Program Files' ;
39
+ return '$programFiles \\ PactDart' ;
40
+
41
+ case 'macos' :
42
+ case 'linux' :
43
+ return '/usr/local/lib' ;
44
+
45
+ default :
46
+ final home = Platform .environment['HOME' ] ??
47
+ Platform .environment['USERPROFILE' ] ??
48
+ '.' ;
49
+ return '$home /.pact_dart/lib' ;
50
+ }
51
+ }
52
+
53
+ String getArchitecture () {
54
+ final abi = Abi .current ().toString ();
55
+ final arch = abi.split ('_' ).last;
56
+
57
+ switch (arch) {
58
+ case 'arm64' :
59
+ case 'arm' :
60
+ return 'aarch64' ;
61
+
62
+ case 'x64' :
63
+ return 'x86_64' ;
64
+
65
+ case 'ia32' :
66
+ return 'x86' ;
67
+
68
+ case 'riscv64' :
69
+ case 'riscv32' :
70
+ throw UnsupportedError ('RISC-V is not currently supported' );
71
+
72
+ default :
73
+ print ('Warning: Unknown architecture: $arch , defaulting to x86_64' );
74
+ return 'x86_64' ;
75
+ }
32
76
}
33
77
34
78
Uri generateDependencyLink (String name, String version, String fileType) {
35
- final operatingSystem =
36
- Platform . operatingSystem == 'macos' ? 'osx' : Platform .operatingSystem;
79
+ final architecture = getArchitecture ();
80
+ final operatingSystem = Platform .operatingSystem;
37
81
38
82
final path =
39
- '/pact-foundation/pact-reference/releases/download/$ name -v$version /$name -$operatingSystem -x86_64 .$fileType .gz' ;
83
+ '/pact-foundation/pact-reference/releases/download/libpact_ffi -v$version /$name -$operatingSystem -$ architecture .$fileType .gz' ;
40
84
41
85
return Uri (scheme: 'https' , host: 'github.com' , path: path);
42
86
}
@@ -45,21 +89,60 @@ Future<void> downloadDependency(String name, String version) async {
45
89
final fileType = getPlatformFileType ();
46
90
final dependencyLink = generateDependencyLink (name, version, fileType);
47
91
48
- final res = await http.get (dependencyLink);
49
- final library = GZipCodec ().decode (res.bodyBytes);
50
-
51
- final libDir = getLibDirectory ();
52
- final libPath = path.join (libDir, '$name .$fileType ' );
53
-
54
- final writeStream = File (libPath.toString ()).openWrite ();
55
- writeStream.add (library);
56
-
57
- await writeStream.close ();
92
+ print ('🛜 Downloading from: ${dependencyLink .toString ()}' );
93
+
94
+ try {
95
+ final res = await http.get (dependencyLink);
96
+ if (res.statusCode != 200 ) {
97
+ throw Exception ('Download failed with status code ${res .statusCode }' );
98
+ }
99
+
100
+ final library = GZipCodec ().decode (res.bodyBytes);
101
+
102
+ final libDir = getLibDirectory ();
103
+ final libDirFile = Directory (libDir);
104
+ await libDirFile.create (recursive: true );
105
+
106
+ final libPath = path.join (libDir, '$name .$fileType ' );
107
+ print ('💾 Installing to: $libPath ' );
108
+
109
+ try {
110
+ await File (libPath).writeAsBytes (library, flush: true );
111
+ print ('✅ Successfully installed $name v$version .' );
112
+ } catch (e) {
113
+ throw Exception (
114
+ 'Unable to write to $libPath . Try running with sudo or specify a different directory with PACT_DART_LIB_DOWNLOAD_PATH environment variable.' );
115
+ }
116
+ } catch (e) {
117
+ print ('😢 An error occurred during installation: $e ' );
118
+ rethrow ;
119
+ }
58
120
}
59
121
60
122
void main () async {
61
123
final dependencyName = Platform .isWindows ? 'pact_ffi' : 'libpact_ffi' ;
62
- final dependencyVersion = '0.4.1' ;
124
+ final dependencyVersion = '0.4.27' ;
125
+ final libDir = getLibDirectory ();
63
126
64
- await downloadDependency (dependencyName, dependencyVersion);
127
+ print ('🚀 Pact Dart Installation' );
128
+ print ('======================' );
129
+ print (
130
+ 'This script will install the $dependencyName library required by Pact Dart:' );
131
+ print ('- Library: $dependencyName v$dependencyVersion ' );
132
+ print ('- Platform: ${Platform .operatingSystem } (${getArchitecture ()})' );
133
+ print ('- Install directory: $libDir ' );
134
+ print ('' );
135
+ print (
136
+ 'Note: You may need admin privileges to write to the installation directory.' );
137
+ print (
138
+ 'If installation fails, you can specify an alternative directory using' );
139
+ print ('the PACT_DART_LIB_DOWNLOAD_PATH environment variable.' );
140
+ print ('' );
141
+
142
+ try {
143
+ await downloadDependency (dependencyName, dependencyVersion);
144
+ } catch (e) {
145
+ print ('\n Something went wrong: $e ' );
146
+ exit (1 );
147
+ }
65
148
}
0 commit comments