@@ -38,6 +38,7 @@ func (pme *Explorer) DownloadAndInstallPlatformUpgrades(
3838 downloadCB rpc.DownloadProgressCB ,
3939 taskCB rpc.TaskProgressCB ,
4040 skipPostInstall bool ,
41+ skipPreUninstall bool ,
4142) (* cores.PlatformRelease , error ) {
4243 if platformRef .PlatformVersion != nil {
4344 return nil , & arduino.InvalidArgumentError {Message : tr ("Upgrade doesn't accept parameters with version" )}
@@ -62,7 +63,7 @@ func (pme *Explorer) DownloadAndInstallPlatformUpgrades(
6263 if err != nil {
6364 return nil , & arduino.PlatformNotFoundError {Platform : platformRef .String ()}
6465 }
65- if err := pme .DownloadAndInstallPlatformAndTools (platformRelease , tools , downloadCB , taskCB , skipPostInstall ); err != nil {
66+ if err := pme .DownloadAndInstallPlatformAndTools (platformRelease , tools , downloadCB , taskCB , skipPostInstall , skipPreUninstall ); err != nil {
6667 return nil , err
6768 }
6869
@@ -75,7 +76,7 @@ func (pme *Explorer) DownloadAndInstallPlatformUpgrades(
7576func (pme * Explorer ) DownloadAndInstallPlatformAndTools (
7677 platformRelease * cores.PlatformRelease , requiredTools []* cores.ToolRelease ,
7778 downloadCB rpc.DownloadProgressCB , taskCB rpc.TaskProgressCB ,
78- skipPostInstall bool ) error {
79+ skipPostInstall bool , skipPreUninstall bool ) error {
7980 log := pme .log .WithField ("platform" , platformRelease )
8081
8182 // Prerequisite checks before install
@@ -142,15 +143,15 @@ func (pme *Explorer) DownloadAndInstallPlatformAndTools(
142143
143144 // If upgrading remove previous release
144145 if installed != nil {
145- uninstallErr := pme .UninstallPlatform (installed , taskCB )
146+ uninstallErr := pme .UninstallPlatform (installed , taskCB , skipPreUninstall )
146147
147148 // In case of error try to rollback
148149 if uninstallErr != nil {
149150 log .WithError (uninstallErr ).Error ("Error upgrading platform." )
150151 taskCB (& rpc.TaskProgress {Message : tr ("Error upgrading platform: %s" , uninstallErr )})
151152
152153 // Rollback
153- if err := pme .UninstallPlatform (platformRelease , taskCB ); err != nil {
154+ if err := pme .UninstallPlatform (platformRelease , taskCB , skipPreUninstall ); err != nil {
154155 log .WithError (err ).Error ("Error rolling-back changes." )
155156 taskCB (& rpc.TaskProgress {Message : tr ("Error rolling-back changes: %s" , err )})
156157 }
@@ -162,7 +163,7 @@ func (pme *Explorer) DownloadAndInstallPlatformAndTools(
162163 for _ , tool := range installedTools {
163164 taskCB (& rpc.TaskProgress {Name : tr ("Uninstalling %s, tool is no more required" , tool )})
164165 if ! pme .IsToolRequired (tool ) {
165- pme .UninstallTool (tool , taskCB )
166+ pme .UninstallTool (tool , taskCB , skipPreUninstall )
166167 }
167168 }
168169
@@ -175,7 +176,7 @@ func (pme *Explorer) DownloadAndInstallPlatformAndTools(
175176 if ! platformRelease .IsInstalled () {
176177 return errors .New (tr ("platform not installed" ))
177178 }
178- stdout , stderr , err := pme .RunPostInstallScript (platformRelease .InstallDir )
179+ stdout , stderr , err := pme .RunPreOrPostScript (platformRelease .InstallDir , "post_install" )
179180 skipEmptyMessageTaskProgressCB (taskCB )(& rpc.TaskProgress {Message : string (stdout ), Completed : true })
180181 skipEmptyMessageTaskProgressCB (taskCB )(& rpc.TaskProgress {Message : string (stderr ), Completed : true })
181182 if err != nil {
@@ -229,16 +230,16 @@ func (pme *Explorer) cacheInstalledJSON(platformRelease *cores.PlatformRelease)
229230 return nil
230231}
231232
232- // RunPostInstallScript runs the post_install.sh (or post_install.bat) script for the
233- // specified platformRelease or toolRelease.
234- func (pme * Explorer ) RunPostInstallScript (installDir * paths.Path ) ([]byte , []byte , error ) {
235- postInstallFilename := "post_install .sh"
233+ // RunPreOrPostScript runs either the post_install.sh (or post_install.bat) or the pre_uninstall.sh (or pre_uninstall.bat)
234+ // script for the specified platformRelease or toolRelease.
235+ func (pme * Explorer ) RunPreOrPostScript (installDir * paths.Path , prefix string ) ([]byte , []byte , error ) {
236+ scriptFilename := prefix + " .sh"
236237 if runtime .GOOS == "windows" {
237- postInstallFilename = "post_install .bat"
238+ scriptFilename = prefix + " .bat"
238239 }
239- postInstall := installDir .Join (postInstallFilename )
240- if postInstall .Exist () && postInstall .IsNotDir () {
241- cmd , err := executils .NewProcessFromPath (pme .GetEnvVarsForSpawnedProcess (), postInstall )
240+ script := installDir .Join (scriptFilename )
241+ if script .Exist () && script .IsNotDir () {
242+ cmd , err := executils .NewProcessFromPath (pme .GetEnvVarsForSpawnedProcess (), script )
242243 if err != nil {
243244 return []byte {}, []byte {}, err
244245 }
@@ -270,7 +271,7 @@ func (pme *Explorer) IsManagedPlatformRelease(platformRelease *cores.PlatformRel
270271}
271272
272273// UninstallPlatform remove a PlatformRelease.
273- func (pme * Explorer ) UninstallPlatform (platformRelease * cores.PlatformRelease , taskCB rpc.TaskProgressCB ) error {
274+ func (pme * Explorer ) UninstallPlatform (platformRelease * cores.PlatformRelease , taskCB rpc.TaskProgressCB , skipPreUninstall bool ) error {
274275 log := pme .log .WithField ("platform" , platformRelease )
275276
276277 log .Info ("Uninstalling platform" )
@@ -289,6 +290,20 @@ func (pme *Explorer) UninstallPlatform(platformRelease *cores.PlatformRelease, t
289290 return & arduino.FailedUninstallError {Message : err .Error ()}
290291 }
291292
293+ if ! skipPreUninstall {
294+ log .Info ("Running pre_uninstall script" )
295+ taskCB (& rpc.TaskProgress {Message : tr ("Running pre_uninstall script." )})
296+ stdout , stderr , err := pme .RunPreOrPostScript (platformRelease .InstallDir , "pre_uninstall" )
297+ skipEmptyMessageTaskProgressCB (taskCB )(& rpc.TaskProgress {Message : string (stdout ), Completed : true })
298+ skipEmptyMessageTaskProgressCB (taskCB )(& rpc.TaskProgress {Message : string (stderr ), Completed : true })
299+ if err != nil {
300+ taskCB (& rpc.TaskProgress {Message : tr ("WARNING cannot run pre_uninstall script: %s" , err ), Completed : true })
301+ }
302+ } else {
303+ log .Info ("Skipping pre_uninstall script." )
304+ taskCB (& rpc.TaskProgress {Message : tr ("Skipping pre_uninstall script." )})
305+ }
306+
292307 if err := platformRelease .InstallDir .RemoveAll (); err != nil {
293308 err = fmt .Errorf (tr ("removing platform files: %s" ), err )
294309 log .WithError (err ).Error ("Error uninstalling" )
@@ -339,7 +354,7 @@ func (pme *Explorer) InstallTool(toolRelease *cores.ToolRelease, taskCB rpc.Task
339354 if ! skipPostInstall {
340355 log .Info ("Running tool post_install script" )
341356 taskCB (& rpc.TaskProgress {Message : tr ("Configuring tool." )})
342- stdout , stderr , err := pme .RunPostInstallScript (toolRelease .InstallDir )
357+ stdout , stderr , err := pme .RunPreOrPostScript (toolRelease .InstallDir , "post_install" )
343358 skipEmptyMessageTaskProgressCB (taskCB )(& rpc.TaskProgress {Message : string (stdout )})
344359 skipEmptyMessageTaskProgressCB (taskCB )(& rpc.TaskProgress {Message : string (stderr )})
345360 if err != nil {
@@ -373,7 +388,7 @@ func (pme *Explorer) IsManagedToolRelease(toolRelease *cores.ToolRelease) bool {
373388}
374389
375390// UninstallTool remove a ToolRelease.
376- func (pme * Explorer ) UninstallTool (toolRelease * cores.ToolRelease , taskCB rpc.TaskProgressCB ) error {
391+ func (pme * Explorer ) UninstallTool (toolRelease * cores.ToolRelease , taskCB rpc.TaskProgressCB , skipPreUninstall bool ) error {
377392 log := pme .log .WithField ("Tool" , toolRelease )
378393 log .Info ("Uninstalling tool" )
379394
@@ -388,6 +403,20 @@ func (pme *Explorer) UninstallTool(toolRelease *cores.ToolRelease, taskCB rpc.Ta
388403 return err
389404 }
390405
406+ if ! skipPreUninstall {
407+ log .Info ("Running pre_uninstall script" )
408+ taskCB (& rpc.TaskProgress {Message : tr ("Running pre_uninstall script." )})
409+ stdout , stderr , err := pme .RunPreOrPostScript (toolRelease .InstallDir , "pre_uninstall" )
410+ skipEmptyMessageTaskProgressCB (taskCB )(& rpc.TaskProgress {Message : string (stdout ), Completed : true })
411+ skipEmptyMessageTaskProgressCB (taskCB )(& rpc.TaskProgress {Message : string (stderr ), Completed : true })
412+ if err != nil {
413+ taskCB (& rpc.TaskProgress {Message : tr ("WARNING cannot run pre_uninstall script: %s" , err ), Completed : true })
414+ }
415+ } else {
416+ log .Info ("Skipping pre_uninstall script." )
417+ taskCB (& rpc.TaskProgress {Message : tr ("Skipping pre_uninstall script." )})
418+ }
419+
391420 if err := toolRelease .InstallDir .RemoveAll (); err != nil {
392421 err = & arduino.FailedUninstallError {Message : err .Error ()}
393422 log .WithError (err ).Error ("Error uninstalling" )
0 commit comments