Browse Source

Finish splitting up commands

pull/8/head
Daniel Martí 11 years ago
parent
commit
adfd16a416
  1. 66
      cmd/fdroidcl/installed.go
  2. 8
      cmd/fdroidcl/list.go
  3. 204
      cmd/fdroidcl/main.go
  4. 58
      cmd/fdroidcl/search.go
  5. 112
      cmd/fdroidcl/show.go
  6. 20
      cmd/fdroidcl/update.go

66
cmd/fdroidcl/installed.go

@ -0,0 +1,66 @@
/* Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc> */
/* See LICENSE for licensing information */
package main
import (
"log"
"github.com/mvdan/fdroidcl"
"github.com/mvdan/fdroidcl/adb"
)
var cmdInstalled = &Command{
Name: "installed",
Short: "List installed apps",
}
func init() {
cmdInstalled.Run = runInstalled
}
func runInstalled(args []string) {
index := mustLoadIndex()
startAdbIfNeeded()
device := oneDevice()
installed := mustInstalled(device)
apps := filterAppsInstalled(index.Apps, installed)
printApps(apps)
}
func oneDevice() adb.Device {
devices, err := adb.Devices()
if err != nil {
log.Fatalf("Could not get devices: %v", err)
}
if len(devices) == 0 {
log.Fatalf("No devices found")
}
if len(devices) > 1 {
log.Fatalf("Too many devices found")
}
return devices[0]
}
func mustInstalled(device adb.Device) []string {
installed, err := device.Installed()
if err != nil {
log.Fatalf("Could not get installed packages: %v", err)
}
return installed
}
func filterAppsInstalled(apps []fdroidcl.App, installed []string) []fdroidcl.App {
instMap := make(map[string]struct{}, len(installed))
for _, id := range installed {
instMap[id] = struct{}{}
}
var result []fdroidcl.App
for _, app := range apps {
if _, e := instMap[app.ID]; !e {
continue
}
result = append(result, app)
}
return result
}

8
cmd/fdroidcl/list.go

@ -5,8 +5,10 @@ package main
import (
"encoding/hex"
"fmt"
"log"
"os"
"strings"
"github.com/mvdan/fdroidcl"
)
@ -57,3 +59,9 @@ func printApps(apps []fdroidcl.App) {
printApp(app, maxIDLen)
}
}
func printApp(app fdroidcl.App, IDLen int) {
fmt.Printf("%s%s %s %s\n", app.ID, strings.Repeat(" ", IDLen-len(app.ID)),
app.Name, app.CurApk.VName)
fmt.Printf(" %s\n", app.Summary)
}

204
cmd/fdroidcl/main.go

