diff --git a/adb/device.go b/adb/device.go index 88e8b68..4dedfb0 100644 --- a/adb/device.go +++ b/adb/device.go @@ -136,13 +136,8 @@ func getAbis(props map[string]string) []string { var installFailureRegex = regexp.MustCompile(`^Failure \[INSTALL_(.+)\]$`) -func withOpts(cmd string, opts []string, args ...string) []string { - v := append([]string{cmd}, opts...) - return append(v, args...) -} - -func (d *Device) install(opts []string, path string) error { - cmd := d.AdbCmd(withOpts("install", opts, path)...) +func (d *Device) Install(path string) error { + cmd := d.AdbCmd(append([]string{"install", "-r"}, path)...) output, err := cmd.CombinedOutput() if err != nil { return err @@ -154,14 +149,6 @@ func (d *Device) install(opts []string, path string) error { return parseError(getFailureCode(installFailureRegex, line)) } -func (d *Device) Install(path string) error { - return d.install(nil, path) -} - -func (d *Device) Upgrade(path string) error { - return d.install([]string{"-r"}, path) -} - func getResultLine(output []byte) string { scanner := bufio.NewScanner(bytes.NewReader(output)) for scanner.Scan() { diff --git a/cmd/fdroidcl/endtoend_test.go b/cmd/fdroidcl/endtoend_test.go index 342f0d9..016117b 100644 --- a/cmd/fdroidcl/endtoend_test.go +++ b/cmd/fdroidcl/endtoend_test.go @@ -128,15 +128,15 @@ func TestCommands(t *testing.T) { t.Run("SearchUpgradable", func(t *testing.T) { mustSucceed(t, regexp.QuoteMeta(chosenApp), ``, cmdSearch, "-u", "-q") }) - t.Run("Upgrade", func(t *testing.T) { - mustSucceed(t, `Upgrading `+regexp.QuoteMeta(chosenApp), ``, - cmdUpgrade, chosenApp) + t.Run("InstallUpgrade", func(t *testing.T) { + mustSucceed(t, `Installing `+regexp.QuoteMeta(chosenApp), ``, + cmdInstall, chosenApp) }) t.Run("SearchUpgradableUpToDate", func(t *testing.T) { mustSucceed(t, ``, regexp.QuoteMeta(chosenApp), cmdSearch, "-u", "-q") }) - t.Run("UpgradeAlreadyInstalled", func(t *testing.T) { - mustFail(t, `is up to date$`, ``, cmdUpgrade, chosenApp) + t.Run("InstallUpToDate", func(t *testing.T) { + mustSucceed(t, `is up to date$`, ``, cmdInstall, chosenApp) }) t.Run("UninstallExisting", func(t *testing.T) { mustSucceed(t, `Uninstalling `+regexp.QuoteMeta(chosenApp), ``, @@ -149,14 +149,14 @@ func mustRun(t *testing.T, success bool, wantRe, negRe string, cmd *Command, arg stdout, stderr = &buf, &buf err := cmd.Run(args) out := buf.String() + if err != nil { + out += err.Error() + } if success && err != nil { t.Fatalf("unexpected error: %v\n%s", err, out) } else if !success && err == nil { t.Fatalf("expected error, got none\n%s", out) } - if err != nil { - out += err.Error() - } // Let '.' match newlines, and treat the output as a single line. wantRe = "(?sm)" + wantRe if !regexp.MustCompile(wantRe).MatchString(out) { diff --git a/cmd/fdroidcl/install.go b/cmd/fdroidcl/install.go index b492fc5..fa4711f 100644 --- a/cmd/fdroidcl/install.go +++ b/cmd/fdroidcl/install.go @@ -12,7 +12,7 @@ import ( var cmdInstall = &Command{ UsageLine: "install ", - Short: "Install an app", + Short: "Install or upgrade an app", } func init() { @@ -35,15 +35,30 @@ func runInstall(args []string) error { if err != nil { return err } + var toInstall []*fdroidcl.App for _, app := range apps { - if _, e := inst[app.ID]; e { - return fmt.Errorf("%s is already installed", app.ID) + p, e := inst[app.ID] + if !e { + // installing an app from scratch + toInstall = append(toInstall, app) + continue } + suggested := app.SuggestedApk(device) + if suggested == nil { + return fmt.Errorf("no suitable APKs found for %s", app.ID) + } + if p.VCode >= suggested.VCode { + fmt.Fprintf(stdout, "%s is up to date\n", app.ID) + // app is already up to date + continue + } + // upgrading an existing app + toInstall = append(toInstall, app) } - return downloadAndDo(apps, device, installApk) + return downloadAndDo(toInstall, device) } -func downloadAndDo(apps []*fdroidcl.App, device *adb.Device, doApk func(*adb.Device, *fdroidcl.Apk, string) error) error { +func downloadAndDo(apps []*fdroidcl.App, device *adb.Device) error { type downloaded struct { apk *fdroidcl.Apk path string @@ -61,7 +76,7 @@ func downloadAndDo(apps []*fdroidcl.App, device *adb.Device, doApk func(*adb.Dev toInstall[i] = downloaded{apk: apk, path: path} } for _, t := range toInstall { - if err := doApk(device, t.apk, t.path); err != nil { + if err := installApk(device, t.apk, t.path); err != nil { return err } } diff --git a/cmd/fdroidcl/main.go b/cmd/fdroidcl/main.go index 21943be..9a0e259 100644 --- a/cmd/fdroidcl/main.go +++ b/cmd/fdroidcl/main.go @@ -162,12 +162,11 @@ var commands = []*Command{ cmdUpdate, cmdSearch, cmdShow, - cmdList, - cmdDevices, - cmdDownload, cmdInstall, - cmdUpgrade, cmdUninstall, + cmdDownload, + cmdDevices, + cmdList, cmdDefaults, cmdVersion, } diff --git a/cmd/fdroidcl/upgrade.go b/cmd/fdroidcl/upgrade.go deleted file mode 100644 index e74652f..0000000 --- a/cmd/fdroidcl/upgrade.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2015, Daniel Martí -// See LICENSE for licensing information - -package main - -import ( - "fmt" - - "mvdan.cc/fdroidcl" - "mvdan.cc/fdroidcl/adb" -) - -var cmdUpgrade = &Command{ - UsageLine: "upgrade ", - Short: "Upgrade an app", -} - -func init() { - cmdUpgrade.Run = runUpgrade -} - -func runUpgrade(args []string) error { - if len(args) < 1 { - return fmt.Errorf("no package names given") - } - apps, err := findApps(args) - if err != nil { - return err - } - device, err := oneDevice() - if err != nil { - return err - } - inst, err := device.Installed() - if err != nil { - return err - } - for _, app := range apps { - p, e := inst[app.ID] - if !e { - return fmt.Errorf("%s is not installed", app.ID) - } - suggested := app.SuggestedApk(device) - if suggested == nil { - return fmt.Errorf("no suitable APKs found for %s", app.ID) - } - if p.VCode >= suggested.VCode { - return fmt.Errorf("%s is up to date", app.ID) - } - } - return downloadAndDo(apps, device, upgradeApk) -} - -func upgradeApk(device *adb.Device, apk *fdroidcl.Apk, path string) error { - fmt.Fprintf(stdout, "Upgrading %s\n", apk.AppID) - if err := device.Upgrade(path); err != nil { - return fmt.Errorf("could not upgrade %s: %v", apk.AppID, err) - } - return nil -}