@@ -17,18 +17,25 @@ package main
1717
1818import (
1919 "context"
20+ "fmt"
2021 "os"
2122 "runtime"
23+ "strings"
2224
2325 "github.com/arduino/go-paths-helper"
2426 runas "github.com/arduino/go-windows-runas"
27+ "github.com/shirou/gopsutil/v4/disk"
2528 "github.com/spf13/cobra"
2629
2730 "github.com/arduino/arduino-flasher-cli/feedback"
2831 "github.com/arduino/arduino-flasher-cli/i18n"
2932 "github.com/arduino/arduino-flasher-cli/updater"
3033)
3134
35+ const GiB = uint64 (1024 * 1024 * 1024 )
36+ const DownloadDiskSpace = uint64 (12 )
37+ const ExtractDiskSpace = uint64 (10 )
38+
3239func newFlashCmd () * cobra.Command {
3340 var forceYes bool
3441 var tempDir string
@@ -90,12 +97,81 @@ func checkDriversInstalled() {
9097}
9198
9299func runFlashCommand (ctx context.Context , args []string , forceYes bool , tempDir string ) {
100+ version := args [0 ]
93101 imagePath , err := paths .New (args [0 ]).Abs ()
94102 if err != nil {
95103 feedback .Fatal (i18n .Tr ("could not find image absolute path: %v" , err ), feedback .ErrBadArgument )
96104 }
97105
98- err = updater .Flash (ctx , imagePath , args [0 ], forceYes , tempDir )
106+ if ! imagePath .Exist () {
107+ client := updater .NewClient ()
108+
109+ temp , err := updater .SetTempDir ("download-" , tempDir )
110+ if err != nil {
111+ feedback .Fatal (i18n .Tr ("error creating a temporary directory to extract the archive: %v" , err ), feedback .ErrBadArgument )
112+ }
113+ defer func () { _ = temp .RemoveAll () }()
114+
115+ // Check if there is enough free disk space before downloading and extracting an image
116+ d , err := disk .Usage (temp .String ())
117+ if err != nil {
118+ feedback .Fatal (err .Error (), feedback .ErrBadArgument )
119+ }
120+ if d .Free / GiB < DownloadDiskSpace {
121+ feedback .Fatal (i18n .Tr ("download and extraction requires up to %d GiB of free space" , DownloadDiskSpace ), feedback .ErrBadArgument )
122+ }
123+
124+ tempImagePath , v , err := updater .DownloadAndExtract (ctx , client , version , temp )
125+
126+ if err != nil {
127+ feedback .Fatal (i18n .Tr ("could not download and extract the image: %v" , err ), feedback .ErrBadArgument )
128+ }
129+
130+ defer func () { _ = tempImagePath .Parent ().RemoveAll () }()
131+
132+ version = v
133+ imagePath = tempImagePath
134+ } else if ! imagePath .IsDir () {
135+ temp , err := updater .SetTempDir ("extract-" , tempDir )
136+ if err != nil {
137+ feedback .Fatal (i18n .Tr ("error creating a temporary directory to extract the archive: %v" , err ), feedback .ErrBadArgument )
138+ }
139+ defer func () { _ = temp .RemoveAll () }()
140+
141+ // Check if there is enough free disk space before extracting an image
142+ d , err := disk .Usage (temp .String ())
143+ if err != nil {
144+ feedback .Fatal (err .Error (), feedback .ErrBadArgument )
145+ }
146+ if d .Free / GiB < ExtractDiskSpace {
147+ feedback .Fatal (i18n .Tr ("extraction requires up to %d GiB of free space" , ExtractDiskSpace ), feedback .ErrBadArgument )
148+ }
149+
150+ err = updater .ExtractImage (ctx , imagePath , temp )
151+ if err != nil {
152+ feedback .Fatal (i18n .Tr ("error extracting the archive: %v" , err ), feedback .ErrBadArgument )
153+ }
154+
155+ tempContent , err := temp .ReadDir (paths .AndFilter (paths .FilterDirectories (), paths .FilterPrefixes ("arduino-unoq-debian-image-" )))
156+ if err != nil {
157+ feedback .Fatal (i18n .Tr ("could not find Debian image directory: %v" , err ), feedback .ErrBadArgument )
158+ }
159+
160+ imagePath = tempContent [0 ]
161+ }
162+
163+ err = updater .FlashBoard (ctx , imagePath .String (), version , func (target string ) (bool , error ) {
164+ feedback .Print ("\n WARNING: flashing a new Linux image on the board will erase any existing data you have on it." )
165+ feedback .Printf ("Do you want to proceed and flash %s on the board? (yes/no)" , target )
166+
167+ var yesInput string
168+ _ , err := fmt .Scanf ("%s\n " , & yesInput )
169+ if err != nil {
170+ return false , err
171+ }
172+ yes := strings .ToLower (yesInput ) == "yes" || strings .ToLower (yesInput ) == "y"
173+ return yes , nil
174+ }, forceYes )
99175 if err != nil {
100176 feedback .Fatal (i18n .Tr ("error flashing the board: %v" , err ), feedback .ErrBadArgument )
101177 }
0 commit comments