Skip to content

Commit 9ea0101

Browse files
committed
Fixed lib install --zip-path pre-install checks
Now it performs all the needed checks to avoid multiple installations
1 parent eb78cb6 commit 9ea0101

File tree

2 files changed

+48
-32
lines changed

2 files changed

+48
-32
lines changed

Diff for: arduino/libraries/librariesmanager/install.go

+46-31
Original file line numberDiff line numberDiff line change
@@ -113,20 +113,20 @@ func (lm *LibrariesManager) Uninstall(lib *libraries.Library) error {
113113
}
114114

115115
// 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 {
119119
return fmt.Errorf(tr("User directory not set"))
120120
}
121121

122-
tmpDir, err := paths.MkTempDir(paths.TempDir().String(), "arduino-cli-lib-")
122+
// Clone library in a temporary directory
123+
tmpDir, err := paths.MkTempDir("", "")
123124
if err != nil {
124125
return err
125126
}
126-
// Deletes temp dir used to extract archive when finished
127127
defer tmpDir.RemoveAll()
128128

129-
file, err := os.Open(archivePath)
129+
file, err := archivePath.Open()
130130
if err != nil {
131131
return err
132132
}
@@ -138,48 +138,63 @@ func (lm *LibrariesManager) InstallZipLib(ctx context.Context, archivePath strin
138138
return fmt.Errorf(tr("extracting archive: %w"), err)
139139
}
140140

141-
paths, err := tmpDir.ReadDir()
141+
libRootFiles, err := tmpDir.ReadDir()
142142
if err != nil {
143143
return err
144144
}
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 {
150147
return fmt.Errorf(tr("archive is not valid: multiple files found in zip file top level"))
151148
}
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]
152153

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 {
157156
return err
158157
}
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 {
163160
return err
164161
}
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-
}()
172162

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) {
175167
if !overwrite {
176-
return fmt.Errorf(tr("library %s already installed"), libraryName)
168+
return fmt.Errorf(tr("library %s already installed"), library.Name)
177169
}
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() {
178187
installPath.RemoveAll()
179188
}
189+
if installPath.Exist() {
190+
return fmt.Errorf(tr("could not create directory %s: a file with the same name exists!", installPath))
191+
}
180192

181193
// 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 {
183198
return fmt.Errorf(tr("moving extracted archive to destination dir: %s"), err)
184199
}
185200

Diff for: commands/lib/install.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/arduino/arduino-cli/arduino/libraries/librariesmanager"
2727
"github.com/arduino/arduino-cli/commands"
2828
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
29+
"github.com/arduino/go-paths-helper"
2930
"github.com/sirupsen/logrus"
3031
)
3132

@@ -156,7 +157,7 @@ func installLibrary(lm *librariesmanager.LibrariesManager, libRelease *libraries
156157
// ZipLibraryInstall FIXMEDOC
157158
func ZipLibraryInstall(ctx context.Context, req *rpc.ZipLibraryInstallRequest, taskCB rpc.TaskProgressCB) error {
158159
lm := commands.GetLibraryManager(req)
159-
if err := lm.InstallZipLib(ctx, req.Path, req.Overwrite); err != nil {
160+
if err := lm.InstallZipLib(ctx, paths.New(req.Path), req.Overwrite); err != nil {
160161
return &arduino.FailedLibraryInstallError{Cause: err}
161162
}
162163
taskCB(&rpc.TaskProgress{Message: tr("Library installed"), Completed: true})

0 commit comments

Comments
 (0)