Browse Source

support F-Droid's CSV export in install

Easy enough to do; we just read from stdin when given no arguments, and
convert the CSV fields to the argument string format.

Fixes #30.
pull/44/head
Daniel Martí 7 years ago
parent
commit
c4ec65d94e
  1. 2
      README.md
  2. 42
      install.go
  3. 12
      main.go
  4. 4
      testdata/scripts/cmds.txt
  5. 9
      testdata/scripts/device.txt

2
README.md

@ -30,7 +30,7 @@ Install an app:
update Update the index
search [<regexp...>] Search available apps
show <appid...> Show detailed info about an app
install <appid...> Install or upgrade apps
install [<appid...>] Install or upgrade apps
uninstall <appid...> Uninstall an app
download <appid...> Download an app
devices List connected devices

42
install.go

@ -4,7 +4,9 @@
package main
import (
"encoding/csv"
"fmt"
"io"
"os"
"mvdan.cc/fdroidcl/adb"
@ -12,8 +14,15 @@ import (
)
var cmdInstall = &Command{
UsageLine: "install <appid...>",
UsageLine: "install [<appid...>]",
Short: "Install or upgrade apps",
Long: `
Install or upgrade apps. When given no arguments, it reads a comma-separated
list of apps to install from standard input, like:
packageName,versionCode,versionName
foo.bar,120,1.2.0
`[1:],
}
var (
@ -26,12 +35,8 @@ func init() {
}
func runInstall(args []string) error {
if *installUpdates {
if len(args) > 0 {
return fmt.Errorf("-u can only be used without arguments")
}
} else if len(args) < 1 {
return fmt.Errorf("no package names given")
if *installUpdates && len(args) > 0 {
return fmt.Errorf("-u can only be used without arguments")
}
device, err := oneDevice()
if err != nil {
@ -54,6 +59,29 @@ func runInstall(args []string) error {
return downloadAndDo(apps, device)
}
if len(args) == 0 {
// The CSV input is as follows:
//
// packageName,versionCode,versionName
// foo.bar,120,1.2.0
// ...
r := csv.NewReader(os.Stdin)
r.FieldsPerRecord = 3
r.Read()
for {
record, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
return fmt.Errorf("error parsing CSV: %v", err)
}
// convert "foo.bar,120" into "foo.bar:120" for findApps
args = append(args, record[0]+":"+record[1])
}
}
apps, err := findApps(args)
if err != nil {
return err

12
main.go

@ -96,9 +96,12 @@ type Command struct {
// The first word in the line is taken to be the command name.
UsageLine string
// Short is the short description.
// Short is the short, single-line description.
Short string
// Long is an optional longer version of the Short description.
Long string
Fset flag.FlagSet
}
@ -113,7 +116,12 @@ func (c *Command) Name() string {
}
func (c *Command) usage() {
fmt.Fprintf(os.Stderr, "usage: %s %s\n", cmdName, c.UsageLine)
fmt.Fprintf(os.Stderr, "usage: %s %s\n\n", cmdName, c.UsageLine)
if c.Long == "" {
fmt.Fprintf(os.Stderr, "%s.\n", c.Short)
} else {
fmt.Fprint(os.Stderr, c.Long)
}
anyFlags := false
c.Fset.VisitAll(func(f *flag.Flag) { anyFlags = true })
if anyFlags {

4
testdata/scripts/cmds.txt vendored

@ -18,8 +18,12 @@ stderr '^usage: fdroidcl \[-h'
! fdroidcl search -h
stderr '^usage: fdroidcl search .*regexp'
stderr '^Search available apps.'
stderr '-i.*Filter installed apps'
! fdroidcl install -h
stderr 'When given no arguments'
! fdroidcl
! fdroidcl install -u some.app

9
testdata/scripts/device.txt vendored

@ -24,6 +24,11 @@ fdroidcl search -i -q
fdroidcl search -u -q
! stdout 'org\.vi_server\.red_screen'
# install via csv input works as expected
stdin applist.csv
fdroidcl install -n
stdout 'install org\.vi_server\.red_screen:1'
# install version code 1
fdroidcl install org.vi_server.red_screen:1
stdout 'Downloading.*red_screen_1.apk'
@ -57,3 +62,7 @@ stdout 'is up to date'
# uninstall an app that exists
fdroidcl uninstall org.vi_server.red_screen
-- applist.csv --
packageName,versionCode,versionName
org.vi_server.red_screen,1,1.0

Loading…
Cancel
Save