Skip to content

Commit

Permalink
Merge pull request #13 from moul/dev/moul/apk
Browse files Browse the repository at this point in the history
  • Loading branch information
moul committed Sep 29, 2020
2 parents ddb80a2 + 8590b44 commit 50ca8b8
Show file tree
Hide file tree
Showing 10 changed files with 460 additions and 28 deletions.
1 change: 1 addition & 0 deletions AUTHORS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Makefile
Expand Up @@ -2,10 +2,13 @@ GOPKG ?= moul.io/pkgman
DOCKER_IMAGE ?= moul/pkgman
GOBINS ?= .

PRE_UNITTEST_STEPS = testdata/gomobile-ipfs-demo-1.1.0.ipa
PRE_UNITTEST_STEPS = testdata/gomobile-ipfs-demo-1.1.0.ipa testdata/gomobile-ipfs-demo-1.2.1.apk
PRE_TEST_STEPS = $(PRE_UNITTEST_STEPS)
testdata/gomobile-ipfs-demo-1.1.0.ipa:
mkdir -p testdata
wget -N -O $@ "https://bintray.com/berty/gomobile-ipfs-demo/download_file?file_path=ios%2F1.1.0%2Fios-demo-1.1.0.ipa"
testdata/gomobile-ipfs-demo-1.2.1.apk:
mkdir -p testdata
wget -N -O $@ "https://bintray.com/berty/gomobile-ipfs-demo/download_file?file_path=android%2F1.2.1%2Fandroid-demo-1.2.1.apk"

include rules.mk
69 changes: 69 additions & 0 deletions depaware.txt
@@ -0,0 +1,69 @@
moul.io/pkgman dependencies: (generated by github.com/tailscale/depaware)

💣 github.com/avast/apkparser from moul.io/pkgman/pkg/apk
github.com/basgys/goxml2json from moul.io/pkgman/pkg/apk
github.com/klauspost/compress/flate from github.com/avast/apkparser
github.com/peterbourgon/ff/v3 from github.com/peterbourgon/ff/v3/ffcli
github.com/peterbourgon/ff/v3/ffcli from moul.io/pkgman
💣 howett.net/plist from moul.io/pkgman/pkg/ipa
moul.io/pkgman/pkg/apk from moul.io/pkgman
moul.io/pkgman/pkg/ipa from moul.io/pkgman
moul.io/u from moul.io/pkgman
golang.org/x/net/html from golang.org/x/net/html/charset
golang.org/x/net/html/atom from golang.org/x/net/html
golang.org/x/net/html/charset from github.com/basgys/goxml2json
golang.org/x/text/encoding from golang.org/x/net/html/charset+
golang.org/x/text/encoding/charmap from golang.org/x/net/html/charset+
golang.org/x/text/encoding/htmlindex from golang.org/x/net/html/charset
golang.org/x/text/encoding/internal from golang.org/x/text/encoding/charmap+
golang.org/x/text/encoding/japanese from golang.org/x/text/encoding/htmlindex
golang.org/x/text/encoding/korean from golang.org/x/text/encoding/htmlindex
golang.org/x/text/encoding/simplifiedchinese from golang.org/x/text/encoding/htmlindex
golang.org/x/text/encoding/traditionalchinese from golang.org/x/text/encoding/htmlindex
golang.org/x/text/encoding/unicode from golang.org/x/text/encoding/htmlindex
golang.org/x/text/language from golang.org/x/text/encoding/htmlindex
golang.org/x/text/runes from golang.org/x/text/encoding/unicode
golang.org/x/text/transform from golang.org/x/net/html/charset+
archive/zip from github.com/avast/apkparser+
bufio from archive/zip+
bytes from bufio+
compress/flate from archive/zip
context from github.com/peterbourgon/ff/v3/ffcli+
crypto from crypto/sha1
crypto/sha1 from moul.io/u
encoding from encoding/json+
encoding/base64 from encoding/json+
encoding/binary from archive/zip+
encoding/hex from howett.net/plist
encoding/json from github.com/peterbourgon/ff/v3+
encoding/xml from github.com/avast/apkparser+
errors from archive/zip+
flag from github.com/peterbourgon/ff/v3+
fmt from compress/flate+
hash from archive/zip+
hash/crc32 from archive/zip+
io from archive/zip+
io/ioutil from archive/zip+
log from moul.io/pkgman
math from compress/flate+
math/bits from compress/flate+
mime from golang.org/x/net/html/charset
os from archive/zip+
os/exec from moul.io/u
os/signal from moul.io/u
path from archive/zip+
path/filepath from io/ioutil+
reflect from encoding/binary+
runtime/debug from github.com/avast/apkparser
sort from compress/flate+
strconv from compress/flate+
strings from archive/zip+
sync from archive/zip+
sync/atomic from context+
syscall from internal/poll+
text/tabwriter from github.com/peterbourgon/ff/v3/ffcli
time from archive/zip+
unicode from bytes+
unicode/utf16 from encoding/json+
unicode/utf8 from archive/zip+
unsafe from github.com/avast/apkparser+
8 changes: 7 additions & 1 deletion go.mod

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 32 additions & 10 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 28 additions & 2 deletions main.go
Expand Up @@ -8,8 +8,9 @@ import (
"os"

"github.com/peterbourgon/ff/v3/ffcli"
"moul.io/godev"
"moul.io/pkgman/pkg/apk"
"moul.io/pkgman/pkg/ipa"
"moul.io/u"
)

