Compare commits

...

173 Commits

Author SHA1 Message Date
Jeff Regan
176ac5b4fa Merge pull request #3104 from Shell32-Natsu/pinToKyaml0.9.2
Pin to kyaml v0.9.2
2020-10-15 14:02:47 -07:00
Donny Xia
dd696b5cb4 Pin to kyaml v0.9.2 2020-10-15 13:55:30 -07:00
Jeff Regan
501404e403 Merge pull request #3103 from monopole/prchecker
Move multi-module-span.go to cmd/prchecker
2020-10-15 13:39:48 -07:00
Jeff Regan
ddf94175ee Merge pull request #3102 from natasha41575/rollbackPortMergeKey
changed port merge key back to containerPort
2020-10-15 12:06:51 -07:00
Jeff Regan
232da9e12b Update Makefile 2020-10-15 11:58:50 -07:00
jregan
8b9ce8eacb Move multi-module-span.go to cmd/prchecker 2020-10-15 11:46:27 -07:00
Natasha Sarkar
ee9a4f2526 changed port merge key back to containerport 2020-10-15 11:43:14 -07:00
Kubernetes Prow Robot
006ce72b2d Merge pull request #3099 from umangachapagain/patch-1
Updated description for commonannotations
2020-10-15 11:35:25 -07:00
Jeff Regan
a80bd15bda Merge pull request #3096 from runewake2/multi-module-golang
Add Support for Paginated Pull Request Responses to Multi-Module Check
2020-10-15 11:23:30 -07:00
Sam Wronski
6c63bb2727 Revert Makefile changes 2020-10-15 10:29:38 -07:00
Jeff Regan
a7ba93b1d8 Merge pull request #3101 from monopole/cleanUpMakeTargets
Cleanup Makefile.
2020-10-15 10:03:37 -07:00
jregan
4a78cd6579 Cleanup Makefile. 2020-10-15 10:02:15 -07:00
Jeff Regan
b2b8c12203 Update README.md 2020-10-15 09:46:35 -07:00
Jeff Regan
8cc281fad6 Merge pull request #3100 from monopole/movePluginatorToCmd
Move pluginator to cmd dir.
2020-10-15 09:43:46 -07:00
jregan
7346813b8d Move pluginator to cmd dir. 2020-10-15 09:22:29 -07:00
Umanga Chapagain
52f3aca22d Updated description for commonannotations 2020-10-15 09:13:39 +05:30
Kubernetes Prow Robot
7464d8ac8f Merge pull request #3097 from Shell32-Natsu/as-current-user
add --as-current-user flag to fn run
2020-10-14 18:09:51 -07:00
Donny Xia
64fda38e2d add --as-current-user flag to fn run 2020-10-14 17:07:03 -07:00
Sam Wronski
4cefb62d41 Add multi-module check to prow-presubmit-check 2020-10-14 15:34:52 -07:00
Jeff Regan
ca45907af0 Merge pull request #3083 from stuartpb/patch-1
Group regex within anchoring
2020-10-14 08:34:28 -07:00
Jeff Regan
dcf43c7f2b Merge pull request #3076 from natasha41575/fetchOpenAPIdata
Fetch openAPI data
2020-10-14 08:20:27 -07:00
Natasha Sarkar
1386ec3850 edited kpt target 2020-10-13 17:19:03 -07:00
Natasha Sarkar
de8e16df15 added script for installing kpt 2020-10-13 17:11:00 -07:00
Natasha Sarkar
222b2d4485 added MYGOBIN variable for kind 2020-10-13 16:25:29 -07:00
Natasha Sarkar
e107020bd2 edited make schema for kyaml 2020-10-13 13:53:25 -07:00
Natasha Sarkar
430665e984 version -> api_version 2020-10-13 13:21:19 -07:00
Kubernetes Prow Robot
017d5673ba Merge pull request #3088 from Shell32-Natsu/arm-build
add arm build
2020-10-12 15:33:22 -07:00
Donny Xia
f346b9803e add arm build 2020-10-12 13:41:24 -07:00
Jeff Regan
7428e08f93 Merge pull request #3081 from Shell32-Natsu/release-container
files for building image when release kustomize
2020-10-12 11:18:09 -07:00
Stuart P. Bentley
3c8e6d7151 Group regex within anchoring
This ensures that anchoring will apply to the entire anchored expression, eg. a pattern like `foo|bar` will only match the strings "foo" and "bar" (`^(?:foo|bar)$`), instead of matching any string that begins with "foo" or ends with "bar" (`^foo|bar$`).
2020-10-10 15:47:38 -07:00
Donny Xia
43bd2f4cdb files for building image when release kustomize 2020-10-09 14:35:17 -07:00
Natasha Sarkar
1dfc9a88a8 moved openapi instructions to top of readme 2020-10-09 12:31:14 -07:00
Natasha Sarkar
01beba8697 formatting documentation: 2020-10-09 12:29:06 -07:00
Natasha Sarkar
b1e01b238b updated documentation 2020-10-09 12:29:06 -07:00
Natasha Sarkar
1f595da9ad updated way to fetch go-bindata 2020-10-09 12:29:06 -07:00
Natasha Sarkar
1cf876927d minor makefile fix 2020-10-09 12:29:06 -07:00
Natasha Sarkar
a422c935d8 added make target to fetch new openapi schema 2020-10-09 12:29:06 -07:00
Jeff Regan
1971816663 Update README.md 2020-10-09 09:45:19 -07:00
Kubernetes Prow Robot
3d1eab872b Merge pull request #3071 from monopole/unpinAll
Unpin api,cmd/config,kyaml
2020-10-08 13:03:06 -07:00
Jeff Regan
10c1b0c5fa Update README.md 2020-10-08 11:34:07 -07:00
Jeff Regan
4d95cd3630 Merge pull request #3072 from monopole/gorepomod
Replace bash release helper scripts with Go progam
2020-10-08 11:10:57 -07:00
jregan
0c169e96e5 Replace bash release helper scripts with Go progam 2020-10-08 10:54:14 -07:00
jregan
5baea8400f Unpin api,cmd/config,kyaml 2020-10-08 09:39:49 -07:00
Jeff Regan
4052cd4fd8 Merge pull request #3069 from monopole/pinToCmdConfigV0.8.2
Pin to cmd/config/v0.8.2,  api/v0.6.3
2020-10-07 19:40:12 -07:00
jregan
21ac400d49 Pin to cmd/config/v0.8.2 2020-10-07 19:21:23 -07:00
Jeff Regan
351a4a48e4 Merge pull request #3068 from monopole/pinToKyamlv0.9.1_cliUtilsv0.20.4
Pin to kyaml/v0.9.1 and cli-utils/v0.20.4
2020-10-07 16:43:04 -07:00
jregan
b3cf475024 Pin to kyaml/v0.9.1 and cli-utils/v0.20.4 2020-10-07 16:23:13 -07:00
Jeff Regan
ded25075b1 Update README.md 2020-10-07 16:17:26 -07:00
Jeff Regan
05b8671d17 Update README.md 2020-10-07 14:35:44 -07:00
Jeff Regan
1bfcc81f08 Merge pull request #3027 from gochist/windows-exec
Support exec plugin on Windows
2020-10-07 14:18:14 -07:00
Jeff Regan
3d058830b9 Merge pull request #2918 from sunny0826/zh-patches
update zh doc api-reference/kustomization/patches
2020-10-07 14:04:53 -07:00
Jeff Regan
bdb53fca9e Merge pull request #3067 from Shell32-Natsu/file-name
make file name more readable when no group
2020-10-07 13:50:28 -07:00
Donny Xia
b7265440f8 make file name more readable when no group 2020-10-07 12:44:45 -07:00
Kubernetes Prow Robot
72e1a27177 Merge pull request #3064 from Shell32-Natsu/comma
remove ',' separator in edit add label/annotation
2020-10-07 10:18:18 -07:00
Kubernetes Prow Robot
0a1fde1e41 Merge pull request #3066 from phanimarupaka/ImproveSetOutputMessage
Improve setter output message
2020-10-06 21:12:42 -07:00
Jeff Regan
ae4618d327 Merge pull request #3065 from natasha41575/updateSchemaForPorts
updated schema to fix port merging issue
2020-10-06 18:00:15 -07:00
Natasha Sarkar
aee6ccb05c added documentation comments 2020-10-06 17:20:18 -07:00
Natasha Sarkar
3cd2a0a2f7 removed comments documenting broken test 2020-10-06 14:48:49 -07:00
Phani Teja Marupaka
c96fa7c347 Improve setter output message 2020-10-06 14:41:14 -07:00
Natasha Sarkar
ad01d8d34e updated schema to fix port merging issue 2020-10-06 14:30:30 -07:00
Donny Xia
b214fa7d5a remove ',' separator in edit add label/annotation 2020-10-06 11:49:39 -07:00
Jeff Regan
68f67c183e Merge pull request #3060 from Shell32-Natsu/doc
Remove the lines about config save command
2020-10-06 09:54:23 -07:00
Jeff Regan
fe5c3a291f Merge pull request #3059 from Shell32-Natsu/metadata
Add metadata field to kustomization file
2020-10-05 15:18:42 -07:00
Donny Xia
f38cc4446b Remove the lines about config save command 2020-10-05 11:29:02 -07:00
Donny Xia
e695b0534d Add metadata field to kustomization file 2020-10-05 11:20:41 -07:00
June Yi
51ecca8f2f Add a comment about the behavior in Windows 2020-10-03 09:49:56 +09:00
Jeff Regan
460c54064c Update README.md 2020-10-02 16:51:13 -07:00
Jeff Regan
50c0200429 Merge pull request #3056 from monopole/mechanicalGoSum
Update generated go.sum files.
2020-10-02 15:25:57 -07:00
jregan
b1b5a95466 Update generated go.sum files. 2020-10-02 14:51:17 -07:00
Jeff Regan
3f71c671df Merge pull request #2948 from dearchap/patch-1
Update _index.md
2020-10-02 14:22:31 -07:00
Jeff Regan
2ce9c02ada Merge pull request #3055 from phanimarupaka/CleanupCfgCommandOutput
Cleanup Cfg/Grep Command Output
2020-10-02 14:22:00 -07:00
Jeff Regan
3ffc13dd6e Merge pull request #3054 from Shell32-Natsu/isnamespaceable
refactor Gkv.isNamespaceableKind
2020-10-02 14:03:08 -07:00
Jeff Regan
2fb8603b2a Merge pull request #3050 from Shell32-Natsu/deployment-annotation
support var ref in deployment template annotations
2020-10-02 14:01:32 -07:00
Jeff Regan
1d4b3fa36c Merge pull request #3048 from Shell32-Natsu/merge-prepend
add option to choose prepend/append patch items to list in merge
2020-10-02 11:53:22 -07:00
Donny Xia
03ea8f3615 update tests 2020-10-02 10:10:05 -07:00
Donny Xia
74d0d7960e add option to choose prepend/append in merge 2020-10-02 09:56:59 -07:00
Phani Teja Marupaka
ffed4c95b3 Cleanup Cfg/Grep Command Output 2020-10-01 16:51:13 -07:00
Donny Xia
c59b393fa4 refactor Gkv.isNamespaceableKind 2020-10-01 11:28:58 -07:00
Jeff Regan
fafe24c9df Merge pull request #3038 from Shell32-Natsu/patch-list
support merge strategy directive in list
2020-10-01 10:53:13 -07:00
Jeff Regan
d62d8dcade Merge pull request #3003 from runewake2/multi-module-golang
Adds a directory spanning check script
2020-09-30 13:39:21 -07:00
Kubernetes Prow Robot
ae7f984c71 Merge pull request #3052 from natasha41575/addIsEmptyToResource
added IsEmpty() method
2020-09-30 13:26:54 -07:00
Natasha Sarkar
7c8c827a88 added IsEmpty() method 2020-09-30 12:17:14 -07:00
Donny Xia
ff927fd11a support merge strategy in list 2020-09-30 10:52:47 -07:00
Donny Xia
a4f6fee6c8 support var ref in deployment template annotations 2020-09-30 10:21:03 -07:00
Jeff Regan
dd8edb1b01 Merge pull request #3040 from natasha41575/fixIssue2896
fixed issue 2896
2020-09-29 17:55:08 -07:00
Kubernetes Prow Robot
bb42d8aa1b Merge pull request #3044 from Shell32-Natsu/element-getter
add GetElementByKey
2020-09-29 17:53:24 -07:00
Donny Xia
bb60c29672 add GetElementByKey 2020-09-29 17:36:07 -07:00
Natasha Sarkar
c93274c224 changed way to test for empty resource 2020-09-29 17:33:12 -07:00
Natasha Sarkar
f5feffbd23 fix for the patchdelete test 2020-09-28 13:28:06 -07:00
Natasha Sarkar
e17bab7e55 updated to include namespace 2020-09-28 11:01:01 -07:00
Natasha Sarkar
bd534441ce fixed issue 2896 2020-09-28 11:01:01 -07:00
June Yi
85f79edc97 Add testcase for ErrIfNotExecutable 2020-09-26 18:01:39 +09:00
Kubernetes Prow Robot
4c48a4ff83 Merge pull request #3033 from Shell32-Natsu/3021
fix multiple match issue in rolebinding
2020-09-25 17:22:48 -07:00
Jeff Regan
eb6c715bc3 Merge pull request #3032 from Shell32-Natsu/default-branch
remove default master branch in cloner
2020-09-25 17:01:54 -07:00
Jeff Regan
1320e0c3dc Merge pull request #2999 from aodinokov/fixenv
Added list of env variables for fn-plugins
2020-09-25 17:00:28 -07:00
Jeff Regan
df0022c985 Merge pull request #2949 from dearchap/cmdline
Chore: docs : Add basic structure for command line options
2020-09-25 16:44:04 -07:00
Jeff Regan
15fc341a13 Merge pull request #2992 from Shell32-Natsu/as-current-user
add as-current-user for fn run
2020-09-25 16:42:49 -07:00
Jeff Regan
dd90c41f85 Merge pull request #2994 from PascalBourdier/patch-1
fix typo
2020-09-25 16:35:11 -07:00
Jeff Regan
3a5951563d Merge pull request #3037 from mortent/RemoveDepOnCliUtils
Remove dependency from cmd/config on cli-utils
2020-09-24 12:59:21 -07:00
Donny Xia
acdfd9a920 remove error from NewContainer 2020-09-24 11:37:49 -07:00
Donny Xia
52016b22dd test without system call 2020-09-24 11:37:48 -07:00
Donny Xia
11049fa0bb add as-current-user for fn run 2020-09-24 11:37:48 -07:00
Morten Torkildsen
db6c825c05 Remove dependency from cmd/config on cli-utils 2020-09-24 11:16:41 -07:00
Jeff Regan
cb7974cf45 Merge pull request #3024 from Shell32-Natsu/master
Add issue templates
2020-09-23 21:46:44 -07:00
Jeff Regan
00111846d3 Merge pull request #3023 from TIKI-Institut/master
Enable the installation of specific versions with the "install_kustomize.sh" script (#3022)
2020-09-23 21:44:53 -07:00
Kubernetes Prow Robot
eafa37810b Merge pull request #3034 from Shell32-Natsu/cfg-tree-kustomization
add Kustomization to cfg tree
2020-09-23 21:44:04 -07:00
Donny Xia
0c0cb9aaba add Kustomization to cfg tree 2020-09-23 13:35:45 -07:00
Donny Xia
b51e09d5fe fix multiple match issue in rolebinding 2020-09-23 13:03:12 -07:00
Donny Xia
c8cd5e55fc Add bug filing link 2020-09-23 11:33:03 -07:00
Kubernetes Prow Robot
103d1461a1 Merge pull request #3029 from phanimarupaka/SetAllSetterDefsOpenAPI
Sync openAPI setter values with schema
2020-09-22 19:26:09 -07:00
Donny Xia
f02af7a48b remove default master branch in cloner 2020-09-22 15:57:50 -07:00
Phani Teja Marupaka
eba9edd7a6 Sync openAPI setter values with schema 2020-09-22 14:05:05 -07:00
Kubernetes Prow Robot
cf38166bd6 Merge pull request #3030 from mortent/FixDotGitFiles
copyutil should not ignore files that just happen to start with .git
2020-09-22 13:42:09 -07:00
Morten Torkildsen
03498b46b8 copyutil should not ignore files that just happen to start with .git 2020-09-22 12:32:06 -07:00
Donny Xia
9fa9c6c30c Update issue templates 2020-09-22 12:08:50 -07:00
Donny Xia
884e35b4c8 issue template 2020-09-22 12:08:50 -07:00
Kubernetes Prow Robot
28787396b2 Merge pull request #3026 from mortent/RenameGetIgnoreFileNameFunc
Drop the get prefix from GetIgnoreFileName function
2020-09-22 10:56:42 -07:00
Jeff Regan
e3cf8987e1 Merge pull request #3025 from seans3/live-command-fix
Small change to live commands retrieval
2020-09-22 09:19:27 -07:00
June Yi
551841b789 Support exec plugin on Windows 2020-09-22 22:42:18 +09:00
Morten Torkildsen
66740dfad6 Drop the get prefix from GetIgnoreFileName function 2020-09-21 20:54:57 -07:00
Kubernetes Prow Robot
537ff024dd Merge pull request #2981 from mortent/SimplifyCmdConfigExt
Simplify the cmd/config ext package
2020-09-21 17:56:47 -07:00
Morten Torkildsen
cfab28a5ff Simplify the cmd/config ext package 2020-09-21 17:30:36 -07:00
Sean Sullivan
471d5ccf84 Small change to live commands retrieval 2020-09-21 16:41:48 -07:00
Timo Walter
6a9e75ee0d Improve the "install_kustomize.sh" script
- fix formatting
- remove unnecessary echo statements
2020-09-21 23:09:16 +02:00
Kubernetes Prow Robot
7500764cbf Merge pull request #3000 from Shell32-Natsu/res-select
fix namespace will match all empty namespace
2020-09-21 13:07:52 -07:00
Donny Xia
544fc60bfe add another test 2020-09-21 12:24:47 -07:00
Jeff Regan
0850eae0b9 Merge pull request #3001 from Shell32-Natsu/patch-delete
handle the "$patch: delete" in patch transformer
2020-09-21 12:03:40 -07:00
Jeff Regan
3818cebe33 Merge pull request #3011 from natasha41575/issue2896test
test for issue 2896
2020-09-21 11:59:51 -07:00
Donny Xia
31b395a33f handle the "$patch: delete" in patch transformer 2020-09-21 11:46:39 -07:00
Natasha Sarkar
ce0dba9217 fixed bug in base test 2020-09-21 11:32:26 -07:00
Natasha Sarkar
9abd0119e1 test for issue 2896 2020-09-21 11:25:54 -07:00
Jeff Regan
b6c6cfa7ac Update README.md 2020-09-21 10:24:08 -07:00
Timo Walter
0c5fc5e694 Extend the install_kustomize.sh to enable the installation of specific versions 2020-09-21 15:16:57 +02:00
Alexey Odinokov
64cbfbe56d added test for env vars 2020-09-21 06:14:09 +00:00
Jeff Regan
6a94eb873f Merge pull request #3018 from monopole/unpinEverything
Unpin api, kyaml and cmd/config
2020-09-20 08:46:55 -07:00
jregan
0bfec6b39b Unpin kyaml, cmd/config and api. 2020-09-20 08:07:32 -07:00
Jeff Regan
9002c338cb Merge pull request #3019 from monopole/installGh
Install gh cli tool via make
2020-09-20 07:39:52 -07:00
jregan
f86cb6479e Install gh cli tool via make 2020-09-20 07:39:16 -07:00
Jeff Regan
8285af8cf1 Merge pull request #3017 from monopole/updateREADME
Update release instructions.
2020-09-19 08:33:25 -07:00
Jeffrey Regan
5fa1282dcb Update release instructions. 2020-09-19 08:32:53 -07:00
Jeff Regan
5a0abc8b12 Merge pull request #3016 from monopole/pinToApiV0.6.2
Pin to api v0.6.2
2020-09-19 08:22:13 -07:00
Jeffrey Regan
3f2508fa94 Pin to api v0.6.2 2020-09-19 07:48:07 -07:00
Jeff Regan
9d992aae68 Merge pull request #3015 from monopole/pinToCmdConfigV0.8.1
Pin to cmd/config/v0.8.1
2020-09-19 07:42:05 -07:00
Jeffrey Regan
8c906b804f Pin to cmd/config/v0.8.1 2020-09-19 07:12:13 -07:00
Jeff Regan
4ff4940fa7 Update README.md 2020-09-18 18:28:42 -07:00
Jeff Regan
09aec5694a Merge pull request #3013 from monopole/generated
Generated pin to cli-utils v0.20.2 hash
2020-09-18 18:26:25 -07:00
Jeffrey Regan
1f917c0499 Generated pin to cli-utils v0.20.2 hash 2020-09-18 17:52:33 -07:00
Kubernetes Prow Robot
225ffc7cd8 Merge pull request #3012 from Shell32-Natsu/remove-network-name
remove --network-name flag from kpt fn run
2020-09-18 16:48:27 -07:00
Kubernetes Prow Robot
eb638cc312 Merge pull request #3009 from Shell32-Natsu/endpoint-service
put endpoints before service
2020-09-18 14:20:28 -07:00
Jeff Regan
7dfb96425e Merge pull request #3010 from monopole/pinToCliUtils_v0.20.2
Pin to cli-utils/v0.20.2
2020-09-18 13:35:02 -07:00
Jeff Regan
6d4c6127c8 Update README.md 2020-09-18 13:18:54 -07:00
Jeff Regan
6aa72b66ef Update README.md 2020-09-18 13:15:52 -07:00
Jeff Regan
f03fdc09cb Update README.md 2020-09-18 13:10:19 -07:00
Jeffrey Regan
30b6eeb460 Pin to cli-utils/v0.20.2 2020-09-18 13:08:53 -07:00
Jeff Regan
bf67fcb6d6 Update README.md 2020-09-18 12:55:59 -07:00
Jeff Regan
4ae420cce1 Merge pull request #3008 from monopole/pinToKyamlv_0_8_1
Pin to kyaml v0.8.1
2020-09-18 12:40:02 -07:00
Donny Xia
87d2187436 remove --network-name flag from kpt fn run 2020-09-18 12:39:49 -07:00
Donny Xia
f1dabbd4fc put endpoints before service 2020-09-18 12:21:03 -07:00
Jeffrey Regan
747e05f2a4 Pin to kyaml v0.8.1 2020-09-18 12:11:03 -07:00
Jeff Regan
3514317b3d Merge pull request #3007 from monopole/unpin
Unpin the dependencies post release.
2020-09-18 11:19:42 -07:00
Jeff Regan
9299821571 Merge pull request #2998 from Shell32-Natsu/network
Change network to a boolean in kpt fn run
2020-09-18 11:12:26 -07:00
Jeffrey Regan
d91f313137 Unpin the dependencies post release. 2020-09-18 09:51:05 -07:00
Jeff Regan
161af9d99c Merge pull request #3002 from monopole/pinToApiV0_6_1
Pin to api/v0.6.1
2020-09-17 17:18:11 -07:00
jregan
b115c95ea1 Pin to api/v0.6.1 2020-09-17 16:27:08 -07:00
Sam Wronski
4c75dac10a Adds a directory spanning check script 2020-09-17 16:18:17 -07:00
Donny Xia
2f8a376ae4 fix namespace will match all empty namespace 2020-09-17 12:46:18 -07:00
Jeff Regan
20cd4bfef9 Merge pull request #2997 from kubernetes-sigs/removeReplaceDir
Update go.mod
2020-09-17 11:02:08 -07:00
Alexey Odinokov
b314ca185f Added list of env variables for fn-plugins
KRM-functions should be able get env variables.
Reflecting in `build` cmd args added in [1]
for `fn run` cmd.

[1]
https://github.com/kubernetes-sigs/kustomize/pull/2988/
2020-09-17 03:41:36 +00:00
Donny Xia
f6c06b58ef Change network to a boolean 2020-09-16 16:20:50 -07:00
Pascal Bourdier
98c88805c3 fix typo
typo
2020-09-16 15:36:36 +02:00
Naveen Gogineni
5a4e2c2898 Add basic structure for command line options for users to be able to place info into them 2020-09-05 11:36:49 -04:00
dearchap
51719d8089 Update _index.md 2020-09-05 10:28:27 -04:00
guoxudong
d4503dfd1e update zh doc patches 2020-08-31 09:38:59 +08:00
338 changed files with 6347 additions and 2131 deletions

8
.dockerignore Normal file
View File

@@ -0,0 +1,8 @@
.github
docs
examples
functions
hack
site
travis
*.md

68
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,68 @@
---
name: Bug report
about: Create a report to help us improve
title: ""
labels:
- kind/bug
assignees: ""
---
<!--
Please read this page: https://kubernetes-sigs.github.io/kustomize/contributing/bugs/ before
filing a bug
-->
<!-- Feel free to skip the sections if they are not applicable. -->
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
**Files that can reproduce the issue**
<!--
We cannot figure out or fix the issue if we don't know how to reproduce. Please
provide a minimum set of files that can reproduce the issue. You can paste the
file contents here or provide a link to a tarball or git repo.
Example:
kustomization.yaml
```
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
...
```
resources.yaml
```
apiVersion: v1
kind: Deployment
...
```
...
-->
**Expected output**
<!-- What's the expected output? -->
**Actual output**
<!-- What's the actual output? -->
**Kustomize version**
<!-- Please use the latest version when it's possible. -->
**Platform**
<!-- Linux/macOS/Windows? -->
**Additional context**
<!-- Add any other context about the problem here. -->

1
.github/ISSUE_TEMPLATE/config.yaml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: true

View File

@@ -0,0 +1,26 @@
---
name: Feature request
about: Suggest an idea for this project
title: ""
labels:
- kind/feature
assignees: ""
---
<!-- Feel free to skip the sections if they are not applicable. -->
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
**Describe the solution you'd like**
<!-- A clear and concise description of what you want to happen. -->
**Describe alternatives you've considered**
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->

9
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@@ -0,0 +1,9 @@
---
name: Question
about: Ask a question about the kustomize
title: "[Question]"
labels: ""
assignees: ""
---
<!-- Please describe your question here -->

View File

@@ -47,35 +47,37 @@ $(MYGOBIN)/golangci-lint-kustomize:
GO111MODULE=on go build -tags=tools -o $(MYGOBIN)/golangci-lint-kustomize github.com/golangci/golangci-lint/cmd/golangci-lint; \
)
$(MYGOBIN)/gorepomod:
cd api; \
go install github.com/monopole/gorepomod
# Install from version specified in api/go.mod.
$(MYGOBIN)/mdrip:
cd api; \
go install github.com/monopole/mdrip
# Install from version specified in api/go.mod.
$(MYGOBIN)/stringer:
cd api; \
go install golang.org/x/tools/cmd/stringer
# Install from version specified in api/go.mod.
$(MYGOBIN)/goimports:
cd api; \
go install golang.org/x/tools/cmd/goimports
# Install resource from whatever is checked out.
$(MYGOBIN)/resource:
cd cmd/resource; \
# Build from local source.
$(MYGOBIN)/gorepomod:
cd cmd/gorepomod; \
go install .
# To pin pluginator, use this recipe instead:
# cd api;
# go install sigs.k8s.io/kustomize/pluginator/v2
# Build from local source.
$(MYGOBIN)/pluginator:
cd pluginator; \
cd cmd/pluginator; \
go install .
# Install kustomize from whatever is checked out.
# Build from local source.
$(MYGOBIN)/prchecker:
cd cmd/prchecker; \
go install .
# Build from local source.
$(MYGOBIN)/kustomize:
cd kustomize; \
go install .
@@ -84,9 +86,11 @@ $(MYGOBIN)/kustomize:
install-tools: \
$(MYGOBIN)/goimports \
$(MYGOBIN)/golangci-lint-kustomize \
$(MYGOBIN)/gh \
$(MYGOBIN)/gorepomod \
$(MYGOBIN)/mdrip \
$(MYGOBIN)/pluginator \
$(MYGOBIN)/prchecker \
$(MYGOBIN)/stringer
### Begin kustomize plugin rules.
@@ -189,8 +193,8 @@ lint-kustomize: install-tools $(builtinplugins)
$(MYGOBIN)/golangci-lint-kustomize -c ../.golangci-kustomize.yml run ./...
cd kustomize; \
$(MYGOBIN)/golangci-lint-kustomize -c ../.golangci-kustomize.yml run ./...
cd pluginator; \
$(MYGOBIN)/golangci-lint-kustomize -c ../.golangci-kustomize.yml run ./...
cd cmd/pluginator; \
$(MYGOBIN)/golangci-lint-kustomize -c ../../.golangci-kustomize.yml run ./...
# Used to add non-default compilation flags when experimenting with
# plugin-to-api compatibility checks.
@@ -321,6 +325,18 @@ $(MYGOBIN)/kind:
rm -rf $$d; \
)
# linux only.
$(MYGOBIN)/gh:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
tgzFile=gh_1.0.0_linux_amd64.tar.gz; \
wget https://github.com/cli/cli/releases/download/v1.0.0/$$tgzFile; \
tar -xvzf $$tgzFile; \
mv gh_1.0.0_linux_amd64/bin/gh $(MYGOBIN)/gh; \
rm -rf $$d \
)
.PHONY: clean
clean: kustomize-external-go-plugin-clean
go clean --cache

