Skip to content

Commit 4117277

Browse files
committed
the archives are first extracted in tmp and then moved to correct place
we remove the root dir if we find one. The logic is similar to: https://github.com/arduino/arduino-cli/blob/7a146635aaa740e748b84bf8fbfdccf1cc420c61/arduino/resources/install.go#L34
1 parent ac88c78 commit 4117277

File tree

1 file changed

+47
-24
lines changed

1 file changed

+47
-24
lines changed

tools/download.go

+47-24
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@ import (
2222
"encoding/hex"
2323
"encoding/json"
2424
"errors"
25+
"fmt"
2526
"io"
2627
"net/http"
2728
"os"
2829
"os/exec"
2930
"path/filepath"
3031
"runtime"
31-
"strings"
3232

3333
"github.com/arduino/arduino-create-agent/v2/pkgs"
34+
"github.com/arduino/go-paths-helper"
3435
"github.com/blang/semver"
3536
"github.com/codeclysm/extract/v3"
3637
)
@@ -120,38 +121,46 @@ func (t *Tools) Download(pack, name, version, behaviour string) error {
120121
return errors.New("checksum doesn't match")
121122
}
122123

123-
// Decompress
124-
t.logger("Unpacking tool " + name)
125-
126-
location := t.directory.Join(pack, correctTool.Name, correctTool.Version).String()
127-
err = os.RemoveAll(location)
128-
124+
tempPath := paths.TempDir()
125+
// Create a temporary dir to extract package
126+
if err := tempPath.MkdirAll(); err != nil {
127+
return fmt.Errorf("creating temp dir for extraction: %s", err)
128+
}
129+
tempDir, err := tempPath.MkTempDir("package-")
129130
if err != nil {
130-
return err
131+
return fmt.Errorf("creating temp dir for extraction: %s", err)
131132
}
133+
defer tempDir.RemoveAll()
132134

135+
t.logger("Unpacking tool " + name)
133136
ctx := context.Background()
134-
135137
reader := bytes.NewReader(body)
136-
err = extract.Archive(ctx, reader, location, func(original string) string {
137-
// Split the original path into components
138-
components := strings.Split(original, string(os.PathSeparator))
139-
// If there's a root directory, remove it
140-
if len(components) > 1 {
141-
return filepath.Join(components[1:]...)
142-
}
143-
return original
144-
})
138+
// Extract into temp directory
139+
if err := extract.Archive(ctx, reader, tempDir.String(), nil); err != nil {
140+
return fmt.Errorf("extracting archive: %s", err)
141+
}
142+
143+
location := t.directory.Join(pack, correctTool.Name, correctTool.Version)
144+
err = location.RemoveAll()
145145
if err != nil {
146146
return err
147147
}
148148

149+
// Check package content and find package root dir
150+
root, err := findPackageRoot(tempDir)
149151
if err != nil {
150-
t.logger("Error extracting the archive: " + err.Error())
151-
return err
152+
return fmt.Errorf("searching package root dir: %s", err)
152153
}
153154

154-
err = t.installDrivers(location)
155+
if err := root.Rename(location); err != nil {
156+
if err := root.CopyDirTo(location); err != nil {
157+
return fmt.Errorf("moving extracted archive to destination dir: %s", err)
158+
}
159+
}
160+
161+
// if the tool contains a post_install script, run it: it means it is a tool that needs to install drivers
162+
// AFAIK this is only the case for the windows-driver tool
163+
err = t.installDrivers(location.String())
155164
if err != nil {
156165
return err
157166
}
@@ -160,13 +169,27 @@ func (t *Tools) Download(pack, name, version, behaviour string) error {
160169
t.logger("Ensure that the files are executable")
161170

162171
// Update the tool map
163-
t.logger("Updating map with location " + location)
172+
t.logger("Updating map with location " + location.String())
164173

165-
t.setMapValue(name, location)
166-
t.setMapValue(name+"-"+correctTool.Version, location)
174+
t.setMapValue(name, location.String())
175+
t.setMapValue(name+"-"+correctTool.Version, location.String())
167176
return t.writeMap()
168177
}
169178

179+
func findPackageRoot(parent *paths.Path) (*paths.Path, error) {
180+
files, err := parent.ReadDir()
181+
if err != nil {
182+
return nil, fmt.Errorf("reading package root dir: %s", err)
183+
}
184+
files.FilterOutPrefix("__MACOSX")
185+
186+
// if there is only one dir, it is the root dir
187+
if len(files) == 1 && files[0].IsDir() {
188+
return files[0], nil
189+
}
190+
return parent, nil
191+
}
192+
170193
func findTool(pack, name, version string, data pkgs.Index) (pkgs.Tool, pkgs.System) {
171194
var correctTool pkgs.Tool
172195
correctTool.Version = "0.0"

0 commit comments

Comments
 (0)