@@ -113,20 +113,20 @@ func (lm *LibrariesManager) Uninstall(lib *libraries.Library) error {
113
113
}
114
114
115
115
// InstallZipLib installs a Zip library on the specified path.
116
- func (lm * LibrariesManager ) InstallZipLib (ctx context.Context , archivePath string , overwrite bool ) error {
117
- libsDir := lm .getLibrariesDir (libraries .User )
118
- if libsDir == nil {
116
+ func (lm * LibrariesManager ) InstallZipLib (ctx context.Context , archivePath * paths. Path , overwrite bool ) error {
117
+ installDir := lm .getLibrariesDir (libraries .User )
118
+ if installDir == nil {
119
119
return fmt .Errorf (tr ("User directory not set" ))
120
120
}
121
121
122
- tmpDir , err := paths .MkTempDir (paths .TempDir ().String (), "arduino-cli-lib-" )
122
+ // Clone library in a temporary directory
123
+ tmpDir , err := paths .MkTempDir ("" , "" )
123
124
if err != nil {
124
125
return err
125
126
}
126
- // Deletes temp dir used to extract archive when finished
127
127
defer tmpDir .RemoveAll ()
128
128
129
- file , err := os .Open (archivePath )
129
+ file , err := archivePath .Open ()
130
130
if err != nil {
131
131
return err
132
132
}
@@ -138,48 +138,63 @@ func (lm *LibrariesManager) InstallZipLib(ctx context.Context, archivePath strin
138
138
return fmt .Errorf (tr ("extracting archive: %w" ), err )
139
139
}
140
140
141
- paths , err := tmpDir .ReadDir ()
141
+ libRootFiles , err := tmpDir .ReadDir ()
142
142
if err != nil {
143
143
return err
144
144
}
145
-
146
- // Ignores metadata from Mac OS X
147
- paths .FilterOutPrefix ("__MACOSX" )
148
-
149
- if len (paths ) > 1 {
145
+ libRootFiles .FilterOutPrefix ("__MACOSX" ) // Ignores metadata from Mac OS X
146
+ if len (libRootFiles ) > 1 {
150
147
return fmt .Errorf (tr ("archive is not valid: multiple files found in zip file top level" ))
151
148
}
149
+ if len (libRootFiles ) == 0 {
150
+ return fmt .Errorf (tr ("archive is not valid: no files found in zip file top level" ))
151
+ }
152
+ tmpInstallPath := libRootFiles [0 ]
152
153
153
- extractionPath := paths [0 ]
154
- libraryName := extractionPath .Base ()
155
-
156
- if err := validateLibrary (extractionPath ); err != nil {
154
+ // Check if the library is valid and load metatada
155
+ if err := validateLibrary (tmpInstallPath ); err != nil {
157
156
return err
158
157
}
159
-
160
- installPath := libsDir .Join (libraryName )
161
-
162
- if err := libsDir .MkdirAll (); err != nil {
158
+ library , err := libraries .Load (tmpInstallPath , libraries .User )
159
+ if err != nil {
163
160
return err
164
161
}
165
- defer func () {
166
- // Clean up install dir if installation failed
167
- files , err := installPath .ReadDir ()
168
- if err == nil && len (files ) == 0 {
169
- installPath .RemoveAll ()
170
- }
171
- }()
172
162
173
- // Delete library folder if already installed
174
- if installPath .IsDir () {
163
+ // Check if the library is already installed and determine install path
164
+ var installPath * paths.Path
165
+ libInstalled , libReplaced , err := lm .InstallPrerequisiteCheck (library .Name , library .Version , libraries .User )
166
+ if errors .Is (err , ErrAlreadyInstalled ) {
175
167
if ! overwrite {
176
- return fmt .Errorf (tr ("library %s already installed" ), libraryName )
168
+ return fmt .Errorf (tr ("library %s already installed" ), library . Name )
177
169
}
170
+ installPath = libInstalled
171
+ } else if err != nil {
172
+ return err
173
+ } else if libReplaced != nil {
174
+ if ! overwrite {
175
+ return fmt .Errorf (tr ("Library %[1]s is already installed, but with a different version: %[2]s" , library .Name , libReplaced ))
176
+ }
177
+ installPath = libReplaced .InstallDir
178
+ } else {
179
+ installPath = installDir .Join (library .Name )
180
+ if ! overwrite && installPath .IsDir () {
181
+ return fmt .Errorf (tr ("library %s already installed" , library .Name ))
182
+ }
183
+ }
184
+
185
+ // Deletes libraries folder if already installed
186
+ if installPath .IsDir () {
178
187
installPath .RemoveAll ()
179
188
}
189
+ if installPath .Exist () {
190
+ return fmt .Errorf (tr ("could not create directory %s: a file with the same name exists!" , installPath ))
191
+ }
180
192
181
193
// Copy extracted library in the destination directory
182
- if err := extractionPath .CopyDirTo (installPath ); err != nil {
194
+ if err := installDir .MkdirAll (); err != nil {
195
+ return err
196
+ }
197
+ if err := tmpInstallPath .CopyDirTo (installPath ); err != nil {
183
198
return fmt .Errorf (tr ("moving extracted archive to destination dir: %s" ), err )
184
199
}
185
200
0 commit comments