4
4
*-------------------------------------------------------------------------------------------*/
5
5
6
6
import * as fs from "fs" ;
7
+ import * as os from "os" ;
7
8
import * as path from "path" ;
8
9
9
10
import * as util from "../common/util" ;
@@ -27,24 +28,24 @@ export interface ILibrary {
27
28
architectures : string [ ] ;
28
29
types : string [ ] ;
29
30
builtIn : boolean ;
31
+ supported : boolean ;
30
32
}
31
33
32
34
export class LibraryManager {
33
- private _libraries : Map < string , ILibrary > ;
35
+ private _libraryMap : Map < string , ILibrary > ;
34
36
35
- // Sorted library group by board type, then alphabetically.
36
- private _sortedLibrary : ILibrary [ ] ;
37
+ private _libraries : ILibrary [ ] ;
37
38
38
39
constructor ( private _settings : IArduinoSettings , private _arduinoApp : ArduinoApp ) {
39
40
}
40
41
41
42
public get libraries ( ) : ILibrary [ ] {
42
- return this . _sortedLibrary ;
43
+ return this . _libraries ;
43
44
}
44
45
45
46
public async loadLibraries ( ) {
46
- this . _libraries = new Map < string , ILibrary > ( ) ;
47
- this . _sortedLibrary = [ ] ;
47
+ this . _libraryMap = new Map < string , ILibrary > ( ) ;
48
+ this . _libraries = [ ] ;
48
49
49
50
await this . _arduinoApp . boardManager . loadPackages ( ) ;
50
51
@@ -55,102 +56,151 @@ export class LibraryManager {
55
56
let packageContent = fs . readFileSync ( libraryIndexFilePath , "utf8" ) ;
56
57
this . parseLibraryIndex ( JSON . parse ( packageContent ) ) ;
57
58
59
+ await this . loadIdeLibraries ( ) ;
58
60
await this . loadInstalledLibraries ( ) ;
59
- await this . sortLibraries ( ) ;
61
+ const builtinLibs = await this . loadBoardLibraries ( ) ;
62
+ this . _libraries = Array . from ( this . _libraryMap . values ( ) ) ;
63
+ this . _libraries = this . _libraries . concat ( builtinLibs ) ;
64
+ this . tagSupportedLibraries ( ) ;
60
65
}
61
66
62
67
private parseLibraryIndex ( rawModel : any ) {
63
68
rawModel . libraries . forEach ( ( library : ILibrary ) => {
64
69
// Arduino install-library program will replace the blank space of the library folder name with underscore,
65
70
// here format library name consistently for better parsing at the next steps.
66
71
const formattedName = library . name . replace ( / \s + / g, "_" ) ;
67
- let existingLib = this . _libraries . get ( formattedName ) ;
72
+ let existingLib = this . _libraryMap . get ( formattedName ) ;
68
73
if ( existingLib ) {
69
74
existingLib . versions . push ( library . version ) ;
70
75
} else {
71
76
library . versions = [ library . version ] ;
72
77
library . builtIn = false ;
73
78
library . version = "" ;
74
- this . _libraries . set ( formattedName , library ) ;
79
+ this . _libraryMap . set ( formattedName , library ) ;
75
80
}
76
81
} ) ;
77
82
}
78
83
79
- private async loadInstalledLibraries ( ) {
80
- let libRoot = this . _settings . libPath ;
84
+ private async loadIdeLibraries ( ) {
85
+ const arduinoPath = this . _settings . arduinoPath ;
86
+ let ideLibraryPath = path . join ( arduinoPath , "libraries" ) ; // linux and win32
87
+ if ( os . platform ( ) === "darwin" ) {
88
+ ideLibraryPath = path . join ( arduinoPath , "Arduino.app/Contents/Java/libraries" ) ;
89
+ }
90
+ const ideLibraries = util . filterJunk ( fs . readdirSync ( ideLibraryPath ) ) ;
91
+ for ( let libDir of ideLibraries ) {
92
+ if ( util . fileExistsSync ( path . join ( ideLibraryPath , libDir , "library.properties" ) ) ) {
93
+ const properties = < any > await util . parseProperties ( path . join ( ideLibraryPath , libDir , "library.properties" ) ) ;
94
+ const formattedName = properties . name . replace ( / \s + / g, "_" ) ;
95
+ let sourceLib = this . _libraryMap . get ( formattedName ) ;
96
+ if ( sourceLib ) {
97
+ sourceLib . version = util . formatVersion ( properties . version ) ;
98
+ sourceLib . builtIn = true ;
99
+ sourceLib . installed = true ;
100
+ sourceLib . installedPath = path . join ( ideLibraryPath , libDir ) ;
101
+ sourceLib . srcPath = path . join ( ideLibraryPath , libDir , "src" ) ;
102
+ // If lib src folder doesn't exist, then fallback to the lib root path as source folder.
103
+ sourceLib . srcPath = util . directoryExistsSync ( sourceLib . srcPath ) ? sourceLib . srcPath : path . join ( ideLibraryPath , libDir ) ;
104
+ }
105
+ }
106
+ }
107
+ }
81
108
109
+ private async loadInstalledLibraries ( ) {
110
+ const libRoot = this . _settings . libPath ;
82
111
if ( ! util . directoryExistsSync ( this . _settings . libPath ) ) {
83
112
return ;
84
113
}
85
114
86
115
let installedLibDirs = util . filterJunk ( fs . readdirSync ( libRoot ) ) ;
87
116
for ( let libDir of installedLibDirs ) {
88
- let sourceLib = this . _libraries . get ( libDir ) ;
89
- if ( sourceLib && util . fileExistsSync ( path . join ( libRoot , libDir , "library.properties" ) ) ) {
117
+ if ( util . fileExistsSync ( path . join ( libRoot , libDir , "library.properties" ) ) ) {
90
118
const properties = < any > await util . parseProperties ( path . join ( libRoot , libDir , "library.properties" ) ) ;
91
- sourceLib . version = util . formatVersion ( properties . version ) ;
92
- sourceLib . installed = true ;
93
- sourceLib . installedPath = path . join ( libRoot , libDir ) ;
94
- sourceLib . srcPath = path . join ( libRoot , libDir , "src" ) ;
95
- // If lib src folder doesn't exist, then fallback to the lib root path as source folder.
96
- sourceLib . srcPath = util . directoryExistsSync ( sourceLib . srcPath ) ? sourceLib . srcPath : path . join ( libRoot , libDir ) ;
119
+ const formattedName = properties . name . replace ( / \s + / g, "_" ) ;
120
+ let sourceLib = this . _libraryMap . get ( formattedName ) ;
121
+ if ( sourceLib ) {
122
+ sourceLib . version = util . formatVersion ( properties . version ) ;
123
+ sourceLib . builtIn = false ;
124
+ sourceLib . installed = true ;
125
+ sourceLib . installedPath = path . join ( libRoot , libDir ) ;
126
+ sourceLib . srcPath = path . join ( libRoot , libDir , "src" ) ;
127
+ // If lib src folder doesn't exist, then fallback to the lib root path as source folder.
128
+ sourceLib . srcPath = util . directoryExistsSync ( sourceLib . srcPath ) ? sourceLib . srcPath : path . join ( libRoot , libDir ) ;
129
+ }
97
130
}
98
131
}
99
132
}
100
133
101
- private async sortLibraries ( ) {
102
- if ( ! this . _arduinoApp . boardManager . currentBoard ) {
103
- return ;
134
+ private async loadBoardLibraries ( ) {
135
+ let builtinLibs = [ ] ;
136
+ const librarySet = new Set ( this . _libraryMap . keys ( ) ) ;
137
+ for ( let board of this . _arduinoApp . boardManager . platforms ) {
138
+ if ( board . installedVersion ) {
139
+ const libs = await this . parseBoardLibraries ( board . rootBoardPath , board . architecture , librarySet ) ;
140
+ builtinLibs = builtinLibs . concat ( libs ) ;
141
+ }
104
142
}
105
- this . _libraries . forEach ( ( _lib ) => {
106
- this . _sortedLibrary . push ( _lib ) ;
107
- } ) ;
108
-
109
- // Filter out not supported library according to the selected board type.
110
- let targetArch = this . _arduinoApp . boardManager . currentBoard . platform . architecture ;
111
- this . _sortedLibrary = this . _sortedLibrary . filter ( ( _lib ) => {
112
- let supportedArch = ( < string [ ] > _lib . architectures ) . find ( ( arch ) => {
113
- return arch . indexOf ( targetArch ) >= 0 || arch . indexOf ( "*" ) >= 0 ;
114
- } ) ;
115
- return supportedArch && supportedArch . length > 0 ;
116
- } ) ;
117
-
118
- this . _sortedLibrary . sort ( ( a , b ) => {
119
- return a . name > b . name ? 1 : - 1 ;
120
- } ) ;
121
- await this . addBuiltInLibs ( ) ;
143
+ return builtinLibs ;
122
144
}
123
145
124
- private async addBuiltInLibs ( ) {
125
- let currentBoard = this . _arduinoApp . boardManager . currentBoard ;
126
- if ( ! currentBoard ) {
127
- return ;
128
- }
129
- let rootBoardPath = currentBoard . platform . rootBoardPath ;
146
+ private async parseBoardLibraries ( rootBoardPath , architecture , librarySet : Set < any > ) {
130
147
let builtInLib = [ ] ;
131
148
let builtInLibPath = path . join ( rootBoardPath , "libraries" ) ;
132
149
if ( util . directoryExistsSync ( builtInLibPath ) ) {
133
150
let libDirs = util . filterJunk ( fs . readdirSync ( builtInLibPath ) ) ;
134
151
if ( ! libDirs || ! libDirs . length ) {
135
- return ;
152
+ return builtInLib ;
136
153
}
137
154
for ( let libDir of libDirs ) {
138
155
if ( ! util . fileExistsSync ( path . join ( builtInLibPath , libDir , "library.properties" ) ) ) {
139
- continue ;
156
+ const properties = < ILibrary > { } ;
157
+ properties . name = libDir ;
158
+ properties . builtIn = true ;
159
+ properties . installedPath = path . join ( builtInLibPath , libDir ) ;
160
+ properties . srcPath = path . join ( builtInLibPath , libDir , "src" ) ;
161
+ // If lib src folder doesn't exist, then fallback to lib root path as source folder.
162
+ properties . srcPath = util . directoryExistsSync ( properties . srcPath ) ? properties . srcPath : path . join ( builtInLibPath , libDir ) ;
163
+ properties . installed = true ;
164
+ properties . architectures = [ architecture ] ;
165
+ // For libraries with the same name, append architecture info to name to avoid duplication.
166
+ if ( librarySet . has ( properties . name ) ) {
167
+ properties . name = properties . name + "(" + architecture + ")" ;
168
+ }
169
+ librarySet . add ( properties . name ) ;
170
+ builtInLib . push ( properties ) ;
171
+ } else {
172
+ let properties = < any > await util . parseProperties ( path . join ( builtInLibPath , libDir , "library.properties" ) ) ;
173
+ properties . version = util . formatVersion ( properties . version ) ;
174
+ properties . builtIn = true ;
175
+ properties . installedPath = path . join ( builtInLibPath , libDir ) ;
176
+ properties . srcPath = path . join ( builtInLibPath , libDir , "src" ) ;
177
+ // If lib src folder doesn't exist, then fallback to lib root path as source folder.
178
+ properties . srcPath = util . directoryExistsSync ( properties . srcPath ) ? properties . srcPath : path . join ( builtInLibPath , libDir ) ;
179
+ properties . installed = true ;
180
+ properties . website = properties . url ;
181
+ properties . architectures = [ architecture ] ;
182
+ // For libraries with the same name, append architecture info to name to avoid duplication.
183
+ if ( librarySet . has ( properties . name ) ) {
184
+ properties . name = properties . name + "(" + architecture + ")" ;
185
+ }
186
+ librarySet . add ( properties . name ) ;
187
+ builtInLib . push ( properties ) ;
140
188
}
141
- let properties = < any > await util . parseProperties ( path . join ( builtInLibPath , libDir , "library.properties" ) ) ;
142
- properties . version = util . formatVersion ( properties . version ) ;
143
- properties . builtIn = true ;
144
- properties . installedPath = path . join ( builtInLibPath , libDir ) ;
145
- properties . srcPath = path . join ( builtInLibPath , libDir , "src" ) ;
146
- // If lib src folder doesn't exist, then fallback to lib root path as source folder.
147
- properties . srcPath = util . directoryExistsSync ( properties . srcPath ) ? properties . srcPath : path . join ( builtInLibPath , libDir ) ;
148
- properties . installed = true ;
149
- properties . website = properties . url ;
150
- builtInLib . push ( properties ) ;
151
189
}
152
190
}
191
+ return builtInLib ;
192
+ }
153
193
154
- this . _sortedLibrary = builtInLib . concat ( this . _sortedLibrary ) ;
194
+ private tagSupportedLibraries ( ) {
195
+ const currentBoard = this . _arduinoApp . boardManager . currentBoard ;
196
+ if ( ! currentBoard ) {
197
+ return ;
198
+ }
199
+ let targetArch = currentBoard . platform . architecture ;
200
+ this . _libraries . forEach ( ( library ) => {
201
+ library . supported = ! ! ( < string [ ] > library . architectures ) . find ( ( arch ) => {
202
+ return arch . indexOf ( targetArch ) >= 0 || arch . indexOf ( "*" ) >= 0 ;
203
+ } ) ;
204
+ } ) ;
155
205
}
156
206
}
0 commit comments