mirror of
https://github.com/ysoftdevs/gardener-extension-shoot-fleet-agent.git
synced 2026-04-17 22:20:09 +02:00
Initial v1.0.0 commit
This commit is contained in:
16
vendor/github.com/ahmetb/gen-crd-api-reference-docs/.gitignore
generated
vendored
Normal file
16
vendor/github.com/ahmetb/gen-crd-api-reference-docs/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Binaries for programs and plugins
|
||||
refdocs
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# goreleaser output
|
||||
dist
|
||||
24
vendor/github.com/ahmetb/gen-crd-api-reference-docs/.goreleaser.yml
generated
vendored
Normal file
24
vendor/github.com/ahmetb/gen-crd-api-reference-docs/.goreleaser.yml
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
builds:
|
||||
- env:
|
||||
- CGO_ENABLED=0
|
||||
# travis ci currently sets GOPATH even with go1.11.
|
||||
# force-setting GO111MODULE=on to use vgo
|
||||
- GO111MODULE=on
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
goarch:
|
||||
- amd64
|
||||
archive:
|
||||
name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
|
||||
files:
|
||||
- LICENSE
|
||||
- template/**
|
||||
- example-config.json
|
||||
checksum:
|
||||
name_template: "checksums.txt"
|
||||
changelog:
|
||||
skip: true
|
||||
release:
|
||||
# releases are uploaded to github by .travis.yml
|
||||
disable: true
|
||||
32
vendor/github.com/ahmetb/gen-crd-api-reference-docs/.travis.yml
generated
vendored
Normal file
32
vendor/github.com/ahmetb/gen-crd-api-reference-docs/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.11.x
|
||||
install:
|
||||
- echo noop
|
||||
before_script:
|
||||
# travis ci currently sets GOPATH even with go1.11.
|
||||
# force-setting GO111MODULE=on to use vgo
|
||||
- env GO111MODULE=on go mod download
|
||||
script:
|
||||
# travis ci currently sets GOPATH even with go1.11.
|
||||
# force-setting GO111MODULE=on to use vgo
|
||||
- env GO111MODULE=on go build -v -o /dev/null
|
||||
deploy:
|
||||
# use goreleaser to prepare dist/
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
||||
script: curl -sL https://git.io/goreleaser | bash
|
||||
# use github release feature to upload dist/
|
||||
- provider: releases
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
||||
file_glob: true
|
||||
file:
|
||||
- dist/*.tar.gz
|
||||
- dist/*.zip
|
||||
- dist/checksums.txt
|
||||
api_key:
|
||||
secure: r1GMgbVDnZTUcny/PbIATW9dXGOTpm2U9iEGaWvpprMO2AGo7ju7SWEJWtjcap3pc0YasyR2/eon9LC0scWY0Xlpeb+g0pRCQ39FABk1Vo3DpmIPRUCFFkaescWmrWDj3ImzjJgZjCewwK6Fo8s8ngnqIlZnE1Hq6ls2xDp6jNVf+Pn7LyqxkK4axFFSPQM9zFX3N1PVUH5RT03bIJfojJZguqnhNfyTvKvHJidoeWU/Ie+fXc4AdPHyP85xrmGHYl68O0HziU6JCLXira8r1FjUgVeYFYC5nnNuylszO6JWqWh1nXYDxs5FGPnZd9N8bEi/2ahiqms8eV7S+/DGzhSoEdHikcBxTgJpZP2VOmvRSITyv3RleJzCeMULTGFQodoxRgA/Q8qZySvInNjstiBjV2Pyucrnn990XQbN8rIV4RmNggJvbAwJNCGjCwS2eB42EKNCODTuzHPbIV0ap4EjvfBBo0cZ2J9M2Q6VzdpNErdntpM1hZl9yymv3MNN4hOiLQKkofoo/QI3cffB8Y0PBPAL8Cs9Mx1bbx+Dr8iitTHBUAt4a5DHFen4MS8znrZ+Cr4kLDD9QPJ8G0oh4tDKq8CJ73Gt+xqkLZEuka0W1awz9essqE7MH20kRJbKa5woTIs0v9njHMpbeqd7KrNV+1e5F5aPRQyiCzaom7c=
|
||||
201
vendor/github.com/ahmetb/gen-crd-api-reference-docs/LICENSE
generated
vendored
Normal file
201
vendor/github.com/ahmetb/gen-crd-api-reference-docs/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
78
vendor/github.com/ahmetb/gen-crd-api-reference-docs/README.md
generated
vendored
Normal file
78
vendor/github.com/ahmetb/gen-crd-api-reference-docs/README.md
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
# Kubernetes Custom Resource API Reference Docs generator
|
||||
|
||||
If you have a project that is Custom Resource Definitions and wanted to generate
|
||||
API Reference Docs [like this][ar] this tool is for you.
|
||||
|
||||
[ar]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/
|
||||
|
||||
## Current Users
|
||||
|
||||
- [**Knative** API reference docs](https://www.knative.dev/docs/reference/)
|
||||
- [**Kubeflow** API reference docs](https://www.kubeflow.org/docs/reference/overview/)
|
||||
- [**Agones** API reference docs](https://agones.dev/site/docs/reference/agones_crd_api_reference/)
|
||||
- [**cert-manager** API reference docs](https://cert-manager.io/docs/reference/api-docs/)
|
||||
- _[[ADD YOUR PROJECT HERE]]_
|
||||
|
||||
## Why
|
||||
|
||||
Normally you would want to use the same [docs generator][dg] as [Kubernetes API
|
||||
reference][ar], but here's why I wrote a different parser/generator:
|
||||
|
||||
1. Today, Kubernetes API [does not][pr] provide OpenAPI specs for CRDs (e.g.
|
||||
Knative), therefore the [gen-apidocs][ga]
|
||||
generator used by Kubernetes won't work.
|
||||
|
||||
2. Even when Kubernetes API starts providing OpenAPI specs for CRDs, your CRD
|
||||
must have a validation schema (e.g. Knative API doesn't!)
|
||||
|
||||
3. Kubernetes [gen-apidocs][ga] parser relies on running a `kube-apiserver` and
|
||||
calling `/apis` endpoint to get OpenAPI specs to generate docs. **This tool
|
||||
doesn't need that!**
|
||||
|
||||
[dg]: https://github.com/kubernetes-incubator/reference-docs/
|
||||
[ga]: https://github.com/kubernetes-incubator/reference-docs/tree/master/gen-apidocs/generators
|
||||
[pr]: https://github.com/kubernetes/kubernetes/pull/71192
|
||||
|
||||
## How
|
||||
|
||||
This is a custom API reference docs generator that uses the
|
||||
[k8s.io/gengo](https://godoc.org/k8s.io/gengo) project to parse types and
|
||||
generate API documentation from it.
|
||||
|
||||
Capabilities of this tool include:
|
||||
|
||||
- Doesn't depend on OpenAPI specs, or kube-apiserver, or a running cluster.
|
||||
- Relies only on the Go source code (pkg/apis/**/*.go) to parse API types.
|
||||
- Can link to other sites for external APIs. For example, if your types have a
|
||||
reference to Kubernetes core/v1.PodSpec, you can link to it.
|
||||
- [Configurable](./example-config.json) settings to hide certain fields or types
|
||||
entirely from the generated output.
|
||||
- Either output to a file or start a live http-server (for rapid iteration).
|
||||
- Supports markdown rendering from godoc type, package and field comments.
|
||||
|
||||
## Try it out
|
||||
|
||||
1. Clone this repository.
|
||||
|
||||
2. Make sure you have go1.11+ instaled. Then run `go build`, you should get a
|
||||
`refdocs` binary executable.
|
||||
|
||||
3. Clone a Knative repository, set GOPATH correctly,
|
||||
and call the compiled binary within that directory.
|
||||
|
||||
```sh
|
||||
# go into a repository root with GOPATH set. (I use my own script
|
||||
# goclone(1) to have a separate GOPATH for each repo I clone.)
|
||||
$ goclone knative/build
|
||||
|
||||
$ /path/to/refdocs \
|
||||
-config "/path/to/example-config.json" \
|
||||
-api-dir "github.com/knative/build/pkg/apis/build/v1alpha1" \
|
||||
-out-file docs.html
|
||||
```
|
||||
|
||||
4. Visit `docs.html` to view the results.
|
||||
|
||||
-----
|
||||
|
||||
This is not an official Google project. See [LICENSE](./LICENSE).
|
||||
28
vendor/github.com/ahmetb/gen-crd-api-reference-docs/example-config.json
generated
vendored
Normal file
28
vendor/github.com/ahmetb/gen-crd-api-reference-docs/example-config.json
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"hideMemberFields": [
|
||||
"TypeMeta"
|
||||
],
|
||||
"hideTypePatterns": [
|
||||
"ParseError$",
|
||||
"List$"
|
||||
],
|
||||
"externalPackages": [
|
||||
{
|
||||
"typeMatchPrefix": "^k8s\\.io/apimachinery/pkg/apis/meta/v1\\.Duration$",
|
||||
"docsURLTemplate": "https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#Duration"
|
||||
},
|
||||
{
|
||||
"typeMatchPrefix": "^k8s\\.io/(api|apimachinery/pkg/apis)/",
|
||||
"docsURLTemplate": "https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#{{lower .TypeIdentifier}}-{{arrIndex .PackageSegments -1}}-{{arrIndex .PackageSegments -2}}"
|
||||
},
|
||||
{
|
||||
"typeMatchPrefix": "^github\\.com/knative/pkg/apis/duck/",
|
||||
"docsURLTemplate": "https://godoc.org/github.com/knative/pkg/apis/duck/{{arrIndex .PackageSegments -1}}#{{.TypeIdentifier}}"
|
||||
}
|
||||
],
|
||||
"typeDisplayNamePrefixOverrides": {
|
||||
"k8s.io/api/": "Kubernetes ",
|
||||
"k8s.io/apimachinery/pkg/apis/": "Kubernetes "
|
||||
},
|
||||
"markdownDisabled": false
|
||||
}
|
||||
12
vendor/github.com/ahmetb/gen-crd-api-reference-docs/go.mod
generated
vendored
Normal file
12
vendor/github.com/ahmetb/gen-crd-api-reference-docs/go.mod
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
module github.com/ahmetb/gen-crd-api-reference-docs
|
||||
|
||||
require (
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/spf13/pflag v1.0.3 // indirect
|
||||
golang.org/x/tools v0.0.0-20190213192042-740235f6c0d8 // indirect
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6
|
||||
k8s.io/klog v0.2.0
|
||||
)
|
||||
23
vendor/github.com/ahmetb/gen-crd-api-reference-docs/go.sum
generated
vendored
Normal file
23
vendor/github.com/ahmetb/gen-crd-api-reference-docs/go.sum
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
golang.org/x/tools v0.0.0-20181221235234-d00ac6d27372 h1:zWPUEY/PjVHT+zO3L8OfkjrtIjf55joTxn/RQP/AjOI=
|
||||
golang.org/x/tools v0.0.0-20181221235234-d00ac6d27372/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190213192042-740235f6c0d8/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
k8s.io/gengo v0.0.0-20181113154421-fd15ee9cc2f7 h1:zjNgw2qqBQmKd0S59lGZBQqFxJqUZroVbDphfnVm5do=
|
||||
k8s.io/gengo v0.0.0-20181113154421-fd15ee9cc2f7/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6 h1:4s3/R4+OYYYUKptXPhZKjQ04WJ6EhQQVFdjOFvCazDk=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog v0.1.0 h1:I5HMfc/DtuVaGR1KPwUrTc476K8NCqNBldC7H4dYEzk=
|
||||
k8s.io/klog v0.1.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.2.0 h1:0ElL0OHzF3N+OhoJTL0uca20SxtYt4X4+bzHeqrB83c=
|
||||
k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
628
vendor/github.com/ahmetb/gen-crd-api-reference-docs/main.go
generated
vendored
Normal file
628
vendor/github.com/ahmetb/gen-crd-api-reference-docs/main.go
generated
vendored
Normal file
@@ -0,0 +1,628 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
texttemplate "text/template"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/russross/blackfriday/v2"
|
||||
"k8s.io/gengo/parser"
|
||||
"k8s.io/gengo/types"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
var (
|
||||
flConfig = flag.String("config", "", "path to config file")
|
||||
flAPIDir = flag.String("api-dir", "", "api directory (or import path), point this to pkg/apis")
|
||||
flTemplateDir = flag.String("template-dir", "template", "path to template/ dir")
|
||||
|
||||
flHTTPAddr = flag.String("http-addr", "", "start an HTTP server on specified addr to view the result (e.g. :8080)")
|
||||
flOutFile = flag.String("out-file", "", "path to output file to save the result")
|
||||
)
|
||||
|
||||
const (
|
||||
docCommentForceIncludes = "// +gencrdrefdocs:force"
|
||||
)
|
||||
|
||||
type generatorConfig struct {
|
||||
// HiddenMemberFields hides fields with specified names on all types.
|
||||
HiddenMemberFields []string `json:"hideMemberFields"`
|
||||
|
||||
// HideTypePatterns hides types matching the specified patterns from the
|
||||
// output.
|
||||
HideTypePatterns []string `json:"hideTypePatterns"`
|
||||
|
||||
// ExternalPackages lists recognized external package references and how to
|
||||
// link to them.
|
||||
ExternalPackages []externalPackage `json:"externalPackages"`
|
||||
|
||||
// TypeDisplayNamePrefixOverrides is a mapping of how to override displayed
|
||||
// name for types with certain prefixes with what value.
|
||||
TypeDisplayNamePrefixOverrides map[string]string `json:"typeDisplayNamePrefixOverrides"`
|
||||
|
||||
// MarkdownDisabled controls markdown rendering for comment lines.
|
||||
MarkdownDisabled bool `json:"markdownDisabled"`
|
||||
}
|
||||
|
||||
type externalPackage struct {
|
||||
TypeMatchPrefix string `json:"typeMatchPrefix"`
|
||||
DocsURLTemplate string `json:"docsURLTemplate"`
|
||||
}
|
||||
|
||||
type apiPackage struct {
|
||||
apiGroup string
|
||||
apiVersion string
|
||||
GoPackages []*types.Package
|
||||
Types []*types.Type // because multiple 'types.Package's can add types to an apiVersion
|
||||
}
|
||||
|
||||
func (v *apiPackage) identifier() string { return fmt.Sprintf("%s/%s", v.apiGroup, v.apiVersion) }
|
||||
|
||||
func init() {
|
||||
klog.InitFlags(nil)
|
||||
flag.Set("alsologtostderr", "true") // for klog
|
||||
flag.Parse()
|
||||
|
||||
if *flConfig == "" {
|
||||
panic("-config not specified")
|
||||
}
|
||||
if *flAPIDir == "" {
|
||||
panic("-api-dir not specified")
|
||||
}
|
||||
if *flHTTPAddr == "" && *flOutFile == "" {
|
||||
panic("-out-file or -http-addr must be specified")
|
||||
}
|
||||
if *flHTTPAddr != "" && *flOutFile != "" {
|
||||
panic("only -out-file or -http-addr can be specified")
|
||||
}
|
||||
if err := resolveTemplateDir(*flTemplateDir); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func resolveTemplateDir(dir string) error {
|
||||
path, err := filepath.Abs(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if fi, err := os.Stat(path); err != nil {
|
||||
return errors.Wrapf(err, "cannot read the %s directory", path)
|
||||
} else if !fi.IsDir() {
|
||||
return errors.Errorf("%s path is not a directory", path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
defer klog.Flush()
|
||||
|
||||
f, err := os.Open(*flConfig)
|
||||
if err != nil {
|
||||
klog.Fatalf("failed to open config file: %+v", err)
|
||||
}
|
||||
d := json.NewDecoder(f)
|
||||
d.DisallowUnknownFields()
|
||||
var config generatorConfig
|
||||
if err := d.Decode(&config); err != nil {
|
||||
klog.Fatalf("failed to parse config file: %+v", err)
|
||||
}
|
||||
|
||||
klog.Infof("parsing go packages in directory %s", *flAPIDir)
|
||||
pkgs, err := parseAPIPackages(*flAPIDir)
|
||||
if err != nil {
|
||||
klog.Fatal(err)
|
||||
}
|
||||
if len(pkgs) == 0 {
|
||||
klog.Fatalf("no API packages found in %s", *flAPIDir)
|
||||
}
|
||||
|
||||
apiPackages, err := combineAPIPackages(pkgs)
|
||||
if err != nil {
|
||||
klog.Fatal(err)
|
||||
}
|
||||
|
||||
mkOutput := func() (string, error) {
|
||||
var b bytes.Buffer
|
||||
err := render(&b, apiPackages, config)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "failed to render the result")
|
||||
}
|
||||
|
||||
// remove trailing whitespace from each html line for markdown renderers
|
||||
s := regexp.MustCompile(`(?m)^\s+`).ReplaceAllString(b.String(), "")
|
||||
return s, nil
|
||||
}
|
||||
|
||||
if *flOutFile != "" {
|
||||
dir := filepath.Dir(*flOutFile)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
klog.Fatalf("failed to create dir %s: %v", dir, err)
|
||||
}
|
||||
s, err := mkOutput()
|
||||
if err != nil {
|
||||
klog.Fatalf("failed: %+v", err)
|
||||
}
|
||||
if err := ioutil.WriteFile(*flOutFile, []byte(s), 0644); err != nil {
|
||||
klog.Fatalf("failed to write to out file: %v", err)
|
||||
}
|
||||
klog.Infof("written to %s", *flOutFile)
|
||||
}
|
||||
|
||||
if *flHTTPAddr != "" {
|
||||
h := func(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
defer func() { klog.Infof("request took %v", time.Since(now)) }()
|
||||
s, err := mkOutput()
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, "error: %+v", err)
|
||||
klog.Warningf("failed: %+v", err)
|
||||
}
|
||||
if _, err := fmt.Fprint(w, s); err != nil {
|
||||
klog.Warningf("response write error: %v", err)
|
||||
}
|
||||
}
|
||||
http.HandleFunc("/", h)
|
||||
klog.Infof("server listening at %s", *flHTTPAddr)
|
||||
klog.Fatal(http.ListenAndServe(*flHTTPAddr, nil))
|
||||
}
|
||||
}
|
||||
|
||||
// groupName extracts the "//+groupName" meta-comment from the specified
|
||||
// package's comments, or returns empty string if it cannot be found.
|
||||
func groupName(pkg *types.Package) string {
|
||||
m := types.ExtractCommentTags("+", pkg.Comments)
|
||||
v := m["groupName"]
|
||||
if len(v) == 1 {
|
||||
return v[0]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func parseAPIPackages(dir string) ([]*types.Package, error) {
|
||||
b := parser.New()
|
||||
// the following will silently fail (turn on -v=4 to see logs)
|
||||
if err := b.AddDirRecursive(*flAPIDir); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scan, err := b.FindTypes()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse pkgs and types")
|
||||
}
|
||||
var pkgNames []string
|
||||
for p := range scan {
|
||||
pkg := scan[p]
|
||||
klog.V(3).Infof("trying package=%v groupName=%s", p, groupName(pkg))
|
||||
|
||||
// Do not pick up packages that are in vendor/ as API packages. (This
|
||||
// happened in knative/eventing-sources/vendor/..., where a package
|
||||
// matched the pattern, but it didn't have a compatible import path).
|
||||
if isVendorPackage(pkg) {
|
||||
klog.V(3).Infof("package=%v coming from vendor/, ignoring.", p)
|
||||
continue
|
||||
}
|
||||
|
||||
if groupName(pkg) != "" && len(pkg.Types) > 0 || containsString(pkg.DocComments, docCommentForceIncludes) {
|
||||
klog.V(3).Infof("package=%v has groupName and has types", p)
|
||||
pkgNames = append(pkgNames, p)
|
||||
}
|
||||
}
|
||||
sort.Strings(pkgNames)
|
||||
var pkgs []*types.Package
|
||||
for _, p := range pkgNames {
|
||||
klog.Infof("using package=%s", p)
|
||||
pkgs = append(pkgs, scan[p])
|
||||
}
|
||||
return pkgs, nil
|
||||
}
|
||||
|
||||
func containsString(sl []string, str string) bool {
|
||||
for _, s := range sl {
|
||||
if str == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// combineAPIPackages groups the Go packages by the <apiGroup+apiVersion> they
|
||||
// offer, and combines the types in them.
|
||||
func combineAPIPackages(pkgs []*types.Package) ([]*apiPackage, error) {
|
||||
pkgMap := make(map[string]*apiPackage)
|
||||
|
||||
for _, pkg := range pkgs {
|
||||
apiGroup, apiVersion, err := apiVersionForPackage(pkg)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not get apiVersion for package %s", pkg.Path)
|
||||
}
|
||||
|
||||
typeList := make([]*types.Type, 0, len(pkg.Types))
|
||||
for _, t := range pkg.Types {
|
||||
typeList = append(typeList, t)
|
||||
}
|
||||
|
||||
id := fmt.Sprintf("%s/%s", apiGroup, apiVersion)
|
||||
v, ok := pkgMap[id]
|
||||
if !ok {
|
||||
pkgMap[id] = &apiPackage{
|
||||
apiGroup: apiGroup,
|
||||
apiVersion: apiVersion,
|
||||
Types: typeList,
|
||||
GoPackages: []*types.Package{pkg},
|
||||
}
|
||||
} else {
|
||||
v.Types = append(v.Types, typeList...)
|
||||
v.GoPackages = append(v.GoPackages, pkg)
|
||||
}
|
||||
}
|
||||
out := make([]*apiPackage, 0, len(pkgMap))
|
||||
for _, v := range pkgMap {
|
||||
out = append(out, v)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// isVendorPackage determines if package is coming from vendor/ dir.
|
||||
func isVendorPackage(pkg *types.Package) bool {
|
||||
vendorPattern := string(os.PathSeparator) + "vendor" + string(os.PathSeparator)
|
||||
return strings.Contains(pkg.SourcePath, vendorPattern)
|
||||
}
|
||||
|
||||
func findTypeReferences(pkgs []*apiPackage) map[*types.Type][]*types.Type {
|
||||
m := make(map[*types.Type][]*types.Type)
|
||||
for _, pkg := range pkgs {
|
||||
for _, typ := range pkg.Types {
|
||||
for _, member := range typ.Members {
|
||||
t := member.Type
|
||||
t = tryDereference(t)
|
||||
m[t] = append(m[t], typ)
|
||||
}
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func isExportedType(t *types.Type) bool {
|
||||
// TODO(ahmetb) use types.ExtractSingleBoolCommentTag() to parse +genclient
|
||||
// https://godoc.org/k8s.io/gengo/types#ExtractCommentTags
|
||||
return strings.Contains(strings.Join(t.SecondClosestCommentLines, "\n"), "+genclient")
|
||||
}
|
||||
|
||||
func fieldName(m types.Member) string {
|
||||
v := reflect.StructTag(m.Tags).Get("json")
|
||||
v = strings.TrimSuffix(v, ",omitempty")
|
||||
v = strings.TrimSuffix(v, ",inline")
|
||||
if v != "" {
|
||||
return v
|
||||
}
|
||||
return m.Name
|
||||
}
|
||||
|
||||
func fieldEmbedded(m types.Member) bool {
|
||||
return strings.Contains(reflect.StructTag(m.Tags).Get("json"), ",inline")
|
||||
}
|
||||
|
||||
func isLocalType(t *types.Type, typePkgMap map[*types.Type]*apiPackage) bool {
|
||||
t = tryDereference(t)
|
||||
_, ok := typePkgMap[t]
|
||||
return ok
|
||||
}
|
||||
|
||||
func renderComments(s []string, markdown bool) string {
|
||||
s = filterCommentTags(s)
|
||||
doc := strings.Join(s, "\n")
|
||||
|
||||
if markdown {
|
||||
// TODO(ahmetb): when a comment includes stuff like "http://<service>"
|
||||
// we treat this as a HTML tag with markdown renderer below. solve this.
|
||||
return string(blackfriday.Run([]byte(doc)))
|
||||
}
|
||||
return nl2br(doc)
|
||||
}
|
||||
|
||||
func safe(s string) template.HTML { return template.HTML(s) }
|
||||
|
||||
func nl2br(s string) string {
|
||||
return strings.Replace(s, "\n\n", string(template.HTML("<br/><br/>")), -1)
|
||||
}
|
||||
|
||||
func hiddenMember(m types.Member, c generatorConfig) bool {
|
||||
for _, v := range c.HiddenMemberFields {
|
||||
if m.Name == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func typeIdentifier(t *types.Type) string {
|
||||
t = tryDereference(t)
|
||||
return t.Name.String() // {PackagePath.Name}
|
||||
}
|
||||
|
||||
// apiGroupForType looks up apiGroup for the given type
|
||||
func apiGroupForType(t *types.Type, typePkgMap map[*types.Type]*apiPackage) string {
|
||||
t = tryDereference(t)
|
||||
|
||||
v := typePkgMap[t]
|
||||
if v == nil {
|
||||
klog.Warningf("WARNING: cannot read apiVersion for %s from type=>pkg map", t.Name.String())
|
||||
return "<UNKNOWN_API_GROUP>"
|
||||
}
|
||||
|
||||
return v.identifier()
|
||||
}
|
||||
|
||||
// anchorIDForLocalType returns the #anchor string for the local type
|
||||
func anchorIDForLocalType(t *types.Type, typePkgMap map[*types.Type]*apiPackage) string {
|
||||
return fmt.Sprintf("%s.%s", apiGroupForType(t, typePkgMap), t.Name.Name)
|
||||
}
|
||||
|
||||
// linkForType returns an anchor to the type if it can be generated. returns
|
||||
// empty string if it is not a local type or unrecognized external type.
|
||||
func linkForType(t *types.Type, c generatorConfig, typePkgMap map[*types.Type]*apiPackage) (string, error) {
|
||||
t = tryDereference(t) // dereference kind=Pointer
|
||||
|
||||
if isLocalType(t, typePkgMap) {
|
||||
return "#" + anchorIDForLocalType(t, typePkgMap), nil
|
||||
}
|
||||
|
||||
var arrIndex = func(a []string, i int) string {
|
||||
return a[(len(a)+i)%len(a)]
|
||||
}
|
||||
|
||||
// types like k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta,
|
||||
// k8s.io/api/core/v1.Container, k8s.io/api/autoscaling/v1.CrossVersionObjectReference,
|
||||
// github.com/knative/build/pkg/apis/build/v1alpha1.BuildSpec
|
||||
if t.Kind == types.Struct || t.Kind == types.Pointer || t.Kind == types.Interface || t.Kind == types.Alias {
|
||||
id := typeIdentifier(t) // gives {{ImportPath.Identifier}} for type
|
||||
segments := strings.Split(t.Name.Package, "/") // to parse [meta, v1] from "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
for _, v := range c.ExternalPackages {
|
||||
r, err := regexp.Compile(v.TypeMatchPrefix)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "pattern %q failed to compile", v.TypeMatchPrefix)
|
||||
}
|
||||
if r.MatchString(id) {
|
||||
tpl, err := texttemplate.New("").Funcs(map[string]interface{}{
|
||||
"lower": strings.ToLower,
|
||||
"arrIndex": arrIndex,
|
||||
}).Parse(v.DocsURLTemplate)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "docs URL template failed to parse")
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
if err := tpl.
|
||||
Execute(&b, map[string]interface{}{
|
||||
"TypeIdentifier": t.Name.Name,
|
||||
"PackagePath": t.Name.Package,
|
||||
"PackageSegments": segments,
|
||||
}); err != nil {
|
||||
return "", errors.Wrap(err, "docs url template execution error")
|
||||
}
|
||||
return b.String(), nil
|
||||
}
|
||||
}
|
||||
klog.Warningf("not found external link source for type %v", t.Name)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// tryDereference returns the underlying type when t is a pointer, map, or slice.
|
||||
func tryDereference(t *types.Type) *types.Type {
|
||||
if t.Elem != nil {
|
||||
return t.Elem
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func typeDisplayName(t *types.Type, c generatorConfig, typePkgMap map[*types.Type]*apiPackage) string {
|
||||
s := typeIdentifier(t)
|
||||
if isLocalType(t, typePkgMap) {
|
||||
s = tryDereference(t).Name.Name
|
||||
}
|
||||
if t.Kind == types.Pointer {
|
||||
s = strings.TrimLeft(s, "*")
|
||||
}
|
||||
|
||||
switch t.Kind {
|
||||
case types.Struct,
|
||||
types.Interface,
|
||||
types.Alias,
|
||||
types.Pointer,
|
||||
types.Slice,
|
||||
types.Builtin:
|
||||
// noop
|
||||
case types.Map:
|
||||
// return original name
|
||||
return t.Name.Name
|
||||
default:
|
||||
klog.Fatalf("type %s has kind=%v which is unhandled", t.Name, t.Kind)
|
||||
}
|
||||
|
||||
// substitute prefix, if registered
|
||||
for prefix, replacement := range c.TypeDisplayNamePrefixOverrides {
|
||||
if strings.HasPrefix(s, prefix) {
|
||||
s = strings.Replace(s, prefix, replacement, 1)
|
||||
}
|
||||
}
|
||||
|
||||
if t.Kind == types.Slice {
|
||||
s = "[]" + s
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func hideType(t *types.Type, c generatorConfig) bool {
|
||||
for _, pattern := range c.HideTypePatterns {
|
||||
if regexp.MustCompile(pattern).MatchString(t.Name.String()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if !isExportedType(t) && unicode.IsLower(rune(t.Name.Name[0])) {
|
||||
// types that start with lowercase
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func typeReferences(t *types.Type, c generatorConfig, references map[*types.Type][]*types.Type) []*types.Type {
|
||||
var out []*types.Type
|
||||
m := make(map[*types.Type]struct{})
|
||||
for _, ref := range references[t] {
|
||||
if !hideType(ref, c) {
|
||||
m[ref] = struct{}{}
|
||||
}
|
||||
}
|
||||
for k := range m {
|
||||
out = append(out, k)
|
||||
}
|
||||
sortTypes(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func sortTypes(typs []*types.Type) []*types.Type {
|
||||
sort.Slice(typs, func(i, j int) bool {
|
||||
t1, t2 := typs[i], typs[j]
|
||||
if isExportedType(t1) && !isExportedType(t2) {
|
||||
return true
|
||||
} else if !isExportedType(t1) && isExportedType(t2) {
|
||||
return false
|
||||
}
|
||||
return t1.Name.Name < t2.Name.Name
|
||||
})
|
||||
return typs
|
||||
}
|
||||
|
||||
func visibleTypes(in []*types.Type, c generatorConfig) []*types.Type {
|
||||
var out []*types.Type
|
||||
for _, t := range in {
|
||||
if !hideType(t, c) {
|
||||
out = append(out, t)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func packageDisplayName(pkg *types.Package, apiVersions map[string]string) string {
|
||||
apiGroupVersion, ok := apiVersions[pkg.Path]
|
||||
if ok {
|
||||
return apiGroupVersion
|
||||
}
|
||||
return pkg.Path // go import path
|
||||
}
|
||||
|
||||
func filterCommentTags(comments []string) []string {
|
||||
var out []string
|
||||
for _, v := range comments {
|
||||
if !strings.HasPrefix(strings.TrimSpace(v), "+") {
|
||||
out = append(out, v)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func isOptionalMember(m types.Member) bool {
|
||||
tags := types.ExtractCommentTags("+", m.CommentLines)
|
||||
_, ok := tags["optional"]
|
||||
return ok
|
||||
}
|
||||
|
||||
func apiVersionForPackage(pkg *types.Package) (string, string, error) {
|
||||
group := groupName(pkg)
|
||||
version := pkg.Name // assumes basename (i.e. "v1" in "core/v1") is apiVersion
|
||||
r := `^v\d+((alpha|beta)\d+)?$`
|
||||
if !regexp.MustCompile(r).MatchString(version) {
|
||||
return "", "", errors.Errorf("cannot infer kubernetes apiVersion of go package %s (basename %q doesn't match expected pattern %s that's used to determine apiVersion)", pkg.Path, version, r)
|
||||
}
|
||||
return group, version, nil
|
||||
}
|
||||
|
||||
// extractTypeToPackageMap creates a *types.Type map to apiPackage
|
||||
func extractTypeToPackageMap(pkgs []*apiPackage) map[*types.Type]*apiPackage {
|
||||
out := make(map[*types.Type]*apiPackage)
|
||||
for _, ap := range pkgs {
|
||||
for _, t := range ap.Types {
|
||||
out[t] = ap
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// packageMapToList flattens the map.
|
||||
func packageMapToList(pkgs map[string]*apiPackage) []*apiPackage {
|
||||
// TODO(ahmetb): we should probably not deal with maps, this type can be
|
||||
// a list everywhere.
|
||||
out := make([]*apiPackage, 0, len(pkgs))
|
||||
for _, v := range pkgs {
|
||||
out = append(out, v)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func render(w io.Writer, pkgs []*apiPackage, config generatorConfig) error {
|
||||
references := findTypeReferences(pkgs)
|
||||
typePkgMap := extractTypeToPackageMap(pkgs)
|
||||
|
||||
t, err := template.New("").Funcs(map[string]interface{}{
|
||||
"isExportedType": isExportedType,
|
||||
"fieldName": fieldName,
|
||||
"fieldEmbedded": fieldEmbedded,
|
||||
"typeIdentifier": func(t *types.Type) string { return typeIdentifier(t) },
|
||||
"typeDisplayName": func(t *types.Type) string { return typeDisplayName(t, config, typePkgMap) },
|
||||
"visibleTypes": func(t []*types.Type) []*types.Type { return visibleTypes(t, config) },
|
||||
"renderComments": func(s []string) string { return renderComments(s, !config.MarkdownDisabled) },
|
||||
"packageDisplayName": func(p *apiPackage) string { return p.identifier() },
|
||||
"apiGroup": func(t *types.Type) string { return apiGroupForType(t, typePkgMap) },
|
||||
"packageAnchorID": func(p *apiPackage) string {
|
||||
// TODO(ahmetb): currently this is the same as packageDisplayName
|
||||
// func, and it's fine since it retuns valid DOM id strings like
|
||||
// 'serving.knative.dev/v1alpha1' which is valid per HTML5, except
|
||||
// spaces, so just trim those.
|
||||
return strings.Replace(p.identifier(), " ", "", -1)
|
||||
},
|
||||
"linkForType": func(t *types.Type) string {
|
||||
v, err := linkForType(t, config, typePkgMap)
|
||||
if err != nil {
|
||||
klog.Fatal(errors.Wrapf(err, "error getting link for type=%s", t.Name))
|
||||
return ""
|
||||
}
|
||||
return v
|
||||
},
|
||||
"anchorIDForType": func(t *types.Type) string { return anchorIDForLocalType(t, typePkgMap) },
|
||||
"safe": safe,
|
||||
"sortedTypes": sortTypes,
|
||||
"typeReferences": func(t *types.Type) []*types.Type { return typeReferences(t, config, references) },
|
||||
"hiddenMember": func(m types.Member) bool { return hiddenMember(m, config) },
|
||||
"isLocalType": isLocalType,
|
||||
"isOptionalMember": isOptionalMember,
|
||||
}).ParseGlob(filepath.Join(*flTemplateDir, "*.tpl"))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "parse error")
|
||||
}
|
||||
|
||||
gitCommit, _ := exec.Command("git", "rev-parse", "--short", "HEAD").Output()
|
||||
return errors.Wrap(t.ExecuteTemplate(w, "packages", map[string]interface{}{
|
||||
"packages": pkgs,
|
||||
"config": config,
|
||||
"gitCommit": strings.TrimSpace(string(gitCommit)),
|
||||
}), "template execution error")
|
||||
}
|
||||
Reference in New Issue
Block a user