Compare commits
6 Commits
36eacab2cd
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
d75363f2ee
|
|||
|
ebb2161ca4
|
|||
|
c68d63fe52
|
|||
|
508c355b86
|
|||
|
6bcd031b5b
|
|||
|
c82444eda2
|
42
fyne-gui-test/go.mod
Normal file
42
fyne-gui-test/go.mod
Normal file
@@ -0,0 +1,42 @@
|
||||
module fyne-gui-test
|
||||
|
||||
go 1.24.3
|
||||
|
||||
require (
|
||||
fyne.io/fyne/v2 v2.6.3
|
||||
)
|
||||
|
||||
require (
|
||||
fyne.io/systray v1.11.0 // indirect
|
||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fredbi/uri v1.1.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/fyne-io/gl-js v0.2.0 // indirect
|
||||
github.com/fyne-io/glfw-js v0.3.0 // indirect
|
||||
github.com/fyne-io/image v0.1.1 // indirect
|
||||
github.com/fyne-io/oksvg v0.1.0 // indirect
|
||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 // indirect
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect
|
||||
github.com/go-text/render v0.2.0 // indirect
|
||||
github.com/go-text/typesetting v0.2.1 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/hack-pad/go-indexeddb v0.3.2 // indirect
|
||||
github.com/hack-pad/safejs v0.1.0 // indirect
|
||||
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade // indirect
|
||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rymdport/portal v0.4.1 // indirect
|
||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
|
||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
github.com/yuin/goldmark v1.7.8 // indirect
|
||||
golang.org/x/image v0.24.0 // indirect
|
||||
golang.org/x/net v0.35.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
133
fyne-gui-test/go.sum
Normal file
133
fyne-gui-test/go.sum
Normal file
@@ -0,0 +1,133 @@
|
||||
fyne.io/fyne v1.4.3 h1:356CnXCiYrrfaLGsB7qLK3c6ktzyh8WR05v/2RBu51I=
|
||||
fyne.io/fyne v1.4.3/go.mod h1:8kiPBNSDmuplxs9WnKCkaWYqbcXFy0DeAzwa6PBO9Z8=
|
||||
fyne.io/fyne/v2 v2.6.3 h1:cvtM2KHeRuH+WhtHiA63z5wJVBkQ9+Ay0UMl9PxFHyA=
|
||||
fyne.io/fyne/v2 v2.6.3/go.mod h1:NGSurpRElVoI1G3h+ab2df3O5KLGh1CGbsMMcX0bPIs=
|
||||
fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg=
|
||||
fyne.io/systray v1.11.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs=
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I=
|
||||
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
||||
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
||||
github.com/fredbi/uri v1.1.0 h1:OqLpTXtyRg9ABReqvDGdJPqZUxs8cyBDOMXBbskCaB8=
|
||||
github.com/fredbi/uri v1.1.0/go.mod h1:aYTUoAXBOq7BLfVJ8GnKmfcuURosB1xyHDIfWeC/iW4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/fyne-io/gl-js v0.2.0 h1:+EXMLVEa18EfkXBVKhifYB6OGs3HwKO3lUElA0LlAjs=
|
||||
github.com/fyne-io/gl-js v0.2.0/go.mod h1:ZcepK8vmOYLu96JoxbCKJy2ybr+g1pTnaBDdl7c3ajI=
|
||||
github.com/fyne-io/glfw-js v0.3.0 h1:d8k2+Y7l+zy2pc7wlGRyPfTgZoqDf3AI4G+2zOWhWUk=
|
||||
github.com/fyne-io/glfw-js v0.3.0/go.mod h1:Ri6te7rdZtBgBpxLW19uBpp3Dl6K9K/bRaYdJ22G8Jk=
|
||||
github.com/fyne-io/image v0.1.1 h1:WH0z4H7qfvNUw5l4p3bC1q70sa5+YWVt6HCj7y4VNyA=
|
||||
github.com/fyne-io/image v0.1.1/go.mod h1:xrfYBh6yspc+KjkgdZU/ifUC9sPA5Iv7WYUBzQKK7JM=
|
||||
github.com/fyne-io/mobile v0.1.2/go.mod h1:/kOrWrZB6sasLbEy2JIvr4arEzQTXBTZGb3Y96yWbHY=
|
||||
github.com/fyne-io/oksvg v0.1.0 h1:7EUKk3HV3Y2E+qypp3nWqMXD7mum0hCw2KEGhI1fnBw=
|
||||
github.com/fyne-io/oksvg v0.1.0/go.mod h1:dJ9oEkPiWhnTFNCmRgEze+YNprJF7YRbpjgpWS4kzoI=
|
||||
github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk=
|
||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 h1:5BVwOaUSBTlVZowGO6VZGw2H/zl9nrd3eCZfYV+NfQA=
|
||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200625191551-73d3c3675aa3/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a h1:vxnBhFDDT+xzxf1jTJKMKZw3H0swfWk9RpWbBbDK5+0=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-text/render v0.2.0 h1:LBYoTmp5jYiJ4NPqDc2pz17MLmA3wHw1dZSVGcOdeAc=
|
||||
github.com/go-text/render v0.2.0/go.mod h1:CkiqfukRGKJA5vZZISkjSYrcdtgKQWRa2HIzvwNN5SU=
|
||||
github.com/go-text/typesetting v0.2.1 h1:x0jMOGyO3d1qFAPI0j4GSsh7M0Q3Ypjzr4+CEVg82V8=
|
||||
github.com/go-text/typesetting v0.2.1/go.mod h1:mTOxEwasOFpAMBjEQDhdWRckoLLeI/+qrQeBCTGEt6M=
|
||||
github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066 h1:qCuYC+94v2xrb1PoS4NIDe7DGYtLnU2wWiQe9a1B1c0=
|
||||
github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff h1:W71vTCKoxtdXgnm1ECDFkfQnpdqAO00zzGXLA5yaEX8=
|
||||
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||
github.com/hack-pad/go-indexeddb v0.3.2 h1:DTqeJJYc1usa45Q5r52t01KhvlSN02+Oq+tQbSBI91A=
|
||||
github.com/hack-pad/go-indexeddb v0.3.2/go.mod h1:QvfTevpDVlkfomY498LhstjwbPW6QC4VC/lxYb0Kom0=
|
||||
github.com/hack-pad/safejs v0.1.0 h1:qPS6vjreAqh2amUqj4WNG1zIw7qlRQJ9K10eDKMCnE8=
|
||||
github.com/hack-pad/safejs v0.1.0/go.mod h1:HdS+bKF1NrE72VoXZeWzxFOVQVUSqZJAG0xNCnb+Tio=
|
||||
github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc=
|
||||
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade h1:FmusiCI1wHw+XQbvL9M+1r/C3SPqKrmBaIOYwVfQoDE=
|
||||
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade/go.mod h1:ZDXo8KHryOWSIqnsb/CiDq7hQUYryCgdVnxbj8tDG7o=
|
||||
github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE=
|
||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M=
|
||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lucor/goinfo v0.0.0-20200401173949-526b5363a13a/go.mod h1:ORP3/rB5IsulLEBwQZCJyyV6niqmI7P4EWSmkug+1Ng=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.1 h1:IxtPxYsR9Gp60cGXjfuR/llTqV8aYMsC472zD0D1vHk=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.1/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
|
||||
github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rymdport/portal v0.4.1 h1:2dnZhjf5uEaeDjeF/yBIeeRo6pNI2QAKm7kq1w/kbnA=
|
||||
github.com/rymdport/portal v0.4.1/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564/go.mod h1:afMbS0qvv1m5tfENCwnOdZGOF8RGR/FsZ7bvBxQGZG4=
|
||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE=
|
||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q=
|
||||
github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU=
|
||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ=
|
||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
|
||||
github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
|
||||
golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190808195139-e713427fea3f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200328031815-3db5fc6bac03/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
43
fyne-gui-test/main.go
Normal file
43
fyne-gui-test/main.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/app"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
func main() {
|
||||
myApp := app.New()
|
||||
window := myApp.NewWindow("Hello World.")
|
||||
window.Resize(fyne.NewSize(700, 400))
|
||||
// window.SetFixedSize(true)
|
||||
|
||||
textEntry := widget.NewMultiLineEntry()
|
||||
textEntry.Wrapping = fyne.TextWrapWord
|
||||
// textEntry.Disable()
|
||||
|
||||
initialText := "This is text"
|
||||
textEntry.SetText(initialText)
|
||||
textEntry.OnChanged = func(text string) {
|
||||
if text != initialText {
|
||||
textEntry.SetText(initialText)
|
||||
}
|
||||
}
|
||||
|
||||
button := widget.NewButton(" [ Close ] ", func() {
|
||||
myApp.Quit()
|
||||
})
|
||||
|
||||
content := container.NewBorder(
|
||||
nil, // top
|
||||
container.NewBorder(nil, nil, nil, button, nil), // bottom
|
||||
nil, // left
|
||||
nil, // right
|
||||
textEntry, // center
|
||||
)
|
||||
|
||||
window.SetContent(content)
|
||||
window.CenterOnScreen()
|
||||
window.ShowAndRun()
|
||||
}
|
||||
3
go-ca/go.mod
Normal file
3
go-ca/go.mod
Normal file
@@ -0,0 +1,3 @@
|
||||
module git.hatter.ink/golang-tests/go-ca
|
||||
|
||||
go 1.24.3
|
||||
75
go-ca/main.go
Normal file
75
go-ca/main.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"math"
|
||||
"math/big"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := innerMain()
|
||||
if err == nil {
|
||||
println("Success")
|
||||
} else {
|
||||
println("Error: ", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func innerMain() error {
|
||||
rootKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rootCert, err := issueRootCertificate(&rootKey.PublicKey, rootKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
println(string(pem.EncodeToMemory(&pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: rootCert,
|
||||
})))
|
||||
return nil
|
||||
}
|
||||
|
||||
func issueRootCertificate(pubKey, parentPrivKey any) ([]byte, error) {
|
||||
now := time.Now()
|
||||
template := x509.Certificate{
|
||||
SerialNumber: generateSerialNumber(),
|
||||
Subject: pkix.Name{
|
||||
CommonName: "Root CA",
|
||||
},
|
||||
NotBefore: now.UTC(),
|
||||
NotAfter: now.AddDate(100, 0, 0).UTC(),
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: true,
|
||||
MaxPathLen: 10,
|
||||
// MaxPathLenZero: true,
|
||||
SubjectKeyId: getKeyId(pubKey),
|
||||
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
|
||||
}
|
||||
parentCert := &template
|
||||
return x509.CreateCertificate(rand.Reader, &template, parentCert, pubKey, parentPrivKey)
|
||||
}
|
||||
|
||||
func getKeyId(pubKey any) []byte {
|
||||
pubKeyBytes, err := x509.MarshalPKIXPublicKey(pubKey)
|
||||
if err != nil {
|
||||
panic("Should not happen")
|
||||
}
|
||||
return sha1.New().Sum(pubKeyBytes)
|
||||
}
|
||||
|
||||
func generateSerialNumber() *big.Int {
|
||||
randInt, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
|
||||
if err != nil {
|
||||
panic("Should not happen")
|
||||
}
|
||||
return randInt
|
||||
}
|
||||
8
go-tpm-non-restricted-key/go.mod
Normal file
8
go-tpm-non-restricted-key/go.mod
Normal file
@@ -0,0 +1,8 @@
|
||||
module git.hatter.ink/go-tpm-non-restricted-key
|
||||
|
||||
go 1.24.3
|
||||
|
||||
require (
|
||||
github.com/google/go-tpm v0.9.5 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
)
|
||||
4
go-tpm-non-restricted-key/go.sum
Normal file
4
go-tpm-non-restricted-key/go.sum
Normal file
@@ -0,0 +1,4 @@
|
||||
github.com/google/go-tpm v0.9.5 h1:ocUmnDebX54dnW+MQWGQRbdaAcJELsa6PqZhJ48KwVU=
|
||||
github.com/google/go-tpm v0.9.5/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
211
go-tpm-non-restricted-key/main.go
Normal file
211
go-tpm-non-restricted-key/main.go
Normal file
@@ -0,0 +1,211 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/asn1"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math/big"
|
||||
"os"
|
||||
|
||||
"github.com/google/go-tpm/legacy/tpm2"
|
||||
"github.com/google/go-tpm/tpmutil"
|
||||
)
|
||||
|
||||
func generateSrk(f *os.File) {
|
||||
tmpl := tpm2.Public{
|
||||
Type: tpm2.AlgRSA,
|
||||
NameAlg: tpm2.AlgSHA256,
|
||||
Attributes: tpm2.FlagFixedTPM | // Key can't leave the TPM.
|
||||
tpm2.FlagFixedParent | // Key can't change parent.
|
||||
tpm2.FlagSensitiveDataOrigin | // Key created by the TPM (not imported).
|
||||
tpm2.FlagUserWithAuth | // Uses (empty) password.
|
||||
tpm2.FlagNoDA | // This flag doesn't do anything, but it's in the spec.
|
||||
tpm2.FlagRestricted | // Key used for TPM challenges, not general decryption.
|
||||
tpm2.FlagDecrypt, // Key can be used to decrypt data.
|
||||
RSAParameters: &tpm2.RSAParams{
|
||||
Symmetric: &tpm2.SymScheme{Alg: tpm2.AlgAES, KeyBits: 128, Mode: tpm2.AlgCFB},
|
||||
KeyBits: 2048,
|
||||
ModulusRaw: make([]byte, 256),
|
||||
},
|
||||
}
|
||||
|
||||
srk, _, err := tpm2.CreatePrimary(f, tpm2.HandleOwner, tpm2.PCRSelection{}, "", "", tmpl)
|
||||
if err != nil {
|
||||
log.Fatalf("creating srk: %v", err)
|
||||
}
|
||||
out, err := tpm2.ContextSave(f, srk)
|
||||
if err != nil {
|
||||
log.Fatalf("saving context: %v", err)
|
||||
}
|
||||
if err := os.WriteFile("srk.ctx", out, 0644); err != nil {
|
||||
log.Fatalf("writing context: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func generateAppKey(f *os.File) {
|
||||
srkCtx, err := os.ReadFile("srk.ctx")
|
||||
if err != nil {
|
||||
log.Fatalf("read srk: %v", err)
|
||||
}
|
||||
srk, err := tpm2.ContextLoad(f, srkCtx)
|
||||
if err != nil {
|
||||
log.Fatalf("load srk: %v", err)
|
||||
}
|
||||
|
||||
tmpl := tpm2.Public{
|
||||
Type: tpm2.AlgECC,
|
||||
NameAlg: tpm2.AlgSHA256,
|
||||
Attributes: tpm2.FlagFixedTPM | // Key can't leave the TPM.
|
||||
tpm2.FlagFixedParent | // Key can't change parent.
|
||||
tpm2.FlagSensitiveDataOrigin | // Key created by the TPM (not imported).
|
||||
tpm2.FlagUserWithAuth | // Uses (empty) password.
|
||||
tpm2.FlagSign, // Key can be used to sign data.
|
||||
ECCParameters: &tpm2.ECCParams{
|
||||
Sign: &tpm2.SigScheme{Alg: tpm2.AlgECDSA, Hash: tpm2.AlgSHA256},
|
||||
CurveID: tpm2.CurveNISTP256,
|
||||
Point: tpm2.ECPoint{
|
||||
XRaw: make([]byte, 32),
|
||||
YRaw: make([]byte, 32),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
privBlob, pubBlob, _, hash, ticket, err := tpm2.CreateKey(f, srk, tpm2.PCRSelection{}, "", "", tmpl)
|
||||
if err != nil {
|
||||
log.Fatalf("create aik: %v", err)
|
||||
}
|
||||
log.Printf("privBlob: %x\n", privBlob)
|
||||
log.Printf("pubBlob: %x\n", pubBlob)
|
||||
log.Printf("hash: %x\n", hash)
|
||||
log.Printf("ticket: %v %s\n", ticket.Type, ticket.Digest)
|
||||
|
||||
appKey, _, err := tpm2.Load(f, srk, "", pubBlob, privBlob)
|
||||
if err != nil {
|
||||
log.Fatalf("load app key: %v", err)
|
||||
}
|
||||
|
||||
// Write key context to disk.
|
||||
appKeyCtx, err := tpm2.ContextSave(f, appKey)
|
||||
if err != nil {
|
||||
log.Fatalf("saving context: %v", err)
|
||||
}
|
||||
if err := os.WriteFile("app.ctx", appKeyCtx, 0644); err != nil {
|
||||
log.Fatalf("writing context: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func fileExists(filename string) bool {
|
||||
_, err := os.Stat(filename)
|
||||
if err == nil {
|
||||
return true
|
||||
}
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return false
|
||||
}
|
||||
panic("Should not happen")
|
||||
}
|
||||
|
||||
type tpmSinger struct {
|
||||
tpm io.ReadWriter
|
||||
h tpmutil.Handle
|
||||
pub crypto.PublicKey
|
||||
}
|
||||
|
||||
func (s *tpmSinger) Public() crypto.PublicKey {
|
||||
return s.pub
|
||||
}
|
||||
|
||||
func (s *tpmSinger) Sign(r io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
|
||||
sig, err := tpm2.Sign(s.tpm, s.h, "", digest, nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("signing data: %v", err)
|
||||
}
|
||||
if sig.RSA != nil {
|
||||
return sig.RSA.Signature, nil
|
||||
}
|
||||
if sig.ECC != nil {
|
||||
return asn1.Marshal(struct {
|
||||
R *big.Int
|
||||
S *big.Int
|
||||
}{sig.ECC.R, sig.ECC.S})
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported signature type: %v", sig.Alg)
|
||||
}
|
||||
|
||||
func newSigner(tpm io.ReadWriter, h tpmutil.Handle) (*tpmSinger, error) {
|
||||
tpmPub, _, _, err := tpm2.ReadPublic(tpm, h)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read public blob: %v", err)
|
||||
}
|
||||
pub, err := tpmPub.Key()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode public key: %v", err)
|
||||
}
|
||||
return &tpmSinger{tpm, h, pub}, nil
|
||||
}
|
||||
|
||||
func getSinger(f *os.File) (*tpmSinger, error) {
|
||||
keyCtx, err := os.ReadFile("app.ctx")
|
||||
if err != nil {
|
||||
log.Fatalf("read app key: %v", err)
|
||||
}
|
||||
key, err := tpm2.ContextLoad(f, keyCtx)
|
||||
if err != nil {
|
||||
log.Fatalf("load app key: %v", err)
|
||||
}
|
||||
|
||||
return newSigner(f, key)
|
||||
}
|
||||
|
||||
// reference: https://ericchiang.github.io/post/tpm-keys/
|
||||
func main() {
|
||||
f, err := os.OpenFile("/dev/tpmrm0", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
log.Fatalf("opening tpm: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if !fileExists("srk.ctx") {
|
||||
generateSrk(f)
|
||||
}
|
||||
if !fileExists("app.ctx") {
|
||||
generateAppKey(f)
|
||||
}
|
||||
|
||||
priv, err := getSinger(f)
|
||||
if err != nil {
|
||||
log.Fatalf("create signer: %v", err)
|
||||
}
|
||||
|
||||
publicKeyDer, err := x509.MarshalPKIXPublicKey(priv.Public())
|
||||
if err != nil {
|
||||
log.Fatalf("public key: %v", err)
|
||||
} else {
|
||||
log.Printf("public key pem: %s\n", base64.StdEncoding.EncodeToString(publicKeyDer))
|
||||
}
|
||||
|
||||
msg := []byte("Hello world!")
|
||||
digest := sha256.Sum256(msg)
|
||||
|
||||
sig, err := priv.Sign(rand.Reader, digest[:], crypto.SHA256)
|
||||
if err != nil {
|
||||
log.Fatalf("signing data: %v", err)
|
||||
}
|
||||
log.Printf("sig: %s\n", hex.EncodeToString(sig))
|
||||
pub, ok := priv.Public().(*ecdsa.PublicKey)
|
||||
if !ok {
|
||||
log.Fatalf("expected ecdsa.PublicKey got: %T", priv.Public())
|
||||
}
|
||||
if !ecdsa.VerifyASN1(pub, digest[:], sig) {
|
||||
log.Fatalf("failed to verify signature")
|
||||
}
|
||||
}
|
||||
7
go-tpm-rand/go.mod
Normal file
7
go-tpm-rand/go.mod
Normal file
@@ -0,0 +1,7 @@
|
||||
module git.hatter.ink/go-tpm-rand
|
||||
|
||||
go 1.24.3
|
||||
|
||||
require github.com/google/go-tpm v0.9.5
|
||||
|
||||
require golang.org/x/sys v0.8.0 // indirect
|
||||
4
go-tpm-rand/go.sum
Normal file
4
go-tpm-rand/go.sum
Normal file
@@ -0,0 +1,4 @@
|
||||
github.com/google/go-tpm v0.9.5 h1:ocUmnDebX54dnW+MQWGQRbdaAcJELsa6PqZhJ48KwVU=
|
||||
github.com/google/go-tpm v0.9.5/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
24
go-tpm-rand/main.go
Normal file
24
go-tpm-rand/main.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/google/go-tpm/legacy/tpm2"
|
||||
)
|
||||
|
||||
// reference: https://ericchiang.github.io/post/tpm-keys/
|
||||
func main() {
|
||||
f, err := os.OpenFile("/dev/tpmrm0", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
log.Fatalf("opening tpm: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
out, err := tpm2.GetRandom(f, 16)
|
||||
if err != nil {
|
||||
log.Fatalf("getting random bytes: %v", err)
|
||||
}
|
||||
fmt.Printf("%x\n", out)
|
||||
}
|
||||
5
okta-bcrypt-issue/go.mod
Normal file
5
okta-bcrypt-issue/go.mod
Normal file
@@ -0,0 +1,5 @@
|
||||
module git.hatter.ink/okta-bcrypt-issue
|
||||
|
||||
go 1.24.1
|
||||
|
||||
require golang.org/x/crypto v0.40.0 // indirect
|
||||
2
okta-bcrypt-issue/go.sum
Normal file
2
okta-bcrypt-issue/go.sum
Normal file
@@ -0,0 +1,2 @@
|
||||
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||
44
okta-bcrypt-issue/main.go
Normal file
44
okta-bcrypt-issue/main.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// https://n0rdy.foo/posts/20250121/okta-bcrypt-lessons-for-better-apis/
|
||||
func main() {
|
||||
// 18 + 55 + 1 = 74, so above 72 characters' limit of BCrypt
|
||||
userId := randomString(18)
|
||||
username := randomString(55)
|
||||
password := "super-duper-secure-password"
|
||||
|
||||
combinedString := fmt.Sprintf("%s:%s:%s", userId, username, password)
|
||||
|
||||
combinedHash, err := bcrypt.GenerateFromPassword([]byte(combinedString), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// let's try to break it
|
||||
wrongPassword := "wrong-password"
|
||||
wrongCombinedString := fmt.Sprintf("%s:%s:%s", userId, username, wrongPassword)
|
||||
|
||||
err = bcrypt.CompareHashAndPassword(combinedHash, []byte(wrongCombinedString))
|
||||
if err != nil {
|
||||
fmt.Println("Password is incorrect")
|
||||
} else {
|
||||
fmt.Println("Password is correct")
|
||||
}
|
||||
}
|
||||
|
||||
func randomString(length int) string {
|
||||
bytes := make([]byte, length)
|
||||
_, err := rand.Read(bytes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return base64.URLEncoding.EncodeToString(bytes)[:length]
|
||||
}
|
||||
29
swift-from-go/Package.swift
Normal file
29
swift-from-go/Package.swift
Normal file
@@ -0,0 +1,29 @@
|
||||
// swift-tools-version:4.2
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "go-swift",
|
||||
products: [
|
||||
// Products define the executables and libraries produced by a package, and make them visible to other packages.
|
||||
.library(
|
||||
name: "go_swift",
|
||||
type: .dynamic,
|
||||
targets: ["go-swift"]),
|
||||
],
|
||||
dependencies: [
|
||||
// Dependencies declare other packages that this package depends on.
|
||||
// .package(url: /* package url */, from: "1.0.0"),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
|
||||
.target(
|
||||
name: "go-swift",
|
||||
dependencies: []),
|
||||
.testTarget(
|
||||
name: "go-swiftTests",
|
||||
dependencies: ["go-swift"]),
|
||||
]
|
||||
)
|
||||
15
swift-from-go/README.md
Normal file
15
swift-from-go/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# go-swift
|
||||
|
||||
> Clone from: https://github.com/onderweg/swift-from-go
|
||||
|
||||
Example code, complementing the blog post: ["Calling Swift from Go"](https://dev.to/gerwert/calling-swift-from-go-5dbk)
|
||||
|
||||
_Note: this repo is more than 3 years old. Feel free to use it as reference, but don't expect it to work with current versions of Go and Swift._
|
||||
|
||||
## Building & Running
|
||||
|
||||
```
|
||||
$ swift build
|
||||
$ go build -o hello
|
||||
$ ./hello
|
||||
```
|
||||
7
swift-from-go/Sources/go-swift/go_swift.swift
Normal file
7
swift-from-go/Sources/go-swift/go_swift.swift
Normal file
@@ -0,0 +1,7 @@
|
||||
@_cdecl("sayHello") // export to C as `sayHello``
|
||||
public func sayHello(namePtr: UnsafePointer<CChar>?) {
|
||||
// Creates a new string by copying the null-terminated UTF-8 data (C String)
|
||||
// referenced by the given pointer.
|
||||
let name = String(cString: namePtr!)
|
||||
print("Welcome, \(name)!")
|
||||
}
|
||||
7
swift-from-go/Tests/LinuxMain.swift
Normal file
7
swift-from-go/Tests/LinuxMain.swift
Normal file
@@ -0,0 +1,7 @@
|
||||
import XCTest
|
||||
|
||||
import go_swiftTests
|
||||
|
||||
var tests = [XCTestCaseEntry]()
|
||||
tests += go_swiftTests.allTests()
|
||||
XCTMain(tests)
|
||||
9
swift-from-go/Tests/go-swiftTests/XCTestManifests.swift
Normal file
9
swift-from-go/Tests/go-swiftTests/XCTestManifests.swift
Normal file
@@ -0,0 +1,9 @@
|
||||
import XCTest
|
||||
|
||||
#if !os(macOS)
|
||||
public func allTests() -> [XCTestCaseEntry] {
|
||||
return [
|
||||
testCase(go_swiftTests.allTests),
|
||||
]
|
||||
}
|
||||
#endif
|
||||
15
swift-from-go/Tests/go-swiftTests/go_swiftTests.swift
Normal file
15
swift-from-go/Tests/go-swiftTests/go_swiftTests.swift
Normal file
@@ -0,0 +1,15 @@
|
||||
import XCTest
|
||||
@testable import go_swift
|
||||
|
||||
final class go_swiftTests: XCTestCase {
|
||||
func testExample() {
|
||||
// This is an example of a functional test case.
|
||||
// Use XCTAssert and related functions to verify your tests produce the correct
|
||||
// results.
|
||||
XCTAssertEqual(go_swift().text, "Hello, World!")
|
||||
}
|
||||
|
||||
static var allTests = [
|
||||
("testExample", testExample),
|
||||
]
|
||||
}
|
||||
2
swift-from-go/include/go_swift.h
Normal file
2
swift-from-go/include/go_swift.h
Normal file
@@ -0,0 +1,2 @@
|
||||
// Manually crafted header file for C Library
|
||||
void sayHello(char* name);
|
||||
22
swift-from-go/main.go
Normal file
22
swift-from-go/main.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -I./include
|
||||
#cgo LDFLAGS: -L.build/debug/ -lgo_swift
|
||||
#include <stdlib.h>
|
||||
#include "include/go_swift.h"
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
func main() {
|
||||
// Convert Go string to C string
|
||||
cstr := C.CString("Bob")
|
||||
|
||||
// Call Swift function `sayHello``
|
||||
C.sayHello(cstr)
|
||||
|
||||
// The C string is allocated in the C heap using malloc.
|
||||
// Therefore memory must be freed when we're done
|
||||
C.free(unsafe.Pointer(cstr))
|
||||
}
|
||||
Reference in New Issue
Block a user