-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Automatically install Symflower with a fixed version for the CI, deve…
…lopment environment and evaluation benchmark Closes #47
- Loading branch information
Showing
12 changed files
with
326 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,11 +35,12 @@ install: # [<Go package] - # Build and install everything, or only the specified | |
go install -v $(PACKAGE) | ||
.PHONY: install | ||
|
||
install-all: install-tools-testing install # Install everything for and of this repository. | ||
install-all: install install-tools-testing # Install everything for and of this repository. | ||
.PHONY: install-all | ||
|
||
install-tools-testing: # Install tools that are used for testing. | ||
go install -v gotest.tools/[email protected] | ||
eval-dev-quality install-tools | ||
.PHONY: install-tools-testing | ||
|
||
test: # [<Go package] - # Test everything, or only the specified package. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/symflower/eval-dev-quality/log" | ||
_ "github.com/symflower/eval-dev-quality/provider/openrouter" | ||
_ "github.com/symflower/eval-dev-quality/provider/symflower" | ||
"github.com/symflower/eval-dev-quality/tools" | ||
) | ||
|
||
// InstallTools holds the "install-tools" command. | ||
type InstallTools struct { | ||
// InstallToolsPath determines where tools for the evaluation are installed. | ||
InstallToolsPath string `long:"install-tools-path" description:"Install tools for the evaluation into this path."` | ||
} | ||
|
||
// Execute executes the command. | ||
func (command *InstallTools) Execute(args []string) (err error) { | ||
log := log.STDOUT() | ||
|
||
if command.InstallToolsPath == "" { | ||
command.InstallToolsPath, err = tools.InstallPathDefault() | ||
if err != nil { | ||
log.Fatalf("ERROR: %s", err) | ||
} | ||
} | ||
|
||
if err := tools.Install(log, command.InstallToolsPath); err != nil { | ||
log.Fatalf("ERROR: %s", err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package cmd | ||
|
||
import ( | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
"github.com/zimmski/osutil" | ||
) | ||
|
||
func TestInstallToolsExecute(t *testing.T) { | ||
temporaryPath := t.TempDir() | ||
|
||
chmodPath, err := exec.LookPath("chmod") | ||
require.NoError(t, err) | ||
t.Setenv("PATH", strings.Join([]string{temporaryPath, filepath.Dir(chmodPath)}, string(os.PathListSeparator))) | ||
|
||
t.Run("Tools are not yet installed", func(t *testing.T) { | ||
symflowerPath, err := exec.LookPath("symflower") | ||
require.Error(t, err) | ||
require.Empty(t, symflowerPath) | ||
}) | ||
|
||
t.Run("Install tools for first time which should install all tools", func(t *testing.T) { | ||
output, err := osutil.Capture(func() { | ||
Execute([]string{ | ||
"install-tools", | ||
"--install-tools-path", temporaryPath, | ||
}) | ||
}) | ||
require.NoError(t, err) | ||
|
||
require.Contains(t, string(output), `Install "symflower" to`) | ||
symflowerPath, err := exec.LookPath("symflower") | ||
require.NoError(t, err) | ||
require.NotEmpty(t, symflowerPath) | ||
}) | ||
|
||
t.Run("Install tools a second time which should install no new tools", func(t *testing.T) { | ||
output, err := osutil.Capture(func() { | ||
Execute([]string{ | ||
"install-tools", | ||
"--install-tools-path", temporaryPath, | ||
}) | ||
}) | ||
require.NoError(t, err) | ||
|
||
require.NotContains(t, string(output), `Install "symflower" to`) | ||
symflowerPath, err := exec.LookPath("symflower") | ||
require.NoError(t, err) | ||
require.NotEmpty(t, symflowerPath) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package tools | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"log" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"regexp" | ||
"runtime" | ||
"strconv" | ||
"strings" | ||
|
||
pkgerrors "github.com/pkg/errors" | ||
"github.com/symflower/eval-dev-quality/util" | ||
"github.com/zimmski/osutil" | ||
) | ||
|
||
// SymflowerVersion holds the version of Symflower required for this revision of the evaluation. | ||
const SymflowerVersion = "35657" | ||
|
||
// SymflowerInstall checks if the "symflower" binary has been installed, and if yes, updates it if necessary and possible. | ||
func SymflowerInstall(log *log.Logger, installPath string) (err error) { | ||
installPath, err = filepath.Abs(installPath) | ||
if err != nil { | ||
return pkgerrors.WithStack(err) | ||
} | ||
|
||
// Check if install path is already used for binaries, or add it if not. | ||
installPathUsed := false | ||
for _, p := range strings.Split(os.Getenv(osutil.EnvironmentPathIdentifier), string(os.PathListSeparator)) { | ||
p = filepath.Clean(p) | ||
if p == installPath { | ||
installPathUsed = true | ||
|
||
break | ||
} | ||
} | ||
if !installPathUsed { | ||
os.Setenv(osutil.EnvironmentPathIdentifier, strings.Join([]string{os.Getenv(osutil.EnvironmentPathIdentifier), installPath}, string(os.PathListSeparator))) // Add the install path last, so we are not overwriting other binaries. | ||
} | ||
|
||
// Check if the "symflower" binary can already be used. | ||
symflowerPath, err := exec.LookPath("symflower") | ||
if err == nil { | ||
log.Printf("Checking \"symflower\" binary %s", symflowerPath) | ||
|
||
symflowerVersionOutput, _, err := util.CommandWithResult(log, &util.Command{ | ||
Command: []string{symflowerPath, "version"}, | ||
}) | ||
if err != nil { | ||
return pkgerrors.WithStack(err) | ||
} | ||
|
||
m := regexp.MustCompile(`symflower v(\d+) on`).FindStringSubmatch(symflowerVersionOutput) | ||
if m == nil { | ||
return pkgerrors.WithStack(pkgerrors.WithMessage(errors.New("cannot find version"), symflowerVersionOutput)) | ||
} | ||
|
||
// Currently the Symflower version is only one integer, so do a poor-man's version comparision. | ||
symflowerVersionInstalled, err := strconv.ParseUint(m[1], 10, 64) | ||
if err != nil { | ||
return pkgerrors.WithStack(err) | ||
} | ||
symflowerVersionWanted, err := strconv.ParseUint(m[1], 10, 64) | ||
if err != nil { | ||
return pkgerrors.WithStack(err) | ||
} | ||
|
||
// Binary is installed in a compatible verison. | ||
if symflowerVersionInstalled >= symflowerVersionWanted { | ||
return nil | ||
} | ||
|
||
// If the binary got installed by the user, let the user handle the update. | ||
if filepath.Dir(symflowerPath) != installPath { | ||
return pkgerrors.WithStack(fmt.Errorf("Found \"symflower\" binary with version %d but need at least %d", symflowerVersionInstalled, symflowerVersionWanted)) | ||
} | ||
} | ||
|
||
// Install Symflower, as it is either outdated or not installed at all. | ||
symflowerInstallPath := filepath.Join(installPath, "symflower") | ||
osIdentifier := runtime.GOOS | ||
var architectureIdentifier string | ||
switch a := runtime.GOARCH; a { | ||
case "386": | ||
architectureIdentifier = "x86" | ||
case "amd64": | ||
architectureIdentifier = "x86_64" | ||
case "arm": | ||
architectureIdentifier = "arm" | ||
case "arm64": | ||
architectureIdentifier = "arm64" | ||
default: | ||
return pkgerrors.WithStack(pkgerrors.WithMessage(err, fmt.Sprintf("unkown architecture %s", a))) | ||
} | ||
|
||
if err := os.MkdirAll(installPath, 0755); err != nil { | ||
return pkgerrors.WithStack(err) | ||
} | ||
|
||
log.Printf("Install \"symflower\" to %s", symflowerInstallPath) | ||
if err := osutil.DownloadFileWithProgress("https://download.symflower.com/local/v"+SymflowerVersion+"/symflower-"+osIdentifier+"-"+architectureIdentifier, symflowerInstallPath); err != nil { | ||
return pkgerrors.WithStack(pkgerrors.WithMessage(err, fmt.Sprintf("cannot download to %s", symflowerInstallPath))) | ||
} | ||
if _, _, err := util.CommandWithResult(log, &util.Command{ | ||
Command: []string{"chmod", "+x", symflowerInstallPath}, | ||
}); err != nil { | ||
return pkgerrors.WithStack(pkgerrors.WithMessage(err, fmt.Sprintf("cannot make %s executable", symflowerInstallPath))) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package tools | ||
|
||
import ( | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
"github.com/symflower/eval-dev-quality/log" | ||
) | ||
|
||
func TestSymflowerInstall(t *testing.T) { | ||
temporaryPath := t.TempDir() | ||
|
||
chmodPath, err := exec.LookPath("chmod") | ||
require.NoError(t, err) | ||
t.Setenv("PATH", strings.Join([]string{temporaryPath, filepath.Dir(chmodPath)}, string(os.PathListSeparator))) | ||
|
||
t.Run("Tools are not yet installed", func(t *testing.T) { | ||
symflowerPath, err := exec.LookPath("symflower") | ||
require.Error(t, err) | ||
require.Empty(t, symflowerPath) | ||
}) | ||
|
||
t.Run("Install tools for first time which should install all tools", func(t *testing.T) { | ||
logOutput, log := log.Buffer() | ||
require.NoError(t, SymflowerInstall(log, temporaryPath)) | ||
|
||
require.Contains(t, logOutput.String(), `Install "symflower" to`) | ||
symflowerPath, err := exec.LookPath("symflower") | ||
require.NoError(t, err) | ||
require.NotEmpty(t, symflowerPath) | ||
}) | ||
|
||
t.Run("Install tools a second time which should install no new tools", func(t *testing.T) { | ||
logOutput, log := log.Buffer() | ||
require.NoError(t, SymflowerInstall(log, temporaryPath)) | ||
|
||
require.NotContains(t, logOutput.String(), `Install "symflower" to`) | ||
symflowerPath, err := exec.LookPath("symflower") | ||
require.NoError(t, err) | ||
require.NotEmpty(t, symflowerPath) | ||
}) | ||
} |
Oops, something went wrong.