mirror of https://github.com/mvdan/fdroidcl.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
2.5 KiB
121 lines
2.5 KiB
// Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc> |
|
// See LICENSE for licensing information |
|
|
|
package main |
|
|
|
import ( |
|
"bufio" |
|
"fmt" |
|
"os" |
|
"regexp" |
|
"sort" |
|
"strings" |
|
) |
|
|
|
var cmdList = &Command{ |
|
UsageLine: "list (categories/users/repos)", |
|
Short: "List all known values of a kind", |
|
} |
|
|
|
func init() { |
|
cmdList.Run = runList |
|
} |
|
|
|
func runList(args []string) error { |
|
if len(args) != 1 { |
|
return fmt.Errorf("need exactly one argument") |
|
} |
|
apps, err := loadIndexes() |
|
if err != nil { |
|
return err |
|
} |
|
values := make(map[string]struct{}) |
|
switch args[0] { |
|
case "categories": |
|
for _, app := range apps { |
|
for _, c := range app.Categories { |
|
values[c] = struct{}{} |
|
} |
|
} |
|
case "users": |
|
if err := listUsers(); err != nil { |
|
return err |
|
} |
|
case "repos": |
|
for _, app := range apps { |
|
values[app.FdroidRepoName] = struct{}{} |
|
} |
|
default: |
|
return fmt.Errorf("invalid argument") |
|
} |
|
result := make([]string, 0, len(values)) |
|
for s := range values { |
|
result = append(result, s) |
|
} |
|
sort.Strings(result) |
|
for _, s := range result { |
|
fmt.Fprintln(os.Stdout, s) |
|
} |
|
return nil |
|
} |
|
|
|
var userIdNameRegex = regexp.MustCompile(`UserInfo{(\d+):([^:}]*):[^}]*}`) |
|
|
|
func listUsers() error { |
|
device, err := oneDevice() |
|
if err != nil { |
|
return err |
|
} |
|
cmd := device.AdbShell("pm", "list", "users") |
|
stdout, err := cmd.StdoutPipe() |
|
if err != nil { |
|
return err |
|
} |
|
if err := cmd.Start(); err != nil { |
|
return err |
|
} |
|
uidHeader := "UID" |
|
nameHeader := "Name" |
|
runningHeader := "Running" |
|
scanner := bufio.NewScanner(stdout) |
|
uids := make([]string, 0) |
|
names := make([]string, 0) |
|
running := make([]bool, 0) |
|
maxUidLen := len(uidHeader) |
|
maxNameLen := len(nameHeader) |
|
for scanner.Scan() { |
|
text := scanner.Text() |
|
m := userIdNameRegex.FindStringSubmatch(text) |
|
if m == nil { |
|
continue |
|
} |
|
uid := m[1] |
|
uids = append(uids, uid) |
|
if uidLen := len(uid); uidLen > maxUidLen { |
|
maxUidLen = uidLen |
|
} |
|
name := m[2] |
|
names = append(names, name) |
|
if nameLen := len(name); nameLen > maxNameLen { |
|
maxNameLen = nameLen |
|
} |
|
currentRunning := false |
|
if strings.HasSuffix(strings.TrimSpace(text), "running") { |
|
currentRunning = true |
|
} |
|
running = append(running, currentRunning) |
|
} |
|
if len(uids) == 0 { |
|
return nil |
|
} |
|
fmt.Printf("%-*s %-*s %s\n", maxUidLen, uidHeader, maxNameLen, nameHeader, runningHeader) |
|
for i, uid := range uids { |
|
name := names[i] |
|
runningStr := "" |
|
if running[i] { |
|
runningStr = "Yes" |
|
} |
|
fmt.Printf("%*s %-*s %s\n", maxUidLen, uid, maxNameLen, name, runningStr) |
|
} |
|
return nil |
|
}
|
|
|