func main() {
Expand All @@ -28,6 +29,11 @@ func run(args []string) error {
ShortUsage: "ipa-plist-json PATH",
Exec: runIpaPlistJSON,
},
{
Name: "apk-manifest",
ShortUsage: "apk-manifest",
Exec: runApkManifest,
},
},
Exec: func(context.Context, []string) error { return flag.ErrHelp },
}
Expand All @@ -50,8 +56,28 @@ func runIpaPlistJSON(_ context.Context, args []string) error {
if err != nil {
return err
}
fmt.Println(godev.PrettyJSON(plist))
fmt.Println(u.PrettyJSON(plist))
}
}
return nil
}

func runApkManifest(_ context.Context, args []string) error {
if len(args) < 1 {
return flag.ErrHelp
}
for _, arg := range args {
pkg, err := apk.Open(arg)
if err != nil {
return err
}
defer pkg.Close()

manifest, err := pkg.Manifest()
if err != nil {
return err
}
fmt.Println(u.PrettyJSON(manifest))
}
return nil
}
106 changes: 106 additions & 0 deletions pkg/apk/apk.go
@@ -0,0 +1,106 @@
package apk

import (
"archive/zip"
"bufio"
"bytes"
"encoding/xml"
"fmt"
"io/ioutil"
"strings"

"github.com/avast/apkparser"
xml2json "github.com/basgys/goxml2json"
)

type Package struct {
r *zip.ReadCloser
}

func Open(path string) (*Package, error) {
r, err := zip.OpenReader(path)
if err != nil {
return nil, fmt.Errorf("open path: %w", err)
}
return &Package{r: r}, nil
}

func (p *Package) Close() error {
return nil
}

func (p Package) Files() []*zip.File {
return p.r.File
}

func (p Package) File(name string) *zip.File {
for _, f := range p.r.File {
if f.Name == name {
return f
}
}
return nil
}

func (p Package) FileBytes(name string) ([]byte, error) {
f := p.File(name)
if f == nil {
return nil, fmt.Errorf("no such file: %s", name)
}

r, err := f.Open()
if err != nil {
return nil, err
}

return ioutil.ReadAll(r)
}

func (p Package) ManifestXML() (string, error) {
b, err := p.FileBytes("AndroidManifest.xml")
if err != nil {
return "", err
}
binbuf := bytes.NewBuffer(b)

xmlbuf := bytes.Buffer{}
xmlwriter := bufio.NewWriter(&xmlbuf)
enc := xml.NewEncoder(xmlwriter)
enc.Indent(" ", " ")
err = apkparser.ParseXml(binbuf, enc, nil)
if err != nil {
return "", err
}

return xmlbuf.String(), nil
}

func (p Package) ManifestJSON() (string, error) {
xmlStr, err := p.ManifestXML()
if err != nil {
return "", err
}

xml := strings.NewReader(xmlStr)
json, err := xml2json.Convert(xml)
if err != nil {
return "", err
}

return json.String(), nil
}

func (p Package) Manifest() (*Manifest, error) {
xmlStr, err := p.ManifestXML()
if err != nil {
return nil, err
}

var manifest Manifest
err = xml.Unmarshal([]byte(xmlStr), &manifest)
if err != nil {
return nil, err
}

return &manifest, nil
}
44 changes: 44 additions & 0 deletions pkg/apk/apk_test.go
@@ -0,0 +1,44 @@
package apk_test

import (
"fmt"
"testing"

"github.com/stretchr/testify/require"
"moul.io/pkgman/pkg/apk"
)

func ExampleOpen() {
pkg, err := apk.Open("path/to/apk")
if err != nil {
panic(err)
}
defer pkg.Close()

fmt.Printf("Loaded APK: %v\n", pkg)
}

func TestOpen_gomobileipfsdemo(t *testing.T) {
testdata := "../../testdata/gomobile-ipfs-demo-1.2.1.apk"
pkg, err := apk.Open(testdata)
if err != nil {
t.Skipf("cannot open testdata %q, skipping", testdata)
}
require.NoError(t, err)
defer pkg.Close()
require.Len(t, pkg.Files(), 451)

manifest, err := pkg.Manifest()
require.NoError(t, err)
require.Equal(t, manifest.Package, "null.example")
require.Equal(t, manifest.MainActivity().Label, "Gomobile IPFS Example")
require.Equal(t, manifest.MainActivity().Name, "ipfs.gomobile.example.MainActivity")

noExists, err := pkg.FileBytes("blahblah")
require.Nil(t, noExists)
require.Error(t, err)

exists, err := pkg.FileBytes("resources.arsc")
require.NoError(t, err)
require.Equal(t, len(exists), 257156)
}

0 comments on commit 50ca8b8

Please sign in to comment.