@@ -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+
170193func 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