Skip to content

Commit 8ef7daa

Browse files
Implement Support for ARM and Use Latest libpact_ffi Library (#19)
1 parent a57ec41 commit 8ef7daa

File tree

3 files changed

+297
-120
lines changed

3 files changed

+297
-120
lines changed

.github/workflows/ci.yml

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,35 @@ on:
44
branches:
55
- "main"
66
pull_request:
7+
workflow_dispatch:
8+
79
jobs:
810
lint:
911
runs-on: ubuntu-latest
1012
steps:
11-
- uses: actions/checkout@v2
13+
- uses: actions/checkout@v3
1214
- uses: dart-lang/setup-dart@v1
15+
with:
16+
sdk: stable
1317
- name: Install dependencies
1418
run: dart pub get
1519
- name: Run analyzers and linters
1620
run: |
1721
dart format --set-exit-if-changed .
1822
dart analyze
23+
1924
tests:
20-
runs-on: ubuntu-latest
25+
runs-on: ${{ matrix.os }}
2126
strategy:
27+
fail-fast: false
2228
matrix:
23-
sdk: [stable, 2.18.7, 2.17.7]
29+
os: [ubuntu-latest, windows-latest, macos-latest]
30+
sdk: [stable, 3.4.0, 3.0.0, 2.19.6, 2.18.7, 2.17.7]
31+
exclude:
32+
- os: windows-latest
33+
sdk: 2.17.7
2434
steps:
25-
- uses: actions/checkout@v2
35+
- uses: actions/checkout@v3
2636
- uses: dart-lang/setup-dart@v1
2737
with:
2838
sdk: ${{ matrix.sdk }}
@@ -33,14 +43,26 @@ jobs:
3343
env:
3444
PACT_DART_LIB_DOWNLOAD_PATH: .
3545
- name: Run unit tests
36-
run: dart test --coverage="coverage" test/
46+
run: dart test -j 1 -r github --coverage="coverage" test/
3747
env:
3848
PACT_DART_LIB_DOWNLOAD_PATH: .
3949
- name: Format coverage
4050
run: dart run coverage:format_coverage --lcov --in=coverage --out=coverage.lcov --report-on=lib
41-
- uses: codecov/codecov-action@v2
51+
- uses: codecov/codecov-action@v3
4252
with:
4353
files: ./coverage.lcov
4454
token: ${{ secrets.CODECOV_TOKEN }}
4555
env:
4656
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
57+
58+
publish-check:
59+
runs-on: ubuntu-latest
60+
steps:
61+
- uses: actions/checkout@v3
62+
- uses: dart-lang/setup-dart@v1
63+
with:
64+
sdk: stable
65+
- name: Install dependencies
66+
run: dart pub get
67+
- name: Validate package for publishing
68+
run: dart pub publish --dry-run

bin/install.dart

Lines changed: 102 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
/// Dart has no way to install native libraries during package installation
1+
/// Install the `libpact` dependency.
22
///
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';
48
import 'dart:io';
59
import 'package:http/http.dart' as http;
610
import 'package:path/path.dart' as path;
@@ -18,7 +22,7 @@ String getPlatformFileType() {
1822

1923
default:
2024
throw UnsupportedError(
21-
'Sorry! ${Platform.operatingSystem} is unsupported by pact_dart.');
25+
'${Platform.operatingSystem} is unsupported by pact_dart.');
2226
}
2327
}
2428

@@ -28,15 +32,55 @@ String getLibDirectory() {
2832
return env;
2933
}
3034

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+
}
3276
}
3377

3478
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;
3781

3882
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';
4084

4185
return Uri(scheme: 'https', host: 'github.com', path: path);
4286
}
@@ -45,21 +89,60 @@ Future<void> downloadDependency(String name, String version) async {
4589
final fileType = getPlatformFileType();
4690
final dependencyLink = generateDependencyLink(name, version, fileType);
4791

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+
}
58120
}
59121

60122
void main() async {
61123
final dependencyName = Platform.isWindows ? 'pact_ffi' : 'libpact_ffi';
62-
final dependencyVersion = '0.4.1';
124+
final dependencyVersion = '0.4.27';
125+
final libDir = getLibDirectory();
63126

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('\nSomething went wrong: $e');
146+
exit(1);
147+
}
65148
}

0 commit comments

Comments
 (0)