Skip to content

fix: redirect postinstall script output to runtime output #2090

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Mar 10, 2023
37 changes: 28 additions & 9 deletions arduino/cores/packagemanager/install_uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package packagemanager

import (
"bytes"
"encoding/json"
"fmt"
"runtime"
Expand Down Expand Up @@ -174,9 +175,13 @@ func (pme *Explorer) DownloadAndInstallPlatformAndTools(
if !platformRelease.IsInstalled() {
return errors.New(tr("platform not installed"))
}
if err := pme.RunPostInstallScript(platformRelease.InstallDir); err != nil {
taskCB(&rpc.TaskProgress{Message: tr("WARNING cannot configure platform: %s", err)})
stdout, stderr, err := pme.RunPostInstallScript(platformRelease.InstallDir)
skipEmptyMessageTaskProgressCB(taskCB)(&rpc.TaskProgress{Message: string(stdout), Completed: true})
skipEmptyMessageTaskProgressCB(taskCB)(&rpc.TaskProgress{Message: string(stderr), Completed: true})
if err != nil {
taskCB(&rpc.TaskProgress{Message: tr("WARNING cannot configure platform: %s", err), Completed: true})
}

} else {
log.Info("Skipping platform configuration.")
taskCB(&rpc.TaskProgress{Message: tr("Skipping platform configuration.")})
Expand Down Expand Up @@ -226,7 +231,7 @@ func (pme *Explorer) cacheInstalledJSON(platformRelease *cores.PlatformRelease)

// RunPostInstallScript runs the post_install.sh (or post_install.bat) script for the
// specified platformRelease or toolRelease.
func (pme *Explorer) RunPostInstallScript(installDir *paths.Path) error {
func (pme *Explorer) RunPostInstallScript(installDir *paths.Path) ([]byte, []byte, error) {
postInstallFilename := "post_install.sh"
if runtime.GOOS == "windows" {
postInstallFilename = "post_install.bat"
Expand All @@ -235,14 +240,16 @@ func (pme *Explorer) RunPostInstallScript(installDir *paths.Path) error {
if postInstall.Exist() && postInstall.IsNotDir() {
cmd, err := executils.NewProcessFromPath(pme.GetEnvVarsForSpawnedProcess(), postInstall)
if err != nil {
return err
return []byte{}, []byte{}, err
}
cmdStdout, cmdStderr := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
cmd.RedirectStdoutTo(cmdStdout)
cmd.RedirectStderrTo(cmdStderr)
cmd.SetDirFromPath(installDir)
if err := cmd.Run(); err != nil {
return err
}
err = cmd.Run()
return cmdStdout.Bytes(), cmdStderr.Bytes(), err
}
return nil
return []byte{}, []byte{}, nil
}

// IsManagedPlatformRelease returns true if the PlatforRelease is managed by the PackageManager
Expand Down Expand Up @@ -335,7 +342,10 @@ func (pme *Explorer) InstallTool(toolRelease *cores.ToolRelease, taskCB rpc.Task
if !skipPostInstall {
log.Info("Running tool post_install script")
taskCB(&rpc.TaskProgress{Message: tr("Configuring tool.")})
if err := pme.RunPostInstallScript(toolRelease.InstallDir); err != nil {
stdout, stderr, err := pme.RunPostInstallScript(toolRelease.InstallDir)
skipEmptyMessageTaskProgressCB(taskCB)(&rpc.TaskProgress{Message: string(stdout)})
skipEmptyMessageTaskProgressCB(taskCB)(&rpc.TaskProgress{Message: string(stderr)})
if err != nil {
taskCB(&rpc.TaskProgress{Message: tr("WARNING cannot configure tool: %s", err)})
}
} else {
Expand Down Expand Up @@ -412,3 +422,12 @@ func (pme *Explorer) IsToolRequired(toolRelease *cores.ToolRelease) bool {
}
return false
}

func skipEmptyMessageTaskProgressCB(taskCB rpc.TaskProgressCB) rpc.TaskProgressCB {
return func(msg *rpc.TaskProgress) {
if msg != nil && len(msg.Message) == 0 {
return
}
taskCB(msg)
}
}
38 changes: 38 additions & 0 deletions arduino/cores/packagemanager/package_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"fmt"
"net/url"
"os"
"runtime"
"strings"
"testing"

"github.com/arduino/arduino-cli/arduino/cores"
Expand Down Expand Up @@ -639,3 +641,39 @@ func TestLegacyPackageConversionToPluggableDiscovery(t *testing.T) {
require.Equal(t, `"{network_cmd}" -address {upload.port.address} -port {upload.port.properties.port} -sketch "{build.path}/{build.project_name}.hex" -upload {upload.port.properties.endpoint_upload} -sync {upload.port.properties.endpoint_sync} -reset {upload.port.properties.endpoint_reset} -sync_exp {upload.port.properties.sync_return}`, platformProps.Get("tools.avrdude__pluggable_network.upload.pattern"))
}
}

func TestRunPostInstall(t *testing.T) {
pmb := packagemanager.NewBuilder(nil, nil, nil, nil, "test")
pm := pmb.Build()
pme, release := pm.NewExplorer()
defer release()

// prepare dummy post install script
dir := paths.New(t.TempDir())

var scriptPath *paths.Path
var err error
if runtime.GOOS == "windows" {
scriptPath = dir.Join("post_install.bat")

err = scriptPath.WriteFile([]byte(
`@echo off
echo sent in stdout
echo sent in stderr 1>&2`))
} else {
scriptPath = dir.Join("post_install.sh")
err = scriptPath.WriteFile([]byte(
`#!/bin/sh
echo "sent in stdout"
echo "sent in stderr" 1>&2`))
}
require.NoError(t, err)
err = os.Chmod(scriptPath.String(), 0777)
require.NoError(t, err)
stdout, stderr, err := pme.RunPostInstallScript(dir)
require.NoError(t, err)

// `HasPrefix` because windows seem to add a trailing space at the end
require.Equal(t, "sent in stdout", strings.Trim(string(stdout), "\n\r "))
require.Equal(t, "sent in stderr", strings.Trim(string(stderr), "\n\r "))
}