mirror of
https://git.sr.ht/~eliasnaur/gio-cmd
synced 2026-07-03 08:25:32 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 74551d3253 | |||
| aecb4723c9 | |||
| 3f0ad89ca9 | |||
| c108ce0a29 | |||
| 1b42337ac0 | |||
| ae8dd5433d | |||
| ab2d621e47 | |||
| 01ffdf788d | |||
| 51c6d8037b | |||
| d1bccae359 | |||
| 37612f9112 | |||
| 03a1ada8ac |
+19
-10
@@ -8,8 +8,10 @@ packages:
|
|||||||
- libxml2-dev
|
- libxml2-dev
|
||||||
- libssl-dev
|
- libssl-dev
|
||||||
- libz-dev
|
- libz-dev
|
||||||
|
- ninja-build # cctools
|
||||||
- llvm-dev # for cctools
|
- llvm-dev # for cctools
|
||||||
- uuid-dev ## for cctools
|
- uuid-dev # for cctools
|
||||||
|
- libblocksruntime-dev # for cctools
|
||||||
- libplist-utils # for gogio
|
- libplist-utils # for gogio
|
||||||
sources:
|
sources:
|
||||||
- https://git.sr.ht/~eliasnaur/gio-cmd
|
- https://git.sr.ht/~eliasnaur/gio-cmd
|
||||||
@@ -17,6 +19,7 @@ sources:
|
|||||||
- https://git.sr.ht/~eliasnaur/giouiorg
|
- https://git.sr.ht/~eliasnaur/giouiorg
|
||||||
- https://github.com/tpoechtrager/cctools-port.git
|
- https://github.com/tpoechtrager/cctools-port.git
|
||||||
- https://github.com/tpoechtrager/apple-libtapi.git
|
- https://github.com/tpoechtrager/apple-libtapi.git
|
||||||
|
- https://github.com/tpoechtrager/apple-libdispatch
|
||||||
- https://github.com/mackyle/xar.git
|
- https://github.com/mackyle/xar.git
|
||||||
environment:
|
environment:
|
||||||
APPLE_TOOLCHAIN_ROOT: /home/build/appletools
|
APPLE_TOOLCHAIN_ROOT: /home/build/appletools
|
||||||
@@ -24,7 +27,7 @@ environment:
|
|||||||
tasks:
|
tasks:
|
||||||
- install_go: |
|
- install_go: |
|
||||||
mkdir -p /home/build/sdk
|
mkdir -p /home/build/sdk
|
||||||
curl -s https://dl.google.com/go/go1.19.8.linux-amd64.tar.gz | tar -C /home/build/sdk -xzf -
|
curl -s https://dl.google.com/go/go1.24.1.linux-amd64.tar.gz | tar -C /home/build/sdk -xzf -
|
||||||
- prepare_toolchain: |
|
- prepare_toolchain: |
|
||||||
mkdir -p $APPLE_TOOLCHAIN_ROOT
|
mkdir -p $APPLE_TOOLCHAIN_ROOT
|
||||||
cd $APPLE_TOOLCHAIN_ROOT
|
cd $APPLE_TOOLCHAIN_ROOT
|
||||||
@@ -42,6 +45,11 @@ tasks:
|
|||||||
- install_appletoolchain: |
|
- install_appletoolchain: |
|
||||||
cd giouiorg
|
cd giouiorg
|
||||||
go build -o $APPLE_TOOLCHAIN_ROOT/tools ./cmd/appletoolchain
|
go build -o $APPLE_TOOLCHAIN_ROOT/tools ./cmd/appletoolchain
|
||||||
|
- build_libdispatch: |
|
||||||
|
cd apple-libdispatch
|
||||||
|
cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_INSTALL_PREFIX=$APPLE_TOOLCHAIN_ROOT/libdispatch .
|
||||||
|
ninja
|
||||||
|
ninja install
|
||||||
- build_xar: |
|
- build_xar: |
|
||||||
cd xar/xar
|
cd xar/xar
|
||||||
ac_cv_lib_crypto_OpenSSL_add_all_ciphers=yes CC=clang ./autogen.sh --prefix=/usr
|
ac_cv_lib_crypto_OpenSSL_add_all_ciphers=yes CC=clang ./autogen.sh --prefix=/usr
|
||||||
@@ -53,15 +61,16 @@ tasks:
|
|||||||
./install.sh
|
./install.sh
|
||||||
- build_cctools: |
|
- build_cctools: |
|
||||||
cd cctools-port/cctools
|
cd cctools-port/cctools
|
||||||
./configure --prefix $APPLE_TOOLCHAIN_ROOT/toolchain --with-libtapi=$APPLE_TOOLCHAIN_ROOT/libtapi --target=x86_64-apple-darwin19
|
./configure --prefix $APPLE_TOOLCHAIN_ROOT/toolchain --with-libtapi=$APPLE_TOOLCHAIN_ROOT/libtapi --with-libdispatch=$APPLE_TOOLCHAIN_ROOT/libdispatch --target=x86_64-apple-darwin19
|
||||||
make install
|
make install
|
||||||
- install_gogio: |
|
- install_gogio: |
|
||||||
cd gio-cmd
|
cd gio-cmd
|
||||||
go install ./gogio
|
go install ./gogio
|
||||||
- test_ios_gogio: |
|
# Broken test.
|
||||||
mkdir tmp
|
# - test_ios_gogio: |
|
||||||
cd tmp
|
# mkdir tmp
|
||||||
go mod init example.com
|
# cd tmp
|
||||||
go get -d gioui.org/example/kitchen
|
# go mod init example.com
|
||||||
export PATH=/home/build/appletools/bin:$PATH
|
# go get -d gioui.org/example/kitchen
|
||||||
gogio -target ios -o app.app gioui.org/example/kitchen
|
# export PATH=/home/build/appletools/bin:$PATH
|
||||||
|
# gogio -target ios -o app.app gioui.org/example/kitchen
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ environment:
|
|||||||
tasks:
|
tasks:
|
||||||
- install_go: |
|
- install_go: |
|
||||||
mkdir -p /home/build/sdk
|
mkdir -p /home/build/sdk
|
||||||
curl https://dl.google.com/go/go1.19.8.freebsd-amd64.tar.gz | tar -C /home/build/sdk -xzf -
|
curl https://dl.google.com/go/go1.24.1.freebsd-amd64.tar.gz | tar -C /home/build/sdk -xzf -
|
||||||
- test_cmd: |
|
- test_cmd: |
|
||||||
cd gio-cmd
|
cd gio-cmd
|
||||||
go test ./...
|
go test ./...
|
||||||
|
|||||||
+4
-5
@@ -1,5 +1,5 @@
|
|||||||
# SPDX-License-Identifier: Unlicense OR MIT
|
# SPDX-License-Identifier: Unlicense OR MIT
|
||||||
image: debian/bookworm
|
image: debian/testing
|
||||||
packages:
|
packages:
|
||||||
- curl
|
- curl
|
||||||
- pkg-config
|
- pkg-config
|
||||||
@@ -24,7 +24,6 @@ packages:
|
|||||||
- scrot
|
- scrot
|
||||||
- sway
|
- sway
|
||||||
- grim
|
- grim
|
||||||
- wine
|
|
||||||
- unzip
|
- unzip
|
||||||
sources:
|
sources:
|
||||||
- https://git.sr.ht/~eliasnaur/gio-cmd
|
- https://git.sr.ht/~eliasnaur/gio-cmd
|
||||||
@@ -39,7 +38,7 @@ secrets:
|
|||||||
tasks:
|
tasks:
|
||||||
- install_go: |
|
- install_go: |
|
||||||
mkdir -p /home/build/sdk
|
mkdir -p /home/build/sdk
|
||||||
curl -s https://dl.google.com/go/go1.19.8.linux-amd64.tar.gz | tar -C /home/build/sdk -xzf -
|
curl -s https://dl.google.com/go/go1.24.1.linux-amd64.tar.gz | tar -C /home/build/sdk -xzf -
|
||||||
- check_gofmt: |
|
- check_gofmt: |
|
||||||
cd gio-cmd
|
cd gio-cmd
|
||||||
test -z "$(gofmt -s -l .)"
|
test -z "$(gofmt -s -l .)"
|
||||||
@@ -57,8 +56,8 @@ tasks:
|
|||||||
# mirror to github
|
# mirror to github
|
||||||
ssh-keyscan github.com > "$HOME"/.ssh/known_hosts && cd gio-cmd && git push --mirror "$github_mirror" || echo "failed mirroring"
|
ssh-keyscan github.com > "$HOME"/.ssh/known_hosts && cd gio-cmd && git push --mirror "$github_mirror" || echo "failed mirroring"
|
||||||
- install_chrome: |
|
- install_chrome: |
|
||||||
curl -s https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
|
sudo curl -o /etc/apt/keyrings/google.pub -s https://dl.google.com/linux/linux_signing_key.pub
|
||||||
sudo sh -c 'echo "deb [arch=amd64] https://dl-ssl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
|
sudo sh -c 'echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/google.pub] https://dl-ssl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
|
||||||
sudo apt-get -qq update
|
sudo apt-get -qq update
|
||||||
sudo apt-get -qq install -y google-chrome-stable
|
sudo apt-get -qq install -y google-chrome-stable
|
||||||
- test: |
|
- test: |
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ environment:
|
|||||||
tasks:
|
tasks:
|
||||||
- install_go: |
|
- install_go: |
|
||||||
mkdir -p /home/build/sdk
|
mkdir -p /home/build/sdk
|
||||||
curl https://dl.google.com/go/go1.19.8.src.tar.gz | tar -C /home/build/sdk -xzf -
|
curl https://dl.google.com/go/go1.24.1.src.tar.gz | tar -C /home/build/sdk -xzf -
|
||||||
cd /home/build/sdk/go/src
|
cd /home/build/sdk/go/src
|
||||||
./make.bash
|
./make.bash
|
||||||
- test_cmd: |
|
- test_cmd: |
|
||||||
|
|||||||
@@ -1,29 +1,28 @@
|
|||||||
module gioui.org/cmd
|
module gioui.org/cmd
|
||||||
|
|
||||||
go 1.21
|
go 1.24.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
gioui.org v0.7.1
|
gioui.org v0.9.0
|
||||||
github.com/akavel/rsrc v0.10.1
|
github.com/akavel/rsrc v0.10.1
|
||||||
github.com/chromedp/cdproto v0.0.0-20191114225735-6626966fbae4
|
github.com/chromedp/cdproto v0.0.0-20250429231605-6ed5b53462d4
|
||||||
github.com/chromedp/chromedp v0.5.2
|
github.com/chromedp/chromedp v0.13.6
|
||||||
golang.org/x/image v0.18.0
|
golang.org/x/image v0.26.0
|
||||||
golang.org/x/sync v0.7.0
|
golang.org/x/sync v0.13.0
|
||||||
golang.org/x/text v0.16.0
|
golang.org/x/text v0.24.0
|
||||||
golang.org/x/tools v0.23.0
|
golang.org/x/tools v0.32.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2 // indirect
|
|
||||||
gioui.org/shader v1.0.8 // indirect
|
gioui.org/shader v1.0.8 // indirect
|
||||||
github.com/go-text/typesetting v0.1.1 // indirect
|
github.com/chromedp/sysutil v1.1.0 // indirect
|
||||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee // indirect
|
github.com/go-json-experiment/json v0.0.0-20250417205406-170dfdcf87d1 // indirect
|
||||||
github.com/gobwas/pool v0.2.0 // indirect
|
github.com/go-text/typesetting v0.3.0 // indirect
|
||||||
github.com/gobwas/ws v1.0.2 // indirect
|
github.com/gobwas/httphead v0.1.0 // indirect
|
||||||
github.com/knq/sysutil v0.0.0-20191005231841-15668db23d08 // indirect
|
github.com/gobwas/pool v0.2.1 // indirect
|
||||||
github.com/mailru/easyjson v0.7.0 // indirect
|
github.com/gobwas/ws v1.4.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect
|
github.com/google/go-cmp v0.7.0 // indirect
|
||||||
golang.org/x/exp/shiny v0.0.0-20240707233637-46b078467d37 // indirect
|
golang.org/x/exp/shiny v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||||
golang.org/x/mod v0.19.0 // indirect
|
golang.org/x/mod v0.24.0 // indirect
|
||||||
golang.org/x/sys v0.22.0 // indirect
|
golang.org/x/sys v0.33.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,46 +1,50 @@
|
|||||||
eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d h1:ARo7NCVvN2NdhLlJE9xAbKweuI9L6UgfTbYb0YwPacY=
|
eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d h1:ARo7NCVvN2NdhLlJE9xAbKweuI9L6UgfTbYb0YwPacY=
|
||||||
eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d/go.mod h1:OYVuxibdk9OSLX8vAqydtRPP87PyTFcT9uH3MlEGBQA=
|
eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d/go.mod h1:OYVuxibdk9OSLX8vAqydtRPP87PyTFcT9uH3MlEGBQA=
|
||||||
gioui.org v0.7.1 h1:l7OVj47n1z8acaszQ6Wlu+Rxme+HqF3q8b+Fs68+x3w=
|
gioui.org v0.9.0 h1:4u7XZwnb5kzQW91Nz/vR0wKD6LdW9CaVF96r3rfy4kc=
|
||||||
gioui.org v0.7.1/go.mod h1:5Kw/q7R1BWc5MKStuTNvhCgSrRqbfHc9Dzfjs4IGgZo=
|
gioui.org v0.9.0/go.mod h1:CjNig0wAhLt9WZxOPAusgFD8x8IRvqt26LdDBa3Jvao=
|
||||||
gioui.org/cpu v0.0.0-20210808092351-bfe733dd3334/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ=
|
gioui.org/cpu v0.0.0-20210808092351-bfe733dd3334/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ=
|
||||||
gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2 h1:AGDDxsJE1RpcXTAxPG2B4jrwVUJGFDjINIPi1jtO6pc=
|
|
||||||
gioui.org/cpu v0.0.0-20210817075930-8d6a761490d2/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ=
|
|
||||||
gioui.org/shader v1.0.8 h1:6ks0o/A+b0ne7RzEqRZK5f4Gboz2CfG+mVliciy6+qA=
|
gioui.org/shader v1.0.8 h1:6ks0o/A+b0ne7RzEqRZK5f4Gboz2CfG+mVliciy6+qA=
|
||||||
gioui.org/shader v1.0.8/go.mod h1:mWdiME581d/kV7/iEhLmUgUK5iZ09XR5XpduXzbePVM=
|
gioui.org/shader v1.0.8/go.mod h1:mWdiME581d/kV7/iEhLmUgUK5iZ09XR5XpduXzbePVM=
|
||||||
github.com/akavel/rsrc v0.10.1 h1:hCCPImjmFKVNGpeLZyTDRHEFC283DzyTXTo0cO0Rq9o=
|
github.com/akavel/rsrc v0.10.1 h1:hCCPImjmFKVNGpeLZyTDRHEFC283DzyTXTo0cO0Rq9o=
|
||||||
github.com/akavel/rsrc v0.10.1/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
github.com/akavel/rsrc v0.10.1/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||||
github.com/chromedp/cdproto v0.0.0-20191114225735-6626966fbae4 h1:QD3KxSJ59L2lxG6MXBjNHxiQO2RmxTQ3XcK+wO44WOg=
|
github.com/chromedp/cdproto v0.0.0-20250429231605-6ed5b53462d4 h1:UZdrvid2JFwnvPlUSEFlE794XZL4Jmrj8fuxfcLECJE=
|
||||||
github.com/chromedp/cdproto v0.0.0-20191114225735-6626966fbae4/go.mod h1:PfAWWKJqjlGFYJEidUM6aVIWPr0EpobeyVWEEmplX7g=
|
github.com/chromedp/cdproto v0.0.0-20250429231605-6ed5b53462d4/go.mod h1:NItd7aLkcfOA/dcMXvl8p1u+lQqioRMq/SqDp71Pb/k=
|
||||||
github.com/chromedp/chromedp v0.5.2 h1:W8xBXQuUnd2dZK0SN/lyVwsQM7KgW+kY5HGnntms194=
|
github.com/chromedp/chromedp v0.13.6 h1:xlNunMyzS5bu3r/QKrb3fzX6ow3WBQ6oao+J65PGZxk=
|
||||||
github.com/chromedp/chromedp v0.5.2/go.mod h1:rsTo/xRo23KZZwFmWk2Ui79rBaVRRATCjLzNQlOFSiA=
|
github.com/chromedp/chromedp v0.13.6/go.mod h1:h8GPP6ZtLMLsU8zFbTcb7ZDGCvCy8j/vRoFmRltQx9A=
|
||||||
github.com/go-text/typesetting v0.1.1 h1:bGAesCuo85nXnEN5LmFMVGAGpGkCPtHrZLi//qD7EJo=
|
github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM=
|
||||||
github.com/go-text/typesetting v0.1.1/go.mod h1:d22AnmeKq/on0HNv73UFriMKc4Ez6EqZAofLhAzpSzI=
|
github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8=
|
||||||
github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04 h1:zBx+p/W2aQYtNuyZNcTfinWvXBQwYtDfme051PR/lAY=
|
github.com/go-json-experiment/json v0.0.0-20250417205406-170dfdcf87d1 h1:+VexzzkMLb1tnvpuQdGT/DicIRW7MN8ozsXqBMgp0Hk=
|
||||||
github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o=
|
github.com/go-json-experiment/json v0.0.0-20250417205406-170dfdcf87d1/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M=
|
||||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
|
github.com/go-text/typesetting v0.3.0 h1:OWCgYpp8njoxSRpwrdd1bQOxdjOXDj9Rqart9ML4iF4=
|
||||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
github.com/go-text/typesetting v0.3.0/go.mod h1:qjZLkhRgOEYMhU9eHBr3AR4sfnGJvOXNLt8yRAySFuY=
|
||||||
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
|
github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066 h1:qCuYC+94v2xrb1PoS4NIDe7DGYtLnU2wWiQe9a1B1c0=
|
||||||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o=
|
||||||
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
|
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||||
github.com/knq/sysutil v0.0.0-20191005231841-15668db23d08 h1:V0an7KRw92wmJysvFvtqtKMAPmvS5O0jtB0nYo6t+gs=
|
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||||
github.com/knq/sysutil v0.0.0-20191005231841-15668db23d08/go.mod h1:dFWs1zEqDjFtnBXsd1vPOZaLsESovai349994nHx3e0=
|
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||||
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
|
github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs=
|
||||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc=
|
||||||
golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
golang.org/x/exp/shiny v0.0.0-20240707233637-46b078467d37 h1:SOSg7+sueresE4IbmmGM60GmlIys+zNX63d6/J4CMtU=
|
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
|
||||||
golang.org/x/exp/shiny v0.0.0-20240707233637-46b078467d37/go.mod h1:3F+MieQB7dRYLTmnncoFbb1crS5lfQoTfDgQy6K4N0o=
|
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
|
||||||
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
|
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
|
||||||
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
|
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||||
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
|
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||||
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
golang.org/x/exp/shiny v0.0.0-20250408133849-7e4ce0ab07d0 h1:tMSqXTK+AQdW3LpCbfatHSRPHeW6+2WuxaVQuHftn80=
|
||||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/exp/shiny v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:ygj7T6vSGhhm/9yTpOQQNvuAUFziTH7RUiH74EoE2C8=
|
||||||
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/image v0.26.0 h1:4XjIFEZWQmCZi6Wv8BoxsDhRU3RVnLX04dToTDAEPlY=
|
||||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
golang.org/x/image v0.26.0/go.mod h1:lcxbMFAovzpnJxzXS3nyL83K27tmqtKzIJpctK8YO5c=
|
||||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||||
|
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
|
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||||
|
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||||
|
golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=
|
||||||
|
golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ type AndroidTestDriver struct {
|
|||||||
var rxAdbDevice = regexp.MustCompile(`(.*)\s+device$`)
|
var rxAdbDevice = regexp.MustCompile(`(.*)\s+device$`)
|
||||||
|
|
||||||
func (d *AndroidTestDriver) Start(path string) {
|
func (d *AndroidTestDriver) Start(path string) {
|
||||||
d.sdkDir = os.Getenv("ANDROID_SDK_ROOT")
|
d.sdkDir = os.Getenv("ANDROID_HOME")
|
||||||
if d.sdkDir == "" {
|
if d.sdkDir == "" {
|
||||||
d.Skipf("Android SDK is required; set $ANDROID_SDK_ROOT")
|
d.Skipf("Android SDK is required; set $ANDROID_HOME")
|
||||||
}
|
}
|
||||||
d.adbPath = filepath.Join(d.sdkDir, "platform-tools", "adb")
|
d.adbPath = filepath.Join(d.sdkDir, "platform-tools", "adb")
|
||||||
if _, err := os.Stat(d.adbPath); os.IsNotExist(err) {
|
if _, err := os.Stat(d.adbPath); os.IsNotExist(err) {
|
||||||
@@ -121,7 +121,7 @@ func (d *AndroidTestDriver) tryUninstall() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *AndroidTestDriver) adb(args ...interface{}) []byte {
|
func (d *AndroidTestDriver) adb(args ...any) []byte {
|
||||||
strs := []string{}
|
strs := []string{}
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
strs = append(strs, fmt.Sprint(arg))
|
strs = append(strs, fmt.Sprint(arg))
|
||||||
|
|||||||
+18
-24
@@ -76,9 +76,9 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func buildAndroid(tmpDir string, bi *buildInfo) error {
|
func buildAndroid(tmpDir string, bi *buildInfo) error {
|
||||||
sdk := os.Getenv("ANDROID_SDK_ROOT")
|
sdk := os.Getenv("ANDROID_HOME")
|
||||||
if sdk == "" {
|
if sdk == "" {
|
||||||
return errors.New("please set ANDROID_SDK_ROOT to the Android SDK path")
|
return errors.New("please set ANDROID_HOME to the Android SDK path")
|
||||||
}
|
}
|
||||||
if _, err := os.Stat(sdk); err != nil {
|
if _, err := os.Stat(sdk); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -179,9 +179,9 @@ func buildAndroid(tmpDir string, bi *buildInfo) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func compileAndroid(tmpDir string, tools *androidTools, bi *buildInfo) (err error) {
|
func compileAndroid(tmpDir string, tools *androidTools, bi *buildInfo) (err error) {
|
||||||
androidHome := os.Getenv("ANDROID_SDK_ROOT")
|
androidHome := os.Getenv("ANDROID_HOME")
|
||||||
if androidHome == "" {
|
if androidHome == "" {
|
||||||
return errors.New("ANDROID_SDK_ROOT is not set. Please point it to the root of the Android SDK")
|
return errors.New("ANDROID_HOME is not set. Please point it to the root of the Android SDK")
|
||||||
}
|
}
|
||||||
javac, err := findJavaC()
|
javac, err := findJavaC()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -191,10 +191,7 @@ func compileAndroid(tmpDir string, tools *androidTools, bi *buildInfo) (err erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
minSDK := 17
|
minSDK := max(bi.minsdk, 17)
|
||||||
if bi.minsdk > minSDK {
|
|
||||||
minSDK = bi.minsdk
|
|
||||||
}
|
|
||||||
tcRoot := filepath.Join(ndkRoot, "toolchains", "llvm", "prebuilt", archNDK())
|
tcRoot := filepath.Join(ndkRoot, "toolchains", "llvm", "prebuilt", archNDK())
|
||||||
var builds errgroup.Group
|
var builds errgroup.Group
|
||||||
for _, a := range bi.archs {
|
for _, a := range bi.archs {
|
||||||
@@ -213,14 +210,14 @@ func compileAndroid(tmpDir string, tools *androidTools, bi *buildInfo) (err erro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
archDir := filepath.Join(tmpDir, "jni", arch.jniArch)
|
archDir := filepath.Join(tmpDir, "jni", arch.jniArch)
|
||||||
if err := os.MkdirAll(archDir, 0755); err != nil {
|
if err := os.MkdirAll(archDir, 0o755); err != nil {
|
||||||
return fmt.Errorf("failed to create %q: %v", archDir, err)
|
return fmt.Errorf("failed to create %q: %v", archDir, err)
|
||||||
}
|
}
|
||||||
libFile := filepath.Join(archDir, "libgio.so")
|
libFile := filepath.Join(archDir, "libgio.so")
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"go",
|
"go",
|
||||||
"build",
|
"build",
|
||||||
"-ldflags=-w -s "+bi.ldflags,
|
"-ldflags=-w -s -extldflags \"-Wl,-z,max-page-size=65536\" "+bi.ldflags,
|
||||||
"-buildmode=c-shared",
|
"-buildmode=c-shared",
|
||||||
"-tags", bi.tags,
|
"-tags", bi.tags,
|
||||||
"-o", libFile,
|
"-o", libFile,
|
||||||
@@ -252,7 +249,7 @@ func compileAndroid(tmpDir string, tools *androidTools, bi *buildInfo) (err erro
|
|||||||
}
|
}
|
||||||
if len(javaFiles) > 0 {
|
if len(javaFiles) > 0 {
|
||||||
classes := filepath.Join(tmpDir, "classes")
|
classes := filepath.Join(tmpDir, "classes")
|
||||||
if err := os.MkdirAll(classes, 0755); err != nil {
|
if err := os.MkdirAll(classes, 0o755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
javac := exec.Command(
|
javac := exec.Command(
|
||||||
@@ -349,13 +346,10 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
|
|||||||
})
|
})
|
||||||
classFiles = append(classFiles, extraJars...)
|
classFiles = append(classFiles, extraJars...)
|
||||||
dexDir := filepath.Join(tmpDir, "apk")
|
dexDir := filepath.Join(tmpDir, "apk")
|
||||||
if err := os.MkdirAll(dexDir, 0755); err != nil {
|
if err := os.MkdirAll(dexDir, 0o755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
minSDK := 16
|
minSDK := max(bi.minsdk, 16)
|
||||||
if bi.minsdk > minSDK {
|
|
||||||
minSDK = bi.minsdk
|
|
||||||
}
|
|
||||||
// https://developer.android.com/distribute/best-practices/develop/target-sdk
|
// https://developer.android.com/distribute/best-practices/develop/target-sdk
|
||||||
targetSDK := 33
|
targetSDK := 33
|
||||||
if bi.targetsdk > 0 {
|
if bi.targetsdk > 0 {
|
||||||
@@ -387,7 +381,7 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
|
|||||||
v21Dir := filepath.Join(resDir, "values-v21")
|
v21Dir := filepath.Join(resDir, "values-v21")
|
||||||
v26mipmapDir := filepath.Join(resDir, `mipmap-anydpi-v26`)
|
v26mipmapDir := filepath.Join(resDir, `mipmap-anydpi-v26`)
|
||||||
for _, dir := range []string{valDir, v21Dir, v26mipmapDir} {
|
for _, dir := range []string{valDir, v21Dir, v26mipmapDir} {
|
||||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -411,17 +405,17 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
|
|||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@mipmap/ic_launcher_adaptive" />
|
<background android:drawable="@mipmap/ic_launcher_adaptive" />
|
||||||
<foreground android:drawable="@mipmap/ic_launcher_adaptive" />
|
<foreground android:drawable="@mipmap/ic_launcher_adaptive" />
|
||||||
</adaptive-icon>`), 0660)
|
</adaptive-icon>`), 0o660)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iconSnip = `android:icon="@mipmap/ic_launcher"`
|
iconSnip = `android:icon="@mipmap/ic_launcher"`
|
||||||
}
|
}
|
||||||
err = os.WriteFile(filepath.Join(valDir, "themes.xml"), []byte(themes), 0660)
|
err = os.WriteFile(filepath.Join(valDir, "themes.xml"), []byte(themes), 0o660)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = os.WriteFile(filepath.Join(v21Dir, "themes.xml"), []byte(themesV21), 0660)
|
err = os.WriteFile(filepath.Join(v21Dir, "themes.xml"), []byte(themesV21), 0o660)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -477,7 +471,7 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
manifest := filepath.Join(tmpDir, "AndroidManifest.xml")
|
manifest := filepath.Join(tmpDir, "AndroidManifest.xml")
|
||||||
if err := os.WriteFile(manifest, manifestBuffer.Bytes(), 0660); err != nil {
|
if err := os.WriteFile(manifest, manifestBuffer.Bytes(), 0o660); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -679,7 +673,7 @@ func signAAB(tmpDir string, aabFile string, tools *androidTools, bi *buildInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
var alias string
|
var alias string
|
||||||
for _, t := range strings.Split(keytoolList, "\n") {
|
for t := range strings.SplitSeq(keytoolList, "\n") {
|
||||||
if i, _ := fmt.Sscanf(t, "Alias name: %s", &alias); i > 0 {
|
if i, _ := fmt.Sscanf(t, "Alias name: %s", &alias); i > 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -750,7 +744,7 @@ func findNDK(androidHome string) (string, error) {
|
|||||||
if bestNDK, found := latestVersionPath(ndks); found {
|
if bestNDK, found := latestVersionPath(ndks); found {
|
||||||
return bestNDK, nil
|
return bestNDK, nil
|
||||||
}
|
}
|
||||||
// The old NDK path was $ANDROID_SDK_ROOT/ndk-bundle.
|
// The old NDK path was $ANDROID_HOME/ndk-bundle.
|
||||||
ndkBundle := filepath.Join(androidHome, "ndk-bundle")
|
ndkBundle := filepath.Join(androidHome, "ndk-bundle")
|
||||||
if _, err := os.Stat(ndkBundle); err == nil {
|
if _, err := os.Stat(ndkBundle); err == nil {
|
||||||
return ndkBundle, nil
|
return ndkBundle, nil
|
||||||
@@ -763,7 +757,7 @@ func findNDK(androidHome string) (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", fmt.Errorf("no NDK found in $ANDROID_SDK_ROOT (%s). Set $ANDROID_NDK_ROOT or use `sdkmanager ndk-bundle` to install the NDK", androidHome)
|
return "", fmt.Errorf("no NDK found in $ANDROID_HOME (%s). Set $ANDROID_NDK_ROOT or use `sdkmanager ndk-bundle` to install the NDK", androidHome)
|
||||||
}
|
}
|
||||||
|
|
||||||
func findKeytool() (string, error) {
|
func findKeytool() (string, error) {
|
||||||
|
|||||||
+8
-7
@@ -56,6 +56,10 @@ func newBuildInfo(pkgPath string) (*buildInfo, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
sp := *signPass
|
||||||
|
if sp == "" {
|
||||||
|
sp = os.Getenv("GOGIO_SIGNPASS")
|
||||||
|
}
|
||||||
bi := &buildInfo{
|
bi := &buildInfo{
|
||||||
appID: appID,
|
appID: appID,
|
||||||
archs: getArchs(),
|
archs: getArchs(),
|
||||||
@@ -70,7 +74,7 @@ func newBuildInfo(pkgPath string) (*buildInfo, error) {
|
|||||||
target: *target,
|
target: *target,
|
||||||
version: ver,
|
version: ver,
|
||||||
key: *signKey,
|
key: *signKey,
|
||||||
password: *signPass,
|
password: sp,
|
||||||
notaryAppleID: *notaryID,
|
notaryAppleID: *notaryID,
|
||||||
notaryPassword: *notaryPass,
|
notaryPassword: *notaryPass,
|
||||||
notaryTeamID: *notaryTeamID,
|
notaryTeamID: *notaryTeamID,
|
||||||
@@ -91,11 +95,8 @@ func (s Semver) String() string {
|
|||||||
func parseSemver(v string) (Semver, error) {
|
func parseSemver(v string) (Semver, error) {
|
||||||
var sv Semver
|
var sv Semver
|
||||||
_, err := fmt.Sscanf(v, "%d.%d.%d.%d", &sv.Major, &sv.Minor, &sv.Patch, &sv.VersionCode)
|
_, err := fmt.Sscanf(v, "%d.%d.%d.%d", &sv.Major, &sv.Minor, &sv.Patch, &sv.VersionCode)
|
||||||
if err != nil {
|
if err != nil || sv.String() != v {
|
||||||
return Semver{}, fmt.Errorf("invalid semver: %q", v)
|
return Semver{}, fmt.Errorf("invalid semver: %q (must match major.minor.patch.versioncode)", v)
|
||||||
}
|
|
||||||
if sv.String() != v {
|
|
||||||
return Semver{}, fmt.Errorf("invalid semver: %q", v)
|
|
||||||
}
|
}
|
||||||
return sv, nil
|
return sv, nil
|
||||||
}
|
}
|
||||||
@@ -180,7 +181,7 @@ func getAppID(pkgMetadata *packageMetadata) string {
|
|||||||
name = "." + domain[0]
|
name = "." + domain[0]
|
||||||
domain[0] = "localhost"
|
domain[0] = "localhost"
|
||||||
} else {
|
} else {
|
||||||
for i := 0; i < len(domain)/2; i++ {
|
for i := range len(domain) / 2 {
|
||||||
opp := len(domain) - 1 - i
|
opp := len(domain) - 1 - i
|
||||||
domain[i], domain[opp] = domain[opp], domain[i]
|
domain[i], domain[opp] = domain[opp], domain[i]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,12 @@ package main
|
|||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
type expval struct {
|
|
||||||
in, out string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAppID(t *testing.T) {
|
func TestAppID(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tests := []expval{
|
tests := []struct {
|
||||||
|
in, out string
|
||||||
|
}{
|
||||||
{"example", "localhost.example"},
|
{"example", "localhost.example"},
|
||||||
{"example.com", "com.example"},
|
{"example.com", "com.example"},
|
||||||
{"www.example.com", "com.example.www"},
|
{"www.example.com", "com.example.www"},
|
||||||
@@ -30,3 +28,32 @@ func TestAppID(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestVersion(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
version string
|
||||||
|
valid bool
|
||||||
|
}{
|
||||||
|
{"v1", false},
|
||||||
|
{"v10.21.333.12", false},
|
||||||
|
{"1.2.3", false},
|
||||||
|
{"1.2.3.4", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range tests {
|
||||||
|
ver, err := parseSemver(test.version)
|
||||||
|
if err != nil {
|
||||||
|
if test.valid {
|
||||||
|
t.Errorf("(%d): %q failed to parse: %v", i, test.version, err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
} else if !test.valid {
|
||||||
|
t.Errorf("(%d): %q was unexpectedly accepted", i, test.version)
|
||||||
|
}
|
||||||
|
if got := ver.String(); got != test.version {
|
||||||
|
t.Errorf("(%d): %q parsed to %q", i, test.version, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+4
-2
@@ -47,8 +47,9 @@ The -appid flag specifies the package name for Android or the bundle id for
|
|||||||
iOS and tvOS. A bundle id must be provisioned through Xcode before the gogio
|
iOS and tvOS. A bundle id must be provisioned through Xcode before the gogio
|
||||||
tool can use it.
|
tool can use it.
|
||||||
|
|
||||||
The -version flag specifies the integer version code for Android and the last
|
The -version flag specifies the semantic version for -buildmode exe. It must
|
||||||
component of the 1.0.X version for iOS and tvOS.
|
be on the form major.minor.patch.versioncode where the version code is used for
|
||||||
|
the integer version number for Android, iOS and tvOS.
|
||||||
|
|
||||||
For Android builds the -minsdk flag specify the minimum SDK level. For example,
|
For Android builds the -minsdk flag specify the minimum SDK level. For example,
|
||||||
use -minsdk 22 to target Android 5.1 (Lollipop) and later.
|
use -minsdk 22 to target Android 5.1 (Lollipop) and later.
|
||||||
@@ -71,6 +72,7 @@ The -signkey flag specifies the path of the keystore, used for signing Android a
|
|||||||
or specifies the name of key on Keychain to sign MacOS app.
|
or specifies the name of key on Keychain to sign MacOS app.
|
||||||
|
|
||||||
The -signpass flag specifies the password of the keystore, ignored if -signkey is not provided.
|
The -signpass flag specifies the password of the keystore, ignored if -signkey is not provided.
|
||||||
|
If -signpass is not sepecified it will be read from the environment variable GOGIO_SIGNPASS.
|
||||||
|
|
||||||
The -notaryid flag specifies the Apple ID to use for notarization of MacOS app.
|
The -notaryid flag specifies the Apple ID to use for notarization of MacOS app.
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import (
|
|||||||
|
|
||||||
"gioui.org/app"
|
"gioui.org/app"
|
||||||
"gioui.org/gpu"
|
"gioui.org/gpu"
|
||||||
|
"gioui.org/io/event"
|
||||||
"gioui.org/io/pointer"
|
"gioui.org/io/pointer"
|
||||||
"gioui.org/io/system"
|
|
||||||
"gioui.org/layout"
|
"gioui.org/layout"
|
||||||
"gioui.org/op"
|
"gioui.org/op"
|
||||||
"gioui.org/op/clip"
|
"gioui.org/op/clip"
|
||||||
@@ -98,7 +98,8 @@ type eglContext struct {
|
|||||||
func main() {
|
func main() {
|
||||||
go func() {
|
go func() {
|
||||||
// Set CustomRenderer so we can provide our own rendering context.
|
// Set CustomRenderer so we can provide our own rendering context.
|
||||||
w := app.NewWindow(app.CustomRenderer(true))
|
w := new(app.Window)
|
||||||
|
w.Option(app.CustomRenderer(true))
|
||||||
if err := loop(w); err != nil {
|
if err := loop(w); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -164,17 +165,17 @@ func loop(w *app.Window) error {
|
|||||||
|
|
||||||
// eglMakeCurrent binds a context to an operating system thread. Prevent Go from switching thread.
|
// eglMakeCurrent binds a context to an operating system thread. Prevent Go from switching thread.
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
for e := range w.Events() {
|
for {
|
||||||
switch e := e.(type) {
|
switch e := w.Event().(type) {
|
||||||
case app.ViewEvent:
|
case app.ViewEvent:
|
||||||
ve = e
|
ve = e
|
||||||
init = true
|
init = true
|
||||||
if size != (image.Point{}) {
|
if size != (image.Point{}) {
|
||||||
recreateContext()
|
recreateContext()
|
||||||
}
|
}
|
||||||
case system.DestroyEvent:
|
case app.DestroyEvent:
|
||||||
return e.Err
|
return e.Err
|
||||||
case system.FrameEvent:
|
case app.FrameEvent:
|
||||||
if init && size != e.Size {
|
if init && size != e.Size {
|
||||||
size = e.Size
|
size = e.Size
|
||||||
recreateContext()
|
recreateContext()
|
||||||
@@ -183,7 +184,7 @@ func loop(w *app.Window) error {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
// Build ops.
|
// Build ops.
|
||||||
gtx := layout.NewContext(&ops, e)
|
gtx := app.NewContext(&ops, e)
|
||||||
|
|
||||||
// Clear background to white, even on embedded platforms such as webassembly.
|
// Clear background to white, even on embedded platforms such as webassembly.
|
||||||
paint.Fill(gtx.Ops, color.NRGBA{A: 0xff, R: 0xff, G: 0xff, B: 0xff})
|
paint.Fill(gtx.Ops, color.NRGBA{A: 0xff, R: 0xff, G: 0xff, B: 0xff})
|
||||||
@@ -205,7 +206,7 @@ func loop(w *app.Window) error {
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
op.InvalidateOp{}.Add(gtx.Ops)
|
gtx.Execute(op.InvalidateCmd{})
|
||||||
log.Println("frame")
|
log.Println("frame")
|
||||||
|
|
||||||
// Trigger window resize detection in ANGLE.
|
// Trigger window resize detection in ANGLE.
|
||||||
@@ -351,13 +352,16 @@ func (w *quarterWidget) Layout(gtx layout.Context) layout.Dimensions {
|
|||||||
defer clip.Rect(image.Rectangle{
|
defer clip.Rect(image.Rectangle{
|
||||||
Max: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y),
|
Max: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y),
|
||||||
}).Push(gtx.Ops).Pop()
|
}).Push(gtx.Ops).Pop()
|
||||||
pointer.InputOp{
|
event.Op(gtx.Ops, w)
|
||||||
Tag: w,
|
for {
|
||||||
Types: pointer.Press,
|
e, ok := gtx.Event(pointer.Filter{
|
||||||
}.Add(gtx.Ops)
|
Target: w,
|
||||||
|
Kinds: pointer.Press,
|
||||||
for _, e := range gtx.Events(w) {
|
})
|
||||||
if e, ok := e.(pointer.Event); ok && e.Type == pointer.Press {
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if e, ok := e.(pointer.Event); ok && e.Kind == pointer.Press {
|
||||||
w.clicked = !w.clicked
|
w.clicked = !w.clicked
|
||||||
// notify when we're done updating the frame.
|
// notify when we're done updating the frame.
|
||||||
notify = notifyInvalidate
|
notify = notifyInvalidate
|
||||||
|
|||||||
+10
-9
@@ -12,6 +12,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -56,7 +57,7 @@ func buildIOS(tmpDir, target string, bi *buildInfo) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bi.archs = append(bi.archs[:i], bi.archs[i+1:]...)
|
bi.archs = slices.Delete(bi.archs, i, i+1)
|
||||||
}
|
}
|
||||||
if !forDevice && !strings.HasSuffix(out, ".app") {
|
if !forDevice && !strings.HasSuffix(out, ".app") {
|
||||||
return fmt.Errorf("the specified output directory %q does not end in .app or .ipa", out)
|
return fmt.Errorf("the specified output directory %q does not end in .app or .ipa", out)
|
||||||
@@ -66,7 +67,7 @@ func buildIOS(tmpDir, target string, bi *buildInfo) error {
|
|||||||
}
|
}
|
||||||
payload := filepath.Join(tmpDir, "Payload")
|
payload := filepath.Join(tmpDir, "Payload")
|
||||||
appDir := filepath.Join(payload, appName+".app")
|
appDir := filepath.Join(payload, appName+".app")
|
||||||
if err := os.MkdirAll(appDir, 0755); err != nil {
|
if err := os.MkdirAll(appDir, 0o755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := exeIOS(tmpDir, target, appDir, bi); err != nil {
|
if err := exeIOS(tmpDir, target, appDir, bi); err != nil {
|
||||||
@@ -139,7 +140,7 @@ func signIOS(bi *buildInfo, tmpDir, app string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
entFile := filepath.Join(tmpDir, "entitlements.plist")
|
entFile := filepath.Join(tmpDir, "entitlements.plist")
|
||||||
if err := os.WriteFile(entFile, []byte(entitlements), 0660); err != nil {
|
if err := os.WriteFile(entFile, []byte(entitlements), 0o660); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
identity := sha1.Sum(certDER)
|
identity := sha1.Sum(certDER)
|
||||||
@@ -157,7 +158,7 @@ func exeIOS(tmpDir, target, app string, bi *buildInfo) error {
|
|||||||
if err := os.RemoveAll(app); err != nil {
|
if err := os.RemoveAll(app); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := os.Mkdir(app, 0755); err != nil {
|
if err := os.Mkdir(app, 0o755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
appName := UppercaseName(bi.name)
|
appName := UppercaseName(bi.name)
|
||||||
@@ -205,7 +206,7 @@ func exeIOS(tmpDir, target, app string, bi *buildInfo) error {
|
|||||||
}
|
}
|
||||||
infoPlist := buildInfoPlist(bi)
|
infoPlist := buildInfoPlist(bi)
|
||||||
plistFile := filepath.Join(app, "Info.plist")
|
plistFile := filepath.Join(app, "Info.plist")
|
||||||
if err := os.WriteFile(plistFile, []byte(infoPlist), 0660); err != nil {
|
if err := os.WriteFile(plistFile, []byte(infoPlist), 0o660); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := os.Stat(bi.iconPath); err == nil {
|
if _, err := os.Stat(bi.iconPath); err == nil {
|
||||||
@@ -233,7 +234,7 @@ func exeIOS(tmpDir, target, app string, bi *buildInfo) error {
|
|||||||
// iosIcons returns the asset plist file to be merged into Info.plist.
|
// iosIcons returns the asset plist file to be merged into Info.plist.
|
||||||
func iosIcons(bi *buildInfo, tmpDir, appDir, icon string) (string, error) {
|
func iosIcons(bi *buildInfo, tmpDir, appDir, icon string) (string, error) {
|
||||||
assets := filepath.Join(tmpDir, "Assets.xcassets")
|
assets := filepath.Join(tmpDir, "Assets.xcassets")
|
||||||
if err := os.Mkdir(assets, 0700); err != nil {
|
if err := os.Mkdir(assets, 0o700); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
appIcon := filepath.Join(assets, "AppIcon.appiconset")
|
appIcon := filepath.Join(assets, "AppIcon.appiconset")
|
||||||
@@ -270,7 +271,7 @@ func iosIcons(bi *buildInfo, tmpDir, appDir, icon string) (string, error) {
|
|||||||
]
|
]
|
||||||
}`
|
}`
|
||||||
contentFile := filepath.Join(appIcon, "Contents.json")
|
contentFile := filepath.Join(appIcon, "Contents.json")
|
||||||
if err := os.WriteFile(contentFile, []byte(contentJson), 0600); err != nil {
|
if err := os.WriteFile(contentFile, []byte(contentJson), 0o600); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
assetPlist := filepath.Join(tmpDir, "assets.plist")
|
assetPlist := filepath.Join(tmpDir, "assets.plist")
|
||||||
@@ -386,7 +387,7 @@ func archiveIOS(tmpDir, target, frameworkRoot string, bi *buildInfo) error {
|
|||||||
frameworkDir := filepath.Join(frameworkRoot, "Versions", "A")
|
frameworkDir := filepath.Join(frameworkRoot, "Versions", "A")
|
||||||
for _, dir := range []string{"Headers", "Modules"} {
|
for _, dir := range []string{"Headers", "Modules"} {
|
||||||
p := filepath.Join(frameworkDir, dir)
|
p := filepath.Join(frameworkDir, dir)
|
||||||
if err := os.MkdirAll(p, 0755); err != nil {
|
if err := os.MkdirAll(p, 0o755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,7 +458,7 @@ func archiveIOS(tmpDir, target, frameworkRoot string, bi *buildInfo) error {
|
|||||||
export *
|
export *
|
||||||
}`, framework)
|
}`, framework)
|
||||||
moduleFile := filepath.Join(frameworkDir, "Modules", "module.modulemap")
|
moduleFile := filepath.Join(frameworkDir, "Modules", "module.modulemap")
|
||||||
return os.WriteFile(moduleFile, []byte(module), 0644)
|
return os.WriteFile(moduleFile, []byte(module), 0o644)
|
||||||
}
|
}
|
||||||
|
|
||||||
func iosCompilerFor(target, arch string, minsdk int) (string, []string, error) {
|
func iosCompilerFor(target, arch string, minsdk int) (string, []string, error) {
|
||||||
|
|||||||
+2
-1
@@ -30,6 +30,7 @@ func (d *JSTestDriver) Start(path string) {
|
|||||||
if raceEnabled {
|
if raceEnabled {
|
||||||
d.Skipf("js/wasm doesn't support -race; skipping")
|
d.Skipf("js/wasm doesn't support -race; skipping")
|
||||||
}
|
}
|
||||||
|
d.Skipf("test fails with \"timed out waiting for a frame to be ready\"")
|
||||||
|
|
||||||
// First, build the app.
|
// First, build the app.
|
||||||
dir := d.tempDir("gio-endtoend-js")
|
dir := d.tempDir("gio-endtoend-js")
|
||||||
@@ -60,7 +61,7 @@ func (d *JSTestDriver) Start(path string) {
|
|||||||
pr, pw := io.Pipe()
|
pr, pw := io.Pipe()
|
||||||
d.Cleanup(func() { pw.Close() })
|
d.Cleanup(func() { pw.Close() })
|
||||||
d.output = pr
|
d.output = pr
|
||||||
chromedp.ListenTarget(ctx, func(ev interface{}) {
|
chromedp.ListenTarget(ctx, func(ev any) {
|
||||||
switch ev := ev.(type) {
|
switch ev := ev.(type) {
|
||||||
case *runtime.EventConsoleAPICalled:
|
case *runtime.EventConsoleAPICalled:
|
||||||
switch ev.Type {
|
switch ev.Type {
|
||||||
|
|||||||
+10
-5
@@ -20,7 +20,7 @@ func buildJS(bi *buildInfo) error {
|
|||||||
if out == "" {
|
if out == "" {
|
||||||
out = bi.name
|
out = bi.name
|
||||||
}
|
}
|
||||||
if err := os.MkdirAll(out, 0700); err != nil {
|
if err := os.MkdirAll(out, 0o700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
@@ -48,7 +48,7 @@ func buildJS(bi *buildInfo) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := os.WriteFile(filepath.Join(out, filepath.Base(bi.iconPath)), icon, 0600); err != nil {
|
if err := os.WriteFile(filepath.Join(out, filepath.Base(bi.iconPath)), icon, 0o600); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
faviconPath = filepath.Base(bi.iconPath)
|
faviconPath = filepath.Base(bi.iconPath)
|
||||||
@@ -70,7 +70,7 @@ func buildJS(bi *buildInfo) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.WriteFile(filepath.Join(out, "index.html"), b.Bytes(), 0600); err != nil {
|
if err := os.WriteFile(filepath.Join(out, "index.html"), b.Bytes(), 0o600); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,9 +78,14 @@ func buildJS(bi *buildInfo) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
wasmJS := filepath.Join(goroot, "misc", "wasm", "wasm_exec.js")
|
// Location of the wasm_exec.js for go>=1.24
|
||||||
|
wasmJS := filepath.Join(goroot, "lib", "wasm", "wasm_exec.js")
|
||||||
if _, err := os.Stat(wasmJS); err != nil {
|
if _, err := os.Stat(wasmJS); err != nil {
|
||||||
return fmt.Errorf("failed to find $GOROOT/misc/wasm/wasm_exec.js driver: %v", err)
|
// Location of the wasm_exec.js for go<1.24
|
||||||
|
wasmJS = filepath.Join(goroot, "misc", "wasm", "wasm_exec.js")
|
||||||
|
if _, err := os.Stat(wasmJS); err != nil {
|
||||||
|
return fmt.Errorf("failed to find $GOROOT/misc/wasm/wasm_exec.js driver: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pkgs, err := packages.Load(&packages.Config{
|
pkgs, err := packages.Load(&packages.Config{
|
||||||
Mode: packages.NeedName | packages.NeedFiles | packages.NeedImports | packages.NeedDeps,
|
Mode: packages.NeedName | packages.NeedFiles | packages.NeedImports | packages.NeedDeps,
|
||||||
|
|||||||
+5
-6
@@ -89,7 +89,7 @@ func (b *macBuilder) setIcon(path string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
out := filepath.Join(b.TempDir, "iconset.iconset")
|
out := filepath.Join(b.TempDir, "iconset.iconset")
|
||||||
if err := os.MkdirAll(out, 0777); err != nil {
|
if err := os.MkdirAll(out, 0o777); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,6 @@ func (b *macBuilder) setIcon(path string) (err error) {
|
|||||||
{path: "icon_16x16@2x.png", size: 32},
|
{path: "icon_16x16@2x.png", size: 32},
|
||||||
{path: "icon_16x16.png", size: 16},
|
{path: "icon_16x16.png", size: 16},
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -171,18 +170,18 @@ func (b *macBuilder) setInfo(buildInfo *buildInfo, name string) error {
|
|||||||
|
|
||||||
func (b *macBuilder) buildProgram(buildInfo *buildInfo, binDest string, name string, arch string) error {
|
func (b *macBuilder) buildProgram(buildInfo *buildInfo, binDest string, name string, arch string) error {
|
||||||
for _, path := range []string{"/Contents/MacOS", "/Contents/Resources"} {
|
for _, path := range []string{"/Contents/MacOS", "/Contents/Resources"} {
|
||||||
if err := os.MkdirAll(filepath.Join(binDest, path), 0755); err != nil {
|
if err := os.MkdirAll(filepath.Join(binDest, path), 0o755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(b.Icons) > 0 {
|
if len(b.Icons) > 0 {
|
||||||
if err := os.WriteFile(filepath.Join(binDest, "/Contents/Resources/icon.icns"), b.Icons, 0755); err != nil {
|
if err := os.WriteFile(filepath.Join(binDest, "/Contents/Resources/icon.icns"), b.Icons, 0o755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.WriteFile(filepath.Join(binDest, "/Contents/Info.plist"), b.Manifest, 0755); err != nil {
|
if err := os.WriteFile(filepath.Join(binDest, "/Contents/Info.plist"), b.Manifest, 0o755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +205,7 @@ func (b *macBuilder) buildProgram(buildInfo *buildInfo, binDest string, name str
|
|||||||
|
|
||||||
func (b *macBuilder) signProgram(buildInfo *buildInfo, binDest string, name string, arch string) error {
|
func (b *macBuilder) signProgram(buildInfo *buildInfo, binDest string, name string, arch string) error {
|
||||||
options := filepath.Join(b.TempDir, "ent.ent")
|
options := filepath.Join(b.TempDir, "ent.ent")
|
||||||
if err := os.WriteFile(options, b.Entitlements, 0777); err != nil {
|
if err := os.WriteFile(options, b.Entitlements, 0o777); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -199,7 +199,7 @@ func buildIcons(baseDir, icon string, variants []iconVariant) error {
|
|||||||
v := v
|
v := v
|
||||||
resizes.Go(func() (err error) {
|
resizes.Go(func() (err error) {
|
||||||
path := filepath.Join(baseDir, v.path)
|
path := filepath.Join(baseDir, v.path)
|
||||||
if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
|
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
f, err := os.Create(path)
|
f, err := os.Create(path)
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ func (d *WaylandTestDriver) Screenshot() image.Image {
|
|||||||
return img
|
return img
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *WaylandTestDriver) swaymsg(args ...interface{}) {
|
func (d *WaylandTestDriver) swaymsg(args ...any) {
|
||||||
strs := []string{"--socket", d.socket}
|
strs := []string{"--socket", d.socket}
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
strs = append(strs, fmt.Sprint(arg))
|
strs = append(strs, fmt.Sprint(arg))
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ const (
|
|||||||
valueText uint16 = 1
|
valueText uint16 = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
func newValue(valueType uint16, key string, input interface{}) windowsInfoValue {
|
func newValue(valueType uint16, key string, input any) windowsInfoValue {
|
||||||
v := windowsInfoValue{
|
v := windowsInfoValue{
|
||||||
Type: valueType,
|
Type: valueType,
|
||||||
Length: 6,
|
Length: 6,
|
||||||
|
|||||||
+1
-1
@@ -145,7 +145,7 @@ func (d *X11TestDriver) Screenshot() image.Image {
|
|||||||
return img
|
return img
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *X11TestDriver) xdotool(args ...interface{}) string {
|
func (d *X11TestDriver) xdotool(args ...any) string {
|
||||||
d.Helper()
|
d.Helper()
|
||||||
strs := make([]string, len(args))
|
strs := make([]string, len(args))
|
||||||
for i, arg := range args {
|
for i, arg := range args {
|
||||||
|
|||||||
+1
-2
@@ -10,6 +10,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"go/format"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -17,8 +18,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"go/format"
|
|
||||||
|
|
||||||
"gioui.org/f32"
|
"gioui.org/f32"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user