Skip to content

Commit 3a19a50

Browse files
feat(sources/oracle): add Oracle Source and Tool (#1456)
## Description --- > Should include a concise description of the changes (bug or feature), it's > impact, along with a summary of the solution ## PR Checklist --- > Thank you for opening a Pull Request! Before submitting your PR, there are a > few things you can do to make sure it goes smoothly: - [ ] Make sure you reviewed [CONTRIBUTING.md](https://github.com/googleapis/genai-toolbox/blob/main/CONTRIBUTING.md) - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/genai-toolbox/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [ ] Ensure the tests and linter pass - [ ] Code coverage does not decrease (if any source code was changed) - [ ] Appropriate docs were updated (if necessary) - [ ] Make sure to add `!` if this involve a breaking change 🛠️ Fixes #488 --------- Co-authored-by: duwenxin <duwenxin@google.com> Co-authored-by: Wenxin Du <117315983+duwenxin99@users.noreply.github.com>
1 parent 98f7ee2 commit 3a19a50

File tree

13 files changed

+1129
-2
lines changed

13 files changed

+1129
-2
lines changed

.ci/integration.cloudbuild.yaml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,32 @@ steps:
703703
"Cassandra" \
704704
cassandra \
705705
cassandra
706-
706+
707+
- id: "oracle"
708+
name: ghcr.io/oracle/oraclelinux8-instantclient:21
709+
waitFor: ["install-dependencies"]
710+
entrypoint: /bin/bash
711+
env:
712+
- "GOPATH=/gopath"
713+
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
714+
- "ORACLE_SERVER_NAME=$_ORACLE_SERVER_NAME"
715+
secretEnv: ["CLIENT_ID", "ORACLE_USER", "ORACLE_PASS", "ORACLE_HOST"]
716+
volumes:
717+
- name: "go"
718+
path: "/gopath"
719+
args:
720+
- -c
721+
- |
722+
# Install the C compiler and Oracle SDK headers needed for cgo
723+
dnf install -y gcc oracle-instantclient-devel
724+
725+
# Install Go
726+
curl -L -o go.tar.gz "https://go.dev/dl/go1.25.1.linux-amd64.tar.gz"
727+
tar -C /usr/local -xzf go.tar.gz
728+
export PATH="/usr/local/go/bin:$$PATH"
729+
730+
go test ./tests/oracle
731+
707732
availableSecrets:
708733
secretManager:
709734
- versionName: projects/$PROJECT_ID/secrets/cloud_sql_pg_user/versions/latest
@@ -794,6 +819,12 @@ availableSecrets:
794819
env: CASSANDRA_PASS
795820
- versionName: projects/$PROJECT_ID/secrets/cassandra_host/versions/latest
796821
env: CASSANDRA_HOST
822+
- versionName: projects/$PROJECT_ID/secrets/oracle_user/versions/latest
823+
env: ORACLE_USER
824+
- versionName: projects/$PROJECT_ID/secrets/oracle_pass/versions/latest
825+
env: ORACLE_PASS
826+
- versionName: projects/$PROJECT_ID/secrets/oracle_host/versions/latest
827+
env: ORACLE_HOST
797828

798829
options:
799830
logging: CLOUD_LOGGING_ONLY
@@ -845,3 +876,4 @@ substitutions:
845876
_YUGABYTEDB_DATABASE: "yugabyte"
846877
_YUGABYTEDB_PORT: "5433"
847878
_YUGABYTEDB_LOADBALANCE: "false"
879+
_ORACLE_SERVER_NAME: "FREEPDB1"

cmd/root.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ import (
139139
_ "github.com/googleapis/genai-toolbox/internal/tools/neo4j/neo4jschema"
140140
_ "github.com/googleapis/genai-toolbox/internal/tools/oceanbase/oceanbaseexecutesql"
141141
_ "github.com/googleapis/genai-toolbox/internal/tools/oceanbase/oceanbasesql"
142+
_ "github.com/googleapis/genai-toolbox/internal/tools/oracle/oracleexecutesql"
143+
_ "github.com/googleapis/genai-toolbox/internal/tools/oracle/oraclesql"
142144
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgresexecutesql"
143145
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistactivequeries"
144146
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistavailableextensions"
@@ -184,6 +186,7 @@ import (
184186
_ "github.com/googleapis/genai-toolbox/internal/sources/mysql"
185187
_ "github.com/googleapis/genai-toolbox/internal/sources/neo4j"
186188
_ "github.com/googleapis/genai-toolbox/internal/sources/oceanbase"
189+
_ "github.com/googleapis/genai-toolbox/internal/sources/oracle"
187190
_ "github.com/googleapis/genai-toolbox/internal/sources/postgres"
188191
_ "github.com/googleapis/genai-toolbox/internal/sources/redis"
189192
_ "github.com/googleapis/genai-toolbox/internal/sources/spanner"
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
title: "Oracle"
3+
type: docs
4+
weight: 1
5+
description: >
6+
Oracle Database is a widely-used relational database management system.
7+
---
8+
9+
## About
10+
11+
[Oracle Database][oracle-docs] is a multi-model database management system produced and marketed by Oracle Corporation. It is commonly used for running online transaction processing (OLTP), data warehousing (DW), and mixed (OLTP & DW) database workloads.
12+
13+
[oracle-docs]: https://www.oracle.com/database/
14+
15+
## Available Tools
16+
17+
- [`oracle-sql`](../tools/oracle/oracle-sql.md)
18+
Execute pre-defined prepared SQL queries in Oracle.
19+
20+
- [`oracle-execute-sql`](../tools/oracle/oracle-execute-sql.md)
21+
Run parameterized SQL queries in Oracle.
22+
23+
## Requirements
24+
25+
### Database User
26+
27+
This source uses standard authentication. You will need to [create an Oracle user][oracle-users] to log in to the database with the necessary permissions.
28+
29+
[oracle-users]:
30+
https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-USER.html
31+
32+
### Oracle Instant Client (OIC)
33+
34+
The underlying database driver requires the [Oracle Instant Client][oracle-ic] libraries to connect to the database. These libraries must be installed on the machine where the application is running.
35+
36+
After installing the client, ensure the library path is correctly configured for your operating system (e.g., by setting the `LD_LIBRARY_PATH` environment variable on Linux or adding the directory to the `PATH` on Windows) so the application can find the necessary files at runtime.
37+
38+
[oracle-ic]: https://www.oracle.com/database/technologies/instant-client/downloads.html
39+
40+
## Connection Methods
41+
42+
You can configure the connection to your Oracle database using one of the following three methods. **You should only use one method** in your source configuration.
43+
44+
### Basic Connection (Host/Port/Service Name)
45+
46+
This is the most straightforward method, where you provide the connection details as separate fields:
47+
48+
- `host`: The IP address or hostname of the database server.
49+
- `port`: The port number the Oracle listener is running on (typically 1521).
50+
- `serviceName`: The service name for the database instance you wish to connect to.
51+
52+
### Connection String
53+
54+
As an alternative, you can provide all the connection details in a single `connectionString`. This is a convenient way to consolidate the connection information. The typical format is `hostname:port/servicename`.
55+
56+
### TNS Alias
57+
58+
For environments that use a `tnsnames.ora` configuration file, you can connect using a TNS (Transparent Network Substrate) alias.
59+
60+
- `tnsAlias`: Specify the alias name defined in your `tnsnames.ora` file.
61+
- `tnsAdmin` (Optional): If your configuration file is not in a standard location, you can use this field to provide the path to the directory containing it. This setting will override the `TNS_ADMIN` environment variable.
62+
63+
## Example
64+
65+
```yaml
66+
sources:
67+
my-oracle-source:
68+
kind: oracle
69+
# --- Choose one connection method ---
70+
# 1. Host, Port, and Service Name
71+
host: 127.0.0.1
72+
port: 1521
73+
serviceName: XEPDB1
74+
75+
# 2. Direct Connection String
76+
connectionString: "127.0.0.1:1521/XEPDB1"
77+
78+
# 3. TNS Alias (requires tnsnames.ora)
79+
tnsAlias: "MY_DB_ALIAS"
80+
tnsAdmin: "/opt/oracle/network/admin" # Optional: overrides TNS_ADMIN env var
81+
82+
user: ${USER_NAME}
83+
password: ${PASSWORD}
84+
85+
```
86+
87+
{{< notice tip >}}
88+
Use environment variable replacement with the format ${ENV_NAME}
89+
instead of hardcoding your secrets into the configuration file.
90+
{{< /notice >}}
91+
92+
## Reference
93+
94+
| **field** | **type** | **required** | **description** |
95+
|------------------|:--------:|:------------:|-----------------------------------------------------------------------------------------------------------------------------|
96+
| kind | string | true | Must be "oracle". |
97+
| user | string | true | Name of the Oracle user to connect as (e.g. "my-oracle-user"). |
98+
| password | string | true | Password of the Oracle user (e.g. "my-password"). |
99+
| host | string | false | IP address or hostname to connect to (e.g. "127.0.0.1"). Required if not using `connectionString` or `tnsAlias`. |
100+
| port | integer | false | Port to connect to (e.g. "1521"). Required if not using `connectionString` or `tnsAlias`. |
101+
| serviceName | string | false | The Oracle service name of the database to connect to. Required if not using `connectionString` or `tnsAlias`. |
102+
| connectionString | string | false | A direct connection string (e.g. "hostname:port/servicename"). Use as an alternative to `host`, `port`, and `serviceName`. |
103+
| tnsAlias | string | false | A TNS alias from a `tnsnames.ora` file. Use as an alternative to `host`/`port` or `connectionString`. |
104+
| tnsAdmin | string | false | Path to the directory containing the `tnsnames.ora` file. This overrides the `TNS_ADMIN` environment variable if it is set. |
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: "Oracle"
3+
type: docs
4+
weight: 1
5+
description: >
6+
Tools that work with Oracle Sources.
7+
---
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
title: "oracle-execute-sql"
3+
type: docs
4+
weight: 1
5+
description: >
6+
An "oracle-execute-sql" tool executes a SQL statement against an Oracle database.
7+
aliases:
8+
- /resources/tools/oracle-execute-sql
9+
---
10+
11+
## About
12+
13+
An `oracle-execute-sql` tool executes a SQL statement against an Oracle
14+
database. It's compatible with the following source:
15+
16+
- [oracle](../../sources/oracle.md)
17+
18+
`oracle-execute-sql` takes one input parameter `sql` and runs the sql
19+
statement against the `source`.
20+
21+
> **Note:** This tool is intended for developer assistant workflows with
22+
> human-in-the-loop and shouldn't be used for production agents.
23+
24+
## Example
25+
26+
```yaml
27+
tools:
28+
execute_sql_tool:
29+
kind: oracle-execute-sql
30+
source: my-oracle-instance
31+
description: Use this tool to execute sql statement.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
title: "oracle-sql"
3+
type: docs
4+
weight: 1
5+
description: >
6+
An "oracle-sql" tool executes a pre-defined SQL statement against an Oracle database.
7+
aliases:
8+
- /resources/tools/oracle-sql
9+
---
10+
11+
## About
12+
13+
An `oracle-sql` tool executes a pre-defined SQL statement against an
14+
Oracle database. It's compatible with the following source:
15+
16+
- [oracle](../../sources/oracle.md)
17+
18+
The specified SQL statement is executed using [prepared statements][oracle-stmt]
19+
for security and performance. It expects parameter placeholders in the SQL query
20+
to be in the native Oracle format (e.g., `:1`, `:2`).
21+
22+
[oracle-stmt]: https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
23+
24+
## Example
25+
26+
> **Note:** This tool uses parameterized queries to prevent SQL injections.
27+
> Query parameters can be used as substitutes for arbitrary expressions.
28+
> Parameters cannot be used as substitutes for identifiers, column names, table
29+
> names, or other parts of the query.
30+
31+
```yaml
32+
tools:
33+
search_flights_by_number:
34+
kind: oracle-sql
35+
source: my-oracle-instance
36+
statement: |
37+
SELECT * FROM flights
38+
WHERE airline = :1
39+
AND flight_number = :2
40+
FETCH FIRST 10 ROWS ONLY
41+
description: |
42+
Use this tool to get information for a specific flight.
43+
Takes an airline code and flight number and returns info on the flight.
44+
Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number.
45+
Example:
46+
{{
47+
"airline": "CY",
48+
"flight_number": "888",
49+
}}
50+
parameters:
51+
- name: airline
52+
type: string
53+
description: Airline unique 2 letter identifier
54+
- name: flight_number
55+
type: string
56+
description: 1 to 4 digit number
57+
```

go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ require (
2828
github.com/go-sql-driver/mysql v1.9.3
2929
github.com/goccy/go-yaml v1.18.0
3030
github.com/gocql/gocql v1.7.0
31+
github.com/godror/godror v0.49.3
3132
github.com/google/go-cmp v0.7.0
3233
github.com/google/uuid v1.6.0
3334
github.com/jackc/pgx/v5 v5.7.6
@@ -85,6 +86,7 @@ require (
8586
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 // indirect
8687
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect
8788
github.com/PuerkitoBio/goquery v1.10.3 // indirect
89+
github.com/VictoriaMetrics/easyproto v0.1.4 // indirect
8890
github.com/ajg/form v1.5.1 // indirect
8991
github.com/apache/arrow/go/v15 v15.0.2 // indirect
9092
github.com/cespare/xxhash/v2 v2.3.0 // indirect
@@ -101,11 +103,13 @@ require (
101103
github.com/felixge/httpsnoop v1.0.4 // indirect
102104
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
103105
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
106+
github.com/go-logfmt/logfmt v0.6.0 // indirect
104107
github.com/go-logr/logr v1.4.3 // indirect
105108
github.com/go-logr/stdr v1.2.2 // indirect
106109
github.com/go-playground/locales v0.14.1 // indirect
107110
github.com/go-playground/universal-translator v0.18.1 // indirect
108111
github.com/goccy/go-json v0.10.5 // indirect
112+
github.com/godror/knownpb v0.3.0 // indirect
109113
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
110114
github.com/golang-sql/sqlexp v0.1.0 // indirect
111115
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect

go.sum

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,10 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8
681681
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
682682
github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo=
683683
github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
684+
github.com/UNO-SOFT/zlog v0.8.1 h1:TEFkGJHtUfTRgMkLZiAjLSHALjwSBdw6/zByMC5GJt4=
685+
github.com/UNO-SOFT/zlog v0.8.1/go.mod h1:yqFOjn3OhvJ4j7ArJqQNA+9V+u6t9zSAyIZdWdMweWc=
686+
github.com/VictoriaMetrics/easyproto v0.1.4 h1:r8cNvo8o6sR4QShBXQd1bKw/VVLSQma/V2KhTBPf+Sc=
687+
github.com/VictoriaMetrics/easyproto v0.1.4/go.mod h1:QlGlzaJnDfFd8Lk6Ci/fuLxfTo3/GThPs2KH23mv710=
684688
github.com/ahmetb/dlog v0.0.0-20170105205344-4fb5f8204f26 h1:3YVZUqkoev4mL+aCwVOSWV4M7pN+NURHL38Z2zq5JKA=
685689
github.com/ahmetb/dlog v0.0.0-20170105205344-4fb5f8204f26/go.mod h1:ymXt5bw5uSNu4jveerFxE0vNYxF8ncqbptntMaFMg3k=
686690
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
@@ -878,6 +882,8 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
878882
github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=
879883
github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk=
880884
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
885+
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
886+
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
881887
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
882888
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
883889
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@@ -905,6 +911,10 @@ github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
905911
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
906912
github.com/gocql/gocql v1.7.0 h1:O+7U7/1gSN7QTEAaMEsJc1Oq2QHXvCWoF3DFK9HDHus=
907913
github.com/gocql/gocql v1.7.0/go.mod h1:vnlvXyFZeLBF0Wy+RS8hrOdbn0UWsWtdg07XJnFxZ+4=
914+
github.com/godror/godror v0.49.3 h1:84CPEu1p3qPvpN7PTHv8NDept+t+d+AoO/7WjYVsFNc=
915+
github.com/godror/godror v0.49.3/go.mod h1:kTMcxZzRw73RT5kn9v3JkBK4kHI6dqowHotqV72ebU8=
916+
github.com/godror/knownpb v0.3.0 h1:+caUdy8hTtl7X05aPl3tdL540TvCcaQA6woZQroLZMw=
917+
github.com/godror/knownpb v0.3.0/go.mod h1:PpTyfJwiOEAzQl7NtVCM8kdPCnp3uhxsZYIzZ5PV4zU=
908918
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
909919
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
910920
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
@@ -1168,6 +1178,8 @@ github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdh
11681178
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
11691179
github.com/neo4j/neo4j-go-driver/v5 v5.28.4 h1:7toxehVcYkZbyxV4W3Ib9VcnyRBQPucF+VwNNmtSXi4=
11701180
github.com/neo4j/neo4j-go-driver/v5 v5.28.4/go.mod h1:Vff8OwT7QpLm7L2yYr85XNWe9Rbqlbeb9asNXJTHO4k=
1181+
github.com/oklog/ulid/v2 v2.0.2 h1:r4fFzBm+bv0wNKNh5eXTwU7i85y5x+uwkxCUTNVQqLc=
1182+
github.com/oklog/ulid/v2 v2.0.2/go.mod h1:mtBL0Qe/0HAx6/a4Z30qxVIAL1eQDweXq5lxOEiwQ68=
11711183
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
11721184
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
11731185
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
@@ -1661,6 +1673,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
16611673
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
16621674
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
16631675
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
1676+
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
1677+
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
16641678
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
16651679
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
16661680
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

0 commit comments

Comments
 (0)