@@ -22,15 +22,16 @@ import (
22
22
"encoding/hex"
23
23
"encoding/json"
24
24
"errors"
25
+ "fmt"
25
26
"io"
26
27
"net/http"
27
28
"os"
28
29
"os/exec"
29
30
"path/filepath"
30
31
"runtime"
31
- "strings"
32
32
33
33
"github.com/arduino/arduino-create-agent/v2/pkgs"
34
+ "github.com/arduino/go-paths-helper"
34
35
"github.com/blang/semver"
35
36
"github.com/codeclysm/extract/v3"
36
37
)
@@ -120,38 +121,46 @@ func (t *Tools) Download(pack, name, version, behaviour string) error {
120
121
return errors .New ("checksum doesn't match" )
121
122
}
122
123
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-" )
129
130
if err != nil {
130
- return err
131
+ return fmt . Errorf ( "creating temp dir for extraction: %s" , err )
131
132
}
133
+ defer tempDir .RemoveAll ()
132
134
135
+ t .logger ("Unpacking tool " + name )
133
136
ctx := context .Background ()
134
-
135
137
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 ()
145
145
if err != nil {
146
146
return err
147
147
}
148
148
149
+ // Check package content and find package root dir
150
+ root , err := findPackageRoot (tempDir )
149
151
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 )
152
153
}
153
154
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 ())
155
164
if err != nil {
156
165
return err
157
166
}
@@ -160,13 +169,27 @@ func (t *Tools) Download(pack, name, version, behaviour string) error {
160
169
t .logger ("Ensure that the files are executable" )
161
170
162
171
// Update the tool map
163
- t .logger ("Updating map with location " + location )
172
+ t .logger ("Updating map with location " + location . String () )
164
173
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 () )
167
176
return t .writeMap ()
168
177
}
169
178
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
+
170
193
func findTool (pack , name , version string , data pkgs.Index ) (pkgs.Tool , pkgs.System ) {
171
194
var correctTool pkgs.Tool
172
195
correctTool .Version = "0.0"
0 commit comments