Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions cmd/dbc/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ type writeDriverManifestMsg struct {
DriverInfo config.DriverInfo
}

type localInstallMsg struct{}

type installState int

const (
Expand Down Expand Up @@ -162,9 +164,16 @@ type progressiveInstallModel struct {
p dbc.FileProgressModel

width, height int
isLocal bool
}

func (m progressiveInstallModel) Init() tea.Cmd {
if strings.HasSuffix(m.Driver, ".tar.gz") || strings.HasSuffix(m.Driver, ".tgz") {
return tea.Batch(m.spinner.Tick, func() tea.Msg {
return localInstallMsg{}
})
}

return tea.Batch(m.spinner.Tick, func() tea.Msg {
drivers, err := m.getDriverRegistry()
if err != nil {
Expand Down Expand Up @@ -281,6 +290,17 @@ func (m progressiveInstallModel) startDownloading() (tea.Model, tea.Cmd) {

func (m progressiveInstallModel) startInstalling(downloaded *os.File) (tea.Model, tea.Cmd) {
m.state = stInstalling
if m.isLocal {
driverName := strings.TrimSuffix(
strings.TrimSuffix(filepath.Base(m.Driver), ".tar.gz"), ".tgz")
parts := strings.Split(driverName, "_"+config.PlatformTuple()+"_")
if len(parts) < 2 {
m.Driver = driverName
} else {
m.Driver = parts[0] // drivername_platform_arch_version grab drivername
}
}

return m, func() tea.Msg {
if m.conflictingInfo.ID != "" {
if err := config.UninstallDriver(m.cfg, m.conflictingInfo); err != nil {
Expand Down Expand Up @@ -313,6 +333,17 @@ func (m progressiveInstallModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, cmd
case []dbc.Driver:
return m.searchForDriver(msg)
case localInstallMsg:
m.isLocal = true
return m, tea.Sequence(
tea.Printf("Installing from local package: %s\n", m.Driver),
func() tea.Msg {
localDrv, err := os.Open(m.Driver)
if err != nil {
return err
}
return localDrv
})
case dbc.PkgInfo:
m.DriverPackage = msg
di, err := config.GetDriver(m.cfg, m.Driver)
Expand All @@ -324,6 +355,10 @@ func (m progressiveInstallModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case *os.File:
return m.startInstalling(msg)
case config.Manifest:
if m.DriverPackage.Version == nil {
m.DriverPackage = msg.ToPackageInfo()
}

m.state = stVerifying
m.postInstallMessage = strings.Join(msg.PostInstall.Messages, "\n")
return m, func() tea.Msg {
Expand Down Expand Up @@ -372,6 +407,10 @@ func (m progressiveInstallModel) View() string {

var b strings.Builder
for s := range stDone {
if m.isLocal && (s == stSearching || s == stDownloading) {
continue
}

if s == m.state {
fmt.Fprintf(&b, "[%s] %s...", m.spinner.View(), s.String())
if s == stDownloading {
Expand Down
59 changes: 59 additions & 0 deletions cmd/dbc/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,62 @@ func (suite *SubcommandTestSuite) TestInstallCreatesSymlinks() {
suite.NoError(err)
suite.Equal(os.ModeSymlink, info.Mode()&os.ModeSymlink, "Expected test-driver-1.toml to be a symlink")
}

func (suite *SubcommandTestSuite) TestInstallLocalPackage() {
packagePath := filepath.Join("testdata", "test-driver-1.tar.gz")
m := InstallCmd{Driver: packagePath, Level: suite.configLevel}.
GetModelCustom(baseModel{getDriverRegistry: getTestDriverRegistry, downloadPkg: downloadTestPkg})
out := suite.runCmd(m)

suite.validateOutput("Installing from local package: "+packagePath+"\r\n\r\n\r"+
"[✓] installing\r\n[✓] verifying signature\r\n",
"\nInstalled test-driver-1 1.0.0 to "+suite.Dir()+"\n", out)
suite.driverIsInstalled("test-driver-1", true)
}

func (suite *SubcommandTestSuite) TestInstallLocalPackageNotFound() {
packagePath := filepath.Join("testdata", "test-driver-2.tar.gz")
m := InstallCmd{Driver: packagePath, Level: suite.configLevel}.
GetModelCustom(baseModel{getDriverRegistry: getTestDriverRegistry, downloadPkg: downloadTestPkg})
out := suite.runCmdErr(m)

errmsg := "no such file or directory"
if runtime.GOOS == "windows" {
errmsg = "The system cannot find the file specified."
}
suite.validateOutput("Installing from local package: "+packagePath+"\r\n\r\nError: open "+packagePath+
": "+errmsg+"\r\n\r ", "", out)
suite.driverIsNotInstalled("test-driver-2")
}

func (suite *SubcommandTestSuite) TestInstallLocalPackageNoSignature() {
packagePath := filepath.Join("testdata", "test-driver-no-sig.tar.gz")
m := InstallCmd{Driver: packagePath}.
GetModelCustom(baseModel{getDriverRegistry: getTestDriverRegistry, downloadPkg: downloadTestPkg})
out := suite.runCmdErr(m)
suite.Contains(out, "signature file 'test-driver-1-not-valid.so.sig' for driver is missing")

suite.Empty(suite.getFilesInTempDir())
suite.NoDirExists(filepath.Join(suite.tempdir, "test-driver-no-sig"))

m = InstallCmd{Driver: packagePath, NoVerify: true}.
GetModelCustom(baseModel{getDriverRegistry: getTestDriverRegistry, downloadPkg: downloadTestPkg})
suite.validateOutput("Installing from local package: "+packagePath+"\r\n\r\n\r"+
"[✓] installing\r\n[✓] verifying signature\r\n",
"\nInstalled test-driver-no-sig 1.1.0 to "+suite.tempdir+"\n", suite.runCmd(m))
}

func (suite *SubcommandTestSuite) TestInstallLocalPackageFixUpName() {
origPackagePath, err := filepath.Abs(filepath.Join("testdata", "test-driver-1.tar.gz"))
suite.Require().NoError(err)
packagePath := filepath.Join(suite.tempdir, "test-driver-1_"+config.PlatformTuple()+"_v1.0.0.tgz")
suite.Require().NoError(os.Symlink(origPackagePath, packagePath))
m := InstallCmd{Driver: packagePath, Level: suite.configLevel}.
GetModelCustom(baseModel{getDriverRegistry: getTestDriverRegistry, downloadPkg: downloadTestPkg})
out := suite.runCmd(m)

suite.validateOutput("Installing from local package: "+packagePath+"\r\n\r\n\r"+
"[✓] installing\r\n[✓] verifying signature\r\n",
"\nInstalled test-driver-1 1.0.0 to "+suite.Dir()+"\n", out)
suite.driverIsInstalled("test-driver-1", true)
}
2 changes: 1 addition & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func InstallDriver(cfg Config, shortName string, downloaded *os.File) (Manifest,
if loc, err = EnsureLocation(cfg); err != nil {
return Manifest{}, fmt.Errorf("could not ensure config location: %w", err)
}
base := strings.TrimSuffix(filepath.Base(downloaded.Name()), ".tar.gz")
base := strings.TrimSuffix(strings.TrimSuffix(filepath.Base(downloaded.Name()), ".tar.gz"), ".tgz")
finalDir := filepath.Join(loc, base)

if err := os.MkdirAll(finalDir, 0o755); err != nil {
Expand Down
12 changes: 12 additions & 0 deletions config/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"strings"

"github.com/Masterminds/semver/v3"
"github.com/columnar-tech/dbc"
"github.com/pelletier/go-toml/v2"
)

Expand All @@ -42,6 +43,17 @@ type Manifest struct {
} `toml:"PostInstall,omitempty"`
}

func (m Manifest) ToPackageInfo() dbc.PkgInfo {
return dbc.PkgInfo{
Driver: dbc.Driver{
Title: m.Name,
Path: m.ID,
License: m.License,
},
Version: m.Version,
}
}

type DriverInfo struct {
ID string
FilePath string
Expand Down
Loading