Skip to content

Provisionkey macos #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
120 changes: 118 additions & 2 deletions gogio/androidbuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type manifestData struct {
Features []string
IconSnip string
AppName string
Schemes []string
}

const (
Expand Down Expand Up @@ -114,6 +115,7 @@ func buildAndroid(tmpDir string, bi *buildInfo) error {
return err
}
var extraJars []string
var extraAARs []string
visitedPkgs := make(map[string]bool)
var visitPkg func(*packages.Package) error
visitPkg = func(p *packages.Package) error {
Expand All @@ -126,6 +128,11 @@ func buildAndroid(tmpDir string, bi *buildInfo) error {
return err
}
extraJars = append(extraJars, jars...)
aars, err := filepath.Glob(filepath.Join(dir, "*.aar"))
if err != nil {
return err
}
extraAARs = append(extraAARs, aars...)
switch {
case p.PkgPath == "net":
perms = append(perms, "network")
Expand Down Expand Up @@ -166,7 +173,7 @@ func buildAndroid(tmpDir string, bi *buildInfo) error {
return fmt.Errorf("the specified output %q does not end in '.apk' or '.aab'", file)
}

if err := exeAndroid(tmpDir, tools, bi, extraJars, perms, isBundle); err != nil {
if err := exeAndroid(tmpDir, tools, bi, extraJars, extraAARs, perms, isBundle); err != nil {
return err
}
if isBundle {
Expand Down Expand Up @@ -335,7 +342,7 @@ func archiveAndroid(tmpDir string, bi *buildInfo, perms []string) (err error) {
return aarw.Close()
}

func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, perms []string, isBundle bool) (err error) {
func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, extraAARs, perms []string, isBundle bool) (err error) {
classes := filepath.Join(tmpDir, "classes")
var classFiles []string
err = filepath.Walk(classes, func(path string, f os.FileInfo, err error) error {
Expand All @@ -347,7 +354,26 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
}
return nil
})

// extract the jar files from the aars
aarOut := filepath.Join(tmpDir, "aars")
for _, aar := range extraAARs {
name := filepath.Base(aar)
name = strings.TrimSuffix(name, filepath.Ext(name))

if err := extractZip(filepath.Join(aarOut, name), aar); err != nil {
return err
}
}

// extract the jar files from the aars
jarsFromAAR, err := filepath.Glob(filepath.Join(aarOut, "*", "*.jar"))
if err != nil {
return err
}
extraJars = append(extraJars, jarsFromAAR...)
classFiles = append(classFiles, extraJars...)

dexDir := filepath.Join(tmpDir, "apk")
if err := os.MkdirAll(dexDir, 0755); err != nil {
return err
Expand Down Expand Up @@ -433,6 +459,24 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
return err
}

resFromAAR, err := filepath.Glob(filepath.Join(aarOut, "*", "res"))
if err != nil {
return err
}

for i, res := range resFromAAR {
resZip := filepath.Join(tmpDir, fmt.Sprintf("aar-%d-resources.zip", i))

_, err = runCmd(exec.Command(
aapt2,
"compile",
"-o", resZip,
"--dir", res))
if err != nil {
return err
}
}

// Link APK.
permissions, features := getPermissions(perms)
appName := UppercaseName(bi.name)
Expand All @@ -445,6 +489,7 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
Features: features,
IconSnip: iconSnip,
AppName: appName,
Schemes: bi.schemes,
}
tmpl, err := template.New("test").Parse(
`<?xml version="1.0" encoding="utf-8"?>
Expand All @@ -461,11 +506,20 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
android:theme="@style/Theme.GioApp"
android:configChanges="screenSize|screenLayout|smallestScreenSize|orientation|keyboardHidden"
android:windowSoftInputMode="adjustResize"
android:launchMode= "singleInstance"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
{{range .Schemes}}
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:scheme="{{.}}"></data>
</intent-filter>
{{end}}
</activity>
</application>
</manifest>`)
Expand All @@ -478,17 +532,49 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
return err
}

manifestsFromAAR, err := filepath.Glob(filepath.Join(aarOut, "*", "AndroidManifest.xml"))
if err != nil {
return err
}

// Merge manifests, if any.
if len(manifestsFromAAR) > 0 {
if _, err := os.Stat(filepath.Join(tools.buildtools, "manifest-merger.jar")); err != nil {
return fmt.Errorf("manifest-merger.jar not found in buildtools. Download it from https://github.com/distriqt/android-manifest-merger and place it in %s", tools.buildtools)
}

cmd := exec.Command("java",
"-jar",
filepath.Join(tools.buildtools, "manifest-merger.jar"),
"--main", manifest,
"--libs", strings.Join(manifestsFromAAR, ":"),
"--out", manifest,
)
if _, err := runCmd(cmd); err != nil {
return err
}
}

linkAPK := filepath.Join(tmpDir, "link.apk")

args := []string{
"link",
"--manifest", manifest,
"-I", tools.androidjar,
"-o", linkAPK,
"--auto-add-overlay",
}
if isBundle {
args = append(args, "--proto-format")
}

allResZip, err := filepath.Glob(filepath.Join(tmpDir, "*-resources.zip"))
if err != nil {
return err
}
for _, resZip := range allResZip {
args = append(args, "-R", resZip)
}
args = append(args, resZip)

if _, err := runCmd(exec.Command(aapt2, args...)); err != nil {
Expand Down Expand Up @@ -1043,3 +1129,33 @@ func (w *errWriter) Write(p []byte) (n int, err error) {
*w.err = err
return
}

func extractZip(out string, zipFile string) error {
//extract the zip file
r, err := zip.OpenReader(zipFile)
if err != nil {
return err
}
defer r.Close()

for _, f := range r.File {
if err := os.MkdirAll(filepath.Dir(filepath.Join(out, f.Name)), 0777); err != nil {
return err
}
if f.FileInfo().IsDir() {
continue
}
out, err := os.Create(filepath.Join(out, f.Name))
rc, err := f.Open()
if err != nil {
return err
}
if _, err := io.Copy(out, rc); err != nil {
return err
}
rc.Close()
out.Close()
}

return nil
}
6 changes: 6 additions & 0 deletions gogio/build_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type buildInfo struct {
notaryAppleID string
notaryPassword string
notaryTeamID string
schemes []string
}

type Semver struct {
Expand All @@ -51,6 +52,10 @@ func newBuildInfo(pkgPath string) (*buildInfo, error) {
if *name != "" {
appName = *name
}
schemes := strings.Split(*schemes, ",")
for i, scheme := range schemes {
schemes[i] = strings.TrimSpace(scheme)
}
ver, err := parseSemver(*version)
if err != nil {
return nil, err
Expand All @@ -72,6 +77,7 @@ func newBuildInfo(pkgPath string) (*buildInfo, error) {
notaryAppleID: *notaryID,
notaryPassword: *notaryPass,
notaryTeamID: *notaryTeamID,
schemes: schemes,
}
return bi, nil
}
Expand Down
8 changes: 7 additions & 1 deletion gogio/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ its deletion.
The -x flag will print all the external commands executed by the gogio tool.

The -signkey flag specifies the path of the keystore, used for signing Android apk/aab files
or specifies the name of key on Keychain to sign MacOS app.
or specifies the name of key on Keychain to sign MacOS app. On iOS/macOS it can be used to
specify the path of provisioning profile (.mobileprovision/.provisionprofile).

The -signpass flag specifies the password of the keystore, ignored if -signkey is not provided.

Expand All @@ -77,4 +78,9 @@ for details. If not provided, the password will be prompted.

The -notaryteamid flag specifies the team ID to use for notarization of MacOS app, ignored if
-notaryid is not provided.

The -schemes flag specifies a list of comma separated URI schemes that the program can
handle. For example, use -schemes yourAppName to receive a transfer.URLEvent for URIs
starting with yourAppName://. It is only supported on Android, iOS, macOS and Windows.
On Windows, it will restrict the program to a single instance.
`
Loading