From 827b97b98fbc35da7c316256bbe1c51e4d74f47f Mon Sep 17 00:00:00 2001 From: rick Date: Sun, 29 Jan 2023 18:42:47 +0800 Subject: [PATCH] feat: add parameterize support to generic package --- pkg/os/fake/fake.go | 7 +++ pkg/os/fake/fake_test.go | 13 +++++- pkg/os/generic_installer.go | 36 +++++++++++--- pkg/os/generic_installer_test.go | 80 ++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 pkg/os/generic_installer_test.go diff --git a/pkg/os/fake/fake.go b/pkg/os/fake/fake.go index 299d480..5533df4 100644 --- a/pkg/os/fake/fake.go +++ b/pkg/os/fake/fake.go @@ -2,6 +2,7 @@ package fake import ( "fmt" + "github.com/linuxsuren/http-downloader/pkg/os/core" ) @@ -9,6 +10,7 @@ import ( type Installer struct { hasError bool support bool + data map[string]string } // NewFakeInstaller returns a Installer @@ -64,3 +66,8 @@ func (d *Installer) Stop() (err error) { } return } + +// SetURLReplace is a fake method +func (d *Installer) SetURLReplace(data map[string]string) { + d.data = data +} diff --git a/pkg/os/fake/fake_test.go b/pkg/os/fake/fake_test.go index 2ee2008..8e254c9 100644 --- a/pkg/os/fake/fake_test.go +++ b/pkg/os/fake/fake_test.go @@ -1,9 +1,10 @@ package fake import ( + "testing" + "github.com/linuxsuren/http-downloader/pkg/os/core" "github.com/stretchr/testify/assert" - "testing" ) func TestNewFakeInstaller(t *testing.T) { @@ -18,4 +19,14 @@ func TestNewFakeInstaller(t *testing.T) { ok, err := installer.WaitForStart() assert.True(t, ok) assert.NotNil(t, err) + + proxyAbleInstaller := &Installer{} + proxyAbleInstaller.SetURLReplace(map[string]string{ + "key": "value", + }) + assert.Equal(t, map[string]string{ + "key": "value", + }, proxyAbleInstaller.data) + + var _ core.ProxyAble = &Installer{} } diff --git a/pkg/os/generic_installer.go b/pkg/os/generic_installer.go index 231246b..06045d5 100644 --- a/pkg/os/generic_installer.go +++ b/pkg/os/generic_installer.go @@ -1,10 +1,13 @@ package os import ( + "bytes" "fmt" - "github.com/linuxsuren/http-downloader/pkg" "os" "strings" + "text/template" + + "github.com/linuxsuren/http-downloader/pkg" "github.com/linuxsuren/http-downloader/pkg/os/apk" "github.com/linuxsuren/http-downloader/pkg/os/dnf" @@ -47,6 +50,7 @@ type genericPackage struct { // inner fields proxyMap map[string]string + env map[string]string execer exec.Execer } @@ -71,15 +75,16 @@ func parseGenericPackages(configFile string, genericPackages *genericPackages) ( // GenericInstallerRegistry registries a generic installer func GenericInstallerRegistry(configFile string, registry core.InstallerRegistry) (err error) { + defaultExecer := exec.DefaultExecer{} genericPackages := &genericPackages{} if err = parseGenericPackages(configFile, genericPackages); err != nil { return } - defaultExecer := exec.DefaultExecer{} // registry all the packages for i := range genericPackages.Packages { genericPackage := genericPackages.Packages[i] + genericPackage.execer = defaultExecer switch genericPackage.PackageManager { case "apt-get": @@ -148,6 +153,7 @@ func (i *genericPackage) Available() (ok bool) { return } func (i *genericPackage) Install() (err error) { + i.loadEnv() for index := range i.PreInstall { preInstall := i.PreInstall[index] @@ -167,6 +173,7 @@ func (i *genericPackage) Install() (err error) { if needInstall { preInstall.Cmd.Args = i.sliceReplace(preInstall.Cmd.Args) + fmt.Println(preInstall.Cmd.Args) if err = i.execer.RunCommand(preInstall.Cmd.Cmd, preInstall.Cmd.Args...); err != nil { return @@ -212,16 +219,19 @@ func (i *genericPackage) SetURLReplace(data map[string]string) { func (i *genericPackage) sliceReplace(args []string) []string { for index, arg := range args { if result := i.urlReplace(arg); result != arg { - args[index] = result + args[index] = strings.TrimSpace(result) } } return args } func (i *genericPackage) urlReplace(old string) string { - if i.proxyMap == nil { - return old - } + if tpl, err := template.New("env").Parse(old); err == nil { + buf := bytes.NewBuffer([]byte{}) + if err = tpl.Execute(buf, i.env); err == nil { + old = buf.String() + } + } for k, v := range i.proxyMap { if !strings.Contains(old, k) { continue @@ -230,3 +240,17 @@ func (i *genericPackage) urlReplace(old string) string { } return old } +func (i *genericPackage) loadEnv() { + if i.env == nil { + i.env = map[string]string{} + } + if i.execer.OS() == exec.OSLinux { + if data, readErr := os.ReadFile("/etc/os-release"); readErr == nil { + for _, line := range strings.Split(string(data), "\n") { + if pair := strings.Split(line, "="); len(pair) == 2 { + i.env[fmt.Sprintf("OS_%s", pair[0])] = strings.TrimPrefix(strings.TrimSuffix(pair[1], `"`), `"`) + } + } + } + } +} diff --git a/pkg/os/generic_installer_test.go b/pkg/os/generic_installer_test.go new file mode 100644 index 0000000..f591cf8 --- /dev/null +++ b/pkg/os/generic_installer_test.go @@ -0,0 +1,80 @@ +package os + +import ( + "errors" + "testing" + + "github.com/linuxsuren/http-downloader/pkg/exec" + "github.com/linuxsuren/http-downloader/pkg/os/fake" + "github.com/stretchr/testify/assert" +) + +func TestURLReplace(t *testing.T) { + genericPkg := &genericPackage{ + env: map[string]string{ + "key": "value", + }, + execer: exec.FakeExecer{ExpectOS: exec.OSLinux}, + } + genericPkg.SetURLReplace(map[string]string{ + "github": "ghproxy", + }) + genericPkg.loadEnv() + assert.Equal(t, "ghproxy-value", genericPkg.urlReplace("github-{{.key}}")) + assert.Equal(t, "value", genericPkg.urlReplace("{{.key}}")) + assert.Equal(t, []string{"value"}, genericPkg.sliceReplace([]string{"{{.key}}"})) + + emptyGenericPkg := &genericPackage{ + execer: exec.FakeExecer{ExpectOS: exec.OSLinux}, + } + emptyGenericPkg.loadEnv() + assert.NotNil(t, emptyGenericPkg.env) + assert.Nil(t, emptyGenericPkg.Start()) + assert.Nil(t, emptyGenericPkg.Stop()) + assert.False(t, emptyGenericPkg.IsService()) + assert.False(t, emptyGenericPkg.Available()) + assert.NotNil(t, emptyGenericPkg.Install()) + assert.NotNil(t, emptyGenericPkg.Uninstall()) + ok, err := emptyGenericPkg.WaitForStart() + assert.True(t, ok) + assert.Nil(t, err) + + withPreInstall := &genericPackage{ + execer: exec.FakeExecer{ + ExpectOS: exec.OSLinux, + }, + PreInstall: []preInstall{{ + Cmd: CmdWithArgs{ + Cmd: "ls", + }, + }, { + IssuePrefix: "good", + Cmd: CmdWithArgs{ + Cmd: "ls", + }, + }, { + IssuePrefix: "Ubuntu", + Cmd: CmdWithArgs{ + Cmd: "ls", + }, + }}, + CommonInstaller: fake.NewFakeInstaller(true, false), + } + assert.Nil(t, withPreInstall.Install()) + + withErrorPreInstall := &genericPackage{ + execer: exec.FakeExecer{ + ExpectOS: exec.OSLinux, + ExpectError: errors.New("error"), + }, + PreInstall: []preInstall{{ + Cmd: CmdWithArgs{ + Cmd: "ls", + }, + }}, + CommonInstaller: fake.NewFakeInstaller(true, true), + } + assert.NotNil(t, withErrorPreInstall.Install()) + assert.NotNil(t, withErrorPreInstall.Uninstall()) + assert.True(t, withErrorPreInstall.Available()) +}