View File

@@ -33,7 +33,7 @@ func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error {
return nil
}
for _, r := range m.Resources() {
if len(r.Map()) == 0 {
if r.IsEmpty() {
// Don't mutate empty objects?
continue
}

View File

@@ -94,14 +94,14 @@ func (p *PatchStrategicMergeTransformerPlugin) Transform(m resmap.ResMap) error
// Some unknown error, let it through.
return err
}
if len(target.Map()) != 0 {
if !target.IsEmpty() {
return errors.Wrapf(
err, "with unexpectedly non-empty object map of size %d",
len(target.Map()))
}
// Fall through to handle deleted object.
}
if len(target.Map()) == 0 {
if target.IsEmpty() {
// This means all fields have been removed from the object.
// This can happen if a patch required deletion of the
// entire resource (not just a part of it). This means

View File

@@ -8,6 +8,7 @@ import (
"strings"
jsonpatch "github.com/evanphx/json-patch"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/filters/patchjson6902"
"sigs.k8s.io/kustomize/api/filters/patchstrategicmerge"
"sigs.k8s.io/kustomize/api/resmap"
@@ -101,7 +102,31 @@ func (p *PatchTransformerPlugin) transformStrategicMerge(m resmap.ResMap, patch
patchCopy.SetGvk(res.GetGvk())
err := p.applySMPatch(res, patchCopy)
if err != nil {
return err
// Check for an error string from UnmarshalJSON that's indicative
// of an object that's missing basic KRM fields, and thus may have been
// entirely deleted (an acceptable outcome). This error handling should
// be deleted along with use of ResMap and apimachinery functions like
// UnmarshalJSON.
if !strings.Contains(err.Error(), "Object 'Kind' is missing") {
// Some unknown error, let it through.
return err
}
if !res.IsEmpty() {
return errors.Wrapf(
err, "with unexpectedly non-empty object map of size %d",
len(res.Map()))
}
// Fall through to handle deleted object.
}
if res.IsEmpty() {
// This means all fields have been removed from the object.
// This can happen if a patch required deletion of the
// entire resource (not just a part of it). This means
// the overall resmap must shrink by one.
err = m.Remove(res.CurId())
if err != nil {
return err
}
}
}
return nil
@@ -114,9 +139,15 @@ func (p *PatchTransformerPlugin) applySMPatch(resource, patch *resource.Resource
if err != nil {
return err
}
return filtersutil.ApplyToJSON(patchstrategicmerge.Filter{
n, ns := resource.GetName(), resource.GetNamespace()
err = filtersutil.ApplyToJSON(patchstrategicmerge.Filter{
Patch: node,
}, resource)
if !resource.IsEmpty() {
resource.SetName(n)
resource.SetNamespace(ns)
}
return err
}
// transformJson6902 applies the provided json6902 patch

View File

@@ -88,12 +88,20 @@ func (f Filter) setScalar(node *yaml.RNode) error {
func filterReferralCandidates(
referrer *resource.Resource,
matches []*resource.Resource) []*resource.Resource {
matches []*resource.Resource,
target resid.Gvk,
) []*resource.Resource {
var ret []*resource.Resource
for _, m := range matches {
if referrer.PrefixesSuffixesEquals(m) {
ret = append(ret, m)
// If target kind is not ServiceAccount, we shouldn't consider condidates which
// doesn't have same namespace.
if target.Kind != "ServiceAccount" && m.GetNamespace() != referrer.GetNamespace() {
continue
}
if !referrer.PrefixesSuffixesEquals(m) {
continue
}
ret = append(ret, m)
}
return ret
}
@@ -118,7 +126,7 @@ func selectReferral(
// If there's more than one match,
// filter the matches by prefix and suffix
if len(matches) > 1 {
filteredMatches := filterReferralCandidates(referrer, matches)
filteredMatches := filterReferralCandidates(referrer, matches, target)
if len(filteredMatches) > 1 {
return "", "", fmt.Errorf(
"multiple matches for %s:\n %v",

View File

@@ -18,7 +18,12 @@ var _ kio.Filter = Filter{}
func (pf Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
var result []*yaml.RNode
for i := range nodes {
r, err := merge2.Merge(pf.Patch, nodes[i])
r, err := merge2.Merge(
pf.Patch, nodes[i],
yaml.MergeOptions{
ListIncreaseDirection: yaml.MergeOptionsListPrepend,
},
)
if err != nil {
return nil, err
}

View File

@@ -67,10 +67,10 @@ spec:
template:
spec:
containers:
- name: foo0
- name: foo1
- name: foo2
- name: foo3
- name: foo0
`,
},
"volumes patch": {
@@ -107,10 +107,10 @@ spec:
template:
spec:
volumes:
- name: foo0
- name: foo1
- name: foo2
- name: foo3
- name: foo0
`,
},
"nested patch": {
@@ -142,6 +142,234 @@ spec:
- name: nginx
args:
- def
`,
},
"remove mapping - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
$patch: delete
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers: []
`,
},
"replace mapping - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
$patch: replace
containers:
- name: new
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: new
`,
},
"merge mapping - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test1
$patch: merge
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test1
`,
},
"remove list - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- whatever
- $patch: delete
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec: {}
`,
},
"replace list - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: replace
image: replace
- $patch: replace
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: replace
image: replace
`,
},
"merge list - directive": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test
image: test
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test2
image: test2
- $patch: merge
`),
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeploy
spec:
template:
spec:
containers:
- name: test2
image: test2
- name: test
image: test
`,
},
}

View File

@@ -17,6 +17,6 @@ require (
k8s.io/apimachinery v0.17.0
k8s.io/client-go v0.17.0
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a
sigs.k8s.io/kustomize/kyaml v0.8.0
sigs.k8s.io/kustomize/kyaml v0.9.2
sigs.k8s.io/yaml v1.2.0
)

View File

@@ -588,8 +588,8 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.8.0 h1:/MqPML99XAm2pbrD/eTpePh5rnU5bpnuTPqb29LpSz4=
sigs.k8s.io/kustomize/kyaml v0.8.0/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/kustomize/kyaml v0.9.2 h1:QNP1Lg4V2wOgBeUim9Kmz1+2GqHtRyfoVEUQH0omrCI=
sigs.k8s.io/kustomize/kyaml v0.9.2/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@@ -527,8 +527,8 @@ k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.8.0 h1:/MqPML99XAm2pbrD/eTpePh5rnU5bpnuTPqb29LpSz4=
sigs.k8s.io/kustomize/kyaml v0.8.0/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/kustomize/kyaml v0.9.2 h1:QNP1Lg4V2wOgBeUim9Kmz1+2GqHtRyfoVEUQH0omrCI=
sigs.k8s.io/kustomize/kyaml v0.9.2/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

View File

@@ -27,9 +27,6 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
return err
}
if repoSpec.Ref == "" {
repoSpec.Ref = "master"
}
cmd := exec.Command(
gitProgram,
"clone",
@@ -45,28 +42,30 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
repoSpec.CloneSpec(), repoSpec.Dir.String())
}
cmd = exec.Command(
gitProgram,
"fetch",
"--depth=1",
"origin",
repoSpec.Ref)
cmd.Dir = repoSpec.Dir.String()
out, err = cmd.CombinedOutput()
if err != nil {
log.Printf("Error fetching ref: %s", out)
return errors.Wrapf(err, "trouble fetching %s", repoSpec.Ref)
}
if repoSpec.Ref != "" {
cmd = exec.Command(
gitProgram,
"fetch",
"--depth=1",
"origin",
repoSpec.Ref)
cmd.Dir = repoSpec.Dir.String()
out, err = cmd.CombinedOutput()
if err != nil {
log.Printf("Error fetching ref: %s", out)
return errors.Wrapf(err, "trouble fetching %s", repoSpec.Ref)
}
cmd = exec.Command(
gitProgram,
"checkout",
"FETCH_HEAD")
cmd.Dir = repoSpec.Dir.String()
out, err = cmd.CombinedOutput()
if err != nil {
log.Printf("Error checking out ref: %s", out)
return errors.Wrapf(err, "trouble checking out %s", repoSpec.Ref)
cmd = exec.Command(
gitProgram,
"checkout",
"FETCH_HEAD")
cmd.Dir = repoSpec.Dir.String()
out, err = cmd.CombinedOutput()
if err != nil {
log.Printf("Error checking out ref: %s", out)
return errors.Wrapf(err, "trouble checking out %s", repoSpec.Ref)
}
}
cmd = exec.Command(

View File

@@ -9,6 +9,7 @@ import (
"io/ioutil"
"os"
"os/exec"
"runtime"
"strings"
"github.com/google/shlex"
@@ -50,7 +51,14 @@ func (p *ExecPlugin) ErrIfNotExecutable() error {
if err != nil {
return err
}
if f.Mode()&0111 == 0000 {
// In Windows, it is not possible to determine whether a
// file is executable through file mode.
// TODO: provide for setting the executable FileMode bit on Windows
// The (fs *fileStat) Mode() (m FileMode) {} function in
// https://golang.org/src/os/types_windows.go
// lacks the ability to set the FileMode executable bit in response
// to file data on Windows.
if f.Mode()&0111 == 0000 && runtime.GOOS != "windows" {
return fmt.Errorf("unexecutable plugin at: %s", p.path)
}
return nil

View File

@@ -4,12 +4,15 @@
package execplugin_test
import (
"path/filepath"
"runtime"
"strings"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/plugins/execplugin"
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/konfig"
fLdr "sigs.k8s.io/kustomize/api/loader"
@@ -89,3 +92,32 @@ metadata:
t.Fatalf("unexpected arg array: %#v", p.Args())
}
}
func TestExecPlugin_ErrIfNotExecutable(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skipf("always returns nil on Windows")
}
srcRoot, err := utils.DeterminePluginSrcRoot(filesys.MakeFsOnDisk())
if err != nil {
t.Error(err)
}
// Test unexecutable plugin
unexecutablePlugin := filepath.Join(
srcRoot, "builtin", "", "secretgenerator", "SecretGenerator.so")
p := NewExecPlugin(unexecutablePlugin)
err = p.ErrIfNotExecutable()
if err == nil {
t.Fatalf("unexpected err: %v", err)
}
// Test executable plugin
executablePlugin := filepath.Join(
srcRoot, "someteam.example.com", "v1", "bashedconfigmap", "BashedConfigMap")
p = NewExecPlugin(executablePlugin)
err = p.ErrIfNotExecutable()
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
}

View File

@@ -74,10 +74,10 @@ func NewFnPlugin(o *types.FnPluginLoadingOptions) *FnPlugin {
runFns: runfn.RunFns{
Functions: []*yaml.RNode{},
Network: o.Network,
NetworkName: o.NetworkName,
EnableStarlark: o.EnableStar,
EnableExec: o.EnableExec,
StorageMounts: toStorageMounts(o.Mounts),
Env: o.Env,
},
}
}

View File

@@ -65,8 +65,8 @@ func TestLoader(t *testing.T) {
t.Fatal(err)
}
for _, behavior := range []types.BuiltinPluginLoadingOptions{
types.BploUseStaticallyLinked,
types.BploLoadFromFileSys} {
/* types.BploUseStaticallyLinked,
types.BploLoadFromFileSys */} {
c, err := konfig.EnabledPluginConfig(behavior)
if err != nil {
t.Fatal(err)

View File

@@ -21,5 +21,5 @@ import (
// major version increments in pluginator with each
// api release to allow this trick to work and not
// introduce cycles.
// _ "sigs.k8s.io/kustomize/pluginator/v2"
// _ "sigs.k8s.io/kustomize/cmd/pluginator/v2"
)

View File

@@ -87,6 +87,9 @@ varReference:
- path: spec/template/spec/volumes/nfs/server
kind: Deployment
- path: spec/template/metadata/annotations
kind: Deployment
- path: spec/rules/host
kind: Ingress

View File

@@ -225,13 +225,13 @@ spec:
spec:
containers:
- env:
- name: foo
value: bar
- name: FOO
valueFrom:
configMapKeyRef:
key: somekey
name: test-infra-app-env-8h5mh7f7ch
- name: foo
value: bar
image: nginx:1.8.0
name: nginx
ports:

View File

@@ -464,3 +464,50 @@ metadata:
name: another-namespace
`)
}
func TestFnContainerEnvVars(t *testing.T) {
skipIfNoDocker(t)
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
generators:
- gener.yaml
`)
// TODO: cheange image to gcr.io/kpt-functions/templater:stable
// when https://github.com/GoogleContainerTools/kpt-functions-catalog/pull/103
// is merged
th.WriteF("/app/gener.yaml", `
apiVersion: v1
kind: ConfigMap
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
container:
image: quay.io/aodinokov/kpt-templater:0.0.1
envs:
- TESTTEMPLATE=value
data:
template: |
apiVersion: v1
kind: ConfigMap
metadata:
name: env
data:
value: '{{ env "TESTTEMPLATE" }}'
`)
m := th.Run("/app", th.MakeOptionsPluginsEnabled())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
data:
value: value
kind: ConfigMap
metadata:
annotations:
config.kubernetes.io/path: configmap_env.yaml
name: env
`)
}

View File

@@ -385,12 +385,12 @@ spec:
- gcePersistentDisk:
pdName: nginx-persistent-storage
name: nginx-persistent-storage
- configMap:
name: staging-team-foo-configmap-in-base-hc6g9dk6g9
name: configmap-in-base
- configMap:
name: staging-configmap-in-overlay-dc6fm46dhm
name: configmap-in-overlay
- configMap:
name: staging-team-foo-configmap-in-base-hc6g9dk6g9
name: configmap-in-base
---
apiVersion: v1
kind: Service

View File

@@ -0,0 +1,106 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func writeIssueBase(th kusttest_test.Harness) {
th.WriteK("base", `
nameSuffix: -test-api
resources:
- deploy.yaml
`)
th.WriteF("base/deploy.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: example
spec:
template:
spec:
containers:
- name: example
image: example:1.0
volumeMounts:
- name: conf
mountPath: /etc/config
volumes:
- name: conf
configMap:
name: conf
`)
}
func TestIssue2896Base(t *testing.T) {
th := kusttest_test.MakeHarness(t)
writeIssueBase(th)
m := th.Run("base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-test-api
spec:
template:
spec:
containers:
- image: example:1.0
name: example
volumeMounts:
- mountPath: /etc/config
name: conf
volumes:
- configMap:
name: conf
name: conf
`)
}
func TestIssue2896Overlay(t *testing.T) {
th := kusttest_test.MakeHarness(t)
writeIssueBase(th)
th.WriteK("overlay", `
resources:
- ../base
patches:
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: example
spec:
template:
spec:
containers:
- name: example
image: example:2.0
`)
m := th.Run("overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-test-api
spec:
template:
spec:
containers:
- image: example:2.0
name: example
volumeMounts:
- mountPath: /etc/config
name: conf
volumes:
- configMap:
name: conf
name: conf
`)
}

View File

@@ -0,0 +1,57 @@
package krusty_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestKustomizationMetadata(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("/app/resources.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: testing123
spec:
replicas: 1
selector: null
template:
spec:
containers:
- name: event
image: testing123
imagePullPolicy: IfNotPresent
imagePullSecrets: []`)
th.WriteK("/app", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
metadata:
annotations:
config.kubernetes.io/local-config: "true"
labels:
foo: bar
name: test_kustomization
resources:
- resources.yaml
`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: testing123
spec:
replicas: 1
selector: null
template:
spec:
containers:
- image: testing123
imagePullPolicy: IfNotPresent
name: event
imagePullSecrets: []
`)
}

View File

@@ -146,12 +146,12 @@ spec:
- gcePersistentDisk:
pdName: nginx-persistent-storage
name: nginx-persistent-storage
- configMap:
name: a-b-configmap-in-base-798k5k7g9f
name: configmap-in-base
- configMap:
name: a-configmap-in-overlay-dc6fm46dhm
name: configmap-in-overlay
- configMap:
name: a-b-configmap-in-base-798k5k7g9f
name: configmap-in-base
---
apiVersion: v1
kind: Service
@@ -351,12 +351,12 @@ spec:
- gcePersistentDisk:
pdName: nginx-persistent-storage
name: nginx-persistent-storage
- configMap:
name: staging-team-foo-configmap-in-base-798k5k7g9f
name: configmap-in-base
- configMap:
name: staging-configmap-in-overlay-dc6fm46dhm
name: configmap-in-overlay
- configMap:
name: staging-team-foo-configmap-in-base-798k5k7g9f
name: configmap-in-base
---
apiVersion: v1
kind: Service

View File

@@ -213,3 +213,132 @@ roleRef:
name: my-role-ns2
`)
}
// The ServiceAccount in subjects in role binding can be across namespace
// but the roleRef is not. This test is used to cover such case.
func TestRoleBindingWhenSubjectsAcrossNamespace(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
resources:
- ./ns1
- ./ns2
`)
th.WriteK("/app/ns1", `
namespace: namespace-1
resources:
- role-ns1.yaml
- rolebinding-ns1.yaml
`)
th.WriteF("/app/ns1/role-ns1.yaml", `
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: testRole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
`)
th.WriteF("/app/ns1/rolebinding-ns1.yaml", `
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: testRoleBinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: testRole
subjects:
- kind: ServiceAccount
name: testAccount
namespace: namespace-2
`)
th.WriteK("/app/ns2", `
namespace: namespace-2
resources:
- role-ns2.yaml
- rolebinding-ns2.yaml
`)
th.WriteF("/app/ns2/role-ns2.yaml", `
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: testRole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
`)
th.WriteF("/app/ns2/rolebinding-ns2.yaml", `
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: testRoleBinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: testRole
subjects:
- kind: ServiceAccount
name: testAccount
namespace: namespace-1
`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: testRole
namespace: namespace-1
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: testRoleBinding
namespace: namespace-1
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: testRole
subjects:
- kind: ServiceAccount
name: testAccount
namespace: namespace-2
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: testRole
namespace: namespace-2
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: testRoleBinding
namespace: namespace-2
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: testRole
subjects:
- kind: ServiceAccount
name: testAccount
namespace: namespace-1
`)
}

View File

@@ -1969,3 +1969,70 @@ spec:
server: kustomized-nfs-server-service.default.srv.cluster.local
`)
}
func TestDeploymentAnnotations(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("/app", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: testConfigMap
envs:
- test.properties
vars:
- name: FOO
objref:
kind: ConfigMap
name: testConfigMap
apiVersion: v1
fieldref:
fieldpath: data.foo
commonAnnotations:
foo: $(FOO)
resources:
- deployment.yaml
`)
th.WriteF("/app/deployment.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test
spec:
template:
spec:
containers:
- name: test
`)
th.WriteF("/app/test.properties", `foo=bar`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
foo: bar
name: test
spec:
template:
metadata:
annotations:
foo: bar
spec:
containers:
- name: test
---
apiVersion: v1
data:
foo: bar
kind: ConfigMap
metadata:
annotations:
foo: bar
name: testConfigMap-798k5k7g9f
`)
}

View File

@@ -5,6 +5,8 @@ package resid
import (
"strings"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// Gvk identifies a Kubernetes API type.
@@ -77,6 +79,22 @@ func (x Gvk) String() string {
return strings.Join([]string{g, v, k}, fieldSep)
}
// StringWoEmptyField returns a string representation of the GVK. Non-exist
// fields will be omitted.
func (x Gvk) StringWoEmptyField() string {
var s []string
if x.Group != "" {
s = append(s, x.Group)
}
if x.Version != "" {
s = append(s, x.Version)
}
if x.Kind != "" {
s = append(s, x.Kind)
}
return strings.Join(s, fieldSep)
}
// Equals returns true if the Gvk's have equal fields.
func (x Gvk) Equals(o Gvk) bool {
return x.Group == o.Group && x.Version == o.Version && x.Kind == o.Kind
@@ -99,6 +117,7 @@ var orderFirst = []string{
"ClusterRoleBinding",
"ConfigMap",
"Secret",
"Endpoints",
"Service",
"LimitRange",
"PriorityClass",
@@ -171,39 +190,22 @@ func (x Gvk) IsSelected(selector *Gvk) bool {
return true
}
var notNamespaceableKinds = []string{
"APIService",
"CSIDriver",
"CSINode",
"CertificateSigningRequest",
"Cluster",
"ClusterRole",
"ClusterRoleBinding",
"ComponentStatus",
"CustomResourceDefinition",
"MutatingWebhookConfiguration",
"Namespace",
"Node",
"PersistentVolume",
"PodSecurityPolicy",
"PriorityClass",
"RuntimeClass",
"SelfSubjectAccessReview",
"SelfSubjectRulesReview",
"StorageClass",
"SubjectAccessReview",
"TokenReview",
"ValidatingWebhookConfiguration",
"VolumeAttachment",
// toKyamlTypeMeta returns a yaml.TypeMeta from x's information.
func (x Gvk) toKyamlTypeMeta() yaml.TypeMeta {
var apiVersion strings.Builder
if x.Group != "" {
apiVersion.WriteString(x.Group)
apiVersion.WriteString("/")
}
apiVersion.WriteString(x.Version)
return yaml.TypeMeta{
APIVersion: apiVersion.String(),
Kind: x.Kind,
}
}
// IsNamespaceableKind returns true if x is a namespaceable Gvk
// Implements https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#not-all-objects-are-in-a-namespace
func (x Gvk) IsNamespaceableKind() bool {
for _, k := range notNamespaceableKinds {
if k == x.Kind {
return false
}
}
return true
return x.toKyamlTypeMeta().IsNamespaceable()
}

View File

@@ -78,6 +78,8 @@ var lessThanTests = []struct {
Gvk{Group: "a", Version: "b", Kind: "ValidatingWebhookConfiguration"}},
{Gvk{Group: "a", Version: "b", Kind: "Service"},
Gvk{Group: "a", Version: "b", Kind: "APIService"}},
{Gvk{Group: "a", Version: "b", Kind: "Endpoints"},
Gvk{Group: "a", Version: "b", Kind: "Service"}},
}
func TestIsLessThan1(t *testing.T) {
@@ -94,15 +96,16 @@ func TestIsLessThan1(t *testing.T) {
var stringTests = []struct {
x Gvk
s string
r string
}{
{Gvk{}, "~G_~V_~K"},
{Gvk{Kind: "k"}, "~G_~V_k"},
{Gvk{Version: "v"}, "~G_v_~K"},
{Gvk{Version: "v", Kind: "k"}, "~G_v_k"},
{Gvk{Group: "g"}, "g_~V_~K"},
{Gvk{Group: "g", Kind: "k"}, "g_~V_k"},
{Gvk{Group: "g", Version: "v"}, "g_v_~K"},
{Gvk{Group: "g", Version: "v", Kind: "k"}, "g_v_k"},
{Gvk{}, "~G_~V_~K", ""},
{Gvk{Kind: "k"}, "~G_~V_k", "k"},
{Gvk{Version: "v"}, "~G_v_~K", "v"},
{Gvk{Version: "v", Kind: "k"}, "~G_v_k", "v_k"},
{Gvk{Group: "g"}, "g_~V_~K", "g"},
{Gvk{Group: "g", Kind: "k"}, "g_~V_k", "g_k"},
{Gvk{Group: "g", Version: "v"}, "g_v_~K", "g_v"},
{Gvk{Group: "g", Version: "v", Kind: "k"}, "g_v_k", "g_v_k"},
}
func TestString(t *testing.T) {
@@ -113,6 +116,14 @@ func TestString(t *testing.T) {
}
}
func TestStringWoEmptyField(t *testing.T) {
for _, hey := range stringTests {
if hey.x.StringWoEmptyField() != hey.r {
t.Fatalf("bad string %s for %v '%s'", hey.x.StringWoEmptyField(), hey.x, hey.r)
}
}
}
func TestParseGroupVersion(t *testing.T) {
tests := []struct {
input string

View File

@@ -514,7 +514,7 @@ func anchorRegex(pattern string) string {
if pattern == "" {
return pattern
}
return "^" + pattern + "$"
return "^(?:" + pattern + ")$"
}
// Select returns a list of resources that
@@ -530,7 +530,7 @@ func (m *resWrangler) Select(s types.Selector) ([]*resource.Resource, error) {
// matches the namespace when namespace is not empty in the selector
// It first tries to match with the original namespace
// then matches with the current namespace
if r.GetNamespace() != "" {
if s.Namespace != "" {
matched := ns.MatchString(orgId.EffectiveNamespace())
if !matched {
matched = ns.MatchString(curId.EffectiveNamespace())
@@ -543,7 +543,7 @@ func (m *resWrangler) Select(s types.Selector) ([]*resource.Resource, error) {
// matches the name when name is not empty in the selector
// It first tries to match with the original name
// then matches with the current name
if r.GetName() != "" {
if s.Name != "" {
matched := nm.MatchString(orgId.Name)
if !matched {
matched = nm.MatchString(curId.Name)

View File

@@ -164,6 +164,18 @@ func TestFindPatchTargets(t *testing.T) {
},
count: 2,
},
{
target: types.Selector{
Namespace: "NotMatched",
},
count: 0,
},
{
target: types.Selector{
Namespace: "ns1",
},
count: 1,
},
}
for _, testcase := range testcases {
actual, err := rm.Select(testcase.target)

View File

@@ -68,6 +68,10 @@ func (r *Resource) GetString(p string) (string, error) {
return r.kunStr.GetString(p)
}
func (r *Resource) IsEmpty() bool {
return len(r.kunStr.Map()) == 0
}
func (r *Resource) Map() map[string]interface{} {
return r.kunStr.Map()
}

View File

@@ -22,6 +22,9 @@ const (
type Kustomization struct {
TypeMeta `json:",inline" yaml:",inline"`
// MetaData is a pointer to avoid marshalling empty struct
MetaData *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
//
// Operators - what kustomize can do.
//

View File

@@ -141,6 +141,13 @@ func TestUnmarshal(t *testing.T) {
y := []byte(`
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
metadata:
name: kust
namespace: default
labels:
foo: bar
annotations:
foo: bar
resources:
- foo
- bar
@@ -151,8 +158,20 @@ namePrefix: cat`)
if err != nil {
t.Fatal(err)
}
meta := ObjectMeta{
Name: "kust",
Namespace: "default",
Labels: map[string]string{
"foo": "bar",
},
Annotations: map[string]string{
"foo": "bar",
},
}
if k.Kind != KustomizationKind || k.APIVersion != KustomizationVersion ||
len(k.Resources) != 2 || k.NamePrefix != "cat" || k.NameSuffix != "dog" {
len(k.Resources) != 2 || k.NamePrefix != "cat" || k.NameSuffix != "dog" ||
k.MetaData.Name != meta.Name || k.MetaData.Namespace != meta.Namespace ||
k.MetaData.Labels["foo"] != meta.Labels["foo"] || k.MetaData.Annotations["foo"] != meta.Annotations["foo"] {
t.Fatalf("wrong unmarshal result: %v", k)
}
}

View File

@@ -6,6 +6,8 @@ package types
// ObjectMeta partially copies apimachinery/pkg/apis/meta/v1.ObjectMeta
// No need for a direct dependence; the fields are stable.
type ObjectMeta struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
}

View File

@@ -53,4 +53,6 @@ type FnPluginLoadingOptions struct {
NetworkName string
// list of mounts
Mounts []string
// list of env variables to pass to fn
Env []string
}

View File

@@ -1,89 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package configcobra
import (
"flag"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/kubectl/pkg/cmd/util"
"sigs.k8s.io/cli-utils/cmd/apply"
"sigs.k8s.io/cli-utils/cmd/destroy"
"sigs.k8s.io/cli-utils/cmd/diff"
"sigs.k8s.io/cli-utils/cmd/initcmd"
"sigs.k8s.io/cli-utils/cmd/preview"
"sigs.k8s.io/cli-utils/pkg/util/factory"
)
func GetLive(name string) *cobra.Command {
cmd := &cobra.Command{
Use: "live",
Short: "Commands for reading and writing resources to a cluster.",
}
ioStreams := genericclioptions.IOStreams{
In: cmd.InOrStdin(),
Out: cmd.OutOrStdout(),
ErrOut: cmd.ErrOrStderr(),
}
flags := cmd.PersistentFlags()
kubeConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag()
kubeConfigFlags.AddFlags(flags)
userAgentKubeConfigFlags := &UserAgentKubeConfigFlags{
Delegate: kubeConfigFlags,
UserAgent: "kustomize",
}
matchVersionKubeConfigFlags := util.NewMatchVersionFlags(
&factory.CachingRESTClientGetter{
Delegate: userAgentKubeConfigFlags,
},
)
matchVersionKubeConfigFlags.AddFlags(cmd.PersistentFlags())
cmd.PersistentFlags().AddGoFlagSet(flag.CommandLine)
f := util.NewFactory(matchVersionKubeConfigFlags)
applyCmd := apply.ApplyCommand(f, ioStreams)
_ = applyCmd.Flags().MarkHidden("no-prune")
cmd.AddCommand(
applyCmd,
initcmd.NewCmdInit(f, ioStreams),
preview.GetPreviewRunner(f, ioStreams).Command,
diff.NewCmdDiff(f, ioStreams),
destroy.GetDestroyRunner(f, ioStreams).Command)
return cmd
}
type UserAgentKubeConfigFlags struct {
Delegate genericclioptions.RESTClientGetter
UserAgent string
}
func (u *UserAgentKubeConfigFlags) ToRESTConfig() (*rest.Config, error) {
clientConfig, err := u.Delegate.ToRESTConfig()
if err != nil {
return nil, err
}
if u.UserAgent != "" {
clientConfig.UserAgent = u.UserAgent
}
return clientConfig, nil
}
func (u *UserAgentKubeConfigFlags) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
return u.Delegate.ToDiscoveryClient()
}
func (u *UserAgentKubeConfigFlags) ToRESTMapper() (meta.RESTMapper, error) {
return u.Delegate.ToRESTMapper()
}
func (u *UserAgentKubeConfigFlags) ToRawKubeConfigLoader() clientcmd.ClientConfig {
return u.Delegate.ToRawKubeConfigLoader()
}

View File

@@ -3,22 +3,8 @@
package ext
import (
"path/filepath"
)
// GetOpenAPIFile returns the path to the file containing supplementary OpenAPI definitions.
// Maybe be overridden to configure which file to read OpenAPI definitions from.
var GetOpenAPIFile = func(args []string) (string, error) {
return filepath.Join(args[0], "Krmfile"), nil
}
// OpenAPIFileName returns the name of the file with openAPI definitions
// uses OpenAPIFile function to derive it
func OpenAPIFileName() (string, error) {
openAPIFileName, err := GetOpenAPIFile([]string{"."})
if err != nil {
return "", err
}
return openAPIFileName, nil
// KRMFileName returns the name of the KRM file. KRM file determines package
// boundaries and contains the openapi information for a package.
var KRMFileName = func() string {
return "Krmfile"
}

View File

@@ -5,15 +5,17 @@ go 1.14
require (
github.com/go-errors/errors v1.0.1
github.com/go-openapi/spec v0.19.5
github.com/google/go-cmp v0.5.2 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/olekukonko/tablewriter v0.0.4
github.com/posener/complete/v2 v2.0.1-alpha.12
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.4.0
github.com/stretchr/testify v1.6.1
golang.org/x/net v0.0.0-20200625001655-4c5254603344 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
k8s.io/apimachinery v0.17.3
k8s.io/cli-runtime v0.17.3
k8s.io/client-go v0.17.3
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd
sigs.k8s.io/cli-utils v0.20.1
sigs.k8s.io/kustomize/kyaml v0.8.0
sigs.k8s.io/kustomize/kyaml v0.9.2
)

View File

@@ -1,20 +1,6 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
@@ -36,62 +22,33 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 h1:w3NnFcKR5241cfmQU5ZZAsf0xcpId6mWOupTvJlUX2U=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustmop/soup v1.1.2-0.20190516214245-38228baa104e/go.mod h1:CgNC6SGbT+Xb8wGGvzilttZL1mc5sQ/5KkcxsZttMIk=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -106,8 +63,6 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/zapr v0.1.0 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54=
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
@@ -161,7 +116,6 @@ github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tF
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-openapi/validate v0.19.8 h1:YFzsdWIDfVuLvIOF+ZmKjVg1MbPJ1QgY9PihMwei1ys=
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
@@ -172,74 +126,48 @@ github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09Vjb
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
@@ -253,9 +181,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -264,15 +191,10 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -286,34 +208,25 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
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/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.4.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -321,53 +234,35 @@ github.com/posener/complete/v2 v2.0.1-alpha.12 h1:0wvkuDfHb5vSZlNBYgpEH4XQHpF46M
github.com/posener/complete/v2 v2.0.1-alpha.12/go.mod h1://JlL91cS2JV7rOl6LVHrRqBXoBUecJu3ILQPgbJiMQ=
github.com/posener/script v1.0.4 h1:nSuXW5ZdmFnQIueLB2s0qvs4oNsUloM1Zydzh75v42w=
github.com/posener/script v1.0.4/go.mod h1:Rg3ijooqulo05aGLyGsHoLmIOUzHUVK19WVgrYBPU/E=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d h1:K6eOUihrFLdZjZnA4XlRp864fmWXv9YTIk7VPLhRacA=
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -379,120 +274,79 @@ github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnR
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180117170059-2c42eef0765b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c h1:Vco5b+cuG5NNfORVxZy6bYZQ7rsigisU1WQFkvQ0L5E=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -501,54 +355,31 @@ golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
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/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -558,79 +389,19 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48=
k8s.io/api v0.0.0-20191214185829-ca1d04f8b0d3/go.mod h1:itOjKREfmUTvcjantxOsyYU5mbFsU7qUnyUuRfF5+5M=
k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4=
k8s.io/api v0.17.3 h1:XAm3PZp3wnEdzekNkcmj/9Y1zdmQYJ1I4GKSBBZ8aG0=
k8s.io/api v0.17.3/go.mod h1:YZ0OTkuw7ipbe305fMpIdf3GLXZKRigjtZaV5gzC2J0=
k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783/go.mod h1:xvae1SZB3E17UpV59AWc271W/Ph25N+bjPyR63X6tPY=
k8s.io/apiextensions-apiserver v0.17.2 h1:cP579D2hSZNuO/rZj9XFRzwJNYb41DbNANJb6Kolpss=
k8s.io/apiextensions-apiserver v0.17.2/go.mod h1:4KdMpjkEjjDI2pPfBA15OscyNldHWdBCfsWMDWAmSTs=
k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655/go.mod h1:nL6pwRT8NgfF8TT68DBI8uEePRt89cSvoXUVqbkWHq4=
k8s.io/apimachinery v0.0.0-20191214185652-442f8fb2f03a/go.mod h1:Ng1IY8TS7sC44KJxT/WUR6qFRfWwahYYYpNXyYRKOCY=
k8s.io/apimachinery v0.0.0-20191216025728-0ee8b4573e3a/go.mod h1:Ng1IY8TS7sC44KJxT/WUR6qFRfWwahYYYpNXyYRKOCY=
k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
k8s.io/apimachinery v0.17.3 h1:f+uZV6rm4/tHE7xXgLyToprg6xWairaClGVkm2t8omg=
k8s.io/apimachinery v0.17.3/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g=
k8s.io/apiserver v0.0.0-20190918160949-bfa5e2e684ad/go.mod h1:XPCXEwhjaFN29a8NldXA901ElnKeKLrLtREO9ZhFyhg=
k8s.io/apiserver v0.17.2/go.mod h1:lBmw/TtQdtxvrTk0e2cgtOxHizXI+d0mmGQURIHQZlo=
k8s.io/cli-runtime v0.0.0-20191214191754-e6dc6d5c8724/go.mod h1:wzlq80lvjgHW9if6MlE4OIGC86MDKsy5jtl9nxz/IYY=
k8s.io/cli-runtime v0.17.2/go.mod h1:aa8t9ziyQdbkuizkNLAw3qe3srSyWh9zlSB7zTqRNPI=
k8s.io/cli-runtime v0.17.3 h1:0ZlDdJgJBKsu77trRUynNiWsRuAvAVPBNaQfnt/1qtc=
k8s.io/cli-runtime v0.17.3/go.mod h1:X7idckYphH4SZflgNpOOViSxetiMj6xI0viMAjM81TA=
k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90/go.mod h1:J69/JveO6XESwVgG53q3Uz5OSfgsv4uxpScmmyYOOlk=
k8s.io/client-go v0.0.0-20191214190045-a32a6f7a3052/go.mod h1:tAaoc/sYuIL0+njJefSAmE28CIcxyaFV4kbIujBlY2s=
k8s.io/client-go v0.0.0-20191219150334-0b8da7416048/go.mod h1:ZEe8ZASDUAuqVGJ+UN0ka0PfaR+b6a6E1PGsSNZRui8=
k8s.io/client-go v0.17.2/go.mod h1:QAzRgsa0C2xl4/eVpeVAZMvikCn8Nm81yqVx3Kk9XYI=
k8s.io/client-go v0.17.3 h1:deUna1Ksx05XeESH6XGCyONNFfiQmDdqeqUvicvP6nU=
k8s.io/client-go v0.17.3/go.mod h1:cLXlTMtWHkuK4tD360KpWz2gG2KtdWEr/OT02i3emRQ=
k8s.io/code-generator v0.0.0-20190912054826-cd179ad6a269/go.mod h1:V5BD6M4CyaN5m+VthcclXWsVcT1Hu+glwa1bi3MIsyE=
k8s.io/code-generator v0.0.0-20191214185510-0b9b3c99f9f2/go.mod h1:BjGKcoq1MRUmcssvHiSxodCco1T6nVIt4YeCT5CMSao=
k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
k8s.io/component-base v0.0.0-20190918160511-547f6c5d7090/go.mod h1:933PBGtQFJky3TEwYx4aEPZ4IxqhWh3R6DCmzqIn1hA=
k8s.io/component-base v0.0.0-20191214190519-d868452632e2/go.mod h1:wupxkh1T/oUDqyTtcIjiEfpbmIHGm8By/vqpSKC6z8c=
k8s.io/component-base v0.17.2 h1:0XHf+cerTvL9I5Xwn9v+0jmqzGAZI7zNydv4tL6Cw6A=
k8s.io/component-base v0.17.2/go.mod h1:zMPW3g5aH7cHJpKYQ/ZsGMcgbsA/VyhEugF3QT1awLs=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd h1:nZX5+wEqTu/EBIYjrZlFOA63z4+Zcy96lDkCZPU9a9c=
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd/go.mod h1:9ehGcuUGjXVZh0qbYSB0vvofQw2JQe6c6cO0k4wu/Oo=
k8s.io/metrics v0.0.0-20191214191643-6b1944c9f765/go.mod h1:5V7rewilItwK0cz4nomU0b3XCcees2Ka5EBYWS1HBeM=
k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
sigs.k8s.io/cli-utils v0.20.1 h1:S3IM4Rmely9oWNAeytx46PhngTwdRxsJ4ixtoGWPc3o=
sigs.k8s.io/cli-utils v0.20.1/go.mod h1:fQkEMmLXduMNmUf1+dgQ5GRJa4OrrLMw3qzAN8YXAU8=
sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg=
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/kustomize/kyaml v0.9.2 h1:QNP1Lg4V2wOgBeUim9Kmz1+2GqHtRyfoVEUQH0omrCI=
sigs.k8s.io/kustomize/kyaml v0.9.2/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
sigs.k8s.io/testing_frameworks v0.1.2 h1:vK0+tvjF0BZ/RYFeZ1E6BYBwHJJXhjuZ3TdsEKH+UQM=
sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=

View File

@@ -85,14 +85,14 @@ func (r *AnnotateRunner) runE(c *cobra.Command, args []string) error {
}
func (r *AnnotateRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
rw := &kio.LocalPackageReadWriter{
PackagePath: pkgPath,
NoDeleteFiles: true,
PackageFileName: ext.KRMFileName(),
}
rw := &kio.LocalPackageReadWriter{PackagePath: pkgPath, NoDeleteFiles: true, PackageFileName: openAPIFileName}
input := []kio.Reader{rw}
output := []kio.Writer{rw}
err = kio.Pipeline{
err := kio.Pipeline{
Inputs: input,
Filters: []kio.Filter{r},
Outputs: output,

View File

@@ -501,7 +501,10 @@ func TestAnnotateSubPackages(t *testing.T) {
name: "annotate-recurse-subpackages",
dataset: "dataset-without-setters",
args: []string{"--kv", "foo=bar", "-R"},
expected: `${baseDir}/mysql/
expected: `${baseDir}/
added annotations in the package
${baseDir}/mysql/
added annotations in the package
${baseDir}/mysql/storage/

View File

@@ -4,9 +4,11 @@
package commands
import (
"bytes"
"fmt"
"io"
"os"
"strings"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
@@ -96,8 +98,10 @@ func (r *CatRunner) runE(c *cobra.Command, args []string) error {
return handleError(c, kio.Pipeline{Inputs: []kio.Reader{input}, Filters: r.catFilters(), Outputs: outputs}.Execute())
}
out := &bytes.Buffer{}
e := executeCmdOnPkgs{
writer: writer,
writer: out,
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
@@ -105,17 +109,21 @@ func (r *CatRunner) runE(c *cobra.Command, args []string) error {
skipPkgPathPrint: true,
}
return e.execute()
}
func (r *CatRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
err := e.execute()
if err != nil {
return err
}
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: openAPIFileName}
outputs, err := r.out(w)
res := strings.TrimSuffix(out.String(), "---")
fmt.Fprintf(writer, "%s", res)
return nil
}
func (r *CatRunner) executeCmd(w io.Writer, pkgPath string) error {
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: ext.KRMFileName()}
out := &bytes.Buffer{}
outputs, err := r.out(out)
if err != nil {
return err
}
@@ -134,7 +142,10 @@ func (r *CatRunner) executeCmd(w io.Writer, pkgPath string) error {
fmt.Fprintf(w, "%s in package %q\n", err.Error(), pkgPath)
}
}
fmt.Fprintf(w, "---")
fmt.Fprint(w, out.String())
if out.String() != "" {
fmt.Fprint(w, "---")
}
return nil
}

View File

@@ -115,7 +115,7 @@ metadata:
app: nginx
spec:
replicas: 3
---`, b.String()) {
`, b.String()) {
return
}
}
@@ -225,7 +225,7 @@ metadata:
app: nginx
spec:
replicas: 3
---`, b.String()) {
`, b.String()) {
return
}
}
@@ -307,7 +307,7 @@ metadata:
image: gcr.io/example/reconciler:v1
spec:
replicas: 3
---`, b.String()) {
`, b.String()) {
return
}
}
@@ -421,7 +421,7 @@ metadata:
app: nginx
spec:
replicas: 3
---`, string(actual)) {
`, string(actual)) {
return
}
}
@@ -536,7 +536,7 @@ metadata:
app: nginx
spec:
replicas: 3
---`, string(actual)) {
`, string(actual)) {
return
}
}
@@ -552,7 +552,8 @@ func TestCatSubPackages(t *testing.T) {
{
name: "cat-recurse-subpackages",
dataset: "dataset-without-setters",
expected: `# Copyright 2019 The Kubernetes Authors.
expected: `
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
@@ -583,7 +584,7 @@ spec:
containers:
- name: storage
image: storage:1.7.7
---`,
`,
},
{
name: "cat-top-level-pkg-no-recurse-subpackages",
@@ -605,7 +606,7 @@ spec:
containers:
- name: mysql
image: mysql:1.7.9
---`,
`,
},
{
name: "cat-nested-pkg-no-recurse-subpackages",
@@ -627,7 +628,7 @@ spec:
containers:
- name: storage
image: storage:1.7.7
---`,
`,
},
}
for i := range tests {

View File

@@ -205,10 +205,6 @@ func (r *CreateSetterRunner) createSetter(c *cobra.Command, args []string) error
}
func (r *CreateSetterRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
r.CreateSetter = settersutil.SetterCreator{
Name: r.CreateSetter.Name,
SetBy: r.CreateSetter.SetBy,
@@ -219,12 +215,12 @@ func (r *CreateSetterRunner) executeCmd(w io.Writer, pkgPath string) error {
FieldValue: r.CreateSetter.FieldValue,
Required: r.CreateSetter.Required,
RecurseSubPackages: r.CreateSetter.RecurseSubPackages,
OpenAPIFileName: openAPIFileName,
OpenAPIPath: filepath.Join(pkgPath, openAPIFileName),
OpenAPIFileName: ext.KRMFileName(),
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
ResourcesPath: pkgPath,
}
err = r.CreateSetter.Create()
err := r.CreateSetter.Create()
if err != nil {
// return err if RecurseSubPackages is false
if !r.CreateSetter.RecurseSubPackages {

View File

@@ -65,22 +65,18 @@ func (r *CreateSubstitutionRunner) runE(c *cobra.Command, args []string) error {
}
func (r *CreateSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
r.CreateSubstitution = settersutil.SubstitutionCreator{
Name: r.CreateSubstitution.Name,
FieldName: r.CreateSubstitution.FieldName,
FieldValue: r.CreateSubstitution.FieldValue,
RecurseSubPackages: r.CreateSubstitution.RecurseSubPackages,
Pattern: r.CreateSubstitution.Pattern,
OpenAPIFileName: openAPIFileName,
OpenAPIPath: filepath.Join(pkgPath, openAPIFileName),
OpenAPIFileName: ext.KRMFileName(),
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
ResourcesPath: pkgPath,
}
err = r.CreateSubstitution.Create()
err := r.CreateSubstitution.Create()
if err != nil {
// return err if RecurseSubPackages is false
if !r.CreateSubstitution.RecurseSubPackages {

View File

@@ -47,14 +47,10 @@ type DeleteSetterRunner struct {
}
func (r *DeleteSetterRunner) preRunE(c *cobra.Command, args []string) error {
var err error
r.DeleteSetter.Name = args[1]
r.DeleteSetter.DefinitionPrefix = fieldmeta.SetterDefinitionPrefix
r.OpenAPIFile, err = ext.GetOpenAPIFile(args)
if err != nil {
return err
}
r.OpenAPIFile = filepath.Join(args[0], ext.KRMFileName())
return nil
}
@@ -75,20 +71,17 @@ func (r *DeleteSetterRunner) runE(c *cobra.Command, args []string) error {
}
func (r *DeleteSetterRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
r.DeleteSetter = settersutil.DeleterCreator{
Name: r.DeleteSetter.Name,
DefinitionPrefix: fieldmeta.SetterDefinitionPrefix,
RecurseSubPackages: r.RecurseSubPackages,
OpenAPIFileName: openAPIFileName,
OpenAPIPath: filepath.Join(pkgPath, openAPIFileName),
OpenAPIFileName: ext.KRMFileName(),
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
ResourcesPath: pkgPath,
}
err = r.DeleteSetter.Delete()
err := r.DeleteSetter.Delete()
if err != nil {
// return err if RecurseSubPackages is false
if !r.DeleteSetter.RecurseSubPackages {

View File

@@ -43,14 +43,10 @@ type DeleteSubstitutionRunner struct {
}
func (r *DeleteSubstitutionRunner) preRunE(c *cobra.Command, args []string) error {
var err error
r.DeleteSubstitution.Name = args[1]
r.DeleteSubstitution.DefinitionPrefix = fieldmeta.SubstitutionDefinitionPrefix
r.OpenAPIFile, err = ext.GetOpenAPIFile(args)
if err != nil {
return err
}
r.OpenAPIFile = filepath.Join(args[0], ext.KRMFileName())
return nil
}
@@ -71,20 +67,16 @@ func (r *DeleteSubstitutionRunner) runE(c *cobra.Command, args []string) error {
}
func (r *DeleteSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
r.DeleteSubstitution = settersutil.DeleterCreator{
Name: r.DeleteSubstitution.Name,
DefinitionPrefix: fieldmeta.SubstitutionDefinitionPrefix,
RecurseSubPackages: r.RecurseSubPackages,
OpenAPIFileName: openAPIFileName,
OpenAPIPath: filepath.Join(pkgPath, openAPIFileName),
OpenAPIFileName: ext.KRMFileName(),
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
ResourcesPath: pkgPath,
}
err = r.DeleteSubstitution.Delete()
err := r.DeleteSubstitution.Delete()
if err != nil {
// return err if RecurseSubPackages is false
if !r.DeleteSubstitution.RecurseSubPackages {

View File

@@ -85,15 +85,11 @@ func (r *ListSettersRunner) runE(c *cobra.Command, args []string) error {
}
func (r *ListSettersRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
r.List = setters2.List{
Name: r.List.Name,
OpenAPIFileName: openAPIFileName,
OpenAPIFileName: ext.KRMFileName(),
}
openAPIPath := filepath.Join(pkgPath, openAPIFileName)
openAPIPath := filepath.Join(pkgPath, ext.KRMFileName())
if err := r.ListSetters(w, openAPIPath, pkgPath); err != nil {
return err
}

View File

@@ -108,7 +108,6 @@ func (r *SetRunner) preRunE(c *cobra.Command, args []string) error {
}
}
if setterVersion == "v2" {
var err error
r.Set.Name = args[1]
if valueFlagSet {
r.Set.Value = r.Values[0]
@@ -125,10 +124,7 @@ func (r *SetRunner) preRunE(c *cobra.Command, args []string) error {
r.Set.Description = r.Perform.Description
r.Set.SetBy = r.Perform.SetBy
r.OpenAPIFile, err = ext.GetOpenAPIFile(args)
if err != nil {
return err
}
r.OpenAPIFile = filepath.Join(args[0], ext.KRMFileName())
}
return nil
}
@@ -155,10 +151,6 @@ func (r *SetRunner) runE(c *cobra.Command, args []string) error {
}
func (r *SetRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
r.Set = settersutil.FieldSetter{
Name: r.Set.Name,
Value: r.Set.Value,
@@ -166,8 +158,8 @@ func (r *SetRunner) executeCmd(w io.Writer, pkgPath string) error {
Description: r.Set.Description,
SetBy: r.Set.SetBy,
Count: 0,
OpenAPIPath: filepath.Join(pkgPath, openAPIFileName),
OpenAPIFileName: openAPIFileName,
OpenAPIPath: filepath.Join(pkgPath, ext.KRMFileName()),
OpenAPIFileName: ext.KRMFileName(),
ResourcesPath: pkgPath,
RecurseSubPackages: r.Set.RecurseSubPackages,
}
@@ -181,7 +173,7 @@ func (r *SetRunner) executeCmd(w io.Writer, pkgPath string) error {
fmt.Fprintf(w, "%s\n", err.Error())
}
} else {
fmt.Fprintf(w, "set %d field(s)\n", count)
fmt.Fprintf(w, "set %d field(s) of setter %q to value %q\n", count, r.Set.Name, r.Set.Value)
}
return nil
}

View File

@@ -1094,13 +1094,13 @@ func TestSetSubPackages(t *testing.T) {
dataset: "dataset-with-setters",
args: []string{"namespace", "otherspace", "-R"},
expected: `${baseDir}/mysql/
set 1 field(s)
set 1 field(s) of setter "namespace" to value "otherspace"
${baseDir}/mysql/nosetters/
setter "namespace" is not found
${baseDir}/mysql/storage/
set 1 field(s)
set 1 field(s) of setter "namespace" to value "otherspace"
`,
},
{
@@ -1109,7 +1109,7 @@ set 1 field(s)
packagePath: "mysql",
args: []string{"namespace", "otherspace"},
expected: `${baseDir}/mysql/
set 1 field(s)
set 1 field(s) of setter "namespace" to value "otherspace"
`,
},
{
@@ -1118,7 +1118,7 @@ set 1 field(s)
packagePath: "mysql/storage",
args: []string{"namespace", "otherspace"},
expected: `${baseDir}/mysql/storage/
set 1 field(s)
set 1 field(s) of setter "namespace" to value "otherspace"
`,
},
}

View File

@@ -69,14 +69,9 @@ func (r *CountRunner) runE(c *cobra.Command, args []string) error {
}
func (r *CountRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: ext.KRMFileName()}
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: openAPIFileName}
err = kio.Pipeline{
err := kio.Pipeline{
Inputs: []kio.Reader{input},
Outputs: r.out(w),
}.Execute()

View File

@@ -86,7 +86,9 @@ func TestCountSubPackages(t *testing.T) {
{
name: "count-recurse-subpackages",
dataset: "dataset-without-setters",
expected: `${baseDir}/mysql/
expected: `${baseDir}/
${baseDir}/mysql/
Deployment: 1
${baseDir}/mysql/storage/

View File

@@ -96,16 +96,11 @@ func (r *FmtRunner) runE(c *cobra.Command, args []string) error {
}
func (r *FmtRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
rw := &kio.LocalPackageReadWriter{
NoDeleteFiles: true,
PackagePath: pkgPath,
KeepReaderAnnotations: r.KeepAnnotations, PackageFileName: openAPIFileName}
err = kio.Pipeline{
KeepReaderAnnotations: r.KeepAnnotations, PackageFileName: ext.KRMFileName()}
err := kio.Pipeline{
Inputs: []kio.Reader{rw}, Filters: r.fmtFilters(), Outputs: []kio.Writer{rw}}.Execute()
if err != nil {

View File

@@ -179,7 +179,10 @@ func TestFmtSubPackages(t *testing.T) {
name: "fmt-recurse-subpackages",
dataset: "dataset-with-setters",
args: []string{"-R"},
expected: `${baseDir}/mysql/
expected: `${baseDir}/
formatted resource files in the package
${baseDir}/mysql/
formatted resource files in the package
${baseDir}/mysql/nosetters/

View File

@@ -4,6 +4,7 @@
package commands
import (
"bytes"
"fmt"
"io"
"strings"
@@ -114,8 +115,10 @@ func (r *GrepRunner) runE(c *cobra.Command, args []string) error {
}.Execute())
}
out := bytes.Buffer{}
e := executeCmdOnPkgs{
writer: c.OutOrStdout(),
writer: &out,
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
@@ -123,23 +126,26 @@ func (r *GrepRunner) runE(c *cobra.Command, args []string) error {
skipPkgPathPrint: true,
}
return e.execute()
}
func (r *GrepRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
err := e.execute()
if err != nil {
return err
}
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: openAPIFileName}
res := strings.TrimSuffix(out.String(), "---")
fmt.Fprintf(c.OutOrStdout(), "%s", res)
err = kio.Pipeline{
return nil
}
func (r *GrepRunner) executeCmd(w io.Writer, pkgPath string) error {
input := kio.LocalPackageReader{PackagePath: pkgPath, PackageFileName: ext.KRMFileName()}
out := &bytes.Buffer{}
err := kio.Pipeline{
Inputs: []kio.Reader{input},
Filters: []kio.Filter{r.GrepFilter},
Outputs: []kio.Writer{kio.ByteWriter{
Writer: w,
Writer: out,
KeepReaderAnnotations: r.KeepAnnotations,
}},
}.Execute()
@@ -153,6 +159,9 @@ func (r *GrepRunner) executeCmd(w io.Writer, pkgPath string) error {
fmt.Fprintf(w, "%s\n", err.Error())
}
}
fmt.Fprintf(w, "---")
fmt.Fprint(w, out.String())
if out.String() != "" {
fmt.Fprint(w, "---")
}
return nil
}

View File

@@ -283,7 +283,8 @@ func TestGrepSubPackages(t *testing.T) {
name: "grep-recurse-subpackages",
dataset: "dataset-without-setters",
args: []string{"kind=Deployment"},
expected: `# Copyright 2019 The Kubernetes Authors.
expected: `
# Copyright 2019 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
apiVersion: apps/v1
@@ -320,7 +321,7 @@ spec:
containers:
- name: storage
image: storage:1.7.7
---`,
`,
},
{
name: "grep-top-level-pkg-no-recurse-subpackages",
@@ -345,7 +346,7 @@ spec:
containers:
- name: mysql
image: mysql:1.7.9
---`,
`,
},
{
name: "grep-nested-pkg-no-recurse-subpackages",
@@ -370,7 +371,15 @@ spec:
containers:
- name: storage
image: storage:1.7.7
---`,
`,
},
{
name: "grep-recurse-subpackages-no-result",
dataset: "dataset-without-setters",
args: []string{"kind=ConfigMap"},
expected: `
`,
},
}
for i := range tests {

View File

@@ -62,8 +62,6 @@ func GetRunFnRunner(name string) *RunFnRunner {
r.Command.Flags().BoolVar(
&r.Network, "network", false, "enable network access for functions that declare it")
r.Command.Flags().StringVar(
&r.NetworkName, "network-name", "bridge", "the docker network to run the container in")
r.Command.Flags().StringArrayVar(
&r.Mounts, "mount", []string{},
"a list of storage options read from the filesystem")
@@ -72,6 +70,8 @@ func GetRunFnRunner(name string) *RunFnRunner {
r.Command.Flags().StringArrayVarP(
&r.Env, "env", "e", []string{},
"a list of environment variables to be used by functions")
r.Command.Flags().BoolVar(
&r.AsCurrentUser, "as-current-user", false, "use the uid and gid that kpt is running with to run the function in the container")
return r
}
@@ -96,10 +96,10 @@ type RunFnRunner struct {
RunFns runfn.RunFns
ResultsDir string
Network bool
NetworkName string
Mounts []string
LogSteps bool
Env []string
AsCurrentUser bool
}
func (r *RunFnRunner) runE(c *cobra.Command, args []string) error {
@@ -133,8 +133,8 @@ func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, dataItems []string
}
if r.Network {
err = fn.PipeE(
yaml.LookupCreate(yaml.MappingNode, "container", "network"),
yaml.SetField("required", yaml.NewScalarRNode("true")))
yaml.Lookup("container"),
yaml.SetField("network", yaml.NewScalarRNode("true")))
if err != nil {
return nil, err
}
@@ -309,13 +309,13 @@ func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
Input: input,
Path: path,
Network: r.Network,
NetworkName: r.NetworkName,
EnableStarlark: r.EnableStar,
EnableExec: r.EnableExec,
StorageMounts: storageMounts,
ResultsDir: r.ResultsDir,
LogSteps: r.LogSteps,
Env: r.Env,
AsCurrentUser: r.AsCurrentUser,
}
// don't consider args for the function

View File

@@ -29,7 +29,6 @@ func TestRunFnCommand_preRunE(t *testing.T) {
output io.Writer
functionPaths []string
network bool
networkName string
mount []string
}{
{
@@ -95,34 +94,32 @@ apiVersion: v1
`,
},
{
name: "network enabled",
args: []string{"run", "dir", "--image", "foo:bar", "--network"},
path: "dir",
network: true,
networkName: "bridge",
name: "network enabled",
args: []string{"run", "dir", "--image", "foo:bar", "--network"},
path: "dir",
network: true,
expected: `
metadata:
name: function-input
annotations:
config.kubernetes.io/function: |
container: {image: 'foo:bar', network: {required: true}}
container: {image: 'foo:bar', network: true}
data: {}
kind: ConfigMap
apiVersion: v1
`,
},
{
name: "with network name",
args: []string{"run", "dir", "--image", "foo:bar", "--network", "--network-name", "foo"},
path: "dir",
network: true,
networkName: "foo",
name: "with network name",
args: []string{"run", "dir", "--image", "foo:bar", "--network"},
path: "dir",
network: true,
expected: `
metadata:
name: function-input
annotations:
config.kubernetes.io/function: |
container: {image: 'foo:bar', network: {required: true}}
container: {image: 'foo:bar', network: true}
data: {}
kind: ConfigMap
apiVersion: v1
@@ -202,7 +199,6 @@ apiVersion: v1
path: "dir",
expectedStruct: &runfn.RunFns{
Path: "dir",
NetworkName: "bridge",
EnableStarlark: true,
Env: []string{},
},
@@ -255,10 +251,9 @@ apiVersion: v1
args: []string{"run", "dir", "--results-dir", "foo/", "--image", "foo:bar", "--", "a=b", "c=d", "e=f"},
path: "dir",
expectedStruct: &runfn.RunFns{
Path: "dir",
NetworkName: "bridge",
ResultsDir: "foo/",
Env: []string{},
Path: "dir",
ResultsDir: "foo/",
Env: []string{},
},
expected: `
metadata:
@@ -291,10 +286,9 @@ apiVersion: v1
args: []string{"run", "dir", "--log-steps"},
path: "dir",
expectedStruct: &runfn.RunFns{
Path: "dir",
NetworkName: "bridge",
LogSteps: true,
Env: []string{},
Path: "dir",
LogSteps: true,
Env: []string{},
},
},
{
@@ -302,9 +296,18 @@ apiVersion: v1
args: []string{"run", "dir", "--env", "FOO=BAR", "-e", "BAR"},
path: "dir",
expectedStruct: &runfn.RunFns{
Path: "dir",
NetworkName: "bridge",
Env: []string{"FOO=BAR", "BAR"},
Path: "dir",
Env: []string{"FOO=BAR", "BAR"},
},
},
{
name: "as current user",
args: []string{"run", "dir", "--as-current-user"},
path: "dir",
expectedStruct: &runfn.RunFns{
Path: "dir",
AsCurrentUser: true,
Env: []string{},
},
},
}
@@ -362,9 +365,6 @@ apiVersion: v1
if !assert.Equal(t, tt.network, r.RunFns.Network) {
t.FailNow()
}
if !assert.Equal(t, tt.networkName, r.RunFns.NetworkName) {
t.FailNow()
}
} else {
if !assert.Equal(t, false, r.RunFns.Network) {
t.FailNow()

View File

@@ -74,17 +74,17 @@ type TreeRunner struct {
structure string
}
func (r *TreeRunner) getMatchFilesGlob() []string {
matchFilesGlob := append([]string{ext.KRMFileName()}, kio.DefaultMatch...)
return append(matchFilesGlob, "Kustomization")
}
func (r *TreeRunner) runE(c *cobra.Command, args []string) error {
var input kio.Reader
var root = "."
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
matchFilesGlob := append([]string{openAPIFileName}, kio.DefaultMatch...)
if len(args) == 1 {
root = filepath.Clean(args[0])
input = kio.LocalPackageReader{PackagePath: args[0], MatchFilesGlob: matchFilesGlob}
input = kio.LocalPackageReader{PackagePath: args[0], MatchFilesGlob: r.getMatchFilesGlob()}
} else {
input = &kio.ByteReader{Reader: c.InOrStdin()}
}
@@ -163,7 +163,7 @@ func (r *TreeRunner) runE(c *cobra.Command, args []string) error {
Writer: c.OutOrStdout(),
Fields: fields,
Structure: kio.TreeStructure(r.structure),
OpenAPIFileName: openAPIFileName,
OpenAPIFileName: ext.KRMFileName(),
}},
}.Execute())
}

View File

@@ -90,6 +90,53 @@ spec:
}
}
func TestTreeCommand_Kustomization(t *testing.T) {
d, err := ioutil.TempDir("", "kustomize-tree-test")
defer os.RemoveAll(d)
if !assert.NoError(t, err) {
return
}
err = ioutil.WriteFile(filepath.Join(d, "f2.yaml"), []byte(`kind: Deployment
metadata:
labels:
app: nginx
name: bar
annotations:
app: nginx
spec:
replicas: 3
`), 0600)
if !assert.NoError(t, err) {
return
}
err = ioutil.WriteFile(filepath.Join(d, "Kustomization"), []byte(`apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- f2.yaml
`), 0600)
if !assert.NoError(t, err) {
return
}
// fmt the files
b := &bytes.Buffer{}
r := commands.GetTreeRunner("")
r.Command.SetArgs([]string{d})
r.Command.SetOut(b)
if !assert.NoError(t, r.Command.Execute()) {
return
}
if !assert.Equal(t, fmt.Sprintf(`%s
├── [Kustomization] Kustomization
└── [f2.yaml] Deployment bar
`, d), b.String()) {
return
}
}
func TestTreeCommand_subpkgs(t *testing.T) {
d, err := ioutil.TempDir("", "kustomize-tree-test")
defer os.RemoveAll(d)

View File

@@ -37,12 +37,7 @@ type executeCmdOnPkgs struct {
// executeCmdOnPkgs takes the function definition for a command to be executed on single package, applies that definition
// recursively on all the subpackages present in rootPkgPath if recurseSubPackages is true, else applies the command on rootPkgPath only
func (e executeCmdOnPkgs) execute() error {
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
pkgsPaths, err := pathutil.DirsWithFile(e.rootPkgPath, openAPIFileName, e.recurseSubPackages)
pkgsPaths, err := pathutil.DirsWithFile(e.rootPkgPath, ext.KRMFileName(), e.recurseSubPackages)
if err != nil {
return err
}
@@ -51,18 +46,24 @@ func (e executeCmdOnPkgs) execute() error {
// at this point, there are no openAPI files in the rootPkgPath
if e.needOpenAPI {
// few executions need openAPI file to be present(ex: setters commands), if true throw an error
return errors.Errorf("unable to find %q in package %q", openAPIFileName, e.rootPkgPath)
return errors.Errorf("unable to find %q in package %q", ext.KRMFileName(), e.rootPkgPath)
}
// add root path for commands which doesn't need openAPI(ex: annotate, fmt)
pkgsPaths = []string{e.rootPkgPath}
}
// for commands which doesn't need openAPI file, make sure that the root package is
// included all the times
if !e.needOpenAPI && !containsString(pkgsPaths, e.rootPkgPath) {
pkgsPaths = append([]string{e.rootPkgPath}, pkgsPaths...)
}
for i := range pkgsPaths {
pkgPath := pkgsPaths[i]
// Add schema present in openAPI file for current package
if e.needOpenAPI {
if err := openapi.AddSchemaFromFile(filepath.Join(pkgPath, openAPIFileName)); err != nil {
if err := openapi.AddSchemaFromFile(filepath.Join(pkgPath, ext.KRMFileName())); err != nil {
return err
}
}
@@ -82,7 +83,7 @@ func (e executeCmdOnPkgs) execute() error {
// Delete schema present in openAPI file for current package
if e.needOpenAPI {
if err := openapi.DeleteSchemaInFile(filepath.Join(pkgPath, openAPIFileName)); err != nil {
if err := openapi.DeleteSchemaInFile(filepath.Join(pkgPath, ext.KRMFileName())); err != nil {
return err
}
}
@@ -150,3 +151,13 @@ func fixDocs(new string, c *cobra.Command) {
c.Long = strings.ReplaceAll(c.Long, cmdName, new)
c.Example = strings.ReplaceAll(c.Example, cmdName, new)
}
// containsString returns true if slice contains s
func containsString(slice []string, s string) bool {
for _, item := range slice {
if item == s {
return true
}
}
return false
}

15
cmd/gorepomod/Makefile Normal file
View File

@@ -0,0 +1,15 @@
MYGOBIN := $(shell go env GOPATH)/bin
$(MYGOBIN)/gorepomod: usage.go
go install .
.PHONY: test
test: $(MYGOBIN)/gorepomod
go test ./...
usage.go: README.md $(MYGOBIN)/goimports
go generate . \
$(MYGOBIN)/goimports -w usage.go
$(MYGOBIN)/goimports:
go install golang.org/x/tools/cmd/goimports

103
cmd/gorepomod/README.md Normal file
View File

@@ -0,0 +1,103 @@
# gorepomod
Helps when you have a git repository with multiple Go modules.
It handles tasks one might otherwise attempt with
```
find ./ -name "go.mod" | xargs {some hack}
```
Run it from a git repository root.
It walks the repository, reads `go.mod` files, builds
a model of Go modules and intra-repo module
dependencies, then performs some operation.
Install:
```
go get sigs.k8s.io/kustomize/cmd/gorepomod
```
## Usage
_Commands that change things (everything but `list`)
do nothing but log commands
unless you add the `--doIt` flag,
allowing the change._
#### `gorepomod list`
Lists modules and intra-repo dependencies.
Use this to get module names for use in other commands.
#### `gorepomod tidy`
Creates a change with mechanical updates
to `go.mod` and `go.sum` files.
#### `gorepomod unpin {module}`
Creates a change to `go.mod` files.
For each module _m_ in the repository,
if _m_ depends on a _{module}_,
then _m_'s dependency on it will be replaced by
a relative path to the in-repo module.
#### `gorepomod pin {module} [{version}]`
Creates a change to `go.mod` files.
The opposite of `unpin`.
The change removes replacements and pins _m_ to a
specific, previously tagged and released version of _{module}_.
The argument _{version}_ defaults to recent version of _{module}_.
_{version}_ should be in semver form, e.g. `v1.2.3`.
#### `gorepomod release {module} [patch|minor|major]`
Computes a new version for the module, tags the repo
with that version, and pushes the tag to the remote.
The value of the 2nd argument, either `patch` (the default),
`minor` or `major`, determines the new version.
If the existing version is _v1.2.7_, then the new version will be:
- `patch` -> _v1.2.8_
- `minor` -> _v1.3.0_
- `major` -> _v2.0.0_
After establishing the the version, the command looks for a branch named
> _release-{module}/-v{major}.{minor}_
If the branch doesn't exist, the command creates it and pushes it to the remote.
The command then creates a new tag in the form
> _{module}/v{major}.{minor}.{patch}_
The command pushes this tag to the remote. This typically triggers
cloud activity to create release artifacts.
#### `gorepomod unrelease {module}`
This undoes the work of `release`, by deleting the
most recent tag both locally and at the remote.
You can then fix whatever, and re-release.
This, however, must be done almost immediately.
If there's a chance someone (or some cloud robot) already
imported the module at the given tag, then don't do this,
because it will confuse module caches.
Do a new patch release instead.

5
cmd/gorepomod/go.mod Normal file
View File

@@ -0,0 +1,5 @@
module sigs.k8s.io/kustomize/cmd/gorepomod
go 1.15
require golang.org/x/mod v0.3.0

14
cmd/gorepomod/go.sum Normal file
View File

@@ -0,0 +1,14 @@
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/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.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/sync v0.0.0-20190423024810-112230192c58/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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -0,0 +1,195 @@
package arguments
import (
"fmt"
"os"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/utils"
)
const (
doItFlag = "--doIt"
cmdPin = "pin"
cmdUnPin = "unpin"
cmdTidy = "tidy"
cmdList = "list"
cmdRelease = "release"
cmdUnRelease = "unrelease"
cmdDebug = "debug"
)
var (
commands = []string{
cmdPin, cmdUnPin, cmdTidy, cmdList, cmdRelease, cmdUnRelease, cmdDebug}
// TODO: make this a PATH-like flag
// e.g.: --excludes ".git:.idea:site:docs"
excSlice = []string{
".git",
".github",
".idea",
"docs",
"examples",
"hack",
"site",
"releasing",
}
)
type Command int
const (
Tidy Command = iota
UnPin
Pin
List
Release
UnRelease
Debug
)
type Args struct {
cmd Command
moduleName misc.ModuleShortName
version semver.SemVer
bump semver.SvBump
doIt bool
}
func (a *Args) GetCommand() Command {
return a.cmd
}
func (a *Args) Bump() semver.SvBump {
return a.bump
}
func (a *Args) Version() semver.SemVer {
return a.version
}
func (a *Args) ModuleName() misc.ModuleShortName {
return a.moduleName
}
func (a *Args) Exclusions() (result []string) {
// Make sure the list has no repeats.
for k := range utils.SliceToSet(excSlice) {
result = append(result, k)
}
return
}
func (a *Args) DoIt() bool {
return a.doIt
}
type myArgs struct {
args []string
doIt bool
}
func (a *myArgs) next() (result string) {
if !a.more() {
panic("no args left")
}
result = a.args[0]
a.args = a.args[1:]
return
}
func (a *myArgs) more() bool {
return len(a.args) > 0
}
func newArgs() *myArgs {
result := &myArgs{}
for _, a := range os.Args[1:] {
if a == doItFlag {
result.doIt = true
} else {
result.args = append(result.args, a)
}
}
return result
}
func Parse() (result *Args, err error) {
result = &Args{}
clArgs := newArgs()
result.doIt = clArgs.doIt
result.moduleName = misc.ModuleUnknown
if !clArgs.more() {
return nil, fmt.Errorf("command needs at least one arg")
}
command := clArgs.next()
switch command {
case cmdPin:
if !clArgs.more() {
return nil, fmt.Errorf("pin needs a moduleName to pin")
}
result.moduleName = misc.ModuleShortName(clArgs.next())
if clArgs.more() {
result.version, err = semver.Parse(clArgs.next())
if err != nil {
return nil, err
}
} else {
result.version = semver.Zero()
}
result.cmd = Pin
case cmdUnPin:
if !clArgs.more() {
return nil, fmt.Errorf("unpin needs a moduleName to unpin")
}
result.moduleName = misc.ModuleShortName(clArgs.next())
result.cmd = UnPin
case cmdTidy:
result.cmd = Tidy
case cmdList:
result.cmd = List
case cmdRelease:
if !clArgs.more() {
return nil, fmt.Errorf("specify {module} to release")
}
result.moduleName = misc.ModuleShortName(clArgs.next())
bump := "patch"
if clArgs.more() {
bump = clArgs.next()
}
switch bump {
case "major":
result.bump = semver.Major
case "minor":
result.bump = semver.Minor
case "patch":
result.bump = semver.Patch
default:
return nil, fmt.Errorf(
"unknown bump %s; specify one of 'major', 'minor' or 'patch'", bump)
}
result.cmd = Release
case cmdUnRelease:
if !clArgs.more() {
return nil, fmt.Errorf("specify {module} to unrelease")
}
result.moduleName = misc.ModuleShortName(clArgs.next())
result.cmd = UnRelease
case cmdDebug:
if !clArgs.more() {
return nil, fmt.Errorf("specify {module} to debug")
}
result.moduleName = misc.ModuleShortName(clArgs.next())
result.cmd = Debug
default:
return nil, fmt.Errorf(
"unknown command %q; must be one of %v", command, commands)
}
if clArgs.more() {
return nil, fmt.Errorf("unknown extra args: %v", clArgs.args)
}
return
}

View File

@@ -0,0 +1,82 @@
package edit
import (
"fmt"
"os/exec"
"strings"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
)
// Editor runs `go mod` commands on an instance of Module.
// If doIt is false, the command is printed, but not run.
type Editor struct {
module misc.LaModule
doIt bool
}
func New(m misc.LaModule, doIt bool) *Editor {
return &Editor{
doIt: doIt,
module: m,
}
}
func (e *Editor) run(args ...string) error {
c := exec.Command(
"go",
append([]string{"mod"}, args...)...)
c.Dir = string(e.module.ShortName())
if e.doIt {
out, err := c.CombinedOutput()
if err != nil {
return fmt.Errorf("%s out=%q", err.Error(), out)
}
} else {
fmt.Printf("in %-60s; %s\n", c.Dir, c.String())
}
return nil
}
func upstairs(depth int) string {
var b strings.Builder
for i := 0; i < depth; i++ {
b.WriteString("../")
}
return b.String()
}
func (e *Editor) Tidy() error {
return e.run("tidy")
}
func (e *Editor) Pin(target misc.LaModule, oldV, newV semver.SemVer) error {
err := e.run(
"edit",
"-dropreplace="+target.ImportPath()+"@"+oldV.String(),
"-require="+target.ImportPath()+"@"+newV.String(),
)
if err != nil {
return err
}
return e.run("tidy")
}
func (e *Editor) UnPin(target misc.LaModule, oldV semver.SemVer) error {
var r strings.Builder
r.WriteString(target.ImportPath())
r.WriteString("@")
r.WriteString(oldV.String())
r.WriteString("=")
r.WriteString(upstairs(e.module.ShortName().Depth()))
r.WriteString(string(target.ShortName()))
err := e.run(
"edit",
"-replace="+r.String(),
)
if err != nil {
return err
}
return e.run("tidy")
}

View File

@@ -0,0 +1,32 @@
package edit
import (
"testing"
)
func TestUpstairs(t *testing.T) {
var testCases = map[string]struct {
depth int
expected string
}{
"zero": {
depth: 0,
expected: "",
},
"one": {
depth: 1,
expected: "../",
},
"five": {
depth: 5,
expected: "../../../../../",
},
}
for n, tc := range testCases {
if tc.expected != upstairs(tc.depth) {
t.Fatalf(
"%s: for depth %d, expected %q, got %q",
n, tc.depth, tc.expected, upstairs(tc.depth))
}
}
}

View File

@@ -0,0 +1,75 @@
package main
import (
"bufio"
"log"
"os"
"strings"
)
const (
inputFile = "README.md"
outputFile = "usage.go"
)
// Convert README.md to a usage function.
func main() {
inFile, err := os.Open(inputFile)
if err != nil {
log.Fatal(err)
}
defer inFile.Close()
scanner := bufio.NewScanner(inFile)
w := NewWriter(outputFile)
w.prLn("// Code generated by internal/gen/main.go; DO NOT EDIT.")
w.prLn("package main")
w.prLn("")
w.prLn("")
w.prLn("const (")
w.prLn(" usageMsg = `")
// Skip the first two lines.
scanner.Scan()
scanner.Scan()
for scanner.Scan() {
line := scanner.Text()
line = strings.Replace(line, "`", "'", -1)
line = strings.Replace(line, "\\[", "[", -1)
line = strings.Replace(line, "\\]", "]", -1)
w.prLn(line)
}
w.prLn("`")
w.prLn(")")
w.close()
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}
type writer struct {
f *os.File
}
func NewWriter(n string) *writer {
f, err := os.Create(n)
if err != nil {
log.Fatalf("unable to create `%s`; %v", n, err)
}
return &writer{f: f}
}
func (w *writer) prLn(line string) {
_, err := w.f.WriteString(line + "\n")
if err != nil {
log.Printf("Trouble writing: %s", line)
log.Fatal(err)
}
}
func (w *writer) close() {
if err := w.f.Close(); err != nil {
log.Fatal(err)
}
}

View File

@@ -0,0 +1,340 @@
package git
import (
"fmt"
"os/exec"
"sort"
"strings"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
)
const (
refsTags = "refs/tags/"
pathSep = "/"
remoteOrigin = misc.TrackedRepo("origin")
remoteUpstream = misc.TrackedRepo("upstream")
mainBranch = "master"
indent = " "
doing = " [x] "
faking = " [ ] "
)
type safetyLevel int
const (
// Commands that don't hurt, e.g. checking out an existing branch.
noHarmDone safetyLevel = iota
// Commands that write, and could be hard to undo.
undoPainful
)
type Verbosity int
const (
Low Verbosity = iota
High
)
var recognizedRemotes = []misc.TrackedRepo{remoteUpstream, remoteOrigin}
// Runner runs specific git tasks using the git CLI.
type Runner struct {
// From which directory do we run the commands.
workDir string
// Run commands, or merely print commands.
doIt bool
// Run commands, or merely print commands.
verbosity Verbosity
}
func NewLoud(wd string, doIt bool) *Runner {
return newRunner(wd, doIt, High)
}
func NewQuiet(wd string, doIt bool) *Runner {
return newRunner(wd, doIt, Low)
}
func newRunner(wd string, doIt bool, v Verbosity) *Runner {
return &Runner{workDir: wd, doIt: doIt, verbosity: v}
}
func (gr *Runner) comment(f string) {
if gr.verbosity == Low {
return
}
fmt.Print(indent)
fmt.Println(f)
}
func (gr *Runner) doing(s string) {
if gr.verbosity == Low {
return
}
fmt.Print(indent)
fmt.Print(doing)
fmt.Println(s)
}
func (gr *Runner) faking(s string) {
if gr.verbosity == Low {
return
}
fmt.Print(indent)
fmt.Print(faking)
fmt.Println(s)
}
func (gr *Runner) run(sl safetyLevel, args ...string) (string, error) {
c := exec.Command("git", args...)
c.Dir = gr.workDir
if gr.doIt || sl == noHarmDone {
gr.doing(c.String())
out, err := c.CombinedOutput()
if err != nil {
return "", fmt.Errorf(
"%s out=%q", err.Error(), strings.TrimSpace(string(out)))
}
return string(out), nil
}
gr.faking(c.String())
return "", nil
}
func (gr *Runner) runNoOut(s safetyLevel, args ...string) error {
_, err := gr.run(s, args...)
return err
}
// TODO: allow for other remote names.
func (gr *Runner) DetermineRemoteToUse() (misc.TrackedRepo, error) {
gr.comment("determining remote to use")
out, err := gr.run(noHarmDone, "remote")
if err != nil {
return "", err
}
remotes := strings.Split(out, "\n")
if len(remotes) < 1 {
return "", fmt.Errorf("need at least one remote")
}
for _, n := range recognizedRemotes {
if contains(remotes, n) {
return n, nil
}
}
return "", fmt.Errorf(
"unable to find recognized remote %v", recognizedRemotes)
}
func contains(list []string, item misc.TrackedRepo) bool {
for _, n := range list {
if n == string(item) {
return true
}
}
return false
}
func (gr *Runner) LoadLocalTags() (result misc.VersionMap, err error) {
gr.comment("loading local tags")
var out string
out, err = gr.run(noHarmDone, "tag", "-l")
if err != nil {
return nil, err
}
result = make(misc.VersionMap)
lines := strings.Split(out, "\n")
for _, l := range lines {
n, v, err := parseModuleSpec(l)
if err != nil {
// ignore it
continue
}
result[n] = append(result[n], v)
}
for _, versions := range result {
sort.Sort(versions)
}
return
}
func (gr *Runner) LoadRemoteTags(
remote misc.TrackedRepo) (result misc.VersionMap, err error) {
gr.comment("loading remote tags")
var out string
out, err = gr.run(noHarmDone, "ls-remote", "--ref", string(remote))
if err != nil {
return nil, err
}
result = make(misc.VersionMap)
lines := strings.Split(out, "\n")
for _, l := range lines {
fields := strings.Fields(l)
if len(fields) < 2 {
// ignore it
continue
}
if !strings.HasPrefix(fields[1], refsTags) {
// ignore it
continue
}
path := fields[1][len(refsTags):]
n, v, err := parseModuleSpec(path)
if err != nil {
// ignore it
continue
}
result[n] = append(result[n], v)
}
for _, versions := range result {
sort.Sort(versions)
}
return
}
func parseModuleSpec(
path string) (n misc.ModuleShortName, v semver.SemVer, err error) {
fields := strings.Split(path, pathSep)
v, err = semver.Parse(fields[len(fields)-1])
if err != nil {
// Silently ignore versions we don't understand.
return "", v, err
}
n = misc.ModuleAtTop
if len(fields) > 1 {
n = misc.ModuleShortName(
strings.Join(fields[:len(fields)-1], pathSep))
}
return
}
func (gr *Runner) Debug(remote misc.TrackedRepo) error {
return nil // gr.CheckoutMainBranch(remote)
}
func (gr *Runner) AssureCleanWorkspace() error {
gr.comment("assuring a clean workspace")
out, err := gr.run(noHarmDone, "status")
if err != nil {
return err
}
if !strings.Contains(out, "nothing to commit, working tree clean") {
return fmt.Errorf("the workspace isn't clean")
}
return nil
}
func (gr *Runner) AssureOnMainBranch() error {
gr.comment("assuring main branch checked out")
out, err := gr.run(noHarmDone, "status")
if err != nil {
return err
}
if !strings.Contains(out, "On branch "+mainBranch) {
return fmt.Errorf("expected to be on branch %q", mainBranch)
}
return nil
}
// CheckoutMainBranch does that.
func (gr *Runner) CheckoutMainBranch() error {
gr.comment("checking out main branch")
return gr.runNoOut(noHarmDone, "checkout", mainBranch)
}
// FetchRemote does that.
func (gr *Runner) FetchRemote(remote misc.TrackedRepo) error {
gr.comment("fetching remote")
return gr.runNoOut(noHarmDone, "fetch", string(remote))
}
// MergeFromRemoteMain does a fast forward only merge with main branch.
func (gr *Runner) MergeFromRemoteMain(remote misc.TrackedRepo) error {
remo := strings.Join(
[]string{string(remote), mainBranch}, pathSep)
gr.comment("merging from remote")
return gr.runNoOut(undoPainful, "merge", "--ff-only", remo)
}
// CheckoutReleaseBranch attempts to checkout or create a branch.
// If it's on the remote already, fail if we cannot check it out locally.
func (gr *Runner) CheckoutReleaseBranch(
remote misc.TrackedRepo, branch string) error {
yes, err := gr.doesRemoteBranchExist(remote, branch)
if err != nil {
return err
}
if yes {
gr.comment("checking out branch")
if out, err := gr.run(noHarmDone, "checkout", branch); err != nil {
fmt.Printf("error with checkout: %q", err.Error())
fmt.Printf("out: %q", out)
return fmt.Errorf(
"branch %q exists on remote %q, but isn't present locally",
branch, string(remote))
}
return nil
}
gr.comment("creating branch")
// The branch doesn't exist. Create it.
out, err := gr.run(noHarmDone, "checkout", "-b", branch)
if err != nil {
return err
}
if !strings.Contains(out, "Switched to a new branch ") {
return fmt.Errorf("unexpected branch creation output: %q", out)
}
return nil
}
func (gr *Runner) doesRemoteBranchExist(
remote misc.TrackedRepo, branch string) (bool, error) {
gr.comment("looking for branch on remote")
out, err := gr.run(noHarmDone, "branch", "-r")
if err != nil {
return false, err
}
lookFor := strings.Join([]string{string(remote), branch}, pathSep)
lines := strings.Split(out, "\n")
for _, l := range lines {
if strings.TrimSpace(l) == lookFor {
return true, nil
}
}
return false, nil
}
func (gr *Runner) PushBranchToRemote(
remote misc.TrackedRepo, branch string) error {
gr.comment("pushing branch to remote")
return gr.runNoOut(undoPainful, "push", "-f", string(remote), branch)
}
func (gr *Runner) CreateLocalReleaseTag(tag, branch string) error {
msg := fmt.Sprintf("\"Release %s on branch %s\"", tag, branch)
gr.comment("creating local release tag")
return gr.runNoOut(
undoPainful,
"tag", "-a",
"-m", msg,
tag)
}
func (gr *Runner) DeleteLocalTag(tag string) error {
gr.comment("deleting local tag")
return gr.runNoOut(undoPainful, "tag", "--delete", tag)
}
func (gr *Runner) PushTagToRemote(
remote misc.TrackedRepo, tag string) error {
gr.comment("pushing tag to remote")
return gr.runNoOut(undoPainful, "push", string(remote), tag)
}
func (gr *Runner) DeleteTagFromRemote(
remote misc.TrackedRepo, tag string) error {
gr.comment("deleting tags from remote")
return gr.runNoOut(undoPainful, "push", string(remote), ":"+refsTags+tag)
}

View File

@@ -0,0 +1,126 @@
package misc
import (
"fmt"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
)
// ModFunc is a function accepting a module, and returning an error.
type ModFunc func(LaModule) error
type LaRepository interface {
// RepoPath is the import of the of repository,
// e.g. github.com/kubernetes-sigs/kustomize
// The directory {srcRoot}/{importPath} should contain a
// dotGit directory.
// This directory might be a Go module, or contain directories
// that are Go modules, or both.
RepoPath() string
// AbsPath is the full local filesystem path.
AbsPath() string
// FindModule returns a module or nil.
FindModule(ModuleShortName) LaModule
}
type LaModule interface {
// ShortName is the module's name without the repo.
ShortName() ModuleShortName
// ImportPath is the relative path below the Go src root,
// which is the same path as would be used to
// import the module.
ImportPath() string
// AbsPath is the absolute path to the module's
// go.mod file on the local file system.
AbsPath() string
// Latest version tagged locally.
VersionLocal() semver.SemVer
// Latest version tagged remotely.
VersionRemote() semver.SemVer
// Does this module depend on the argument, and
// if so at what version?
DependsOn(LaModule) (bool, semver.SemVer)
// GetReplacements returns a list of replacements.
GetReplacements() []string
}
// VersionMap holds the versions associated with modules.
type VersionMap map[ModuleShortName]semver.Versions
func (m VersionMap) Report() {
for n, versions := range m {
fmt.Println(n)
for _, v := range versions {
fmt.Print(" ")
fmt.Println(v)
}
}
}
func (m VersionMap) Latest(
n ModuleShortName) semver.SemVer {
versions := m[n]
if versions == nil {
return semver.Zero()
}
return versions[0]
}
type LesModules []LaModule
func (s LesModules) LenLongestName() (ans int) {
for _, m := range s {
l := len(m.ShortName())
if l > ans {
ans = l
}
}
return
}
func (s LesModules) Apply(f ModFunc) error {
for _, m := range s {
err := f(m)
if err != nil {
return err
}
}
return nil
}
func (s LesModules) Find(target ModuleShortName) LaModule {
for _, m := range s {
if m.ShortName() == target {
return m
}
}
return nil
}
func (s LesModules) GetAllThatDependOn(
target LaModule) (result TaggedModules) {
for _, m := range s {
if yes, v := m.DependsOn(target); yes {
result = append(result, TaggedModule{M: m, V: v})
}
}
return
}
func (s LesModules) InternalDeps(
target LaModule) (result TaggedModules) {
for _, m := range s {
if yes, v := target.DependsOn(m); yes {
result = append(result, TaggedModule{M: m, V: v})
}
}
return
}

View File

@@ -0,0 +1,23 @@
package misc
import (
"path/filepath"
"strings"
)
// ModuleShortName is the in-repo path to the directory holding the module
// (holding the go.mod file). It's the unique in-repo name of the module.
// It's the name used to tag the repo at a particular module version.
// E.g. "" (empty), "kyaml", "cmd/config", "plugin/example/whatever".
type ModuleShortName string
// Never used in a tag.
const ModuleAtTop = ModuleShortName("{top}")
const ModuleUnknown = ModuleShortName("{unknown}")
func (m ModuleShortName) Depth() int {
if m == ModuleAtTop || m == ModuleUnknown {
return 0
}
return strings.Count(string(m), string(filepath.Separator)) + 1
}

View File

@@ -0,0 +1,36 @@
package misc_test
import (
"testing"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
)
func TestDepth(t *testing.T) {
var testCases = map[string]struct {
path string
expectedDepth int
}{
"zero": {
path: "{top}",
expectedDepth: 0,
},
"one": {
path: "one",
expectedDepth: 1,
},
"three": {
path: "one/two/three",
expectedDepth: 3,
},
}
for n, tc := range testCases {
m := misc.ModuleShortName(tc.path)
d := m.Depth()
if d != tc.expectedDepth {
t.Fatalf(
"%s: %s, expected %d, got %d",
n, tc.path, tc.expectedDepth, d)
}
}
}

View File

@@ -0,0 +1,42 @@
package misc
import (
"fmt"
"strings"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
)
// TaggedModule is a module known to be tagged with the given version.
type TaggedModule struct {
M LaModule
V semver.SemVer
}
func (p TaggedModule) String() string {
if p.V.IsZero() {
return string(p.M.ShortName())
}
return string(p.M.ShortName()) + "/" + p.V.String()
}
type TaggedModules []TaggedModule
func (s TaggedModules) String() string {
// format := "%-"+strconv.Itoa(s.LenLongestString()+2)+"s"
var b strings.Builder
for i := range s {
b.WriteString(fmt.Sprintf("%-15s", s[i]))
}
return b.String()
}
func (s TaggedModules) LenLongestString() (ans int) {
for _, m := range s {
l := len(m.String())
if l > ans {
ans = l
}
}
return
}

View File

@@ -0,0 +1,4 @@
package misc
// TrackedRepo identifies a git remote repository.
type TrackedRepo string

View File

@@ -0,0 +1,79 @@
package mod
import (
"fmt"
"path/filepath"
"golang.org/x/mod/modfile"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
)
// Module is an immutable representation of a Go module.
type Module struct {
repo misc.LaRepository
shortName misc.ModuleShortName
mf *modfile.File
vLocal semver.SemVer
vRemote semver.SemVer
}
func New(
repo misc.LaRepository,
shortName misc.ModuleShortName,
mf *modfile.File,
vl semver.SemVer,
vr semver.SemVer) *Module {
return &Module{
repo: repo,
shortName: shortName,
mf: mf,
vLocal: vl,
vRemote: vr,
}
}
func (m *Module) GitRepo() misc.LaRepository {
return m.repo
}
func (m *Module) VersionLocal() semver.SemVer {
return m.vLocal
}
func (m *Module) VersionRemote() semver.SemVer {
return m.vRemote
}
func (m *Module) ShortName() misc.ModuleShortName {
return m.shortName
}
func (m *Module) ImportPath() string {
return filepath.Join(m.repo.RepoPath(), string(m.ShortName()))
}
func (m *Module) AbsPath() string {
return filepath.Join(m.repo.AbsPath(), string(m.ShortName()))
}
func (m *Module) DependsOn(target misc.LaModule) (bool, semver.SemVer) {
for _, r := range m.mf.Require {
if r.Mod.Path == target.ImportPath() {
v, err := semver.Parse(r.Mod.Version)
if err != nil {
panic(err)
}
return true, v
}
}
return false, semver.Zero()
}
func (m *Module) GetReplacements() (result []string) {
for _, r := range m.mf.Replace {
result = append(
result, fmt.Sprintf("%s => %s", r.Old.String(), r.New.String()))
}
return
}

View File

@@ -0,0 +1 @@
package mod_test

View File

@@ -0,0 +1,134 @@
package repo
import (
"fmt"
"path/filepath"
"strings"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/git"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/utils"
)
const (
dotGitFileName = ".git"
srcHint = "/src/"
goModFile = "go.mod"
)
// DotGitData holds basic information about a local .git file
type DotGitData struct {
// srcPath is the absolute path to the local Go src directory.
// This used to be $GOPATH/src.
// It's the directory containing git repository clones.
srcPath string
// The path below srcPath to a particular repository
// directory, a directory containing a .git directory.
// Typically {repoOrg}/{repoUserName}, e.g. sigs.k8s.io/cli-utils
repoPath string
}
func (dg *DotGitData) SrcPath() string {
return dg.srcPath
}
func (dg *DotGitData) RepoPath() string {
return dg.repoPath
}
func (dg *DotGitData) AbsPath() string {
return filepath.Join(dg.srcPath, dg.repoPath)
}
// NewDotGitDataFromPath wants the incoming path to hold dotGit
// E.g.
// ~/gopath/src/sigs.k8s.io/kustomize
// ~/gopath/src/github.com/monopole/gorepomod
func NewDotGitDataFromPath(path string) (*DotGitData, error) {
if !utils.DirExists(filepath.Join(path, dotGitFileName)) {
return nil, fmt.Errorf(
"%q doesn't have a %q file", path, dotGitFileName)
}
// This is an attempt to figure out where the user has cloned
// their repos. In the old days, it was an import path under
// $GOPATH/src. If we cannot guess it, we may need to ask for it,
// or maybe proceed without knowing it.
index := strings.Index(path, srcHint)
if index < 0 {
return nil, fmt.Errorf(
"path %q doesn't contain %q", path, srcHint)
}
return &DotGitData{
srcPath: path[:index+len(srcHint)-1],
repoPath: path[index+len(srcHint):],
}, nil
}
// It's a factory factory.
func (dg *DotGitData) NewRepoFactory(
exclusions []string) (*ManagerFactory, error) {
modules, err := loadProtoModules(dg.AbsPath(), exclusions)
if err != nil {
return nil, err
}
err = dg.checkModules(modules)
if err != nil {
return nil, err
}
runner := git.NewQuiet(dg.AbsPath(), true)
remoteName, err := runner.DetermineRemoteToUse()
if err != nil {
return nil, err
}
// Some tags might exist for modules that
// have been renamed or deleted; ignore those.
// There might be newer tags locally than remote,
// so report both.
localTags, err := runner.LoadLocalTags()
if err != nil {
return nil, err
}
remoteTags, err := runner.LoadRemoteTags(remoteName)
if err != nil {
return nil, err
}
return &ManagerFactory{
dg: dg,
modules: modules,
remoteName: remoteName,
versionMapLocal: localTags,
versionMapRemote: remoteTags,
}, nil
}
func (dg *DotGitData) checkModules(modules []*protoModule) error {
for _, pm := range modules {
file := filepath.Join(pm.PathToGoMod(), goModFile)
// Do the paths make sense?
if !strings.HasPrefix(pm.FullPath(), dg.RepoPath()) {
return fmt.Errorf(
"module %q doesn't start with the repository name %q",
pm.FullPath(), dg.RepoPath())
}
shortName := pm.ShortName(dg.RepoPath())
if shortName == misc.ModuleAtTop {
if pm.PathToGoMod() != dg.AbsPath() {
return fmt.Errorf("in %q, problem with top module", file)
}
} else {
// Do the relative path and short name make sense?
if !strings.HasSuffix(pm.PathToGoMod(), string(shortName)) {
return fmt.Errorf(
"in %q, the module name %q doesn't match the file's pathToGoMod %q",
file, shortName, pm.PathToGoMod())
}
}
}
return nil
}

View File

@@ -0,0 +1,6 @@
package repo
import "testing"
func TestLoadTags(t *testing.T) {
}

View File

@@ -0,0 +1,194 @@
package repo
import (
"fmt"
"strconv"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/edit"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/git"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/semver"
)
// Manager manages a git repo.
// All data already loaded and validated, it's ready to go.
type Manager struct {
// Underlying file system facts.
dg *DotGitData
// The remote used for fetching tags, pushing tags,
// and pushing release branches.
remoteName misc.TrackedRepo
// The list of known Go modules in the repo.
modules misc.LesModules
}
func (mgr *Manager) AbsPath() string {
return mgr.dg.AbsPath()
}
func (mgr *Manager) RepoPath() string {
return mgr.dg.RepoPath()
}
func (mgr *Manager) FindModule(
target misc.ModuleShortName) misc.LaModule {
return mgr.modules.Find(target)
}
func (mgr *Manager) Tidy(doIt bool) error {
return mgr.modules.Apply(func(m misc.LaModule) error {
return edit.New(m, doIt).Tidy()
})
}
func (mgr *Manager) Pin(
doIt bool, target misc.LaModule, newV semver.SemVer) error {
return mgr.modules.Apply(func(m misc.LaModule) error {
if yes, oldVersion := m.DependsOn(target); yes {
return edit.New(m, doIt).Pin(target, oldVersion, newV)
}
return nil
})
}
func (mgr *Manager) UnPin(doIt bool, target misc.LaModule) error {
return mgr.modules.Apply(func(m misc.LaModule) error {
if yes, oldVersion := m.DependsOn(target); yes {
return edit.New(m, doIt).UnPin(target, oldVersion)
}
return nil
})
}
func hasUnPinnedDeps(m misc.LaModule) string {
if len(m.GetReplacements()) > 0 {
return "yes"
}
return ""
}
func (mgr *Manager) List() error {
fmt.Printf(" src path: %s\n", mgr.dg.SrcPath())
fmt.Printf(" repo path: %s\n", mgr.RepoPath())
fmt.Printf(" remote: %s\n", mgr.remoteName)
format := "%-" +
strconv.Itoa(mgr.modules.LenLongestName()+2) +
"s%-11s%-11s%17s %s\n"
fmt.Printf(
format, "NAME", "LOCAL", "REMOTE",
"HAS-UNPINNED-DEPS", "INTRA-REPO-DEPENDENCIES")
return mgr.modules.Apply(func(m misc.LaModule) error {
fmt.Printf(
format, m.ShortName(),
m.VersionLocal().Pretty(),
m.VersionRemote().Pretty(),
hasUnPinnedDeps(m),
mgr.modules.InternalDeps(m))
return nil
})
}
func determineBranchAndTag(
m misc.LaModule, v semver.SemVer) (string, string) {
if m.ShortName() == misc.ModuleAtTop {
return fmt.Sprintf("release-%s", v.BranchLabel()), v.String()
}
return fmt.Sprintf(
"release-%s-%s", m.ShortName(), v.BranchLabel()),
string(m.ShortName()) + "/" + v.String()
}
func (mgr *Manager) Debug(_ misc.LaModule, doIt bool) error {
gr := git.NewLoud(mgr.AbsPath(), doIt)
return gr.Debug(mgr.remoteName)
}
// Release supports a gitlab flow style release process.
//
// * All development happens in the branch named "master".
// * Each minor release gets its own branch.
// *
func (mgr *Manager) Release(
target misc.LaModule, bump semver.SvBump, doIt bool) error {
if reps := target.GetReplacements(); len(reps) > 0 {
return fmt.Errorf(
"to release %q, first pin these replacements: %v",
target.ShortName(), reps)
}
newVersion := target.VersionLocal().Bump(bump)
if newVersion.Equals(target.VersionRemote()) {
return fmt.Errorf(
"version %s already exists on remote - delete it first", newVersion)
}
if newVersion.LessThan(target.VersionRemote()) {
fmt.Printf(
"version %s is less than the most recent remote version (%s)",
newVersion, target.VersionRemote())
}
gr := git.NewLoud(mgr.AbsPath(), doIt)
relBranch, relTag := determineBranchAndTag(target, newVersion)
fmt.Printf(
"Releasing %s, stepping from %s to %s\n",
target.ShortName(), target.VersionLocal(), newVersion)
if err := gr.AssureCleanWorkspace(); err != nil {
return err
}
if err := gr.FetchRemote(mgr.remoteName); err != nil {
return err
}
if err := gr.CheckoutMainBranch(); err != nil {
return err
}
if err := gr.MergeFromRemoteMain(mgr.remoteName); err != nil {
return err
}
if err := gr.AssureCleanWorkspace(); err != nil {
return err
}
if err := gr.CheckoutReleaseBranch(mgr.remoteName, relBranch); err != nil {
return err
}
if err := gr.MergeFromRemoteMain(mgr.remoteName); err != nil {
return err
}
if err := gr.PushBranchToRemote(mgr.remoteName, relBranch); err != nil {
return err
}
if err := gr.CreateLocalReleaseTag(relTag, relBranch); err != nil {
return err
}
if err := gr.PushTagToRemote(mgr.remoteName, relTag); err != nil {
return err
}
if err := gr.CheckoutMainBranch(); err != nil {
return err
}
return nil
}
func (mgr *Manager) UnRelease(target misc.LaModule, doIt bool) error {
fmt.Printf(
"Unreleasing %s/%s\n",
target.ShortName(), target.VersionRemote())
_, tag := determineBranchAndTag(target, target.VersionRemote())
gr := git.NewLoud(mgr.AbsPath(), doIt)
if err := gr.DeleteTagFromRemote(mgr.remoteName, tag); err != nil {
return err
}
if err := gr.DeleteLocalTag(tag); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,35 @@
package repo
import (
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/mod"
)
// ManagerFactory is a collection of clean data needed to build
// clean, fully wired up instances of Manager.
type ManagerFactory struct {
dg *DotGitData
modules []*protoModule
remoteName misc.TrackedRepo
versionMapLocal misc.VersionMap
versionMapRemote misc.VersionMap
}
func (mf *ManagerFactory) NewRepoManager() *Manager {
result := &Manager{
dg: mf.dg,
remoteName: mf.remoteName,
}
var modules misc.LesModules
for _, pm := range mf.modules {
shortName := pm.ShortName(mf.dg.RepoPath())
modules = append(
modules,
mod.New(
result, shortName, pm.mf,
mf.versionMapLocal.Latest(shortName),
mf.versionMapRemote.Latest(shortName)))
}
result.modules = modules
return result
}

View File

@@ -0,0 +1,101 @@
package repo
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"golang.org/x/mod/modfile"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/utils"
)
const (
dotDir = "."
)
// protoModule holds parts being collected to represent a module.
type protoModule struct {
pathToGoMod string
mf *modfile.File
}
func (pm *protoModule) FullPath() string {
return pm.mf.Module.Mod.Path
}
func (pm *protoModule) PathToGoMod() string {
return pm.pathToGoMod
}
// Represents the trailing version label in a module name.
// See https://blog.golang.org/v2-go-modules
var trailingVersionPattern = regexp.MustCompile("/v\\d+$")
func (pm *protoModule) ShortName(
repoImportPath string) misc.ModuleShortName {
fp := pm.FullPath()
if fp == repoImportPath {
return misc.ModuleAtTop
}
p := fp[len(repoImportPath)+1:]
stripped := trailingVersionPattern.ReplaceAllString(p, "")
return misc.ModuleShortName(stripped)
}
func loadProtoModules(
repoRoot string, exclusions []string) (result []*protoModule, err error) {
var paths []string
paths, err = getPathsToModules(repoRoot, exclusions)
if err != nil {
return
}
for _, p := range paths {
var pm *protoModule
pm, err = loadProtoModule(p)
if err != nil {
return
}
result = append(result, pm)
}
return
}
func loadProtoModule(path string) (*protoModule, error) {
mPath := filepath.Join(path, goModFile)
content, err := ioutil.ReadFile(mPath)
if err != nil {
return nil, fmt.Errorf("error reading %q: %v\n", mPath, err)
}
f, err := modfile.Parse(mPath, content, nil)
if err != nil {
return nil, err
}
return &protoModule{pathToGoMod: path, mf: f}, nil
}
func getPathsToModules(
repoRoot string, exclusions []string) (result []string, err error) {
exclusionMap := utils.SliceToSet(exclusions)
err = filepath.Walk(
repoRoot,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("trouble at pathToGoMod %q: %v\n", path, err)
}
if info.IsDir() {
if _, ok := exclusionMap[info.Name()]; ok {
return filepath.SkipDir
}
return nil
}
if info.Name() == goModFile {
result = append(result, path[:len(path)-len(goModFile)-1])
return filepath.SkipDir
}
return nil
})
return
}

View File

@@ -0,0 +1,47 @@
package repo
import (
"testing"
"golang.org/x/mod/modfile"
"golang.org/x/mod/module"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
)
func TestShortName(t *testing.T) {
var testCases = map[string]struct {
name misc.ModuleShortName
modFile *modfile.File
}{
"one": {
name: misc.ModuleShortName("garage"),
modFile: &modfile.File{
Module: &modfile.Module{
Mod: module.Version{
Path: "gh.com/micheal/garage",
Version: "v2.3.4",
},
},
},
},
"three": {
name: misc.ModuleShortName("fruit/yellow/banana"),
modFile: &modfile.File{
Module: &modfile.Module{
Mod: module.Version{
Path: "gh.com/micheal/fruit/yellow/banana",
Version: "v2.3.4",
},
},
},
},
}
for n, tc := range testCases {
m := protoModule{pathToGoMod: "irrelevant", mf: tc.modFile}
actual := m.ShortName("gh.com/micheal")
if actual != tc.name {
t.Errorf(
"%s: expected %s, got %s", n, tc.name, actual)
}
}
}

View File

@@ -0,0 +1,98 @@
package semver
import (
"fmt"
"strconv"
"strings"
)
// SemVer is the immutable semantic version per https://semver.org
type SemVer struct {
major int
minor int
patch int
}
func New(major, minor, patch int) SemVer {
return SemVer{
major: major,
minor: minor,
patch: patch,
}
}
var zero = New(0, 0, 0)
func Zero() SemVer {
return zero
}
// Versions implements sort.Interface to get decreasing order.
type Versions []SemVer
func (v Versions) Len() int { return len(v) }
func (v Versions) Less(i, j int) bool { return v[j].LessThan(v[i]) }
func (v Versions) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
func Parse(raw string) (SemVer, error) {
if len(raw) < 6 {
// e.g. minimal length is 6, e.g. "v1.2.3"
return zero, fmt.Errorf("%q too short to be a version", raw)
}
if raw[0] != 'v' {
return zero, fmt.Errorf("%q must start with letter 'v'", raw)
}
fields := strings.Split(raw[1:], ".")
if len(fields) < 3 {
return zero, fmt.Errorf("%q doesn't have the form v1.2.3", raw)
}
n := make([]int, 3)
for i := 0; i < 3; i++ {
var err error
n[i], err = strconv.Atoi(fields[i])
if err != nil {
return zero, err
}
}
return New(n[0], n[1], n[2]), nil
}
func (v SemVer) Bump(b SvBump) SemVer {
switch b {
case Major:
return New(v.major+1, 0, 0)
case Minor:
return New(v.major, v.minor+1, 0)
default:
return New(v.major, v.minor, v.patch+1)
}
}
func (v SemVer) BranchLabel() string {
return fmt.Sprintf("v%d.%d", v.major, v.minor)
}
func (v SemVer) String() string {
return fmt.Sprintf("v%d.%d.%d", v.major, v.minor, v.patch)
}
func (v SemVer) Pretty() string {
if v.IsZero() {
return ""
}
return v.String()
}
func (v SemVer) Equals(o SemVer) bool {
return v.major == o.major && v.minor == o.minor && v.patch == o.patch
}
func (v SemVer) LessThan(o SemVer) bool {
return v.major < o.major ||
(v.major == o.major && v.minor < o.minor) ||
(v.major == o.major && v.minor == o.minor && v.patch < o.patch)
}
func (v SemVer) IsZero() bool {
return v.Equals(zero)
}

View File

@@ -0,0 +1,105 @@
package semver
import (
"testing"
)
func TestParse(t *testing.T) {
var testCases = map[string]struct {
raw string
v SemVer
errMsg string
}{
"one": {
raw: "v1.2.3",
v: SemVer{major: 1, minor: 2, patch: 3},
errMsg: "",
},
"two": {
raw: "v2.0.9999",
v: SemVer{major: 2, minor: 0, patch: 9999},
errMsg: "",
},
"three": {
raw: "pizza",
v: zero,
errMsg: "\"pizza\" too short to be a version",
},
"non-digit": {
raw: "v1.x.222",
v: zero,
errMsg: "strconv.Atoi: parsing \"x\": invalid syntax",
},
"bad fields": {
raw: "v1.222",
v: zero,
errMsg: "\"v1.222\" doesn't have the form v1.2.3",
},
}
for n, tc := range testCases {
v, err := Parse(tc.raw)
if err == nil {
if tc.errMsg != "" {
t.Errorf(
"%s: no error, but expected err %q", n, tc.errMsg)
}
if !v.Equals(tc.v) {
t.Errorf(
"%s: expected %v, got %v", n, tc.v, v)
}
} else {
if tc.errMsg == "" {
t.Errorf(
"%s: unexpected error %v", n, err)
} else {
if tc.errMsg != err.Error() {
t.Errorf(
"%s: expected err msg %q, but got %q",
n, tc.errMsg, err.Error())
}
}
}
}
}
func TestLessThan(t *testing.T) {
var testCases = map[string]struct {
v1 SemVer
v2 SemVer
expected bool
}{
"one": {
v1: SemVer{major: 2, minor: 2, patch: 3},
v2: SemVer{major: 1, minor: 2, patch: 3},
expected: false,
},
"two": {
v1: SemVer{major: 1, minor: 3, patch: 3},
v2: SemVer{major: 1, minor: 2, patch: 3},
expected: false,
},
"three": {
v1: SemVer{major: 1, minor: 2, patch: 4},
v2: SemVer{major: 1, minor: 2, patch: 3},
expected: false,
},
"eq": {
v1: SemVer{major: 2, minor: 2, patch: 3},
v2: SemVer{major: 2, minor: 2, patch: 3},
expected: false,
},
"four": {
v1: zero,
v2: SemVer{major: 0, minor: 0, patch: 1},
expected: true,
},
}
for n, tc := range testCases {
actual := tc.v1.LessThan(tc.v2)
if actual != tc.expected {
t.Errorf(
"%s: expected %v, got %v for %s LessThan %s",
n, tc.expected, actual, tc.v1.String(), tc.v2.String())
}
}
}

View File

@@ -0,0 +1,17 @@
package semver
type SvBump int
const (
Patch SvBump = iota
Minor
Major
)
func (b SvBump) String() string {
return map[SvBump]string{
Patch: "Patch",
Minor: "Minor",
Major: "Major",
}[b]
}

View File

@@ -0,0 +1,26 @@
package utils
import (
"log"
"os"
)
func DirExists(name string) bool {
info, err := os.Stat(name)
if os.IsNotExist(err) {
return false
}
return info.IsDir()
}
func SliceToSet(slice []string) map[string]bool {
result := make(map[string]bool)
for _, x := range slice {
if _, ok := result[x]; ok {
log.Fatalf("programmer error - repeated value: %s", x)
} else {
result[x] = true
}
}
return result
}

84
cmd/gorepomod/main.go Normal file
View File

@@ -0,0 +1,84 @@
package main
import (
"fmt"
"os"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/arguments"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/repo"
)
//go:generate go run internal/gen/main.go
func loadRepoManager(args *arguments.Args) (*repo.Manager, error) {
path, err := os.Getwd()
if err != nil {
return nil, err
}
dg, err := repo.NewDotGitDataFromPath(path)
if err != nil {
return nil, err
}
pr, err := dg.NewRepoFactory(args.Exclusions())
if err != nil {
return nil, err
}
return pr.NewRepoManager(), nil
}
func actualMain() error {
args, err := arguments.Parse()
if err != nil {
return err
}
mgr, err := loadRepoManager(args)
if err != nil {
return err
}
var targetModule misc.LaModule = nil
if args.ModuleName() != misc.ModuleUnknown {
targetModule = mgr.FindModule(args.ModuleName())
if targetModule == nil {
return fmt.Errorf(
"cannot find module %q in repo %s",
args.ModuleName(), mgr.RepoPath())
}
}
switch args.GetCommand() {
case arguments.List:
return mgr.List()
case arguments.Tidy:
return mgr.Tidy(args.DoIt())
case arguments.Pin:
v := args.Version()
if v.IsZero() {
v = targetModule.VersionLocal()
}
return mgr.Pin(args.DoIt(), targetModule, v)
case arguments.UnPin:
return mgr.UnPin(args.DoIt(), targetModule)
case arguments.Release:
return mgr.Release(targetModule, args.Bump(), args.DoIt())
case arguments.UnRelease:
return mgr.UnRelease(targetModule, args.DoIt())
case arguments.Debug:
return mgr.Debug(targetModule, args.DoIt())
default:
return fmt.Errorf("cannot handle cmd %v", args.GetCommand())
}
}
func main() {
if len(os.Args) < 2 {
fmt.Print(usageMsg)
return
}
if err := actualMain(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

109
cmd/gorepomod/usage.go Normal file
View File

@@ -0,0 +1,109 @@
// Code generated by internal/gen/main.go; DO NOT EDIT.
package main
const (
usageMsg = `
Helps when you have a git repository with multiple Go modules.
It handles tasks one might otherwise attempt with
'''
find ./ -name "go.mod" | xargs {some hack}
'''
Run it from a git repository root.
It walks the repository, reads 'go.mod' files, builds
a model of Go modules and intra-repo module
dependencies, then performs some operation.
Install:
'''
go get github.com/monopole/gorepomod
'''
## Usage
_Commands that change things (everything but 'list')
do nothing but log commands
unless you add the '--doIt' flag,
allowing the change._
#### 'gorepomod list'
Lists modules and intra-repo dependencies.
Use this to get module names for use in other commands.
#### 'gorepomod tidy'
Creates a change with mechanical updates
to 'go.mod' and 'go.sum' files.
#### 'gorepomod unpin {module}'
Creates a change to 'go.mod' files.
For each module _m_ in the repository,
if _m_ depends on a _{module}_,
then _m_'s dependency on it will be replaced by
a relative path to the in-repo module.
#### 'gorepomod pin {module} [{version}]'
Creates a change to 'go.mod' files.
The opposite of 'unpin'.
The change removes replacements and pins _m_ to a
specific, previously tagged and released version of _{module}_.
The argument _{version}_ defaults to recent version of _{module}_.
_{version}_ should be in semver form, e.g. 'v1.2.3'.
#### 'gorepomod release {module} [patch|minor|major]'
Computes a new version for the module, tags the repo
with that version, and pushes the tag to the remote.
The value of the 2nd argument, either 'patch' (the default),
'minor' or 'major', determines the new version.
If the existing version is _v1.2.7_, then the new version will be:
- 'patch' -> _v1.2.8_
- 'minor' -> _v1.3.0_
- 'major' -> _v2.0.0_
After establishing the the version, the command looks for a branch named
> _release-{module}/-v{major}.{minor}_
If the branch doesn't exist, the command creates it and pushes it to the remote.
The command then creates a new tag in the form
> _{module}/v{major}.{minor}.{patch}_
The command pushes this tag to the remote. This typically triggers
cloud activity to create release artifacts.
#### 'gorepomod unrelease {module}'
This undoes the work of 'release', by deleting the
most recent tag both locally and at the remote.
You can then fix whatever, and re-release.
This, however, must be done almost immediately.
If there's a chance someone (or some cloud robot) already
imported the module at the given tag, then don't do this,
because it will confuse module caches.
Do a new patch release instead.
`
)

7
cmd/pluginator/go.mod Normal file
View File

@@ -0,0 +1,7 @@
module sigs.k8s.io/kustomize/pluginator/v2
go 1.14
require sigs.k8s.io/kustomize/api v0.6.3
replace sigs.k8s.io/kustomize/api v0.6.3 => ../../api

View File

@@ -16,8 +16,10 @@ github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmU
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
@@ -67,6 +69,7 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM=
@@ -86,11 +89,13 @@ github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
@@ -105,6 +110,7 @@ github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsd
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw=
github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
@@ -115,6 +121,7 @@ github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dp
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
@@ -221,6 +228,7 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@@ -258,6 +266,7 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
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 v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
@@ -306,6 +315,7 @@ github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRci
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
@@ -370,6 +380,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -399,6 +410,7 @@ golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -453,6 +465,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71 h1:Xe2gvTZUJpsvOWUnvmL/tmhVBZUmHSvLbMjRj6NUUKo=
gopkg.in/yaml.v3 v3.0.0-20200121175148-a6ecf24a6d71/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -469,7 +482,8 @@ k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.8.0/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/kustomize/kyaml v0.9.2 h1:QNP1Lg4V2wOgBeUim9Kmz1+2GqHtRyfoVEUQH0omrCI=
sigs.k8s.io/kustomize/kyaml v0.9.2/go.mod h1:UTm64bSWVdBUA8EQoYCxVOaBQxUdIOr5LKWxA4GNbkw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

8
cmd/prchecker/go.mod Normal file
View File

@@ -0,0 +1,8 @@
module sigs.k8s.io/kustomize/cmd/prchecker
go 1.15
require (
github.com/google/go-github v17.0.0+incompatible
github.com/google/go-querystring v1.0.0 // indirect
)

4
cmd/prchecker/go.sum Normal file
View File

@@ -0,0 +1,4 @@
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=

119
cmd/prchecker/main.go Normal file
View File

@@ -0,0 +1,119 @@
// prchecker examines pull requests
//
// - When a PR includes files from multiple modules that we'd rather not
// modify at the same time (in an effort to have more self-contained
// release notes), the script will exit with a non-zero exit code.
//
// Usage:
//
// go run . \
// -owner=kubernetes-sigs \
// -repo=kustomize \
// -pr=2997 \
// cmd/config api kustomize kyaml
package main
import (
"context"
"flag"
"fmt"
"os"
"strings"
"github.com/google/go-github/github"
)
func main() {
owner := flag.String("owner", "", "the github repository owner name")
repo := flag.String("repo", "", "the github repository name")
pullrequest := flag.Int("pr", -1, "the pull request number")
flag.Parse()
// Treat all following arguments as restricted directories
restrictedPaths := flag.Args()
// Short circuit check if restricted paths is less than 2
// Conflicts won't exist in this scenario so we don't need to call the API
if len(restrictedPaths) <= 1 {
fmt.Println("Check not run. Add at least two restricted paths and run again.")
os.Exit(0)
}
client := github.NewClient(nil)
files, err := ListAllPullRequestFiles(client, owner, pullrequest, repo)
if err != nil {
fmt.Println("Unable to retrieve pull request details:", err.Error())
os.Exit(2)
}
contributedRestrictedPaths := CountRestrictedPathUses(files, restrictedPaths)
modifiedRestrictedDirectories := CountModifiedRestrictedDirectories(contributedRestrictedPaths)
// Exit with error if two or more restricted directories where modified
if modifiedRestrictedDirectories > 1 {
fmt.Println("Modifications to multiple restricted directories occurred.")
os.Exit(1)
}
}
// ListAllPullRequestFiles retrieves as many files as possible for the
// target pull request.
//
// Note: GitHub API limits ListFiles to a maximum of 3000 files. Very large
// changes which exceed this limit may pass this check even if they
// do contain spanning changes.
// see: https://developer.github.com/v3/pulls/#list-pull-requests-files
func ListAllPullRequestFiles(client *github.Client, owner *string, pullrequest *int, repo *string) ([]*github.CommitFile, error) {
// foundFiles across all pages from github api
var foundFiles []*github.CommitFile
// GitHub returns the first 30 files by default, increase this value
// Note: Page 1 is the first page of results. Page 0 is an end of list mark.
// Github only returns (max) 100 results per page and PR's may exceed this
// so loop until all pages have been enumerated.
options := &github.ListOptions{PerPage: 100, Page: 1}
for options.Page != 0 {
files, response, err := client.PullRequests.ListFiles(context.Background(), *owner, *repo, *pullrequest, options)
// If an error has occurred while querying api exit early, report error
if err != nil {
return nil, err
}
foundFiles = append(foundFiles, files...)
// setup next page to continue loop
options = &github.ListOptions{PerPage: 100, Page: response.NextPage}
}
return foundFiles, nil
}
// CountModifiedRestrictedDirectories Accepts a map of paths and the number of
// occurances and returns the count of the paths which had a non-zero value.
func CountModifiedRestrictedDirectories(contributedRestrictedPaths map[string]int) int {
modifiedRestrictedDirectories := 0
for _, occurance := range contributedRestrictedPaths {
if occurance != 0 {
modifiedRestrictedDirectories++
}
}
return modifiedRestrictedDirectories
}
// CountRestrictedPathUses Constructs a map that contains the number of
// references keyed to each restricted path. This provides details about how
// many files in the list are associated with each restricted path.
func CountRestrictedPathUses(files []*github.CommitFile, restrictedPaths []string) map[string]int {
contributedRestrictedPaths := make(map[string]int)
for _, path := range restrictedPaths {
contributedRestrictedPaths[path] = 0
}
for _, file := range files {
for path := range contributedRestrictedPaths {
if strings.HasPrefix(*file.Filename, path) {
contributedRestrictedPaths[path]++
}
}
}
return contributedRestrictedPaths
}

Some files were not shown because too many files have changed in this diff Show More