From eb3c0abee20a64f6dc47b0793f60a486d143ac14 Mon Sep 17 00:00:00 2001 From: "Hana (Hyang-Ah) Kim" Date: Sat, 16 Oct 2021 15:12:49 -0400 Subject: [PATCH] example/ivy: make ivy as a separate module, and update to use AndroidX golang.org/x/mobile/example/ivy module specifies dependency on golang.org/x/mobile and robpike.io/ivy versions. - Updated to use AndroidX and target API level 30 to meet the current Google Play policies https://support.google.com/googleplay/android-developer/answer/9859152?visit_id=637402646062706504-1797308153&rd=1#targetsdk&zippy=%2Ctarget-api-level-requirements-for-play-console - Updated demo.ivy script (copied from https://github.com/robpike/ivy/blob/66c48de6ebd134f4207b5155ca0569d08cdca313/demo/demo.ivy) - Added example/ivy/android/README.md Change-Id: Ie613ecdba4c3d77b5c45ef8a792fba6ee8a2c5cf Reviewed-on: https://go-review.googlesource.com/c/mobile/+/356729 Run-TryBot: Hyang-Ah Hana Kim TryBot-Result: Go Bot Trust: Cherry Mui Reviewed-by: Robert Findley --- .gitignore | 4 ++ example/ivy/android/README | 8 --- example/ivy/android/README.md | 42 +++++++++++++ example/ivy/android/app/build.gradle | 14 ++--- .../android/app/src/main/AndroidManifest.xml | 6 +- .../ivy/android/app/src/main/assets/demo.ivy | 62 ++++++++++++++----- .../main/java/org/golang/ivy/AboutIvy.java | 3 +- .../src/main/java/org/golang/ivy/Help.java | 8 +-- .../java/org/golang/ivy/MainActivity.java | 4 +- example/ivy/android/build.gradle | 5 +- example/ivy/doc.go | 7 +++ example/ivy/go.mod | 15 +++++ example/ivy/go.sum | 40 ++++++++++++ example/ivy/tools.go | 14 +++++ 14 files changed, 189 insertions(+), 43 deletions(-) delete mode 100644 example/ivy/android/README create mode 100644 example/ivy/android/README.md mode change 100755 => 100644 example/ivy/android/app/src/main/assets/demo.ivy create mode 100644 example/ivy/doc.go create mode 100644 example/ivy/go.mod create mode 100644 example/ivy/go.sum create mode 100644 example/ivy/tools.go diff --git a/.gitignore b/.gitignore index 201387b..bdda4d0 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,13 @@ last-change *.framework *.xcframework *.aar +*.jar *.iml .idea .gradle +*.properties +example/ivy/**/build/ +example/ivy/android/gradle/ # Xcode configuration files. *.xcworkspace diff --git a/example/ivy/android/README b/example/ivy/android/README deleted file mode 100644 index 683864a..0000000 --- a/example/ivy/android/README +++ /dev/null @@ -1,8 +0,0 @@ -Ivy Android app - -Run - -$ gomobile bind -o app/ivy.aar robpike.io/ivy/mobile - -and import this project in Android Studio. If you prefer the command -line, use gradle to build directly. diff --git a/example/ivy/android/README.md b/example/ivy/android/README.md new file mode 100644 index 0000000..d5923ea --- /dev/null +++ b/example/ivy/android/README.md @@ -0,0 +1,42 @@ +## Ivy Big Number Calculator (Android) + +[Ivy (robpike.io/ivy)](https://robpike.io/ivy) is an interpreter for an APL-like language written in Go. +This repository hosts a minimal Android project used for its [Android version](https://play.google.com/store/apps/details?id=org.golang.ivy&hl=en_US&gl=US). + +### How to build + +Requirements + - Go 1.17 or newer + - Android SDK + - Android NDK + - `golang.org/x/mobile/cmd/gomobile` + +The `gomobile` command uses `ANDROID_HOME` and `ANDROID_NDK_HOME` environment variables. +``` +export ANDROID_HOME=/path/to/sdk-directory +export ANDROID_NDK_HOME=/path/to/ndk-directory +``` + +Note: Both ANDROID_SDK_ROOT and ANDROID_NDK_HOME are deprecated in Android tooling, but `gomobile` still uses it. In many cases, `ANDROID_HOME` corresponds to the new [`ANDROID_SDK_ROOT`](https://developer.android.com/studio/command-line/variables). If you installed NDK using [Android Studio's SDK manager](https://developer.android.com/studio/projects/install-ndk#default-version), use the `$ANDROID_SDK_ROOT/ndk//` directory as `ANDROID_NDK_HOME` (where `` is the NDK version you want to use when compiling `robpike.io/ivy` for Android. + +(TODO: update `gomobile` to work with modern Android layout) + +From this directory, run: + +```sh + go install golang.org/x/mobile/cmd/gomobile@latest + go install golang.org/x/mobile/cmd/gobind@latest + + # Make sure `gomobile` and `gobind` is in your `PATH`. + gomobile bind -o app/ivy.aar robpike.io/ivy/mobile +``` + +Open this directory from Android Studio, and build. + +`robpike.io/ivy` and `golang.org/x/mobile` are required dependencies of this main module. In order to update them: + +``` + go get -d golang.org/x/mobile@latest + go get -d robpike.io/ivy/mobile + go mod tidy +``` diff --git a/example/ivy/android/app/build.gradle b/example/ivy/android/app/build.gradle index 559b34c..91ce182 100644 --- a/example/ivy/android/app/build.gradle +++ b/example/ivy/android/app/build.gradle @@ -1,17 +1,11 @@ apply plugin: 'com.android.application' -repositories { - flatDir { - dirs '.' - } -} - android { - compileSdkVersion 23 + compileSdkVersion 30 defaultConfig { applicationId 'org.golang.ivy' minSdkVersion 15 - targetSdkVersion 23 + targetSdkVersion 30 versionCode 3 versionName '1.0.2' } @@ -26,6 +20,6 @@ android { } dependencies { - implementation 'com.android.support:appcompat-v7:23.3.0' - implementation (name:'ivy', ext:'aar') + implementation 'androidx.appcompat:appcompat:1.0.0' + implementation files('ivy.aar') } diff --git a/example/ivy/android/app/src/main/AndroidManifest.xml b/example/ivy/android/app/src/main/AndroidManifest.xml index ac3d5a9..8aa99a7 100644 --- a/example/ivy/android/app/src/main/AndroidManifest.xml +++ b/example/ivy/android/app/src/main/AndroidManifest.xml @@ -16,14 +16,16 @@ android:label="@string/app_name" android:logo="@mipmap/ic_launcher" android:theme="@style/IvyAppTheme" - android:windowSoftInputMode="adjustResize|stateAlwaysVisible"> + android:windowSoftInputMode="adjustResize|stateAlwaysVisible" + android:fullBackupContent="true"> + android:configChanges="orientation|screenSize" + android:exported="true"> diff --git a/example/ivy/android/app/src/main/assets/demo.ivy b/example/ivy/android/app/src/main/assets/demo.ivy old mode 100755 new mode 100644 index d455366..6e3d9a3 --- a/example/ivy/android/app/src/main/assets/demo.ivy +++ b/example/ivy/android/app/src/main/assets/demo.ivy @@ -1,4 +1,5 @@ -# This is ivy. Type a newline to advance to each new step. Type one now. +# This is a demo of ivy. Type a newline to advance to each new step. Type one now. +# At any time, type the word "quit" or EOF to end the demo and return to ivy. # Each step in the demo is one line of input followed by some output from ivy. Type a newline now to see. 2+2 # The first line you see above (2+2) is input; the next (4) is output from a running ivy. @@ -24,7 +25,7 @@ 1/3 ** 2 # We'll see non-integral exponents later. # Even when a number is input in floating notation, it is still an exact rational number inside. 1.2 -# In fact, ivy is a "bignum" calculator that can handle huge numbers and rationals made of huge numers. +# In fact, ivy is a "bignum" calculator that can handle huge numbers and rationals made of huge numbers. 1e10 # Still an integer. 1e100 # Still an integer. 1e10/3 # Not an integer, but an exact rational. @@ -42,11 +43,13 @@ code '💩' # char's inverse, the value of given character, here printed in # Vectors are written and displayed with spaces between the elements. 1 2 3 1 4/3 5/3 (2+1/3) +# Note that without the parens this becomes (1 4/3 5/3 2)+1/3 +1 4/3 5/3 2+1/3 # Vectors of characters print without quotes or spaces. 'h' 'e' 'l' 'l' 'o' # This is a nicer way to write 'h' 'e' 'l' 'l' 'o'. It means the same. 'hello' -# Arithmetic works on vectors. +# Arithmetic works elementwise on vectors. 1 2 3 + 4 5 6 # Arithmetic between scalar and vector also works, either way. 23 + 1 2 3 @@ -78,13 +81,13 @@ iota 15 */iota 100 # Type this: */iota 10000 # That printed using floating-point notation for manageability but it is still an integer inside. -# max and min are binary operators that do the obvious. (Use semicolons to separate expresssions.) +# max and min are binary operators that do the obvious. (Use semicolons to separate expressions.) 3 max 7; 'is max and'; 3 min 7; 'is min' # Like all binary arithmetic operators, max applies elementwise. 2 3 4 max 4 3 2 -# Reduce using max to find maxmimum element in vector. +# Reduce using max to find maximum element in vector. max/2 34 42 233 2 2 521 14 1 4 1 55 133 -# Ivy allows multidimensional arrays. The shape operator binary rho builds them. +# Ivy allows multidimensional arrays. The binary shape operator, rho, builds them. # Dimension (which may be a vector) on the left, data on the right. 5 rho 1 5 5 rho 1 @@ -113,6 +116,8 @@ x**10 # That's a letter 'o', dot, star. # Any operator works; here is how to make an identity matrix. x = iota 5; x o.== x +# Assignment is an operator, so you can save an intermediate expression. +x o.== x = iota 5 # Random numbers: Use a unary ? to roll an n-sided die from 1 to n. ?100 ?100 @@ -144,7 +149,7 @@ x = ?10 rho 6; x 2**64 2**iota 64 -1+2**63 -# Settings are made and queried with a leading right paren. )help lists the settings +# Settings are made and queried with a leading right paren. )help helps with settings and other commands. )help # Use )base to switch input and output to base 16. )base 16 @@ -155,8 +160,9 @@ _ (2**40)-1 # The largest 64-bit number base 16. )obase 10 # Output base 10, input base still 16. )base --1+2**63 # The largest 63-bit number base 10. --1+2**64 # The largest 64-bit number base 10. +# The largest 63-bit number base 10. +-1+2**40 # The largest 64-bit number base 10. +-1+2**3F # The largest 63-bit number base 10. # Go back to base 10 input and output. )base 10 # Rationals can be very big too. @@ -188,21 +194,21 @@ e**1e6 log e**1e6 log e**1e8 log 1e1000000 # Yes, that is 10 to the millionth power. -# Transcendentals. (The low bits aren't always quite right...) +# Transcendentals. (The low bit isn't always right...) sin pi/2 cos .25*pi * -1 + iota 9 log iota 6 # Successive approximations to e. (We force the calculation to use float using the "float" unary operator. Why?) (float 1+10**-iota 9) ** 10**iota 9 # Default precision is 256 bits of mantissa. We can go up to 10000. -)prec 3000 # Units are bits, not digits. +)prec 3350 # Units are bits, not digits. 2 log 10 == 3.321. Add a few more bits for floating point errors. e )format '%.1000g' # Units are digits. (Sorry for the inconsistency.) e pi sqrt 2 e**1e6 -log e**1e6 # Only 904 good digits; the log algorithm is numerically weak. (Ideas welcome.) +log e**1e6 (2**1e3)/(3**1e2) # User-defined operators are declared as unary or binary (or both). This one computes the (unary) average. op avg x = (+/x)/rho x @@ -218,12 +224,40 @@ op popcount n = +/n base 2 popcount 7 popcount 1e6 popcount 1e100 -# Here is one to sum the digits. The unary operator text turns its argument into text, like Sprintf. +# Here is one to sum the digits. The unary operator text turns its argument into text, like sprintf. op sumdigits x = t = text x; +/(code (t in '0123456789') sel t) - code '0' # Break it down: The sel operator selects from the right based on the non-zero elements in the left. # The in operator generates a selector by choosing only the bytes that are ASCII digits. sumdigits 99 sumdigits iota 10 sumdigits '23 skidoo' # Note: It counts only the digits. +# The binary text operator takes a format string (% optional) on the left and formats the value. +'%x' text 1234 +# We can use this for another version of popcount: %b is binary. +op popcount n = +/'1' == '%b' text n +popcount 7 +popcount 1e6 +popcount 1e100 +# A classic (expensive!) algorithm to count primes. +op primes N = (not T in T o.* T) sel T = 1 drop iota N +# The assignment to T gives 2..N. We use outer product to build an array of all products. +# Then we find all elements of T that appear in the product matrix, invert that, and select from the original. +primes 100 +# A final trick. +# The binary ? operator "deals": x?y selects at random x distinct integers from 1..y inclusive. +5?10 +# We can use this to shuffle a deck of cards. The suits are ♠♡♣♢, the values +# A234567890JQK (using 0 for 10, for simplicity). +# Create the deck using outer product with the ravel operator: +"A234567890JQK" o., "♠♡♣♢" +# To shuffle it, ravel into into a vector and index that by 1 through 52, shuffled. +(, "A234567890JQK" o., "♠♡♣♢")[52?52] +# There is no looping construct in ivy, but there is a conditional evaluator. +# Within a user-defined operator, one can write a condition expression +# using a binary operator, ":". If the left-hand operand is true (integer non-zero), +# the user-defined operator will return the right-hand operand as its +# result; otherwise execution continues. +op a gcd b = a == b: a; a > b: b gcd a-b; a gcd b-a +1562 gcd !11 # That's it! Have fun. -# For more information visit https://godoc.org/robpike.io/ivy +# For more information visit https://pkg.go.dev/robpike.io/ivy diff --git a/example/ivy/android/app/src/main/java/org/golang/ivy/AboutIvy.java b/example/ivy/android/app/src/main/java/org/golang/ivy/AboutIvy.java index 3b89eb5..f9ec5c0 100644 --- a/example/ivy/android/app/src/main/java/org/golang/ivy/AboutIvy.java +++ b/example/ivy/android/app/src/main/java/org/golang/ivy/AboutIvy.java @@ -9,7 +9,6 @@ package org.golang.ivy; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; @@ -17,6 +16,8 @@ import android.view.ViewGroup; import android.webkit.WebView; import android.webkit.WebViewClient; +import androidx.appcompat.app.AppCompatActivity; + /* * Handles About menu item. */ diff --git a/example/ivy/android/app/src/main/java/org/golang/ivy/Help.java b/example/ivy/android/app/src/main/java/org/golang/ivy/Help.java index b17f854..5a5abe7 100644 --- a/example/ivy/android/app/src/main/java/org/golang/ivy/Help.java +++ b/example/ivy/android/app/src/main/java/org/golang/ivy/Help.java @@ -10,11 +10,12 @@ package org.golang.ivy; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; import android.view.MenuItem; import android.webkit.WebView; import android.webkit.WebViewClient; +import androidx.appcompat.app.AppCompatActivity; + import mobile.Mobile; /* @@ -37,12 +38,11 @@ public class Help extends AppCompatActivity { } }); webView.getSettings().setDefaultTextEncodingName("utf-8"); - // org.golang.ivy.Mobile was generated - // using gomobile bind -javapkg=org.golang.ivy robpike.io/ivy/mobile. + // mobile.Mobile was generated using gomobile bind robpike.io/ivy/mobile. String helpMsg = Mobile.help(); // loadData has a rendering bug: https://code.google.com/p/android/issues/detail?id=6965 - webView.loadDataWithBaseURL("http://godoc.org/robpike.io/ivy", helpMsg, "text/html", "UTF-8", null); + webView.loadDataWithBaseURL("http://pkg.go.dev/robpike.io/ivy", helpMsg, "text/html", "UTF-8", null); webView.setBackgroundColor(getResources().getColor(R.color.body)); } diff --git a/example/ivy/android/app/src/main/java/org/golang/ivy/MainActivity.java b/example/ivy/android/app/src/main/java/org/golang/ivy/MainActivity.java index 04008a2..1a3c021 100644 --- a/example/ivy/android/app/src/main/java/org/golang/ivy/MainActivity.java +++ b/example/ivy/android/app/src/main/java/org/golang/ivy/MainActivity.java @@ -12,7 +12,6 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.util.Log; import android.util.Pair; @@ -28,10 +27,13 @@ import android.widget.ImageButton; import android.widget.ScrollView; import android.widget.Toast; +import androidx.appcompat.app.AppCompatActivity; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +// This is in ivy.aar. import mobile.Mobile; /* diff --git a/example/ivy/android/build.gradle b/example/ivy/android/build.gradle index 8110722..3d1d988 100644 --- a/example/ivy/android/build.gradle +++ b/example/ivy/android/build.gradle @@ -2,17 +2,16 @@ buildscript { repositories { + mavenCentral() google() - jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.0' + classpath 'com.android.tools.build:gradle:7.0.3' } } allprojects { repositories { google() - jcenter() } } diff --git a/example/ivy/doc.go b/example/ivy/doc.go new file mode 100644 index 0000000..fa37ea9 --- /dev/null +++ b/example/ivy/doc.go @@ -0,0 +1,7 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This is an empty package. +// We have this package to convince this is buildable and go mod tidy can work. +package dummy diff --git a/example/ivy/go.mod b/example/ivy/go.mod new file mode 100644 index 0000000..fe8775a --- /dev/null +++ b/example/ivy/go.mod @@ -0,0 +1,15 @@ +module golang.org/x/mobile/example/ivy + +go 1.17 + +require ( + golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7 + robpike.io/ivy v0.1.4 +) + +require ( + golang.org/x/mod v0.4.2 // indirect + golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect + golang.org/x/tools v0.1.2 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect +) diff --git a/example/ivy/go.sum b/example/ivy/go.sum new file mode 100644 index 0000000..3f33541 --- /dev/null +++ b/example/ivy/go.sum @@ -0,0 +1,40 @@ +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7 h1:CyFUjc175y/mbMjxe+WdqI72jguLyjQChKCDe9mfTvg= +golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7/go.mod h1:c4YKU3ZylDmvbw+H/PSvm42vhdWbuxCzbonauEAP9B8= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +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-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +robpike.io/ivy v0.1.4 h1:H61eItFW1TGNhq02v9UFDz+x5z4GkC3PNjJUVyizWb8= +robpike.io/ivy v0.1.4/go.mod h1:6B/DGaft5rvYiF7MgCTiZAAvH5W7vtu0eS2BW77updo= diff --git a/example/ivy/tools.go b/example/ivy/tools.go new file mode 100644 index 0000000..ab067c2 --- /dev/null +++ b/example/ivy/tools.go @@ -0,0 +1,14 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package dummy + +// This is a dummy go file to add required module dependencies to go.mod. + +import ( + _ "golang.org/x/mobile/bind" + _ "robpike.io/ivy" +)