@ -8,133 +8,8 @@ import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
"github.com/mvdan/appdir"
"github.com/mvdan/fdroidcl"
"github.com/mvdan/fdroidcl/adb"
)
func appMatches(fields []string, terms []string) bool {
fieldLoop:
for _, field := range fields {
for _, term := range terms {
if !strings.Contains(field, term) {
continue fieldLoop
}
}
return true
}
return false
}
func filterAppsSearch(apps []fdroidcl.App, terms []string) []fdroidcl.App {
for _, term := range terms {
term = strings.ToLower(term)
}
var result []fdroidcl.App
for _, app := range apps {
fields := []string{
strings.ToLower(app.ID),
strings.ToLower(app.Name),
strings.ToLower(app.Summary),
strings.ToLower(app.Desc),
}
if !appMatches(fields, terms) {
continue
}
result = append(result, app)
}
return result
}
func filterAppsInstalled(apps []fdroidcl.App, installed []string) []fdroidcl.App {
instMap := make(map[string]struct{}, len(installed))
for _, id := range installed {
instMap[id] = struct{}{}
}
var result []fdroidcl.App
for _, app := range apps {
if _, e := instMap[app.ID]; !e {
continue
}
result = append(result, app)
}
return result
}
func printApp(app fdroidcl.App, IDLen int) {
fmt.Printf("%s%s %s %s\n", app.ID, strings.Repeat(" ", IDLen-len(app.ID)),
app.Name, app.CurApk.VName)
fmt.Printf(" %s\n", app.Summary)
}
func printAppDetailed(app fdroidcl.App) {
p := func(title string, format string, args ...interface{}) {
if format == "" {
fmt.Println(title)
} else {
fmt.Printf("%s %s\n", title, fmt.Sprintf(format, args...))
}
}
p("Package :", "%s", app.ID)
p("Name :", "%s", app.Name)
p("Summary :", "%s", app.Summary)
p("Current Version :", "%s (%d)", app.CurApk.VName, app.CurApk.VCode)
p("Upstream Version :", "%s (%d)", app.CVName, app.CVCode)
p("License :", "%s", app.License)
if app.Categs != nil {
p("Categories :", "%s", strings.Join(app.Categs, ", "))
}
if app.Website != "" {
p("Website :", "%s", app.Website)
}
if app.Source != "" {
p("Source :", "%s", app.Source)
}
if app.Tracker != "" {
p("Tracker :", "%s", app.Tracker)
}
if app.Changelog != "" {
p("Changelog :", "%s", app.Changelog)
}
if app.Donate != "" {
p("Donate :", "%s", app.Donate)
}
if app.Bitcoin != "" {
p("Bitcoin :", "bitcoin:%s", app.Bitcoin)
}
if app.Litecoin != "" {
p("Litecoin :", "litecoin:%s", app.Litecoin)
}
if app.Dogecoin != "" {
p("Dogecoin :", "dogecoin:%s", app.Dogecoin)
}
if app.FlattrID != "" {
p("Flattr :", "https://flattr.com/thing/%s", app.FlattrID)
}
fmt.Println()
p("Description :", "")
fmt.Println()
app.TextDesc(os.Stdout)
fmt.Println()
p("Available Versions :", "")
for _, apk := range app.Apks {
fmt.Println()
p(" Name :", "%s (%d)", apk.VName, apk.VCode)
p(" Size :", "%d", apk.Size)
p(" MinSdk :", "%d", apk.MinSdk)
if apk.MaxSdk > 0 {
p(" MaxSdk :", "%d", apk.MaxSdk)
}
if apk.ABIs != nil {
p(" ABIs :", "%s", strings.Join(apk.ABIs, ", "))
}
}
}
func init() {
flag.Usage = func() {
fmt.Fprintln(os.Stderr, "Usage: fdroidcl [-h] <command> [<args>]")
@ -149,44 +24,6 @@ func init() {
}
}
func appSubdir(appdir string) string {
p := filepath.Join(appdir, "fdroidcl")
if err := os.MkdirAll(p, 0755); err != nil {
log.Fatalf("Could not create app dir: %v", err)
}
return p
}
func indexPath(name string) string {
cache, err := appdir.Cache()
if err != nil {
log.Fatalf("Could not determine cache dir: %v", err)
}
return filepath.Join(appSubdir(cache), repoName+".jar")
}
func mustInstalled(device adb.Device) []string {
installed, err := device.Installed()
if err != nil {
log.Fatalf("Could not get installed packages: %v", err)
}
return installed
}
func oneDevice() adb.Device {
devices, err := adb.Devices()
if err != nil {
log.Fatalf("Could not get devices: %v", err)
}
if len(devices) == 0 {
log.Fatalf("No devices found")
}
if len(devices) > 1 {
log.Fatalf("Too many devices found")
}
return devices[0]
}
// A Command is an implementation of a go command
// like go build or go fix.
type Command struct {
@ -208,6 +45,10 @@ type Command struct {
var commands = []*Command{
cmdUpdate,
cmdList,
cmdSearch,
cmdShow,
cmdDevices,
cmdInstalled,
}
func main() {
@ -230,43 +71,6 @@ func main() {
}
switch args[0] {
case "search":
args = args[1:]
index := mustLoadIndex()
apps := filterAppsSearch(index.Apps, args)
printApps(apps)
case "show":
args = args[1:]
index := mustLoadIndex()
found := make(map[string]*fdroidcl.App, len(args))
for _, appID := range args {
found[appID] = nil
}
for i := range index.Apps {
app := &index.Apps[i]
_, e := found[app.ID]
if !e {
continue
}
found[app.ID] = app
}
for i, appID := range args {
app, _ := found[appID]
if app == nil {
log.Fatalf("Could not find app with ID '%s'", appID)
}
if i > 0 {
fmt.Printf("\n--\n\n")
}
printAppDetailed(*app)
}
case "installed":
index := mustLoadIndex()
startAdbIfNeeded()
device := oneDevice()
installed := mustInstalled(device)
apps := filterAppsInstalled(index.Apps, installed)
printApps(apps)
default:
log.Printf("Unrecognised command '%s'\n\n", args[0])
flag.Usage()

58
cmd/fdroidcl/search.go

@ -0,0 +1,58 @@
/* Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc> */
/* See LICENSE for licensing information */
package main
import (
"strings"
"github.com/mvdan/fdroidcl"
)
var cmdSearch = &Command{
Name: "search",
Short: "Search available apps",
}
func init() {
cmdSearch.Run = runSearch
}
func runSearch(args []string) {
index := mustLoadIndex()
apps := filterAppsSearch(index.Apps, args)
printApps(apps)
}
func filterAppsSearch(apps []fdroidcl.App, terms []string) []fdroidcl.App {
for _, term := range terms {
term = strings.ToLower(term)
}
var result []fdroidcl.App
for _, app := range apps {
fields := []string{
strings.ToLower(app.ID),
strings.ToLower(app.Name),
strings.ToLower(app.Summary),
strings.ToLower(app.Desc),
}
if !appMatches(fields, terms) {
continue
}
result = append(result, app)
}
return result
}
func appMatches(fields []string, terms []string) bool {
fieldLoop:
for _, field := range fields {
for _, term := range terms {
if !strings.Contains(field, term) {
continue fieldLoop
}
}
return true
}
return false
}

112
cmd/fdroidcl/show.go

@ -0,0 +1,112 @@
/* Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc> */
/* See LICENSE for licensing information */
package main
import (
"fmt"
"log"
"os"
"strings"
"github.com/mvdan/fdroidcl"
)
var cmdShow = &Command{
Name: "show",
Short: "Show detailed info of an app",
}
func init() {
cmdShow.Run = runShow
}
func runShow(args []string) {
index := mustLoadIndex()
found := make(map[string]*fdroidcl.App, len(args))
for _, appID := range args {
found[appID] = nil
}
for i := range index.Apps {
app := &index.Apps[i]
_, e := found[app.ID]
if !e {
continue
}
found[app.ID] = app
}
for i, appID := range args {
app, _ := found[appID]
if app == nil {
log.Fatalf("Could not find app with ID '%s'", appID)
}
if i > 0 {
fmt.Printf("\n--\n\n")
}
printAppDetailed(*app)
}
}
func printAppDetailed(app fdroidcl.App) {
p := func(title string, format string, args ...interface{}) {
if format == "" {
fmt.Println(title)
} else {
fmt.Printf("%s %s\n", title, fmt.Sprintf(format, args...))
}
}
p("Package :", "%s", app.ID)
p("Name :", "%s", app.Name)
p("Summary :", "%s", app.Summary)
p("Current Version :", "%s (%d)", app.CurApk.VName, app.CurApk.VCode)
p("Upstream Version :", "%s (%d)", app.CVName, app.CVCode)
p("License :", "%s", app.License)
if app.Categs != nil {
p("Categories :", "%s", strings.Join(app.Categs, ", "))
}
if app.Website != "" {
p("Website :", "%s", app.Website)
}
if app.Source != "" {
p("Source :", "%s", app.Source)
}
if app.Tracker != "" {
p("Tracker :", "%s", app.Tracker)
}
if app.Changelog != "" {
p("Changelog :", "%s", app.Changelog)
}
if app.Donate != "" {
p("Donate :", "%s", app.Donate)
}
if app.Bitcoin != "" {
p("Bitcoin :", "bitcoin:%s", app.Bitcoin)
}
if app.Litecoin != "" {
p("Litecoin :", "litecoin:%s", app.Litecoin)
}
if app.Dogecoin != "" {
p("Dogecoin :", "dogecoin:%s", app.Dogecoin)
}
if app.FlattrID != "" {
p("Flattr :", "https://flattr.com/thing/%s", app.FlattrID)
}
fmt.Println()
p("Description :", "")
fmt.Println()
app.TextDesc(os.Stdout)
fmt.Println()
p("Available Versions :", "")
for _, apk := range app.Apks {
fmt.Println()
p(" Name :", "%s (%d)", apk.VName, apk.VCode)
p(" Size :", "%d", apk.Size)
p(" MinSdk :", "%d", apk.MinSdk)
if apk.MaxSdk > 0 {
p(" MaxSdk :", "%d", apk.MaxSdk)
}
if apk.ABIs != nil {
p(" ABIs :", "%s", strings.Join(apk.ABIs, ", "))
}
}
}

20
cmd/fdroidcl/update.go

@ -6,6 +6,10 @@ package main
import (
"fmt"
"log"
"os"
"path/filepath"
"github.com/mvdan/appdir"
)
var cmdUpdate = &Command{
@ -30,3 +34,19 @@ func updateIndex() error {
}
return nil
}
func indexPath(name string) string {
cache, err := appdir.Cache()
if err != nil {
log.Fatalf("Could not determine cache dir: %v", err)
}
return filepath.Join(appSubdir(cache), repoName+".jar")
}
func appSubdir(appdir string) string {
p := filepath.Join(appdir, "fdroidcl")
if err := os.MkdirAll(p, 0755); err != nil {
log.Fatalf("Could not create app dir: %v", err)
}
return p
}

Loading…
Cancel
Save