@@ -2,47 +2,128 @@ import * as fs from "fs";
2
2
import * as path from "path" ;
3
3
import axios from 'axios' ;
4
4
import AdmZip from 'adm-zip' ;
5
+ import { platform , arch } from 'os' ;
5
6
6
- const canBridgeTag = "v2.3.0 " ;
7
+ const canBridgeTag = "v2.3.1 " ;
7
8
const canBridgeReleaseAssetUrlPrefix = `https://github.com/unofficial-rev-port/CANBridge/releases/download/${ canBridgeTag } ` ;
8
9
9
10
const externalCompileTimeDepsPath = 'externalCompileTimeDeps' ;
10
- const runtimeArtifactsPath = path . join ( 'prebuilds' , 'win32-x64' ) ;
11
+ const runtimeArtifactsPath = {
12
+ win : 'prebuilds/win32-x64' ,
13
+ osx : 'prebuilds/darwin-x64' ,
14
+ osxArm : 'prebuilds/darwin-arm64' ,
15
+ linux : 'prebuilds/linux-x64' ,
16
+ linuxArm : 'prebuilds/linux-arm64' ,
17
+ linuxArm32 : 'prebuilds/linux-arm32'
18
+ } ;
11
19
const tempDir = 'temp' ;
12
20
13
21
try {
14
- await Promise . all ( Array . of (
15
- downloadCanBridgeArtifact ( 'CANBridge.lib' , externalCompileTimeDepsPath ) ,
16
- downloadCanBridgeArtifact ( 'CANBridge.dll' , runtimeArtifactsPath ) ,
17
- downloadCanBridgeArtifact ( 'wpiHal.lib' , externalCompileTimeDepsPath ) ,
18
- downloadCanBridgeArtifact ( 'wpiHal.dll' , runtimeArtifactsPath ) ,
19
- downloadCanBridgeArtifact ( 'wpiutil.lib' , externalCompileTimeDepsPath ) ,
20
- downloadCanBridgeArtifact ( 'wpiutil.dll' , runtimeArtifactsPath ) ,
21
- downloadCanBridgeArtifact ( 'headers .zip', tempDir ) ,
22
- ) ) ;
23
-
22
+ // TODO: Do not hardcode the filenames, instead get them from the GitHub API -> Look at Octokit: https://github.com/octokit/octokit.js
23
+ await Promise . all ( [
24
+ 'CANBridge-linuxarm32-LinuxARM32.zip' ,
25
+ 'CANBridge-linuxarm64-LinuxARM64.zip' ,
26
+ 'CANBridge-linuxx86-64-Linux64.zip' ,
27
+ 'CANBridge-osxuniversal-MacOS64.zip' ,
28
+ 'CANBridge-osxuniversal-MacOSARM64.zip' ,
29
+ 'CANBridge-windowsx86-64-Win64 .zip',
30
+ 'headers.zip'
31
+ ] . map ( filename => downloadCanBridgeArtifact ( filename ) ) ) ;
24
32
console . log ( "CANBridge download completed" ) ;
25
- console . log ( "Extracting headers" ) ;
26
33
34
+
35
+ console . log ( "Extracting headers" ) ;
36
+ const zipFiles = fs . readdirSync ( tempDir ) . filter ( filename => filename . endsWith ( '.zip' ) && filename !== 'headers.zip' ) ;
37
+ for ( const filename of zipFiles ) {
38
+ await unzipCanBridgeArtifact ( filename , tempDir ) ;
39
+ }
27
40
const headersZip = new AdmZip ( path . join ( tempDir , "headers.zip" ) ) ;
41
+ headersZip . extractAllTo ( path . join ( externalCompileTimeDepsPath , 'include' ) ) ;
42
+ console . log ( "Headers extracted" ) ;
43
+
44
+ moveRuntimeDeps ( ) ;
28
45
29
- await headersZip . extractAllTo ( path . join ( externalCompileTimeDepsPath , 'include' ) ) ;
46
+ moveCompileTimeDeps ( ) ;
30
47
} catch ( e ) {
31
48
if ( axios . isAxiosError ( e ) && e . request ) {
32
- console . error ( `Failed to download CANBridge file ${ e . request . protocol } //${ e . request . host } / ${ e . request . path } ` ) ;
49
+ console . error ( `Failed to download CANBridge file ${ e . request . protocol } //${ e . request . host } ${ e . request . path } ` ) ;
33
50
} else {
34
- console . error ( `Failed to download CANBridge ` ) ;
51
+ console . error ( `Other error occurred: ${ e . message } ` ) ;
35
52
// For non-axios errors, the stacktrace will likely be helpful
36
53
throw e ;
37
54
}
38
55
process . exit ( 1 ) ;
39
56
} finally {
40
57
if ( fs . existsSync ( tempDir ) ) {
41
- fs . rmSync ( tempDir , { recursive : true } ) ;
58
+ fs . rmSync ( tempDir , { recursive : true , force : true } ) ;
42
59
}
43
60
}
44
61
45
- async function downloadCanBridgeArtifact ( filename , destDir ) {
62
+ /**
63
+ * Move external compile time dependencies to the correct directory
64
+ *
65
+ * This function is used to move the external compile time dependencies to the correct directory based on the platform and architecture from downloaded artifacts
66
+ */
67
+ function moveCompileTimeDeps ( ) {
68
+ console . log ( "Moving external compile time dependencies to correct directories" ) ;
69
+ if ( platform ( ) === 'win32' ) {
70
+ const deps = [ 'CANBridge.lib' , 'wpiHal.lib' , 'wpiutil.lib' ] ;
71
+ deps . forEach ( dep => moveExternalCompileTimeDeps ( path . join ( 'win32-x64' , dep ) ) ) ;
72
+ } else if ( platform ( ) === 'darwin' ) {
73
+ const deps = [ 'libCANBridge.a' ] ;
74
+ const archDepMap = {
75
+ x64 : 'darwin-x64' ,
76
+ arm64 : 'darwin-arm64'
77
+ } ;
78
+ deps . forEach ( dep => moveExternalCompileTimeDeps ( path . join ( archDepMap [ arch ( ) ] , dep ) ) ) ;
79
+ } else if ( platform ( ) === 'linux' ) {
80
+ const deps = [ 'libCANBridge.a' ] ;
81
+ const archDepMap = {
82
+ x64 : 'linux-x64' ,
83
+ arm64 : 'linux-arm64' ,
84
+ arm : 'linux-arm32'
85
+ } ;
86
+ deps . forEach ( dep => moveExternalCompileTimeDeps ( path . join ( archDepMap [ arch ( ) ] , dep ) ) ) ;
87
+ }
88
+ console . log ( "External compile time dependencies moved to correct directories" ) ;
89
+ }
90
+
91
+ /**
92
+ * Move runtime dependencies to the correct directory
93
+ *
94
+ * This function is used to move the runtime dependencies to the correct directory based on the platform and architecture from downloaded artifacts
95
+ */
96
+ function moveRuntimeDeps ( ) {
97
+ console . log ( "Moving artifacts to correct directories" ) ;
98
+ if ( platform ( ) === 'win32' ) {
99
+ const deps = [ 'CANBridge.dll' , 'wpiHal.dll' , 'wpiutil.dll' ] ;
100
+ deps . forEach ( dep => moveRuntimeArtifactsDeps ( path . join ( 'win32-x64' , dep ) , runtimeArtifactsPath . win ) ) ;
101
+ } else if ( platform ( ) === 'darwin' ) {
102
+ const deps = [ 'libCANBridge.dylib' , 'libwpiHal.dylib' , 'libwpiutil.dylib' ] ;
103
+ const archDepMap = {
104
+ x64 : runtimeArtifactsPath . osx ,
105
+ arm64 : runtimeArtifactsPath . osxArm
106
+ } ;
107
+ deps . forEach ( dep => moveRuntimeArtifactsDeps ( path . join ( archDepMap [ arch ( ) ] , dep ) , archDepMap [ arch ( ) ] ) ) ;
108
+ } else if ( platform ( ) === 'linux' ) {
109
+ const deps = [ 'libCANBridge.so' , 'libwpiHal.so' , 'libwpiutil.so' ] ;
110
+ const archDepMap = {
111
+ x64 : runtimeArtifactsPath . linux ,
112
+ arm64 : runtimeArtifactsPath . linuxArm ,
113
+ arm : runtimeArtifactsPath . linuxArm32
114
+ } ;
115
+ deps . forEach ( dep => moveRuntimeArtifactsDeps ( path . join ( archDepMap [ arch ( ) ] , dep ) , archDepMap [ arch ( ) ] ) ) ;
116
+ }
117
+ console . log ( "CANBridge artifacts moved to correct directories" ) ;
118
+ }
119
+
120
+ /**
121
+ * Download artifacts from the CANBridge GitHub release page
122
+ *
123
+ * @param {* } filename filename of the artifact to download
124
+ * @param {* } destDir destination directory to save the artifact, defaults to tempDir
125
+ */
126
+ async function downloadCanBridgeArtifact ( filename , destDir = tempDir ) {
46
127
fs . mkdirSync ( destDir , { recursive : true } ) ;
47
128
const response = await axios . get ( `${ canBridgeReleaseAssetUrlPrefix } /${ filename } ` , { responseType : "stream" } ) ;
48
129
const fileStream = fs . createWriteStream ( `${ destDir } /${ filename } ` ) ;
@@ -51,3 +132,41 @@ async function downloadCanBridgeArtifact(filename, destDir) {
51
132
fileStream . on ( 'finish' , resolve ) ;
52
133
} ) ;
53
134
}
135
+
136
+ /**
137
+ * Unzip the CANBridge artifacts
138
+ *
139
+ * @param {string } filename - filename of the artifact to unzip
140
+ * @param {string } destDir - destination directory to unzip the artifact
141
+ */
142
+ async function unzipCanBridgeArtifact ( filename , destDir ) {
143
+ const zip = new AdmZip ( `${ destDir } /${ filename } ` ) ;
144
+ let filepath ;
145
+ if ( filename . includes ( 'linuxarm32' ) ) filepath = "linux-arm32" ;
146
+ else if ( filename . includes ( 'linuxarm64' ) ) filepath = "linux-arm64" ;
147
+ else if ( filename . includes ( 'linuxx86-64' ) ) filepath = "linux-x64" ;
148
+ else if ( filename . includes ( 'MacOS64' ) ) filepath = "darwin-x64" ;
149
+ else if ( filename . includes ( 'MacOSARM64' ) ) filepath = "darwin-arm64" ;
150
+ else if ( filename . includes ( 'windowsx86-64' ) ) filepath = "win32-x64" ;
151
+ zip . extractAllTo ( `${ destDir } /${ filepath } ` ) ;
152
+ }
153
+
154
+ /**
155
+ * Move runtime artifacts to the correct directory
156
+ *
157
+ * @param {* } filename filename of the artifact to move
158
+ * @param {* } destDir destination directory to save the artifact
159
+ */
160
+ function moveRuntimeArtifactsDeps ( filename , destDir ) {
161
+ fs . mkdirSync ( destDir , { recursive : true } ) ;
162
+ fs . renameSync ( path . join ( tempDir , filename ) , path . join ( destDir , path . basename ( filename ) ) ) ;
163
+ }
164
+
165
+ /**
166
+ * Move External Compile Time Dependencies to the correct directory
167
+ *
168
+ * @param {* } filename filename of the artifact to move
169
+ */
170
+ function moveExternalCompileTimeDeps ( filename ) {
171
+ fs . renameSync ( path . join ( tempDir , filename ) , path . join ( externalCompileTimeDepsPath , path . basename ( filename ) ) ) ;
172
+ }
0 commit comments