mirror of
https://github.com/taigrr/yq
synced 2025-01-18 04:53:17 -08:00
Compare commits
607 Commits
0.1
...
4.0.0-alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e1ce4ca70 | ||
|
|
9bd9468526 | ||
|
|
75044e480c | ||
|
|
36084a60a9 | ||
|
|
9b48cf80e0 | ||
|
|
bb3b08e648 | ||
|
|
dcacad1e7e | ||
|
|
3356061e1e | ||
|
|
2c062bc2a5 | ||
|
|
088ec36acd | ||
|
|
83cb6421df | ||
|
|
a57944d123 | ||
|
|
79867473d5 | ||
|
|
b3efcdc202 | ||
|
|
af2aa9ad91 | ||
|
|
db4762ef7c | ||
|
|
860655b4cd | ||
|
|
d91b25840a | ||
|
|
019acfe456 | ||
|
|
af39fc737d | ||
|
|
f8a700e400 | ||
|
|
708ff02e8d | ||
|
|
2edf64182b | ||
|
|
b290a65602 | ||
|
|
05520c2168 | ||
|
|
5ab584afac | ||
|
|
b1f139c965 | ||
|
|
0cb2ff5b2e | ||
|
|
d6ff198d63 | ||
|
|
e515b8c2db | ||
|
|
b63b9644aa | ||
|
|
461c3e719c | ||
|
|
643f2467ee | ||
|
|
4edb3e9021 | ||
|
|
41c08891d3 | ||
|
|
85d059340b | ||
|
|
badd476730 | ||
|
|
65e6e492cd | ||
|
|
6a698332dd | ||
|
|
49615f5581 | ||
|
|
4f574efdc4 | ||
|
|
73cf6224f2 | ||
|
|
4bc98776a6 | ||
|
|
1910563bfe | ||
|
|
2ddf8dd4ed | ||
|
|
49b810cedd | ||
|
|
391ab8d70c | ||
|
|
b026ebf2c3 | ||
|
|
5e544a5b7e | ||
|
|
60511f5f92 | ||
|
|
59296b7d12 | ||
|
|
fccd03036f | ||
|
|
6829d8cb78 | ||
|
|
449fb8952c | ||
|
|
afffb2c3ba | ||
|
|
829ca3b424 | ||
|
|
d19e9f6917 | ||
|
|
6a0a4efa7b | ||
|
|
288aec942c | ||
|
|
7c4cf72468 | ||
|
|
b025000f20 | ||
|
|
1ba1e90e58 | ||
|
|
e0d1aed5b9 | ||
|
|
e6fd6905eb | ||
|
|
0a2a3c4374 | ||
|
|
ac076cd34a | ||
|
|
8170eec6d1 | ||
|
|
23083ed974 | ||
|
|
93aaa8ccee | ||
|
|
d7716551cf | ||
|
|
c791e5c663 | ||
|
|
a6d4dbb8b8 | ||
|
|
c7ebdda530 | ||
|
|
a0d940638c | ||
|
|
c09513803a | ||
|
|
f95226e267 | ||
|
|
f479a7e8e3 | ||
|
|
f7d4695837 | ||
|
|
5ee52f9506 | ||
|
|
c2159d9861 | ||
|
|
95bc1e1599 | ||
|
|
e037c57725 | ||
|
|
e32bc43c4e | ||
|
|
a8bdc12d83 | ||
|
|
ae59ad57f4 | ||
|
|
c321600afa | ||
|
|
4c95efa469 | ||
|
|
996ee0b433 | ||
|
|
bb9cb0c60e | ||
|
|
a125495eec | ||
|
|
7fa2835e13 | ||
|
|
e0f5cb3c59 | ||
|
|
87550b7fe5 | ||
|
|
5554301c29 | ||
|
|
3b0aaac626 | ||
|
|
65cb472604 | ||
|
|
fbba38c9b7 | ||
|
|
e5948c4f16 | ||
|
|
4eaadf98d0 | ||
|
|
eedbb0a99f | ||
|
|
7dabc57b65 | ||
|
|
fcd3a90f67 | ||
|
|
88e99e5336 | ||
|
|
a8cfccd3af | ||
|
|
3355e80d85 | ||
|
|
f528b28938 | ||
|
|
5b7b390a33 | ||
|
|
4f12e09e78 | ||
|
|
ee732fbf0b | ||
|
|
1507f929a2 | ||
|
|
c11c3df84f | ||
|
|
06bb3ac826 | ||
|
|
778f8c6916 | ||
|
|
9f43a4a265 | ||
|
|
bb6f07d147 | ||
|
|
759456e375 | ||
|
|
5e59803037 | ||
|
|
a0cb691601 | ||
|
|
fea8510061 | ||
|
|
b380ea2892 | ||
|
|
d66a709213 | ||
|
|
2fc39b3865 | ||
|
|
ee07edbd88 | ||
|
|
b11661a1be | ||
|
|
eac218980e | ||
|
|
80e7f46538 | ||
|
|
086f0ec6b9 | ||
|
|
89cbe63343 | ||
|
|
07cd3d4b8b | ||
|
|
b7b6988e76 | ||
|
|
9de2039c31 | ||
|
|
767709fef5 | ||
|
|
d9ae8e1e5a | ||
|
|
b0fa0e5b86 | ||
|
|
6777d639c0 | ||
|
|
de8dcff803 | ||
|
|
765ada4dc6 | ||
|
|
1405584892 | ||
|
|
8c9c326342 | ||
|
|
e90b00957b | ||
|
|
71f5f76213 | ||
|
|
b9e304e7a4 | ||
|
|
d473c39a44 | ||
|
|
9624410add | ||
|
|
b55fe48bd8 | ||
|
|
721dd57ed4 | ||
|
|
6fc3566acd | ||
|
|
4b63d92a3c | ||
|
|
3ccd32a47e | ||
|
|
3f913afbb9 | ||
|
|
ff598e1933 | ||
|
|
23de61a8d7 | ||
|
|
64135a16e1 | ||
|
|
06d8715cbe | ||
|
|
e15633023f | ||
|
|
6f0a329331 | ||
|
|
55511de9af | ||
|
|
2db69c91c9 | ||
|
|
33e35d10dd | ||
|
|
dfdbbbb24a | ||
|
|
55c4d01a91 | ||
|
|
7dc3d62bb6 | ||
|
|
11116804c5 | ||
|
|
f68b24323e | ||
|
|
8f166a9848 | ||
|
|
3c36db9285 | ||
|
|
605d6fab9b | ||
|
|
1f9a3f5f6c | ||
|
|
a06320f13c | ||
|
|
279996533d | ||
|
|
efe942727d | ||
|
|
e4dc70cc84 | ||
|
|
8ade1275e2 | ||
|
|
e1e05d85e3 | ||
|
|
b99467432e | ||
|
|
6b07143af7 | ||
|
|
ed234e37ce | ||
|
|
c0e4917d52 | ||
|
|
2713893f87 | ||
|
|
6bb221e973 | ||
|
|
7eb01a81da | ||
|
|
5c117204fa | ||
|
|
a4fa8f1341 | ||
|
|
69caccd2d3 | ||
|
|
67fb924e0e | ||
|
|
b64187fe32 | ||
|
|
8e6ceba2ac | ||
|
|
6ef04e1e77 | ||
|
|
10029420a5 | ||
|
|
f91093d5fe | ||
|
|
090432d241 | ||
|
|
22d5bd3615 | ||
|
|
0d477841da | ||
|
|
1f72817d74 | ||
|
|
125d04a75b | ||
|
|
08f6a90603 | ||
|
|
da398765b8 | ||
|
|
d356fa0d0b | ||
|
|
d22bfc241b | ||
|
|
954affea23 | ||
|
|
b0d1afb601 | ||
|
|
b286636909 | ||
|
|
bdf47c9797 | ||
|
|
1cc20d52bb | ||
|
|
651d9edf88 | ||
|
|
903605df39 | ||
|
|
0f9facc84b | ||
|
|
5af86b1333 | ||
|
|
2bd2a85a4c | ||
|
|
ceb76e5c17 | ||
|
|
44322f0248 | ||
|
|
0347516d82 | ||
|
|
a46386e093 | ||
|
|
f5c3beb159 | ||
|
|
9864afc4e7 | ||
|
|
69fae2d9cb | ||
|
|
83c13ce392 | ||
|
|
d83c46eec2 | ||
|
|
65802f9e0e | ||
|
|
07309e1685 | ||
|
|
24e906bae6 | ||
|
|
f084f2bb23 | ||
|
|
96a4161a92 | ||
|
|
5cc01e43bc | ||
|
|
9de2573009 | ||
|
|
29521f2e3e | ||
|
|
af5724ba29 | ||
|
|
0a39d29c53 | ||
|
|
72cd3e4a2a | ||
|
|
d40ad9649d | ||
|
|
63313ebb02 | ||
|
|
de3bfaef60 | ||
|
|
108b5cb093 | ||
|
|
b116f40348 | ||
|
|
ea9df0eede | ||
|
|
b7dd3e8e0a | ||
|
|
dc13fa99f7 | ||
|
|
179049a535 | ||
|
|
2fa8b24272 | ||
|
|
f1dbe13f21 | ||
|
|
02258fbaae | ||
|
|
6f0538173b | ||
|
|
6840ea8c78 | ||
|
|
70b88fa778 | ||
|
|
bfc1a621c4 | ||
|
|
166f866f28 | ||
|
|
b3598aaa43 | ||
|
|
14ac791eaf | ||
|
|
25293a6894 | ||
|
|
d828b214cc | ||
|
|
9e47685271 | ||
|
|
699fce9da4 | ||
|
|
f52de57652 | ||
|
|
b7554e6e76 | ||
|
|
ec25511f1b | ||
|
|
c6a52012ab | ||
|
|
63ded205e8 | ||
|
|
d1c1ab0a75 | ||
|
|
6ec8386f9e | ||
|
|
4dbe3636c2 | ||
|
|
4a5bd0ff5b | ||
|
|
44f36833cf | ||
|
|
789ea02096 | ||
|
|
7c27491dd6 | ||
|
|
720cc8f798 | ||
|
|
abda0e38af | ||
|
|
5cd4c347b0 | ||
|
|
1a4d8158ba | ||
|
|
8a65822b0b | ||
|
|
b7148adf20 | ||
|
|
64d38e9f03 | ||
|
|
3a387e65be | ||
|
|
56ba7c9a43 | ||
|
|
d203ec7b56 | ||
|
|
e2f79a3dae | ||
|
|
2d7be26ad5 | ||
|
|
350a8343e9 | ||
|
|
a3f8f9df10 | ||
|
|
35fd5b7ae4 | ||
|
|
2d237e7e8e | ||
|
|
74c7a4e027 | ||
|
|
f18c5161e0 | ||
|
|
eeeeeffd7b | ||
|
|
96955ffa9c | ||
|
|
9361b8b3e9 | ||
|
|
24dcb56466 | ||
|
|
728cbe991a | ||
|
|
854f5f0fc9 | ||
|
|
feba7b04fa | ||
|
|
0621307391 | ||
|
|
924eb6c462 | ||
|
|
52eef67e37 | ||
|
|
38d35185bc | ||
|
|
d8c29b26c1 | ||
|
|
e3f4eedd51 | ||
|
|
690da9ee74 | ||
|
|
1f7f1b0def | ||
|
|
1aa5ec1d40 | ||
|
|
a065a47b37 | ||
|
|
625cfdac75 | ||
|
|
4dbdd4a805 | ||
|
|
8a6af1720d | ||
|
|
0652f67a91 | ||
|
|
df52383ffb | ||
|
|
707ad09ba5 | ||
|
|
cf389bed4a | ||
|
|
ff5b23251b | ||
|
|
9925b26b9d | ||
|
|
93dbe80a77 | ||
|
|
27604289f4 | ||
|
|
3f36a18791 | ||
|
|
1e541cd65f | ||
|
|
5204a13685 | ||
|
|
3d3eaf3034 | ||
|
|
4fb44dbc47 | ||
|
|
784513dd18 | ||
|
|
865a55645c | ||
|
|
949bf1c1d7 | ||
|
|
19fe718cfb | ||
|
|
290579ac7f | ||
|
|
d7392f7b58 | ||
|
|
a3cebec2fd | ||
|
|
b81fd638d7 | ||
|
|
2344638da4 | ||
|
|
8be006fba4 | ||
|
|
53a4a47ce3 | ||
|
|
5988d0cffa | ||
|
|
b7640946ac | ||
|
|
d061b2f9f9 | ||
|
|
8c0046a622 | ||
|
|
586ffb833b | ||
|
|
9771e7001c | ||
|
|
8da9a81702 | ||
|
|
d97f1d8be2 | ||
|
|
dad61ec615 | ||
|
|
676fc63219 | ||
|
|
972e2b9575 | ||
|
|
aad15ccc6e | ||
|
|
5fc13bdccd | ||
|
|
95fec2984e | ||
|
|
64d1e58f97 | ||
|
|
4b3fbb878f | ||
|
|
26a09e6ec0 | ||
|
|
ceafed30f9 | ||
|
|
b8b2c9de61 | ||
|
|
f5fdf98c38 | ||
|
|
29986db8f8 | ||
|
|
1f4e3a9cde | ||
|
|
b6da773dde | ||
|
|
8020d4253b | ||
|
|
3c701fe98e | ||
|
|
97d1aa2b26 | ||
|
|
d05391e244 | ||
|
|
d1cec1ad18 | ||
|
|
fe5842e5f9 | ||
|
|
e0d8cd6bf6 | ||
|
|
8f5ffe47ff | ||
|
|
5acc1e661e | ||
|
|
a9c0ef571c | ||
|
|
7a28531f2f | ||
|
|
5de2bea1b4 | ||
|
|
7320b8d3c9 | ||
|
|
2f70e6f27a | ||
|
|
a9e871ee00 | ||
|
|
bc4bab9380 | ||
|
|
665d9079fa | ||
|
|
7b54a44fcf | ||
|
|
94148e4398 | ||
|
|
f8553162ca | ||
|
|
be532bf2fe | ||
|
|
e9b8265ca3 | ||
|
|
0f8b864321 | ||
|
|
e5bcfedbe9 | ||
|
|
a5f5fb2562 | ||
|
|
84de9c078d | ||
|
|
c7f5261036 | ||
|
|
6e35356a84 | ||
|
|
b2fe3e6738 | ||
|
|
774badfef4 | ||
|
|
c4e9516aa6 | ||
|
|
323089eb64 | ||
|
|
53289366a5 | ||
|
|
cda9a82906 | ||
|
|
2dbde6b9fb | ||
|
|
f8c1c3c1b4 | ||
|
|
238a1241d2 | ||
|
|
8a61ef072a | ||
|
|
4f178d2317 | ||
|
|
133e55105c | ||
|
|
5e5468af3b | ||
|
|
9b4972e46e | ||
|
|
23543ee031 | ||
|
|
75c7d40c44 | ||
|
|
44b8a5e80f | ||
|
|
77c8f22a79 | ||
|
|
386a0ca3c3 | ||
|
|
53a20d4421 | ||
|
|
478208b7c4 | ||
|
|
1159d0a212 | ||
|
|
8861b392a8 | ||
|
|
16bde80334 | ||
|
|
8a3fb32f36 | ||
|
|
48dcc15281 | ||
|
|
d7040e3933 | ||
|
|
ef579d4ccf | ||
|
|
785ee68a76 | ||
|
|
90fe9c6512 | ||
|
|
a9ade5a832 | ||
|
|
8d6e3a6a75 | ||
|
|
7a6689eb40 | ||
|
|
e6660e2460 | ||
|
|
28169b04f7 | ||
|
|
742cf748ac | ||
|
|
54c06cdb4c | ||
|
|
ef5f745da3 | ||
|
|
25025f2771 | ||
|
|
ebb8b34b31 | ||
|
|
9a5e4ee828 | ||
|
|
0a2dd29940 | ||
|
|
50dfce86c9 | ||
|
|
e55006e935 | ||
|
|
d8fed62f03 | ||
|
|
52a39bf31e | ||
|
|
d84254c30f | ||
|
|
18bb4eee96 | ||
|
|
86b9fe3ef9 | ||
|
|
2c15048ddb | ||
|
|
ce2ee42f71 | ||
|
|
c2c49dcb17 | ||
|
|
60de18391c | ||
|
|
c86f8b426b | ||
|
|
b3532e0a61 | ||
|
|
b3b60665e4 | ||
|
|
df08b055cf | ||
|
|
e822313e82 | ||
|
|
a9f25c9d76 | ||
|
|
0a8c268dcc | ||
|
|
a0e70279a8 | ||
|
|
25c9c22d8d | ||
|
|
d46d555b07 | ||
|
|
fb87f638f2 | ||
|
|
facc81d1f4 | ||
|
|
c1f9065c68 | ||
|
|
be84cc3082 | ||
|
|
a2571da1a1 | ||
|
|
6d6e476ac8 | ||
|
|
ae0c042ae6 | ||
|
|
867ec92d3a | ||
|
|
113586b5e0 | ||
|
|
c38f19e0a9 | ||
|
|
8ca85b1c64 | ||
|
|
08870f8ec9 | ||
|
|
94b217984c | ||
|
|
2f5a481cc3 | ||
|
|
1a4064429d | ||
|
|
1b22e1d812 | ||
|
|
297522cbdd | ||
|
|
be991fdacd | ||
|
|
be08214773 | ||
|
|
9e971ebeae | ||
|
|
f340db5795 | ||
|
|
ab852ceafa | ||
|
|
06a843e9b2 | ||
|
|
ebdc092688 | ||
|
|
27089d1ca1 | ||
|
|
1853585d22 | ||
|
|
0124d26086 | ||
|
|
0d68bea3dc | ||
|
|
54603b3607 | ||
|
|
c86aeca325 | ||
|
|
a4f124f24f | ||
|
|
090b377fa5 | ||
|
|
3a4d62d820 | ||
|
|
6053c8c136 | ||
|
|
c5a45ba7d5 | ||
|
|
56a0771cd1 | ||
|
|
8072e66d46 | ||
|
|
26153b3eb5 | ||
|
|
f2e10f21c7 | ||
|
|
d3ecf7aa88 | ||
|
|
ee8ffd458a | ||
|
|
8f15dba812 | ||
|
|
92ce195424 | ||
|
|
e725a2cec5 | ||
|
|
37de7a3505 | ||
|
|
e96794a420 | ||
|
|
120ef8e4dc | ||
|
|
db1954da25 | ||
|
|
e552dbb6ab | ||
|
|
298126864f | ||
|
|
d30cd8cc75 | ||
|
|
e6ee86930b | ||
|
|
0ea3c71df7 | ||
|
|
ef99bedf45 | ||
|
|
6e1a5aef2c | ||
|
|
70bd860287 | ||
|
|
0abda0098c | ||
|
|
a409a7e82b | ||
|
|
0e4f9e8579 | ||
|
|
0c932ba7dc | ||
|
|
cb48ba7173 | ||
|
|
dc4f8a6adb | ||
|
|
1f6d7a50b2 | ||
|
|
6fc3bdf58f | ||
|
|
87b33e8603 | ||
|
|
cc7eb84388 | ||
|
|
9e3f8ebd0a | ||
|
|
28bcbd321f | ||
|
|
9dd4503b23 | ||
|
|
185d1faadb | ||
|
|
7b004cb456 | ||
|
|
54c73eb34f | ||
|
|
3b03a0852a | ||
|
|
a00e6c5316 | ||
|
|
9d1a5b17b8 | ||
|
|
c5f80a105d | ||
|
|
c17f8df8f8 | ||
|
|
66c8390d54 | ||
|
|
dda9b1f087 | ||
|
|
683de28c64 | ||
|
|
51fa1a87b7 | ||
|
|
b9ac6a3d9d | ||
|
|
499974c27e | ||
|
|
72bd88cfa5 | ||
|
|
6980be3800 | ||
|
|
2933ea1684 | ||
|
|
cf2f23d747 | ||
|
|
45e9ad870f | ||
|
|
53b2c64747 | ||
|
|
359ca5a117 | ||
|
|
79baa49eaa | ||
|
|
2cda78ce0b | ||
|
|
6d1e61c410 | ||
|
|
86639acf70 | ||
|
|
3beee3f804 | ||
|
|
1ed8e7017e | ||
|
|
5514d2300b | ||
|
|
5bb0934710 | ||
|
|
cdd78af4bc | ||
|
|
d07e436065 | ||
|
|
b2a0964de2 | ||
|
|
69e6bb354d | ||
|
|
ec25886528 | ||
|
|
c2000a446b | ||
|
|
08ba0083be | ||
|
|
909b62be54 | ||
|
|
0facf35d60 | ||
|
|
a7c4813703 | ||
|
|
373e0a5eb7 | ||
|
|
124c57f9d9 | ||
|
|
fb73a793bd | ||
|
|
c22394b540 | ||
|
|
b1ff47022b | ||
|
|
82f1230db8 | ||
|
|
a3190f1504 | ||
|
|
44ee869e47 | ||
|
|
5d2d37a5f8 | ||
|
|
e3fc944709 | ||
|
|
6ee9db9a70 | ||
|
|
0d75edfb67 | ||
|
|
037314af8a | ||
|
|
2a283b4ef7 | ||
|
|
7ef556f22b | ||
|
|
6b566fd983 | ||
|
|
001925a4d4 | ||
|
|
3dee7b89d2 | ||
|
|
c955815aab | ||
|
|
3720bf8211 | ||
|
|
5f09aabf4c | ||
|
|
98751cf607 | ||
|
|
2ec3b59da2 | ||
|
|
56c923228d | ||
|
|
c122b9a843 | ||
|
|
15f51d4bf0 | ||
|
|
219105f999 | ||
|
|
955ecc2547 | ||
|
|
1d5fbd5ad0 | ||
|
|
1605938c2c | ||
|
|
2780903b60 | ||
|
|
81672d4efe | ||
|
|
6a696c81db | ||
|
|
805729e4f7 | ||
|
|
7db31006da | ||
|
|
8409be1cdf | ||
|
|
c03c4813d4 | ||
|
|
5ee6a9b9ca | ||
|
|
8efc46deae | ||
|
|
e4d5769f29 | ||
|
|
fea6e0db3d | ||
|
|
6823d43325 | ||
|
|
da4b1a6449 | ||
|
|
3a90629822 | ||
|
|
8aa69fc9ba | ||
|
|
690442d02e | ||
|
|
d1c545cca0 | ||
|
|
c4af37ed68 | ||
|
|
01845ea923 | ||
|
|
58bdb3ed21 | ||
|
|
0cb8a47ccb | ||
|
|
35ceb01222 | ||
|
|
c1b803364a | ||
|
|
364c1a8af3 | ||
|
|
2a0290aeac | ||
|
|
4ea8d5c4ee | ||
|
|
eeb16443d4 | ||
|
|
eebd319246 | ||
|
|
5a3c3a7152 |
1
.dockerignore
Normal file
1
.dockerignore
Normal file
@@ -0,0 +1 @@
|
||||
bin
|
||||
48
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
48
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
version of yq:
|
||||
operating system:
|
||||
|
||||
**Input Yaml**
|
||||
Concise yaml document(s) (as simple as possible to show the bug)
|
||||
data1.yml:
|
||||
```yaml
|
||||
this: should really work
|
||||
```
|
||||
|
||||
data2.yml:
|
||||
```yaml
|
||||
but: it strangely didn't
|
||||
```
|
||||
|
||||
**Command**
|
||||
The command you ran:
|
||||
```
|
||||
yq merge data1.yml data2.yml
|
||||
```
|
||||
|
||||
**Actual behavior**
|
||||
|
||||
```yaml
|
||||
cat: meow
|
||||
```
|
||||
|
||||
**Expected behavior**
|
||||
|
||||
```yaml
|
||||
this: should really work
|
||||
but: it strangely didn't
|
||||
```
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
36
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
36
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**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**
|
||||
If we have data1.yml like:
|
||||
|
||||
```yaml
|
||||
country: Australia
|
||||
```
|
||||
|
||||
And we run a command:
|
||||
|
||||
```bash
|
||||
yq predictWeather data1.yml
|
||||
```
|
||||
|
||||
it could output
|
||||
|
||||
```yaml
|
||||
temp: 32
|
||||
```
|
||||
|
||||
**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.
|
||||
34
.github/workflows/go.yml
vendored
Normal file
34
.github/workflows/go.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: Build
|
||||
on: [push]
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.15
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.15
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
go get -v -t -d ./...
|
||||
if [ -f Gopkg.toml ]; then
|
||||
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||
dep ensure
|
||||
fi
|
||||
|
||||
- name: Download deps
|
||||
run: |
|
||||
export PATH=${PATH}:`go env GOPATH`/bin
|
||||
scripts/devtools.sh
|
||||
- name: Build
|
||||
run: |
|
||||
export PATH=${PATH}:`go env GOPATH`/bin
|
||||
make local build
|
||||
15
.gitignore
vendored
15
.gitignore
vendored
@@ -6,7 +6,9 @@
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
bin
|
||||
build
|
||||
build-done
|
||||
.DS_Store
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
@@ -20,8 +22,19 @@ _cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
coverage.out
|
||||
coverage.html
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
yaml
|
||||
vendor/
|
||||
tmp/
|
||||
cover/
|
||||
yq
|
||||
|
||||
# snapcraft
|
||||
parts/
|
||||
prime/
|
||||
.snapcraft/
|
||||
yq*.snap
|
||||
|
||||
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at mikefarah@gmail.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
8
CONTRIBUTING.md
Normal file
8
CONTRIBUTING.md
Normal file
@@ -0,0 +1,8 @@
|
||||
1. Install (golang)[https://golang.org/]
|
||||
1. Run `scripts/devtools.sh` to install the required devtools
|
||||
2. Run `make [local] vendor` to install the vendor dependencies
|
||||
2. Run `make [local] test` to ensure you can run the existing tests
|
||||
3. Write unit tests - (see existing examples). Changes will not be accepted without corresponding unit tests.
|
||||
4. Make the code changes.
|
||||
5. `make [local] test` to lint code and run tests
|
||||
6. Profit! ok no profit, but raise a PR and get kudos :)
|
||||
25
Dockerfile
Normal file
25
Dockerfile
Normal file
@@ -0,0 +1,25 @@
|
||||
FROM golang:1.15 as builder
|
||||
|
||||
WORKDIR /go/src/mikefarah/yq
|
||||
|
||||
# cache devtools
|
||||
COPY ./scripts/devtools.sh /go/src/mikefarah/yq/scripts/devtools.sh
|
||||
RUN ./scripts/devtools.sh
|
||||
|
||||
COPY . /go/src/mikefarah/yq
|
||||
|
||||
RUN CGO_ENABLED=0 make local build
|
||||
|
||||
# Choose alpine as a base image to make this useful for CI, as many
|
||||
# CI tools expect an interactive shell inside the container
|
||||
FROM alpine:3.12 as production
|
||||
|
||||
COPY --from=builder /go/src/mikefarah/yq/yq /usr/bin/yq
|
||||
RUN chmod +x /usr/bin/yq
|
||||
|
||||
ARG VERSION=none
|
||||
LABEL version=${VERSION}
|
||||
|
||||
WORKDIR /workdir
|
||||
|
||||
ENTRYPOINT [/usr/bin/yq]
|
||||
30
Dockerfile.dev
Normal file
30
Dockerfile.dev
Normal file
@@ -0,0 +1,30 @@
|
||||
FROM golang:1.15
|
||||
|
||||
COPY scripts/devtools.sh /opt/devtools.sh
|
||||
|
||||
RUN set -e -x \
|
||||
&& /opt/devtools.sh
|
||||
|
||||
# install mkdocs
|
||||
RUN set -ex \
|
||||
&& buildDeps=' \
|
||||
build-essential \
|
||||
python3-dev \
|
||||
' \
|
||||
&& apt-get update && apt-get install -y --no-install-recommends \
|
||||
$buildDeps \
|
||||
python3 \
|
||||
python3-setuptools \
|
||||
python3-wheel \
|
||||
python3-pip \
|
||||
&& pip3 install --upgrade \
|
||||
pip \
|
||||
'Markdown>=2.6.9' \
|
||||
'mkdocs>=0.16.3' \
|
||||
'mkdocs-material>=1.10.1' \
|
||||
'markdown-include>=0.5.1' \
|
||||
&& apt-get purge -y --auto-remove $buildDeps \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV CGO_ENABLED 0
|
||||
ENV GOPATH /go:/yq
|
||||
19
LICENSE
Normal file
19
LICENSE
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2017 Mike Farah
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
114
Makefile
Normal file
114
Makefile
Normal file
@@ -0,0 +1,114 @@
|
||||
MAKEFLAGS += --warn-undefined-variables
|
||||
SHELL := /bin/bash
|
||||
.SHELLFLAGS := -o pipefail -euc
|
||||
.DEFAULT_GOAL := install
|
||||
|
||||
include Makefile.variables
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo 'Management commands for cicdtest:'
|
||||
@echo
|
||||
@echo 'Usage:'
|
||||
@echo ' ## Develop / Test Commands'
|
||||
@echo ' make build Build yq binary.'
|
||||
@echo ' make install Install yq.'
|
||||
@echo ' make xcompile Build cross-compiled binaries of yq.'
|
||||
@echo ' make vendor Install dependencies to vendor directory.'
|
||||
@echo ' make format Run code formatter.'
|
||||
@echo ' make check Run static code analysis (lint).'
|
||||
@echo ' make test Run tests on project.'
|
||||
@echo ' make cover Run tests and capture code coverage metrics on project.'
|
||||
@echo ' make clean Clean the directory tree of produced artifacts.'
|
||||
@echo
|
||||
@echo ' ## Utility Commands'
|
||||
@echo ' make setup Configures Minishfit/Docker directory mounts.'
|
||||
@echo
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -rf bin build cover *.out
|
||||
|
||||
## prefix before other make targets to run in your local dev environment
|
||||
local: | quiet
|
||||
@$(eval DOCKRUN= )
|
||||
@mkdir -p tmp
|
||||
@touch tmp/dev_image_id
|
||||
quiet: # this is silly but shuts up 'Nothing to be done for `local`'
|
||||
@:
|
||||
|
||||
prepare: tmp/dev_image_id
|
||||
tmp/dev_image_id: Dockerfile.dev scripts/devtools.sh
|
||||
@mkdir -p tmp
|
||||
@docker rmi -f ${DEV_IMAGE} > /dev/null 2>&1 || true
|
||||
@docker build -t ${DEV_IMAGE} -f Dockerfile.dev .
|
||||
@docker inspect -f "{{ .ID }}" ${DEV_IMAGE} > tmp/dev_image_id
|
||||
|
||||
# ----------------------------------------------
|
||||
# build
|
||||
.PHONY: build
|
||||
build: build/dev
|
||||
|
||||
.PHONY: build/dev
|
||||
build/dev: test *.go
|
||||
@mkdir -p bin/
|
||||
${DOCKRUN} go build --ldflags "$(LDFLAGS)"
|
||||
${DOCKRUN} bash ./scripts/acceptance.sh
|
||||
|
||||
## Compile the project for multiple OS and Architectures.
|
||||
xcompile: check
|
||||
@rm -rf build/
|
||||
@mkdir -p build
|
||||
${DOCKRUN} bash ./scripts/xcompile.sh
|
||||
@find build -type d -exec chmod 755 {} \; || :
|
||||
@find build -type f -exec chmod 755 {} \; || :
|
||||
|
||||
.PHONY: install
|
||||
install: build
|
||||
${DOCKRUN} go install
|
||||
|
||||
# Each of the fetch should be an entry within vendor.json; not currently included within project
|
||||
.PHONY: vendor
|
||||
vendor: tmp/dev_image_id
|
||||
${DOCKRUN} go mod vendor
|
||||
|
||||
# ----------------------------------------------
|
||||
# develop and test
|
||||
|
||||
.PHONY: format
|
||||
format: vendor
|
||||
${DOCKRUN} bash ./scripts/format.sh
|
||||
|
||||
.PHONY: check
|
||||
check: format
|
||||
${DOCKRUN} bash ./scripts/check.sh
|
||||
|
||||
.PHONY: test
|
||||
test: check
|
||||
${DOCKRUN} bash ./scripts/test.sh
|
||||
|
||||
.PHONY: cover
|
||||
cover: check
|
||||
@rm -rf cover/
|
||||
@mkdir -p cover
|
||||
${DOCKRUN} bash ./scripts/coverage.sh
|
||||
@find cover -type d -exec chmod 755 {} \; || :
|
||||
@find cover -type f -exec chmod 644 {} \; || :
|
||||
|
||||
.PHONY: build-docs
|
||||
build-docs: prepare mkdocs.yml mkdocs/*
|
||||
${DOCKRUN} mkdocs build
|
||||
@find docs -type d -exec chmod 755 {} \; || :
|
||||
@find docs -type f -exec chmod 644 {} \; || :
|
||||
|
||||
.PHONY: release
|
||||
release: xcompile
|
||||
${DOCKRUN} bash ./scripts/publish.sh
|
||||
|
||||
# ----------------------------------------------
|
||||
# utilities
|
||||
|
||||
.PHONY: setup
|
||||
setup:
|
||||
@bash ./scripts/setup.sh
|
||||
38
Makefile.variables
Normal file
38
Makefile.variables
Normal file
@@ -0,0 +1,38 @@
|
||||
export PROJECT = yq
|
||||
IMPORT_PATH := github.com/mikefarah/${PROJECT}
|
||||
|
||||
export GIT_COMMIT = $(shell git rev-parse --short HEAD)
|
||||
export GIT_DIRTY = $(shell test -n "$$(git status --porcelain)" && echo "+CHANGES" || true)
|
||||
export GIT_DESCRIBE = $(shell git describe --tags --always)
|
||||
LDFLAGS :=
|
||||
LDFLAGS += -X main.GitCommit=${GIT_COMMIT}${GIT_DIRTY}
|
||||
LDFLAGS += -X main.GitDescribe=${GIT_DESCRIBE}
|
||||
|
||||
GITHUB_TOKEN ?=
|
||||
|
||||
# Windows environment?
|
||||
CYG_CHECK := $(shell hash cygpath 2>/dev/null && echo 1)
|
||||
ifeq ($(CYG_CHECK),1)
|
||||
VBOX_CHECK := $(shell hash VBoxManage 2>/dev/null && echo 1)
|
||||
|
||||
# Docker Toolbox (pre-Windows 10)
|
||||
ifeq ($(VBOX_CHECK),1)
|
||||
ROOT := /${PROJECT}
|
||||
else
|
||||
# Docker Windows
|
||||
ROOT := $(shell cygpath -m -a "$(shell pwd)")
|
||||
endif
|
||||
else
|
||||
# all non-windows environments
|
||||
ROOT := $(shell pwd)
|
||||
endif
|
||||
|
||||
DEV_IMAGE := ${PROJECT}_dev
|
||||
|
||||
DOCKRUN := docker run --rm \
|
||||
-e LDFLAGS="${LDFLAGS}" \
|
||||
-e GITHUB_TOKEN="${GITHUB_TOKEN}" \
|
||||
-v ${ROOT}/vendor:/go/src \
|
||||
-v ${ROOT}:/${PROJECT}/src/${IMPORT_PATH} \
|
||||
-w /${PROJECT}/src/${IMPORT_PATH} \
|
||||
${DEV_IMAGE}
|
||||
185
README.md
185
README.md
@@ -1,47 +1,166 @@
|
||||
# yaml
|
||||
yaml command line tool written in go
|
||||
# yq
|
||||
|
||||
Allows you to read (and soon update) yaml files given a yaml path.
|
||||
   
|
||||
|
||||
|
||||
a lightweight and portable command-line YAML processor
|
||||
|
||||
The aim of the project is to be the [jq](https://github.com/stedolan/jq) or sed of yaml files.
|
||||
|
||||
## Install
|
||||
|
||||
### [Download the latest binary](https://github.com/mikefarah/yq/releases/latest)
|
||||
|
||||
### MacOS:
|
||||
```
|
||||
go get github.com/mikefarah/yaml
|
||||
brew install yq
|
||||
```
|
||||
|
||||
## Read examples
|
||||
### Ubuntu and other Linux distros supporting `snap` packages:
|
||||
```
|
||||
yaml <yaml file> <path>
|
||||
snap install yq
|
||||
```
|
||||
|
||||
### Basic
|
||||
Given a sample.yaml file of:
|
||||
```yaml
|
||||
b:
|
||||
c: 2
|
||||
#### Snap notes
|
||||
`yq` installs with [_strict confinement_](https://docs.snapcraft.io/snap-confinement/6233) in snap, this means it doesn't have direct access to root files. To read root files you can:
|
||||
|
||||
```
|
||||
then
|
||||
sudo cat /etc/myfile | yq r - a.path
|
||||
```
|
||||
|
||||
And to write to a root file you can either use [sponge](https://linux.die.net/man/1/sponge):
|
||||
```
|
||||
sudo cat /etc/myfile | yq w - a.path value | sudo sponge /etc/myfile
|
||||
```
|
||||
or write to a temporary file:
|
||||
```
|
||||
sudo cat /etc/myfile | yq w - a.path value | sudo tee /etc/myfile.tmp
|
||||
sudo mv /etc/myfile.tmp /etc/myfile
|
||||
rm /etc/myfile.tmp
|
||||
```
|
||||
|
||||
### wget
|
||||
|
||||
Use wget to download the pre-compiled binaries:
|
||||
|
||||
```bash
|
||||
yaml sample.yaml b.c
|
||||
wget https://github.com/mikefarah/yq/releases/download/{VERSION}/{BINARY} -O /usr/bin/yq &&\
|
||||
chmod +x /usr/bin/yq
|
||||
```
|
||||
will output the value of '2'.
|
||||
|
||||
### Arrays
|
||||
You can give an index to access a specific element:
|
||||
e.g.: given a sample file of
|
||||
```yaml
|
||||
b:
|
||||
e:
|
||||
- name: fred
|
||||
value: 3
|
||||
- name: sam
|
||||
value: 4
|
||||
```
|
||||
then
|
||||
```
|
||||
yaml sample.yaml b.e.1.name
|
||||
```
|
||||
will output 'sam'
|
||||
For instance, VERSION=3.4.0 and BINARY=yq_linux_amd64
|
||||
|
||||
## TODO
|
||||
* Updating yaml files
|
||||
* Handling '.' in path names
|
||||
|
||||
### Run with Docker
|
||||
|
||||
#### Oneshot use:
|
||||
|
||||
```bash
|
||||
docker run --rm -v "${PWD}":/workdir mikefarah/yq yq [flags] <command> FILE...
|
||||
```
|
||||
|
||||
#### Run commands interactively:
|
||||
|
||||
```bash
|
||||
docker run --rm -it -v "${PWD}":/workdir mikefarah/yq sh
|
||||
```
|
||||
|
||||
It can be useful to have a bash function to avoid typing the whole docker command:
|
||||
|
||||
```bash
|
||||
yq() {
|
||||
docker run --rm -i -v "${PWD}":/workdir mikefarah/yq yq "$@"
|
||||
}
|
||||
```
|
||||
|
||||
### Go Get:
|
||||
```
|
||||
GO111MODULE=on go get github.com/mikefarah/yq/v3
|
||||
```
|
||||
|
||||
## Community Supported Installation methods
|
||||
As these are supported by the community :heart: - however, they may be out of date with the officially supported releases.
|
||||
|
||||
|
||||
### Windows:
|
||||
```
|
||||
choco install yq
|
||||
```
|
||||
Supported by @chillum (https://chocolatey.org/packages/yq)
|
||||
|
||||
### Alpine Linux
|
||||
- Enable edge/community repo by adding ```$MIRROR/alpine/edge/community``` to ```/etc/apk/repositories```
|
||||
- Update database index with ```apk update```
|
||||
- Install yq with ```apk add yq```
|
||||
|
||||
Supported by Tuan Hoang
|
||||
https://pkgs.alpinelinux.org/package/edge/community/x86/yq
|
||||
|
||||
|
||||
### On Ubuntu 16.04 or higher from Debian package:
|
||||
```sh
|
||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys CC86BB64
|
||||
sudo add-apt-repository ppa:rmescandon/yq
|
||||
sudo apt update
|
||||
sudo apt install yq -y
|
||||
```
|
||||
Supported by @rmescandon (https://launchpad.net/~rmescandon/+archive/ubuntu/yq)
|
||||
|
||||
## Features
|
||||
- Written in portable go, so you can download a lovely dependency free binary
|
||||
- [Colorize the output](https://mikefarah.gitbook.io/yq/usage/output-format#colorize-output)
|
||||
- [Deep read a yaml file with a given path expression](https://mikefarah.gitbook.io/yq/commands/read#basic)
|
||||
- [List matching paths of a given path expression](https://mikefarah.gitbook.io/yq/commands/read#path-only)
|
||||
- [Return the lengths of arrays/object/scalars](https://mikefarah.gitbook.io/yq/commands/read#printing-length-of-the-results)
|
||||
- Update a yaml file given a [path expression](https://mikefarah.gitbook.io/yq/commands/write-update#basic) or [script file](https://mikefarah.gitbook.io/yq/commands/write-update#basic)
|
||||
- Update creates any missing entries in the path on the fly
|
||||
- Deeply [compare](https://mikefarah.gitbook.io/yq/commands/compare) yaml files
|
||||
- Keeps yaml formatting and comments when updating
|
||||
- [Validate a yaml file](https://mikefarah.gitbook.io/yq/commands/validate)
|
||||
- Create a yaml file given a [deep path and value](https://mikefarah.gitbook.io/yq/commands/create#creating-a-simple-yaml-file) or a [script file](https://mikefarah.gitbook.io/yq/commands/create#creating-using-a-create-script)
|
||||
- [Prefix a path to a yaml file](https://mikefarah.gitbook.io/yq/commands/prefix)
|
||||
- [Convert to/from json to yaml](https://mikefarah.gitbook.io/yq/usage/convert)
|
||||
- [Pipe data in by using '-'](https://mikefarah.gitbook.io/yq/commands/read#from-stdin)
|
||||
- [Merge](https://mikefarah.gitbook.io/yq/commands/merge) multiple yaml files with various options for [overriding](https://mikefarah.gitbook.io/yq/commands/merge#overwrite-values) and [appending](https://mikefarah.gitbook.io/yq/commands/merge#append-values-with-arrays)
|
||||
- Supports multiple documents in a single yaml file for [reading](https://mikefarah.gitbook.io/yq/commands/read#multiple-documents), [writing](https://mikefarah.gitbook.io/yq/commands/write-update#multiple-documents) and [merging](https://mikefarah.gitbook.io/yq/commands/merge#multiple-documents)
|
||||
- General shell completion scripts (bash/zsh/fish/powershell) (https://mikefarah.gitbook.io/yq/commands/shell-completion)
|
||||
|
||||
## [Usage](https://mikefarah.gitbook.io/yq/)
|
||||
|
||||
Check out the [documentation](https://mikefarah.gitbook.io/yq/) for more detailed and advanced usage.
|
||||
|
||||
```
|
||||
Usage:
|
||||
yq [flags]
|
||||
yq [command]
|
||||
|
||||
Available Commands:
|
||||
compare yq x [--prettyPrint/-P] dataA.yaml dataB.yaml 'b.e(name==fr*).value'
|
||||
delete yq d [--inplace/-i] [--doc/-d index] sample.yaml 'b.e(name==fred)'
|
||||
help Help about any command
|
||||
merge yq m [--inplace/-i] [--doc/-d index] [--overwrite/-x] [--append/-a] sample.yaml sample2.yaml
|
||||
new yq n [--script/-s script_file] a.b.c newValue
|
||||
prefix yq p [--inplace/-i] [--doc/-d index] sample.yaml a.b.c
|
||||
read yq r [--printMode/-p pv] sample.yaml 'b.e(name==fr*).value'
|
||||
shell-completion Generates shell completion scripts
|
||||
validate yq v sample.yaml
|
||||
write yq w [--inplace/-i] [--script/-s script_file] [--doc/-d index] sample.yaml 'b.e(name==fr*).value' newValue
|
||||
|
||||
Flags:
|
||||
-C, --colors print with colors
|
||||
-h, --help help for yq
|
||||
-I, --indent int sets indent level for output (default 2)
|
||||
-P, --prettyPrint pretty print
|
||||
-j, --tojson output as json. By default it prints a json document in one line, use the prettyPrint flag to print a formatted doc.
|
||||
-v, --verbose verbose mode
|
||||
-V, --version Print version information and quit
|
||||
|
||||
Use "yq [command] --help" for more information about a command.
|
||||
```
|
||||
|
||||
## Upgrade from V2
|
||||
If you've been using v2 and want/need to upgrade, checkout the [upgrade guide](https://mikefarah.gitbook.io/yq/upgrading-from-v2).
|
||||
|
||||
## Known Issues / Missing Features
|
||||
- `yq` attempts to preserve comment positions and whitespace as much as possible, but it does not handle all scenarios (see https://github.com/go-yaml/yaml/tree/v3 for details)
|
||||
- You cannot (yet) select multiple paths/keys from the yaml to be printed out (https://github.com/mikefarah/yq/issues/287)
|
||||
|
||||
13
action.yml
Normal file
13
action.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
name: 'yq - portable yaml processor'
|
||||
description: 'create, read, update, delete, merge, validate and do more with yaml'
|
||||
icon: command
|
||||
color: gray-dark
|
||||
inputs:
|
||||
cmd:
|
||||
description: 'The Command which should be run'
|
||||
required: true
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'github-action/Dockerfile'
|
||||
args:
|
||||
- ${{ inputs.cmd }}
|
||||
83
cmd/commands_test.go
Normal file
83
cmd/commands_test.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package cmd
|
||||
|
||||
// import (
|
||||
// "strings"
|
||||
// "testing"
|
||||
|
||||
// "github.com/mikefarah/yq/v3/test"
|
||||
// "github.com/spf13/cobra"
|
||||
// )
|
||||
|
||||
// func getRootCommand() *cobra.Command {
|
||||
// return New()
|
||||
// }
|
||||
|
||||
// func TestRootCmd(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
// if !strings.Contains(result.Output, "Usage:") {
|
||||
// t.Error("Expected usage message to be printed out, but the usage message was not found.")
|
||||
// }
|
||||
// }
|
||||
|
||||
// func TestRootCmd_Help(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "--help")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
// if !strings.Contains(result.Output, "yq is a lightweight and portable command-line YAML processor. It aims to be the jq or sed of yaml files.") {
|
||||
// t.Error("Expected usage message to be printed out, but the usage message was not found.")
|
||||
// }
|
||||
// }
|
||||
|
||||
// func TestRootCmd_VerboseLong(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "--verbose")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
// if !verbose {
|
||||
// t.Error("Expected verbose to be true")
|
||||
// }
|
||||
// }
|
||||
|
||||
// func TestRootCmd_VerboseShort(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "-v")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
// if !verbose {
|
||||
// t.Error("Expected verbose to be true")
|
||||
// }
|
||||
// }
|
||||
|
||||
// func TestRootCmd_VersionShort(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "-V")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// if !strings.Contains(result.Output, "yq version") {
|
||||
// t.Error("expected version message to be printed out, but the message was not found.")
|
||||
// }
|
||||
// }
|
||||
|
||||
// func TestRootCmd_VersionLong(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "--version")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// if !strings.Contains(result.Output, "yq version") {
|
||||
// t.Error("expected version message to be printed out, but the message was not found.")
|
||||
// }
|
||||
// }
|
||||
18
cmd/constant.go
Normal file
18
cmd/constant.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package cmd
|
||||
|
||||
var unwrapScalar = true
|
||||
|
||||
// var writeInplace = false
|
||||
var outputToJSON = false
|
||||
|
||||
// var exitStatus = false
|
||||
var forceColor = false
|
||||
var forceNoColor = false
|
||||
var colorsEnabled = false
|
||||
var indent = 2
|
||||
var noDocSeparators = false
|
||||
var nullInput = false
|
||||
var verbose = false
|
||||
var version = false
|
||||
|
||||
// var log = logging.MustGetLogger("yq")
|
||||
64
cmd/evaluate_all_command.go
Normal file
64
cmd/evaluate_all_command.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/mikefarah/yq/v4/pkg/yqlib"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func createEvaluateAllCommand() *cobra.Command {
|
||||
var cmdEvalAll = &cobra.Command{
|
||||
Use: "eval-all [expression] [yaml_file1]...",
|
||||
Aliases: []string{"ea"},
|
||||
Short: "Loads _all_ yaml documents of _all_ yaml files and runs expression once",
|
||||
Example: `
|
||||
yq es '.a.b | length' file1.yml file2.yml
|
||||
yq es < sample.yaml
|
||||
yq es -n '{"a": "b"}'
|
||||
`,
|
||||
Long: "Evaluate All:\nUseful when you need to run an expression across several yaml documents or files. Consumes more memory than eval",
|
||||
RunE: evaluateAll,
|
||||
}
|
||||
return cmdEvalAll
|
||||
}
|
||||
func evaluateAll(cmd *cobra.Command, args []string) error {
|
||||
// 0 args, read std in
|
||||
// 1 arg, null input, process expression
|
||||
// 1 arg, read file in sequence
|
||||
// 2+ args, [0] = expression, file the rest
|
||||
|
||||
var err error
|
||||
stat, _ := os.Stdin.Stat()
|
||||
pipingStdIn := (stat.Mode() & os.ModeCharDevice) == 0
|
||||
|
||||
out := cmd.OutOrStdout()
|
||||
|
||||
fileInfo, _ := os.Stdout.Stat()
|
||||
|
||||
if forceColor || (!forceNoColor && (fileInfo.Mode()&os.ModeCharDevice) != 0) {
|
||||
colorsEnabled = true
|
||||
}
|
||||
printer := yqlib.NewPrinter(out, outputToJSON, unwrapScalar, colorsEnabled, indent, !noDocSeparators)
|
||||
|
||||
switch len(args) {
|
||||
case 0:
|
||||
if pipingStdIn {
|
||||
err = yqlib.EvaluateAllFileStreams("", []string{"-"}, printer)
|
||||
} else {
|
||||
cmd.Println(cmd.UsageString())
|
||||
return nil
|
||||
}
|
||||
case 1:
|
||||
if nullInput {
|
||||
err = yqlib.EvaluateAllFileStreams(args[0], []string{}, printer)
|
||||
} else {
|
||||
err = yqlib.EvaluateAllFileStreams("", []string{args[0]}, printer)
|
||||
}
|
||||
default:
|
||||
err = yqlib.EvaluateAllFileStreams(args[0], args[1:], printer)
|
||||
}
|
||||
|
||||
cmd.SilenceUsage = true
|
||||
return err
|
||||
}
|
||||
64
cmd/evalute_sequence_command.go
Normal file
64
cmd/evalute_sequence_command.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/mikefarah/yq/v4/pkg/yqlib"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func createEvaluateSequenceCommand() *cobra.Command {
|
||||
var cmdEvalSequence = &cobra.Command{
|
||||
Use: "eval [expression] [yaml_file1]...",
|
||||
Aliases: []string{"e"},
|
||||
Short: "Apply expression to each document in each yaml file given in sequence",
|
||||
Example: `
|
||||
yq es '.a.b | length' file1.yml file2.yml
|
||||
yq es < sample.yaml
|
||||
yq es -n '{"a": "b"}'
|
||||
`,
|
||||
Long: "Evaluate Sequence:\nIterate over each yaml document, apply the expression and print the results, in sequence.",
|
||||
RunE: evaluateSequence,
|
||||
}
|
||||
return cmdEvalSequence
|
||||
}
|
||||
func evaluateSequence(cmd *cobra.Command, args []string) error {
|
||||
// 0 args, read std in
|
||||
// 1 arg, null input, process expression
|
||||
// 1 arg, read file in sequence
|
||||
// 2+ args, [0] = expression, file the rest
|
||||
|
||||
var err error
|
||||
stat, _ := os.Stdin.Stat()
|
||||
pipingStdIn := (stat.Mode() & os.ModeCharDevice) == 0
|
||||
|
||||
out := cmd.OutOrStdout()
|
||||
|
||||
fileInfo, _ := os.Stdout.Stat()
|
||||
|
||||
if forceColor || (!forceNoColor && (fileInfo.Mode()&os.ModeCharDevice) != 0) {
|
||||
colorsEnabled = true
|
||||
}
|
||||
printer := yqlib.NewPrinter(out, outputToJSON, unwrapScalar, colorsEnabled, indent, !noDocSeparators)
|
||||
|
||||
switch len(args) {
|
||||
case 0:
|
||||
if pipingStdIn {
|
||||
err = yqlib.EvaluateFileStreamsSequence("", []string{"-"}, printer)
|
||||
} else {
|
||||
cmd.Println(cmd.UsageString())
|
||||
return nil
|
||||
}
|
||||
case 1:
|
||||
if nullInput {
|
||||
err = yqlib.EvaluateAllFileStreams(args[0], []string{}, printer)
|
||||
} else {
|
||||
err = yqlib.EvaluateFileStreamsSequence("", []string{args[0]}, printer)
|
||||
}
|
||||
default:
|
||||
err = yqlib.EvaluateFileStreamsSequence(args[0], args[1:], printer)
|
||||
}
|
||||
|
||||
cmd.SilenceUsage = true
|
||||
return err
|
||||
}
|
||||
58
cmd/root.go
Normal file
58
cmd/root.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
logging "gopkg.in/op/go-logging.v1"
|
||||
)
|
||||
|
||||
func New() *cobra.Command {
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "yq",
|
||||
Short: "yq is a lightweight and portable command-line YAML processor.",
|
||||
Long: `yq is a lightweight and portable command-line YAML processor. It aims to be the jq or sed of yaml files.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if version {
|
||||
cmd.Print(GetVersionDisplay())
|
||||
return nil
|
||||
}
|
||||
cmd.Println(cmd.UsageString())
|
||||
return nil
|
||||
|
||||
},
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
cmd.SetOut(cmd.OutOrStdout())
|
||||
var format = logging.MustStringFormatter(
|
||||
`%{color}%{time:15:04:05} %{shortfunc} [%{level:.4s}]%{color:reset} %{message}`,
|
||||
)
|
||||
var backend = logging.AddModuleLevel(
|
||||
logging.NewBackendFormatter(logging.NewLogBackend(os.Stderr, "", 0), format))
|
||||
|
||||
if verbose {
|
||||
backend.SetLevel(logging.DEBUG, "")
|
||||
} else {
|
||||
backend.SetLevel(logging.ERROR, "")
|
||||
}
|
||||
|
||||
logging.SetBackend(backend)
|
||||
},
|
||||
}
|
||||
|
||||
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose mode")
|
||||
rootCmd.PersistentFlags().BoolVarP(&outputToJSON, "tojson", "j", false, "output as json. Set indent to 0 to print json in one line.")
|
||||
rootCmd.PersistentFlags().BoolVarP(&nullInput, "null-input", "n", false, "Don't read input, simply evaluate the expression given. Useful for creating yaml docs from scratch.")
|
||||
rootCmd.PersistentFlags().BoolVarP(&noDocSeparators, "no-doc", "N", false, "Don't print document separators (---)")
|
||||
|
||||
rootCmd.PersistentFlags().IntVarP(&indent, "indent", "I", 2, "sets indent level for output")
|
||||
rootCmd.Flags().BoolVarP(&version, "version", "V", false, "Print version information and quit")
|
||||
|
||||
rootCmd.PersistentFlags().BoolVarP(&forceColor, "colors", "C", false, "force print with colors")
|
||||
rootCmd.PersistentFlags().BoolVarP(&forceNoColor, "no-colors", "M", false, "force print with no colors")
|
||||
rootCmd.AddCommand(
|
||||
createEvaluateSequenceCommand(),
|
||||
createEvaluateAllCommand(),
|
||||
completionCmd,
|
||||
)
|
||||
return rootCmd
|
||||
}
|
||||
61
cmd/shell-completion.go
Normal file
61
cmd/shell-completion.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var completionCmd = &cobra.Command{
|
||||
Use: "shell-completion [bash|zsh|fish|powershell]",
|
||||
Short: "Generate completion script",
|
||||
Long: `To load completions:
|
||||
|
||||
Bash:
|
||||
|
||||
$ source <(yq shell-completion bash)
|
||||
|
||||
# To load completions for each session, execute once:
|
||||
Linux:
|
||||
$ yq shell-completion bash > /etc/bash_completion.d/yq
|
||||
MacOS:
|
||||
$ yq shell-completion bash > /usr/local/etc/bash_completion.d/yq
|
||||
|
||||
Zsh:
|
||||
|
||||
# If shell completion is not already enabled in your environment you will need
|
||||
# to enable it. You can execute the following once:
|
||||
|
||||
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
|
||||
|
||||
# To load completions for each session, execute once:
|
||||
$ yq shell-completion zsh > "${fpath[1]}/_yq"
|
||||
|
||||
# You will need to start a new shell for this setup to take effect.
|
||||
|
||||
Fish:
|
||||
|
||||
$ yq shell-completion fish | source
|
||||
|
||||
# To load completions for each session, execute once:
|
||||
$ yq shell-completion fish > ~/.config/fish/completions/yq.fish
|
||||
`,
|
||||
DisableFlagsInUseLine: true,
|
||||
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
|
||||
Args: cobra.ExactValidArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var err error = nil
|
||||
switch args[0] {
|
||||
case "bash":
|
||||
err = cmd.Root().GenBashCompletion(os.Stdout)
|
||||
case "zsh":
|
||||
err = cmd.Root().GenZshCompletion(os.Stdout)
|
||||
case "fish":
|
||||
err = cmd.Root().GenFishCompletion(os.Stdout, true)
|
||||
case "powershell":
|
||||
err = cmd.Root().GenPowerShellCompletion(os.Stdout)
|
||||
}
|
||||
return err
|
||||
|
||||
},
|
||||
}
|
||||
49
cmd/version.go
Normal file
49
cmd/version.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// The git commit that was compiled. This will be filled in by the compiler.
|
||||
var (
|
||||
GitCommit string
|
||||
GitDescribe string
|
||||
|
||||
// Version is main version number that is being run at the moment.
|
||||
Version = "4.0.0-alpha1"
|
||||
|
||||
// VersionPrerelease is a pre-release marker for the version. If this is "" (empty string)
|
||||
// then it means that it is a final release. Otherwise, this is a pre-release
|
||||
// such as "dev" (in development), "beta", "rc1", etc.
|
||||
VersionPrerelease = ""
|
||||
)
|
||||
|
||||
// ProductName is the name of the product
|
||||
const ProductName = "yq"
|
||||
|
||||
// GetVersionDisplay composes the parts of the version in a way that's suitable
|
||||
// for displaying to humans.
|
||||
func GetVersionDisplay() string {
|
||||
return fmt.Sprintf("%s version %s\n", ProductName, getHumanVersion())
|
||||
}
|
||||
|
||||
func getHumanVersion() string {
|
||||
version := Version
|
||||
if GitDescribe != "" {
|
||||
version = GitDescribe
|
||||
}
|
||||
|
||||
release := VersionPrerelease
|
||||
if release != "" {
|
||||
if !strings.Contains(version, release) {
|
||||
version += fmt.Sprintf("-%s", release)
|
||||
}
|
||||
if GitCommit != "" {
|
||||
version += fmt.Sprintf(" (%s)", GitCommit)
|
||||
}
|
||||
}
|
||||
|
||||
// Strip off any single quotes added by the git information.
|
||||
return strings.Replace(version, "'", "", -1)
|
||||
}
|
||||
51
cmd/version_test.go
Normal file
51
cmd/version_test.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package cmd
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestGetVersionDisplay(t *testing.T) {
|
||||
var expectedVersion = ProductName + " version " + Version
|
||||
if VersionPrerelease != "" {
|
||||
expectedVersion = expectedVersion + "-" + VersionPrerelease
|
||||
}
|
||||
expectedVersion = expectedVersion + "\n"
|
||||
tests := []struct {
|
||||
name string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "Display Version",
|
||||
want: expectedVersion,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if got := GetVersionDisplay(); got != tt.want {
|
||||
t.Errorf("%q. GetVersionDisplay() = %v, want %v", tt.name, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_getHumanVersion(t *testing.T) {
|
||||
GitDescribe = "e42813d"
|
||||
GitCommit = "e42813d+CHANGES"
|
||||
var wanted string
|
||||
if VersionPrerelease == "" {
|
||||
wanted = GitDescribe
|
||||
} else {
|
||||
wanted = "e42813d-" + VersionPrerelease + " (e42813d+CHANGES)"
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "Git Variables defined",
|
||||
want: wanted,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if got := getHumanVersion(); got != tt.want {
|
||||
t.Errorf("%q. getHumanVersion() = %v, want %v", tt.name, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
61
cmd/write.go
Normal file
61
cmd/write.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package cmd
|
||||
|
||||
// import (
|
||||
// "github.com/spf13/cobra"
|
||||
// )
|
||||
|
||||
// func createWriteCmd() *cobra.Command {
|
||||
// var cmdWrite = &cobra.Command{
|
||||
// Use: "write [yaml_file] [path_expression] [value]",
|
||||
// Aliases: []string{"w"},
|
||||
// Short: "yq w [--inplace/-i] [--script/-s script_file] [--doc/-d index] sample.yaml 'b.e(name==fr*).value' newValue",
|
||||
// Example: `
|
||||
// yq write things.yaml 'a.b.c' true
|
||||
// yq write things.yaml 'a.*.c' true
|
||||
// yq write things.yaml 'a.**' true
|
||||
// yq write things.yaml 'a.(child.subchild==co*).c' true
|
||||
// yq write things.yaml 'a.b.c' --tag '!!str' true # force 'true' to be interpreted as a string instead of bool
|
||||
// yq write things.yaml 'a.b.c' --tag '!!float' 3
|
||||
// yq write --inplace -- things.yaml 'a.b.c' '--cat' # need to use '--' to stop processing arguments as flags
|
||||
// yq w -i things.yaml 'a.b.c' cat
|
||||
// yq w -i -s update_script.yaml things.yaml
|
||||
// yq w things.yaml 'a.b.d[+]' foo # appends a new node to the 'd' array
|
||||
// yq w --doc 2 things.yaml 'a.b.d[+]' foo # updates the 3rd document of the yaml file
|
||||
// `,
|
||||
// Long: `Updates the yaml file w.r.t the given path and value.
|
||||
// Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
||||
|
||||
// Append value to array adds the value to the end of array.
|
||||
|
||||
// Update Scripts:
|
||||
// Note that you can give an update script to perform more sophisticated update. Update script
|
||||
// format is list of update commands (update or delete) like so:
|
||||
// ---
|
||||
// - command: update
|
||||
// path: b.c
|
||||
// value:
|
||||
// #great
|
||||
// things: frog # wow!
|
||||
// - command: delete
|
||||
// path: b.d
|
||||
// `,
|
||||
// RunE: writeProperty,
|
||||
// }
|
||||
// cmdWrite.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||
// cmdWrite.PersistentFlags().StringVarP(&writeScript, "script", "s", "", "yaml script for updating yaml")
|
||||
// cmdWrite.PersistentFlags().StringVarP(&sourceYamlFile, "from", "f", "", "yaml file for updating yaml (as-is)")
|
||||
// cmdWrite.PersistentFlags().StringVarP(&customTag, "tag", "t", "", "set yaml tag (e.g. !!int)")
|
||||
// cmdWrite.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
// cmdWrite.PersistentFlags().StringVarP(&customStyle, "style", "", "", "formatting style of the value: single, double, folded, flow, literal, tagged")
|
||||
// cmdWrite.PersistentFlags().StringVarP(&anchorName, "anchorName", "", "", "anchor name")
|
||||
// cmdWrite.PersistentFlags().BoolVarP(&makeAlias, "makeAlias", "", false, "create an alias using the value as the anchor name")
|
||||
// return cmdWrite
|
||||
// }
|
||||
|
||||
// func writeProperty(cmd *cobra.Command, args []string) error {
|
||||
// var updateCommands, updateCommandsError = readUpdateCommands(args, 3, "Must provide <filename> <path_to_update> <value>", true)
|
||||
// if updateCommandsError != nil {
|
||||
// return updateCommandsError
|
||||
// }
|
||||
// return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
|
||||
// }
|
||||
610
cmd/write_test.go
Normal file
610
cmd/write_test.go
Normal file
@@ -0,0 +1,610 @@
|
||||
package cmd
|
||||
|
||||
// import (
|
||||
// "fmt"
|
||||
// "runtime"
|
||||
// "strings"
|
||||
// "testing"
|
||||
|
||||
// "github.com/mikefarah/yq/v3/test"
|
||||
// )
|
||||
|
||||
// func TestWriteCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c 7", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 7
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteKeepCommentsCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3 # comment
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c 7", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 7 # comment
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteWithTaggedStyleCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: dog
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c cat --tag=!!str --style=tagged", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: !!str cat
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteWithDoubleQuotedStyleCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: dog
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c cat --style=double", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: "cat"
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteUpdateStyleOnlyCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: dog
|
||||
// d: things
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.* --style=single", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 'dog'
|
||||
// d: 'things'
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteUpdateTagOnlyCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: true
|
||||
// d: false
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.* --tag=!!str", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: "true"
|
||||
// d: "false"
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteWithSingleQuotedStyleCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: dog
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c cat --style=single", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 'cat'
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteWithLiteralStyleCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: dog
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c cat --style=literal", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: |-
|
||||
// cat
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteWithFoldedStyleCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: dog
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c cat --style=folded", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: >-
|
||||
// cat
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteEmptyMultiDocCmd(t *testing.T) {
|
||||
// content := `# this is empty
|
||||
// ---
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s c 7", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `c: 7
|
||||
|
||||
// # this is empty
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteSurroundingEmptyMultiDocCmd(t *testing.T) {
|
||||
// content := `---
|
||||
// # empty
|
||||
// ---
|
||||
// cat: frog
|
||||
// ---
|
||||
|
||||
// # empty
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s -d1 c 7", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `
|
||||
|
||||
// # empty
|
||||
// ---
|
||||
// cat: frog
|
||||
// c: 7
|
||||
// ---
|
||||
|
||||
// # empty
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteFromFileCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// source := `kittens: are cute # sure are!`
|
||||
// fromFilename := test.WriteTempYamlFile(source)
|
||||
// defer test.RemoveTempYamlFile(fromFilename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c -f %s", filename, fromFilename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c:
|
||||
// kittens: are cute # sure are!
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteEmptyCmd(t *testing.T) {
|
||||
// content := ``
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c 7", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 7
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteAutoCreateCmd(t *testing.T) {
|
||||
// content := `applications:
|
||||
// - name: app
|
||||
// env:`
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s applications[0].env.hello world", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `applications:
|
||||
// - name: app
|
||||
// env:
|
||||
// hello: world
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteCmdScript(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// updateScript := `- command: update
|
||||
// path: b.c
|
||||
// value: 7`
|
||||
// scriptFilename := test.WriteTempYamlFile(updateScript)
|
||||
// defer test.RemoveTempYamlFile(scriptFilename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write --script %s %s", scriptFilename, filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 7
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteCmdEmptyScript(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// updateScript := ``
|
||||
// scriptFilename := test.WriteTempYamlFile(updateScript)
|
||||
// defer test.RemoveTempYamlFile(scriptFilename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write --script %s %s", scriptFilename, filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteMultiCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// ---
|
||||
// apples: great
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s -d 1 apples ok", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 3
|
||||
// ---
|
||||
// apples: ok
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
// func TestWriteInvalidDocumentIndexCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s -df apples ok", filename))
|
||||
// if result.Error == nil {
|
||||
// t.Error("Expected command to fail due to invalid path")
|
||||
// }
|
||||
// expectedOutput := `Document index f is not a integer or *: strconv.ParseInt: parsing "f": invalid syntax`
|
||||
// test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
// }
|
||||
|
||||
// func TestWriteBadDocumentIndexCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s -d 1 apples ok", filename))
|
||||
// if result.Error == nil {
|
||||
// t.Error("Expected command to fail due to invalid path")
|
||||
// }
|
||||
// expectedOutput := `asked to process document index 1 but there are only 1 document(s)`
|
||||
// test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
// }
|
||||
// func TestWriteMultiAllCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// ---
|
||||
// apples: great
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s -d * apples ok", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 3
|
||||
// apples: ok
|
||||
// ---
|
||||
// apples: ok`
|
||||
// test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n "))
|
||||
// }
|
||||
|
||||
// func TestWriteCmd_EmptyArray(t *testing.T) {
|
||||
// content := `b: 3`
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s a []", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b: 3
|
||||
// a: []
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteCmd_Error(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "write")
|
||||
// if result.Error == nil {
|
||||
// t.Error("Expected command to fail due to missing arg")
|
||||
// }
|
||||
// expectedOutput := `Must provide <filename> <path_to_update> <value>`
|
||||
// test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
// }
|
||||
|
||||
// func TestWriteCmd_ErrorUnreadableFile(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "write fake-unknown a.b 3")
|
||||
// if result.Error == nil {
|
||||
// t.Error("Expected command to fail due to unknown file")
|
||||
// }
|
||||
// var expectedOutput string
|
||||
// if runtime.GOOS == "windows" {
|
||||
// expectedOutput = `open fake-unknown: The system cannot find the file specified.`
|
||||
// } else {
|
||||
// expectedOutput = `open fake-unknown: no such file or directory`
|
||||
// }
|
||||
// test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
// }
|
||||
|
||||
// func TestWriteCmd_Inplace(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write -i %s b.c 7", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// gotOutput := test.ReadTempYamlFile(filename)
|
||||
// expectedOutput := `b:
|
||||
// c: 7`
|
||||
// test.AssertResult(t, expectedOutput, strings.Trim(gotOutput, "\n "))
|
||||
// }
|
||||
|
||||
// func TestWriteCmd_InplaceError(t *testing.T) {
|
||||
// content := `b: cat
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write -i %s b.c 7", filename))
|
||||
// if result.Error == nil {
|
||||
// t.Error("Expected Error to occur!")
|
||||
// }
|
||||
// gotOutput := test.ReadTempYamlFile(filename)
|
||||
// test.AssertResult(t, content, gotOutput)
|
||||
// }
|
||||
|
||||
// func TestWriteCmd_Append(t *testing.T) {
|
||||
// content := `b:
|
||||
// - foo
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b[+] 7", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// - foo
|
||||
// - 7
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteCmd_AppendInline(t *testing.T) {
|
||||
// content := `b: [foo]`
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b[+] 7", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b: [foo, 7]
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteCmd_AppendInlinePretty(t *testing.T) {
|
||||
// content := `b: [foo]`
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s -P b[+] 7", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// - foo
|
||||
// - 7
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteCmd_AppendEmptyArray(t *testing.T) {
|
||||
// content := `a: 2
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b[+] v", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `a: 2
|
||||
// b:
|
||||
// - v
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteCmd_SplatArray(t *testing.T) {
|
||||
// content := `b:
|
||||
// - c: thing
|
||||
// - c: another thing
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b[*].c new", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// - c: new
|
||||
// - c: new
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteCmd_SplatMap(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: thing
|
||||
// d: another thing
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.* new", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: new
|
||||
// d: new
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
// func TestWriteCmd_SplatMapEmpty(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: thing
|
||||
// d: another thing
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c.* new", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: {}
|
||||
// d: another thing
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
76
debian/changelog
vendored
Normal file
76
debian/changelog
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
yq (3.3.2) focal; urgency=medium
|
||||
|
||||
* Bug fix: existStatus bug (#459)
|
||||
* Automatically makes a os temp directory if it does not exist (#461)
|
||||
|
||||
-- Roberto Mier Escandon <rmescandon@gmail.com> Fri, 07 Aug 2020 18:53:01 +0200
|
||||
|
||||
yq (3.3-0) focal; urgency=medium
|
||||
|
||||
* You can control string styles (quotes) using the new --style flag
|
||||
* String values now always have quotes when outputting to json
|
||||
* Negative array indices now traverse the array backwards
|
||||
* Added a --stripComments flag to print yaml without any comments
|
||||
* Bumped go to version 1.14
|
||||
|
||||
-- Roberto Mier Escandon <rmescandon@gmail.com> Thu, 30 Apr 2020 20:45:44 +0200
|
||||
|
||||
yq (3.1-2) eoan; urgency=medium
|
||||
|
||||
* Bug fix: yq 3 was removing empty inline-style objects and arrays (#355)
|
||||
* Bug fix: Merge option returned different output when switching order of
|
||||
merging files(#347)
|
||||
* Bug fix: Add new object to existing array object was failing in 3.1.1 (#361)
|
||||
* Bug fix: yq 3 empty keys did not allow merging of values (#356)
|
||||
* Bug fix: keys quoted during merge (#363)
|
||||
* Bug fix: Correct length with wc -l (#362)
|
||||
* Bug fix: Write to empty document removed path (#359)
|
||||
|
||||
-- Roberto Mier Escandon <rmescandon@gmail.com> Mon, 24 Feb 2020 20:31:58 +0100
|
||||
|
||||
yq (3.1-1) eoan; urgency=medium
|
||||
|
||||
* Keeps yaml comments and formatting, can specify yaml tags when updating.
|
||||
* Handles anchors
|
||||
* Can print out matching paths and values when splatting
|
||||
* JSON output works for all commands
|
||||
* Yaml files with multiple documents are printed out as one JSON
|
||||
document per line.
|
||||
* Deep splat (**) to match arbitrary paths
|
||||
* Update scripts file format has changed to be more powerful
|
||||
* Reading and splatting, matching results are printed once per line
|
||||
* Bugfixing
|
||||
|
||||
-- Roberto Mier Escandon <rmescandon@gmail.com> Tue, 11 Feb 2020 22:18:24 +0100
|
||||
|
||||
yq (2.2-1) bionic; urgency=medium
|
||||
|
||||
* Added Windows support for the "--inplace" command flag
|
||||
* Prefix now supports arrays
|
||||
* Add prefix command
|
||||
* Bump Alpine version to 3.8
|
||||
* Improved docker build process
|
||||
* Lint fixes
|
||||
* Build support for all linux architectures supported by gox
|
||||
|
||||
-- Roberto Mier Escandon <rmescandon@gmail.com> Sat, 19 Jan 2019 15:50:47 +0100
|
||||
|
||||
yq (2.1-0) bionic; urgency=medium
|
||||
|
||||
* Ability to read multiple documents in a single file
|
||||
* Ability to append list items instead of overwriting
|
||||
|
||||
-- Roberto Mier EscandĂłn <rmescandon@gmail.com> Tue, 10 Jul 2018 14:02:42 +0200
|
||||
|
||||
yq (2.0-0) bionic; urgency=medium
|
||||
|
||||
* Release 2.0.0
|
||||
|
||||
-- Roberto Mier EscandĂłn <rmescandon@gmail.com> Wed, 20 Jun 2018 10:29:53 +0200
|
||||
|
||||
yq (1.15-0) bionic; urgency=medium
|
||||
|
||||
* Release 1.15
|
||||
|
||||
-- Roberto Mier EscandĂłn <rmescandon@gmail.com> Wed, 06 Jun 2018 11:32:03 +0200
|
||||
|
||||
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@@ -0,0 +1 @@
|
||||
10
|
||||
22
debian/control
vendored
Normal file
22
debian/control
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Source: yq
|
||||
Section: devel
|
||||
Priority: optional
|
||||
Maintainer: Roberto Mier EscandĂłn <rmescandon@gmail.com>
|
||||
Build-Depends: debhelper (>=10),
|
||||
dh-golang (>=1.34),
|
||||
golang-1.13,
|
||||
rsync
|
||||
Standards-Version: 4.1.4
|
||||
Homepage: https://github.com/mikefarah/yq.git
|
||||
Vcs-Browser: https://github.com/mikefarah/yq.git
|
||||
Vcs-Git: https://github.com/mikefarah/yq.git
|
||||
XS-Go-Import-Path: github.com/mikefarah/yq
|
||||
XSBC-Original-Maintainer: Roberto Mier EscandĂłn <rmescandon@gmail.com>
|
||||
|
||||
Package: yq
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: lightweight and portable command-line YAML processor
|
||||
.
|
||||
The aim of the project is to be the
|
||||
[jq](https://github.com/stedolan/jq) or sed of yaml files.
|
||||
24
debian/copyright
vendored
Normal file
24
debian/copyright
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: yq
|
||||
Source: https://github.com/mikefarah/yq.git
|
||||
|
||||
Files: *
|
||||
Copyright: 2017 Mike Farah
|
||||
License: Expat
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
2
debian/gbp.conf
vendored
Normal file
2
debian/gbp.conf
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
[DEFAULT]
|
||||
pristine-tar = True
|
||||
57
debian/rules
vendored
Executable file
57
debian/rules
vendored
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/make -f
|
||||
#
|
||||
# Copyright (C) 2018 Roberto Mier EscandĂłn <rmescandon@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 3 as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
PROJECT := yq
|
||||
OWNER := mikefarah
|
||||
REPO := github.com
|
||||
GOVERSION := 1.13
|
||||
|
||||
export DH_OPTIONS
|
||||
export DH_GOPKG := ${REPO}/${OWNER}/${PROJECT}
|
||||
export GOROOT := /usr/lib/go-${GOVERSION}
|
||||
export GOPATH := ${CURDIR}/_build
|
||||
export GOBIN := ${GOPATH}/bin
|
||||
export PATH := ${GOROOT}/bin:${GOBIN}:${PATH}
|
||||
export GOCACHE := /tmp/gocache
|
||||
export GOFLAGS := -mod=vendor
|
||||
|
||||
SRCDIR := ${GOPATH}/src/${DH_GOPKG}
|
||||
DESTDIR := ${CURDIR}/debian/${PROJECT}
|
||||
BINDIR := /usr/bin
|
||||
ASSETSDIR := /usr/share/${PROJECT}
|
||||
|
||||
%:
|
||||
dh $@ --builddirectory=${GOPATH} --buildsystem=golang
|
||||
|
||||
override_dh_auto_build:
|
||||
mkdir -p ${SRCDIR}
|
||||
mkdir -p ${GOBIN}
|
||||
# copy project to local srcdir to build from there
|
||||
rsync -avz --progress --exclude=_build --exclude=debian --exclude=tmp. --exclude=go.mod --exclude=docs . $(SRCDIR)
|
||||
# build go code
|
||||
(cd ${SRCDIR} && go install -buildmode=pie ./...)
|
||||
|
||||
override_dh_auto_test:
|
||||
(cd ${SRCDIR} && go test -v ./...)
|
||||
|
||||
override_dh_auto_install:
|
||||
cp ${GOBIN}/yq ${DESTDIR}/${BINDIR}
|
||||
cp -f ${SRCDIR}/LICENSE ${DESTDIR}/${ASSETSDIR}
|
||||
chmod a+x ${DESTDIR}/${BINDIR}/yq
|
||||
|
||||
override_dh_auto_clean:
|
||||
dh_clean
|
||||
rm -rf ${CURDIR}/_build
|
||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (native)
|
||||
3
debian/yq.dirs
vendored
Normal file
3
debian/yq.dirs
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
usr/bin
|
||||
usr/share/yq
|
||||
usr/share/man/man1
|
||||
11
examples/array.yaml
Normal file
11
examples/array.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- become: true
|
||||
gather_facts: false
|
||||
hosts: lalaland
|
||||
name: "Apply smth"
|
||||
roles:
|
||||
- lala
|
||||
- land
|
||||
serial: 1
|
||||
- become: false
|
||||
gather_facts: true
|
||||
8
examples/bad.yaml
Normal file
8
examples/bad.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
b:
|
||||
d: be gone
|
||||
c: 2
|
||||
e:
|
||||
- name: Billy Bob # comment over here
|
||||
|
||||
---
|
||||
[123123
|
||||
4
examples/data1-no-comments.yaml
Normal file
4
examples/data1-no-comments.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
a: simple
|
||||
b: [1, 2]
|
||||
c:
|
||||
test: 1
|
||||
4
examples/data1.yaml
Normal file
4
examples/data1.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
a: simple # just the best
|
||||
b: [1, 2]
|
||||
c:
|
||||
test: 1
|
||||
7
examples/data2.yaml
Normal file
7
examples/data2.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
a: other # better than the original
|
||||
b: [3, 4]
|
||||
c:
|
||||
toast: leave
|
||||
test: 1
|
||||
tell: 1
|
||||
tasty.taco: cool
|
||||
4
examples/data3.yaml
Normal file
4
examples/data3.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
a: "simple" # just the best
|
||||
b: [1, 3]
|
||||
c:
|
||||
test: 1
|
||||
2
examples/empty.yaml
Normal file
2
examples/empty.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
# a: apple
|
||||
# b: cat
|
||||
7
examples/instruction_sample.yaml
Normal file
7
examples/instruction_sample.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
- command: update
|
||||
path: b.c
|
||||
value:
|
||||
#great
|
||||
things: frog # wow!
|
||||
- command: delete
|
||||
path: b.d
|
||||
19
examples/merge-anchor.yaml
Normal file
19
examples/merge-anchor.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
foo: &foo
|
||||
a: foo_a
|
||||
thing: foo_thing
|
||||
c: foo_c
|
||||
|
||||
bar: &bar
|
||||
b: bar_b
|
||||
thing: bar_thing
|
||||
c: bar_c
|
||||
|
||||
foobarList:
|
||||
b: foobarList_b
|
||||
<<: [*foo,*bar]
|
||||
c: foobarList_c
|
||||
|
||||
foobar:
|
||||
c: foobar_c
|
||||
<<: *foo
|
||||
thing: foobar_thing
|
||||
5
examples/multiline-text.yaml
Normal file
5
examples/multiline-text.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
test: |
|
||||
abcdefg
|
||||
hijklmno
|
||||
|
||||
|
||||
18
examples/multiple_docs.yaml
Normal file
18
examples/multiple_docs.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
commonKey: first document
|
||||
a: Easy! as one two three
|
||||
b:
|
||||
c: 2
|
||||
d: [3, 4]
|
||||
e:
|
||||
- name: fred
|
||||
value: 3
|
||||
- name: sam
|
||||
value: 4
|
||||
---
|
||||
commonKey: second document
|
||||
another:
|
||||
document: here
|
||||
---
|
||||
commonKey: third document
|
||||
wow:
|
||||
- here is another
|
||||
7
examples/multiple_docs_small.yaml
Normal file
7
examples/multiple_docs_small.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
a: Easy! as one two three
|
||||
---
|
||||
another:
|
||||
document: here
|
||||
---
|
||||
- 1
|
||||
- 2
|
||||
2
examples/numbered_keys.yml
Normal file
2
examples/numbered_keys.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
5:
|
||||
6: camel!
|
||||
2
examples/order.yaml
Normal file
2
examples/order.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
version: 3
|
||||
application: MyApp
|
||||
6
examples/order.yml
Normal file
6
examples/order.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
version: '2'
|
||||
services:
|
||||
test:
|
||||
image: ubuntu:14.04
|
||||
stdin_open: true
|
||||
tty: true
|
||||
1
examples/sample.json
Normal file
1
examples/sample.json
Normal file
@@ -0,0 +1 @@
|
||||
{"a":"Easy! as one two three","b":{"c":2,"d":[3,4],"e":[{"name":"fred","value":3},{"name":"sam","value":4}]},"ab":"must appear last"}
|
||||
@@ -1,9 +1,11 @@
|
||||
a: Easy! as one two three
|
||||
# Some doc
|
||||
|
||||
a: true
|
||||
b:
|
||||
c: 2
|
||||
d: [3, 4]
|
||||
d: [3, 4, 5]
|
||||
e:
|
||||
- name: fred
|
||||
value: 3
|
||||
- name: sam
|
||||
value: 4
|
||||
value: 4
|
||||
1
examples/sample_array.yaml
Normal file
1
examples/sample_array.yaml
Normal file
@@ -0,0 +1 @@
|
||||
[1,2,3]
|
||||
2
examples/sample_array_2.yaml
Normal file
2
examples/sample_array_2.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
- 4
|
||||
- 5
|
||||
1
examples/sample_text.yaml
Normal file
1
examples/sample_text.yaml
Normal file
@@ -0,0 +1 @@
|
||||
hi
|
||||
5
examples/simple-anchor-exploded.yaml
Normal file
5
examples/simple-anchor-exploded.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
foo:
|
||||
a: 1
|
||||
|
||||
foobar:
|
||||
a: 1
|
||||
5
examples/simple-anchor.yaml
Normal file
5
examples/simple-anchor.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
foo: &foo
|
||||
a: 1
|
||||
|
||||
foobar:
|
||||
<<: *foo
|
||||
5
github-action/Dockerfile
Normal file
5
github-action/Dockerfile
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM mikefarah/yq:3
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
4
github-action/entrypoint.sh
Executable file
4
github-action/entrypoint.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh -l
|
||||
|
||||
echo "$1"
|
||||
eval $1
|
||||
19
go.mod
Normal file
19
go.mod
Normal file
@@ -0,0 +1,19 @@
|
||||
module github.com/mikefarah/yq/v4
|
||||
|
||||
require (
|
||||
github.com/elliotchance/orderedmap v1.3.0
|
||||
github.com/fatih/color v1.9.0
|
||||
github.com/goccy/go-yaml v1.8.1
|
||||
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
|
||||
github.com/mattn/go-colorable v0.1.7 // indirect
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/timtadh/data-structures v0.5.3 // indirect
|
||||
github.com/timtadh/lexmachine v0.2.2
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
|
||||
)
|
||||
|
||||
go 1.15
|
||||
188
go.sum
Normal file
188
go.sum
Normal file
@@ -0,0 +1,188 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
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/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
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/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
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/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/elliotchance/orderedmap v1.3.0 h1:k6m77/d0zCXTjsk12nX40TkEBkSICq8T4s6R6bpCqU0=
|
||||
github.com/elliotchance/orderedmap v1.3.0/go.mod h1:8hdSl6jmveQw8ScByd3AaNHNk51RhbTazdqtTty+NFw=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/goccy/go-yaml v1.8.1 h1:JuZRFlqLM5cWF6A+waL8AKVuCcqvKOuhJtUQI+L3ez0=
|
||||
github.com/goccy/go-yaml v1.8.1/go.mod h1:wS4gNoLalDSJxo/SpngzPQ2BN4uuZVLCmbM4S3vd4+Y=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
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/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/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/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.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o=
|
||||
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
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/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
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/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
|
||||
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
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/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/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=
|
||||
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.4.0/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-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
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/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/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
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 v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
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.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=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/timtadh/data-structures v0.5.3 h1:F2tEjoG9qWIyUjbvXVgJqEOGJPMIiYn7U5W5mE+i/vQ=
|
||||
github.com/timtadh/data-structures v0.5.3/go.mod h1:9R4XODhJ8JdWFEI8P/HJKqxuJctfBQw6fDibMQny2oU=
|
||||
github.com/timtadh/lexmachine v0.2.2 h1:g55RnjdYazm5wnKv59pwFcBJHOyvTPfDEoz21s4PHmY=
|
||||
github.com/timtadh/lexmachine v0.2.2/go.mod h1:GBJvD5OAfRn/gnp92zb9KTgHLB7akKyxmVivoYCcjQI=
|
||||
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/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
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.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/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-20181220203305-927f97764cc3/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-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
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/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-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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/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=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190311212946-11955173bddd h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
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=
|
||||
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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 h1:6D+BvnJ/j6e222UW8s2qTSe3wGBtvo0MbVQG/c5k8RE=
|
||||
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/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 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
7
mkdocs.yml
Normal file
7
mkdocs.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
docs_dir: mkdocs
|
||||
site_dir: docs
|
||||
site_name: Yq
|
||||
theme: 'material'
|
||||
repo_name: 'mikefarah/yq'
|
||||
repo_url: 'https://github.com/mikefarah/yq'
|
||||
|
||||
101
pkg/yqlib/candidate_node.go
Normal file
101
pkg/yqlib/candidate_node.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type CandidateNode struct {
|
||||
Node *yaml.Node // the actual node
|
||||
Path []interface{} /// the path we took to get to this node
|
||||
Document uint // the document index of this node
|
||||
Filename string
|
||||
}
|
||||
|
||||
func (n *CandidateNode) GetKey() string {
|
||||
return fmt.Sprintf("%v - %v", n.Document, n.Path)
|
||||
}
|
||||
|
||||
func (n *CandidateNode) Copy() (*CandidateNode, error) {
|
||||
clone := &CandidateNode{}
|
||||
err := copier.Copy(clone, n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clone, nil
|
||||
}
|
||||
|
||||
// updates this candidate from the given candidate node
|
||||
func (n *CandidateNode) UpdateFrom(other *CandidateNode) {
|
||||
n.UpdateAttributesFrom(other)
|
||||
n.Node.Content = other.Node.Content
|
||||
n.Node.Value = other.Node.Value
|
||||
n.Node.Alias = other.Node.Alias
|
||||
}
|
||||
|
||||
func (n *CandidateNode) UpdateAttributesFrom(other *CandidateNode) {
|
||||
if n.Node.Kind != other.Node.Kind {
|
||||
// clear out the contents when switching to a different type
|
||||
// e.g. map to array
|
||||
n.Node.Content = make([]*yaml.Node, 0)
|
||||
n.Node.Value = ""
|
||||
}
|
||||
n.Node.Kind = other.Node.Kind
|
||||
n.Node.Tag = other.Node.Tag
|
||||
|
||||
// merge will pickup the style of the new thing
|
||||
// when autocreating nodes
|
||||
if n.Node.Style == 0 {
|
||||
n.Node.Style = other.Node.Style
|
||||
}
|
||||
n.Node.FootComment = n.Node.FootComment + other.Node.FootComment
|
||||
n.Node.HeadComment = n.Node.HeadComment + other.Node.HeadComment
|
||||
n.Node.LineComment = n.Node.LineComment + other.Node.LineComment
|
||||
}
|
||||
|
||||
func (n *CandidateNode) PathStackToString() string {
|
||||
return mergePathStackToString(n.Path)
|
||||
}
|
||||
|
||||
func mergePathStackToString(pathStack []interface{}) string {
|
||||
var sb strings.Builder
|
||||
for index, path := range pathStack {
|
||||
switch path.(type) {
|
||||
case int, int64:
|
||||
// if arrayMergeStrategy == AppendArrayMergeStrategy {
|
||||
// sb.WriteString("[+]")
|
||||
// } else {
|
||||
sb.WriteString(fmt.Sprintf("[%v]", path))
|
||||
// }
|
||||
|
||||
default:
|
||||
s := fmt.Sprintf("%v", path)
|
||||
var _, errParsingInt = strconv.ParseInt(s, 10, 64) // nolint
|
||||
|
||||
hasSpecial := strings.Contains(s, ".") || strings.Contains(s, "[") || strings.Contains(s, "]") || strings.Contains(s, "\"")
|
||||
hasDoubleQuotes := strings.Contains(s, "\"")
|
||||
wrappingCharacterStart := "\""
|
||||
wrappingCharacterEnd := "\""
|
||||
if hasDoubleQuotes {
|
||||
wrappingCharacterStart = "("
|
||||
wrappingCharacterEnd = ")"
|
||||
}
|
||||
if hasSpecial || errParsingInt == nil {
|
||||
sb.WriteString(wrappingCharacterStart)
|
||||
}
|
||||
sb.WriteString(s)
|
||||
if hasSpecial || errParsingInt == nil {
|
||||
sb.WriteString(wrappingCharacterEnd)
|
||||
}
|
||||
}
|
||||
|
||||
if index < len(pathStack)-1 {
|
||||
sb.WriteString(".")
|
||||
}
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
61
pkg/yqlib/color_print.go
Normal file
61
pkg/yqlib/color_print.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/goccy/go-yaml/lexer"
|
||||
"github.com/goccy/go-yaml/printer"
|
||||
)
|
||||
|
||||
// Thanks @risentveber!
|
||||
|
||||
const escape = "\x1b"
|
||||
|
||||
func format(attr color.Attribute) string {
|
||||
return fmt.Sprintf("%s[%dm", escape, attr)
|
||||
}
|
||||
|
||||
func ColorizeAndPrint(bytes []byte, writer io.Writer) error {
|
||||
tokens := lexer.Tokenize(string(bytes))
|
||||
var p printer.Printer
|
||||
p.Bool = func() *printer.Property {
|
||||
return &printer.Property{
|
||||
Prefix: format(color.FgHiMagenta),
|
||||
Suffix: format(color.Reset),
|
||||
}
|
||||
}
|
||||
p.Number = func() *printer.Property {
|
||||
return &printer.Property{
|
||||
Prefix: format(color.FgHiMagenta),
|
||||
Suffix: format(color.Reset),
|
||||
}
|
||||
}
|
||||
p.MapKey = func() *printer.Property {
|
||||
return &printer.Property{
|
||||
Prefix: format(color.FgCyan),
|
||||
Suffix: format(color.Reset),
|
||||
}
|
||||
}
|
||||
p.Anchor = func() *printer.Property {
|
||||
return &printer.Property{
|
||||
Prefix: format(color.FgHiYellow),
|
||||
Suffix: format(color.Reset),
|
||||
}
|
||||
}
|
||||
p.Alias = func() *printer.Property {
|
||||
return &printer.Property{
|
||||
Prefix: format(color.FgHiYellow),
|
||||
Suffix: format(color.Reset),
|
||||
}
|
||||
}
|
||||
p.String = func() *printer.Property {
|
||||
return &printer.Property{
|
||||
Prefix: format(color.FgGreen),
|
||||
Suffix: format(color.Reset),
|
||||
}
|
||||
}
|
||||
_, err := writer.Write([]byte(p.PrintTokens(tokens) + "\n"))
|
||||
return err
|
||||
}
|
||||
5
pkg/yqlib/constants.go
Normal file
5
pkg/yqlib/constants.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package yqlib
|
||||
|
||||
import "gopkg.in/op/go-logging.v1"
|
||||
|
||||
var log = logging.MustGetLogger("yq-lib")
|
||||
48
pkg/yqlib/data_tree_navigator.go
Normal file
48
pkg/yqlib/data_tree_navigator.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"container/list"
|
||||
|
||||
"gopkg.in/op/go-logging.v1"
|
||||
)
|
||||
|
||||
type dataTreeNavigator struct {
|
||||
navigationPrefs NavigationPrefs
|
||||
}
|
||||
|
||||
type NavigationPrefs struct {
|
||||
FollowAlias bool
|
||||
}
|
||||
|
||||
type DataTreeNavigator interface {
|
||||
// given a list of CandidateEntities and a pathNode,
|
||||
// this will process the list against the given pathNode and return
|
||||
// a new list of matching candidates
|
||||
GetMatchingNodes(matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error)
|
||||
}
|
||||
|
||||
func NewDataTreeNavigator(navigationPrefs NavigationPrefs) DataTreeNavigator {
|
||||
return &dataTreeNavigator{navigationPrefs}
|
||||
}
|
||||
|
||||
func (d *dataTreeNavigator) GetMatchingNodes(matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||
if pathNode == nil {
|
||||
log.Debugf("getMatchingNodes - nothing to do")
|
||||
return matchingNodes, nil
|
||||
}
|
||||
log.Debugf("Processing Op: %v", pathNode.Operation.toString())
|
||||
if log.IsEnabledFor(logging.DEBUG) {
|
||||
for el := matchingNodes.Front(); el != nil; el = el.Next() {
|
||||
log.Debug(NodeToString(el.Value.(*CandidateNode)))
|
||||
}
|
||||
}
|
||||
log.Debug(">>")
|
||||
handler := pathNode.Operation.OperationType.Handler
|
||||
if handler != nil {
|
||||
return handler(d, matchingNodes, pathNode)
|
||||
}
|
||||
return nil, fmt.Errorf("Unknown operator %v", pathNode.Operation.OperationType)
|
||||
|
||||
}
|
||||
163
pkg/yqlib/doc/Assign Operator.md
Normal file
163
pkg/yqlib/doc/Assign Operator.md
Normal file
@@ -0,0 +1,163 @@
|
||||
This operator is used to update node values. It can be used in either the:
|
||||
|
||||
### plain form: `=`
|
||||
Which will assign the LHS node values to the RHS node values. The RHS expression is run against the matching nodes in the pipeline.
|
||||
|
||||
### relative form: `|=`
|
||||
This will do a similar thing to the plain form, however, the RHS expression is run against _the LHS nodes_. This is useful for updating values based on old values, e.g. increment.
|
||||
## Examples
|
||||
### Update parent to be the child value
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b:
|
||||
g: foof
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a |= .b' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
g: foof
|
||||
```
|
||||
|
||||
### Update to be the sibling value
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b: child
|
||||
b: sibling
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a = .b' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: sibling
|
||||
b: sibling
|
||||
```
|
||||
|
||||
### Updated multiple paths
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: fieldA
|
||||
b: fieldB
|
||||
c: fieldC
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '(.a, .c) |= "potatoe"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: potatoe
|
||||
b: fieldB
|
||||
c: potatoe
|
||||
```
|
||||
|
||||
### Update string value
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b: apple
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a.b = "frog"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
b: frog
|
||||
```
|
||||
|
||||
### Update string value via |=
|
||||
Note there is no difference between `=` and `|=` when the RHS is a scalar
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b: apple
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a.b |= "frog"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
b: frog
|
||||
```
|
||||
|
||||
### Update selected results
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b: apple
|
||||
c: cactus
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a[] | select(. == "apple") |= "frog"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
b: frog
|
||||
c: cactus
|
||||
```
|
||||
|
||||
### Update array values
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- candy
|
||||
- apple
|
||||
- sandy
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.[] | select(. == "*andy") |= "bogs"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- bogs
|
||||
- apple
|
||||
- bogs
|
||||
```
|
||||
|
||||
### Update empty object
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
'': null
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a.b |= "bogs"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
'': null
|
||||
a:
|
||||
b: bogs
|
||||
```
|
||||
|
||||
### Update empty object and array
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
'': null
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a.b[0] |= "bogs"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
'': null
|
||||
a:
|
||||
b:
|
||||
- bogs
|
||||
```
|
||||
|
||||
41
pkg/yqlib/doc/Collect into Array.md
Normal file
41
pkg/yqlib/doc/Collect into Array.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Collect into Array
|
||||
|
||||
This creates an array using the expression between the square brackets.
|
||||
|
||||
|
||||
## Examples
|
||||
### Collect empty
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input '[]'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
```
|
||||
|
||||
### Collect single
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input '["cat"]'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- cat
|
||||
```
|
||||
|
||||
### Collect many
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: dog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '[.a, .b]' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- cat
|
||||
- dog
|
||||
```
|
||||
|
||||
79
pkg/yqlib/doc/Collect into Object.md
Normal file
79
pkg/yqlib/doc/Collect into Object.md
Normal file
@@ -0,0 +1,79 @@
|
||||
This is used to construct objects (or maps). This can be used against existing yaml, or to create fresh yaml documents.
|
||||
## Examples
|
||||
### Collect empty object
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input '{}'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
```
|
||||
|
||||
### Wrap (prefix) existing object
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
name: Mike
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '{"wrap": .}' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
wrap:
|
||||
name: Mike
|
||||
```
|
||||
|
||||
### Using splat to create multiple objects
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
name: Mike
|
||||
pets:
|
||||
- cat
|
||||
- dog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '{.name: .pets[]}' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
Mike: cat
|
||||
Mike: dog
|
||||
```
|
||||
|
||||
### Working with multiple documents
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
name: Mike
|
||||
pets:
|
||||
- cat
|
||||
- dog
|
||||
---
|
||||
name: Rosey
|
||||
pets:
|
||||
- monkey
|
||||
- sheep
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '{.name: .pets[]}' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
Mike: cat
|
||||
Mike: dog
|
||||
Rosey: monkey
|
||||
Rosey: sheep
|
||||
```
|
||||
|
||||
### Creating yaml from scratch
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input '{"wrap": "frog"}'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
wrap: frog
|
||||
```
|
||||
|
||||
120
pkg/yqlib/doc/Comments Operator.md
Normal file
120
pkg/yqlib/doc/Comments Operator.md
Normal file
@@ -0,0 +1,120 @@
|
||||
Use these comment operators to set or retrieve comments.
|
||||
## Examples
|
||||
### Set line comment
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a lineComment="single"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: cat # single
|
||||
```
|
||||
|
||||
### Set head comment
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '. headComment="single"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
# single
|
||||
|
||||
a: cat
|
||||
```
|
||||
|
||||
### Set foot comment, using an expression
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '. footComment=.a' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: cat
|
||||
|
||||
# cat
|
||||
```
|
||||
|
||||
### Remove comment
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat # comment
|
||||
b: dog # leave this
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a lineComment=""' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: cat
|
||||
b: dog # leave this
|
||||
```
|
||||
|
||||
### Remove all comments
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat # comment
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.. comments=""' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: cat
|
||||
```
|
||||
|
||||
### Get line comment
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat # meow
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a | lineComment' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
meow
|
||||
```
|
||||
|
||||
### Get head comment
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat # meow
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '. | headComment' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
|
||||
```
|
||||
|
||||
### Get foot comment
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat # meow
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '. | footComment' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
|
||||
```
|
||||
|
||||
66
pkg/yqlib/doc/Delete Operator.md
Normal file
66
pkg/yqlib/doc/Delete Operator.md
Normal file
@@ -0,0 +1,66 @@
|
||||
Deletes matching entries in maps or arrays.
|
||||
## Examples
|
||||
### Delete entry in map
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: dog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval 'del(.b)' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: cat
|
||||
```
|
||||
|
||||
### Delete entry in array
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval 'del(.[1])' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- 1
|
||||
- 3
|
||||
```
|
||||
|
||||
### Delete no matches
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: dog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval 'del(.c)' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: cat
|
||||
b: dog
|
||||
```
|
||||
|
||||
### Delete matching entries
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: dog
|
||||
c: bat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval 'del( .[] | select(. == "*at") )' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
b: dog
|
||||
```
|
||||
|
||||
55
pkg/yqlib/doc/Document Index Operator.md
Normal file
55
pkg/yqlib/doc/Document Index Operator.md
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
## Examples
|
||||
### Retrieve a document index
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
---
|
||||
a: frog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a | documentIndex' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
0
|
||||
---
|
||||
1
|
||||
```
|
||||
|
||||
### Filter by document index
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
---
|
||||
a: frog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval 'select(. | documentIndex == 1)' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: frog
|
||||
```
|
||||
|
||||
### Print Document Index with matches
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
---
|
||||
a: frog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a | ({"match": ., "doc": (. | documentIndex)})' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
match: cat
|
||||
doc: 0
|
||||
match: frog
|
||||
doc: 1
|
||||
```
|
||||
|
||||
62
pkg/yqlib/doc/Equals Operator.md
Normal file
62
pkg/yqlib/doc/Equals Operator.md
Normal file
@@ -0,0 +1,62 @@
|
||||
## Equals Operator
|
||||
|
||||
This is a boolean operator that will return ```true``` if the LHS is equal to the RHS and ``false`` otherwise.
|
||||
|
||||
```
|
||||
.a == .b
|
||||
```
|
||||
|
||||
It is most often used with the select operator to find particular nodes:
|
||||
|
||||
```
|
||||
select(.a == .b)
|
||||
```
|
||||
|
||||
|
||||
## Examples
|
||||
### Match string
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- cat
|
||||
- goat
|
||||
- dog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.[] | (. == "*at")' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
true
|
||||
true
|
||||
false
|
||||
```
|
||||
|
||||
### Match number
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- 3
|
||||
- 4
|
||||
- 5
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.[] | (. == 4)' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
false
|
||||
true
|
||||
false
|
||||
```
|
||||
|
||||
### Match nulls
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input 'null == ~'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
true
|
||||
```
|
||||
|
||||
99
pkg/yqlib/doc/Explode Operator.md
Normal file
99
pkg/yqlib/doc/Explode Operator.md
Normal file
@@ -0,0 +1,99 @@
|
||||
Explodes (or dereferences) aliases and anchors.
|
||||
## Examples
|
||||
### Explode alias and anchor
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
f:
|
||||
a: &a cat
|
||||
b: *a
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval 'explode(.f)' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
f:
|
||||
a: cat
|
||||
b: cat
|
||||
```
|
||||
|
||||
### Explode with no aliases or anchors
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: mike
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval 'explode(.a)' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: mike
|
||||
```
|
||||
|
||||
### Explode with alias keys
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
f:
|
||||
a: &a cat
|
||||
*a: b
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval 'explode(.f)' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
f:
|
||||
a: cat
|
||||
cat: b
|
||||
```
|
||||
|
||||
### Explode with merge anchors
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
foo: &foo
|
||||
a: foo_a
|
||||
thing: foo_thing
|
||||
c: foo_c
|
||||
bar: &bar
|
||||
b: bar_b
|
||||
thing: bar_thing
|
||||
c: bar_c
|
||||
foobarList:
|
||||
b: foobarList_b
|
||||
!!merge <<:
|
||||
- *foo
|
||||
- *bar
|
||||
c: foobarList_c
|
||||
foobar:
|
||||
c: foobar_c
|
||||
!!merge <<: *foo
|
||||
thing: foobar_thing
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval 'explode(.)' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
foo:
|
||||
a: foo_a
|
||||
thing: foo_thing
|
||||
c: foo_c
|
||||
bar:
|
||||
b: bar_b
|
||||
thing: bar_thing
|
||||
c: bar_c
|
||||
foobarList:
|
||||
b: bar_b
|
||||
a: foo_a
|
||||
thing: bar_thing
|
||||
c: foobarList_c
|
||||
foobar:
|
||||
c: foo_c
|
||||
a: foo_a
|
||||
thing: foobar_thing
|
||||
```
|
||||
|
||||
121
pkg/yqlib/doc/Mulitply Operator.md
Normal file
121
pkg/yqlib/doc/Mulitply Operator.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Mulitply Operator
|
||||
## Examples
|
||||
### Merge objects together
|
||||
sample.yml:
|
||||
```yaml
|
||||
{a: {also: me}, b: {also: {g: wizz}}}
|
||||
```
|
||||
Expression
|
||||
```bash
|
||||
yq '. * {"a":.b}' < sample.yml
|
||||
```
|
||||
Result
|
||||
```yaml
|
||||
{a: {also: {g: wizz}}, b: {also: {g: wizz}}}
|
||||
```
|
||||
### Merge keeps style of LHS
|
||||
sample.yml:
|
||||
```yaml
|
||||
a: {things: great}
|
||||
b:
|
||||
also: "me"
|
||||
|
||||
```
|
||||
Expression
|
||||
```bash
|
||||
yq '. * {"a":.b}' < sample.yml
|
||||
```
|
||||
Result
|
||||
```yaml
|
||||
a: {things: great, also: "me"}
|
||||
b:
|
||||
also: "me"
|
||||
```
|
||||
### Merge arrays
|
||||
sample.yml:
|
||||
```yaml
|
||||
{a: [1,2,3], b: [3,4,5]}
|
||||
```
|
||||
Expression
|
||||
```bash
|
||||
yq '. * {"a":.b}' < sample.yml
|
||||
```
|
||||
Result
|
||||
```yaml
|
||||
{a: [3, 4, 5], b: [3, 4, 5]}
|
||||
```
|
||||
### Merge to prefix an element
|
||||
sample.yml:
|
||||
```yaml
|
||||
{a: cat, b: dog}
|
||||
```
|
||||
Expression
|
||||
```bash
|
||||
yq '. * {"a": {"c": .a}}' < sample.yml
|
||||
```
|
||||
Result
|
||||
```yaml
|
||||
{a: {c: cat}, b: dog}
|
||||
```
|
||||
### Merge with simple aliases
|
||||
sample.yml:
|
||||
```yaml
|
||||
{a: &cat {c: frog}, b: {f: *cat}, c: {g: thongs}}
|
||||
```
|
||||
Expression
|
||||
```bash
|
||||
yq '.c * .b' < sample.yml
|
||||
```
|
||||
Result
|
||||
```yaml
|
||||
{g: thongs, f: *cat}
|
||||
```
|
||||
### Merge does not copy anchor names
|
||||
sample.yml:
|
||||
```yaml
|
||||
{a: {c: &cat frog}, b: {f: *cat}, c: {g: thongs}}
|
||||
```
|
||||
Expression
|
||||
```bash
|
||||
yq '.c * .a' < sample.yml
|
||||
```
|
||||
Result
|
||||
```yaml
|
||||
{g: thongs, c: frog}
|
||||
```
|
||||
### Merge with merge anchors
|
||||
sample.yml:
|
||||
```yaml
|
||||
|
||||
foo: &foo
|
||||
a: foo_a
|
||||
thing: foo_thing
|
||||
c: foo_c
|
||||
|
||||
bar: &bar
|
||||
b: bar_b
|
||||
thing: bar_thing
|
||||
c: bar_c
|
||||
|
||||
foobarList:
|
||||
b: foobarList_b
|
||||
<<: [*foo,*bar]
|
||||
c: foobarList_c
|
||||
|
||||
foobar:
|
||||
c: foobar_c
|
||||
<<: *foo
|
||||
thing: foobar_thing
|
||||
|
||||
```
|
||||
Expression
|
||||
```bash
|
||||
yq '.foobar * .foobarList' < sample.yml
|
||||
```
|
||||
Result
|
||||
```yaml
|
||||
c: foobarList_c
|
||||
<<: [*foo, *bar]
|
||||
thing: foobar_thing
|
||||
b: foobarList_b
|
||||
```
|
||||
196
pkg/yqlib/doc/Multiply Operator.md
Normal file
196
pkg/yqlib/doc/Multiply Operator.md
Normal file
@@ -0,0 +1,196 @@
|
||||
Like the multiple operator in `jq`, depending on the operands, this multiply operator will do different things. Currently only objects are supported, which have the effect of merging the RHS into the LHS.
|
||||
|
||||
Upcoming versions of `yq` will add support for other types of multiplication (numbers, strings).
|
||||
|
||||
Note that when merging objects, this operator returns the merged object (not the parent). This will be clearer in the examples below.
|
||||
## Examples
|
||||
### Merge objects together, returning merged result only
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
field: me
|
||||
fieldA: cat
|
||||
b:
|
||||
field:
|
||||
g: wizz
|
||||
fieldB: dog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a * .b' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
field:
|
||||
g: wizz
|
||||
fieldA: cat
|
||||
fieldB: dog
|
||||
```
|
||||
|
||||
### Merge objects together, returning parent object
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
field: me
|
||||
fieldA: cat
|
||||
b:
|
||||
field:
|
||||
g: wizz
|
||||
fieldB: dog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '. * {"a":.b}' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
field:
|
||||
g: wizz
|
||||
fieldA: cat
|
||||
fieldB: dog
|
||||
b:
|
||||
field:
|
||||
g: wizz
|
||||
fieldB: dog
|
||||
```
|
||||
|
||||
### Merge keeps style of LHS
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: {things: great}
|
||||
b:
|
||||
also: "me"
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '. * {"a":.b}' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: {things: great, also: "me"}
|
||||
b:
|
||||
also: "me"
|
||||
```
|
||||
|
||||
### Merge arrays
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
b:
|
||||
- 3
|
||||
- 4
|
||||
- 5
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '. * {"a":.b}' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
- 3
|
||||
- 4
|
||||
- 5
|
||||
b:
|
||||
- 3
|
||||
- 4
|
||||
- 5
|
||||
```
|
||||
|
||||
### Merge to prefix an element
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: dog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '. * {"a": {"c": .a}}' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
c: cat
|
||||
b: dog
|
||||
```
|
||||
|
||||
### Merge with simple aliases
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: &cat
|
||||
c: frog
|
||||
b:
|
||||
f: *cat
|
||||
c:
|
||||
g: thongs
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.c * .b' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
g: thongs
|
||||
f: *cat
|
||||
```
|
||||
|
||||
### Merge does not copy anchor names
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
c: &cat frog
|
||||
b:
|
||||
f: *cat
|
||||
c:
|
||||
g: thongs
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.c * .a' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
g: thongs
|
||||
c: frog
|
||||
```
|
||||
|
||||
### Merge with merge anchors
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
foo: &foo
|
||||
a: foo_a
|
||||
thing: foo_thing
|
||||
c: foo_c
|
||||
bar: &bar
|
||||
b: bar_b
|
||||
thing: bar_thing
|
||||
c: bar_c
|
||||
foobarList:
|
||||
b: foobarList_b
|
||||
!!merge <<:
|
||||
- *foo
|
||||
- *bar
|
||||
c: foobarList_c
|
||||
foobar:
|
||||
c: foobar_c
|
||||
!!merge <<: *foo
|
||||
thing: foobar_thing
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.foobar * .foobarList' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
c: foobarList_c
|
||||
<<:
|
||||
- *foo
|
||||
- *bar
|
||||
thing: foobar_thing
|
||||
b: foobarList_b
|
||||
```
|
||||
|
||||
72
pkg/yqlib/doc/Not Operator.md
Normal file
72
pkg/yqlib/doc/Not Operator.md
Normal file
@@ -0,0 +1,72 @@
|
||||
This is a boolean operator and will return `true` when given a `false` value (including null), and `false` otherwise.
|
||||
## Examples
|
||||
### Not true is false
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input 'true | not'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
false
|
||||
```
|
||||
|
||||
### Not false is true
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input 'false | not'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
true
|
||||
```
|
||||
|
||||
### String values considered to be true
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input '"cat" | not'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
false
|
||||
```
|
||||
|
||||
### Empty string value considered to be true
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input '"" | not'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
false
|
||||
```
|
||||
|
||||
### Numbers are considered to be true
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input '1 | not'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
false
|
||||
```
|
||||
|
||||
### Zero is considered to be true
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input '0 | not'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
false
|
||||
```
|
||||
|
||||
### Null is considered to be false
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input '~ | not'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
true
|
||||
```
|
||||
|
||||
125
pkg/yqlib/doc/Recursive Descent Operator.md
Normal file
125
pkg/yqlib/doc/Recursive Descent Operator.md
Normal file
@@ -0,0 +1,125 @@
|
||||
This operator recursively matches all children nodes given of a particular element, including that node itself. This is most often used to apply a filter recursively against all matches, for instance to set the `style` of all nodes in a yaml doc:
|
||||
|
||||
```bash
|
||||
yq eval '.. style= "flow"' file.yaml
|
||||
```
|
||||
## Examples
|
||||
### Map
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b: apple
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '..' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
b: apple
|
||||
b: apple
|
||||
apple
|
||||
```
|
||||
|
||||
### Array
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '..' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
1
|
||||
2
|
||||
3
|
||||
```
|
||||
|
||||
### Array of maps
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- a: cat
|
||||
- 2
|
||||
- true
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '..' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
- a: cat
|
||||
- 2
|
||||
- true
|
||||
a: cat
|
||||
cat
|
||||
2
|
||||
true
|
||||
```
|
||||
|
||||
### Aliases are not traversed
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: &cat
|
||||
c: frog
|
||||
b: *cat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '..' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: &cat
|
||||
c: frog
|
||||
b: *cat
|
||||
&cat
|
||||
c: frog
|
||||
frog
|
||||
*cat
|
||||
```
|
||||
|
||||
### Merge docs are not traversed
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
foo: &foo
|
||||
a: foo_a
|
||||
thing: foo_thing
|
||||
c: foo_c
|
||||
bar: &bar
|
||||
b: bar_b
|
||||
thing: bar_thing
|
||||
c: bar_c
|
||||
foobarList:
|
||||
b: foobarList_b
|
||||
!!merge <<:
|
||||
- *foo
|
||||
- *bar
|
||||
c: foobarList_c
|
||||
foobar:
|
||||
c: foobar_c
|
||||
!!merge <<: *foo
|
||||
thing: foobar_thing
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.foobar | ..' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
c: foobar_c
|
||||
!!merge <<: *foo
|
||||
thing: foobar_thing
|
||||
foobar_c
|
||||
*foo
|
||||
foobar_thing
|
||||
```
|
||||
|
||||
39
pkg/yqlib/doc/Select Operator.md
Normal file
39
pkg/yqlib/doc/Select Operator.md
Normal file
@@ -0,0 +1,39 @@
|
||||
Select is used to filter arrays and maps by a boolean expression.
|
||||
## Examples
|
||||
### Select elements from array
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- cat
|
||||
- goat
|
||||
- dog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.[] | select(. == "*at")' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
cat
|
||||
goat
|
||||
```
|
||||
|
||||
### Select and update matching values in map
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
things: cat
|
||||
bob: goat
|
||||
horse: dog
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '(.a[] | select(. == "*at")) |= "rabbit"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a:
|
||||
things: rabbit
|
||||
bob: rabbit
|
||||
horse: dog
|
||||
```
|
||||
|
||||
165
pkg/yqlib/doc/Style Operator.md
Normal file
165
pkg/yqlib/doc/Style Operator.md
Normal file
@@ -0,0 +1,165 @@
|
||||
The style operator can be used to get or set the style of nodes (e.g. string style, yaml style)
|
||||
## Examples
|
||||
### Set tagged style
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: 5
|
||||
c: 3.2
|
||||
e: true
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.. style="tagged"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
!!map
|
||||
a: !!str cat
|
||||
b: !!int 5
|
||||
c: !!float 3.2
|
||||
e: !!bool true
|
||||
```
|
||||
|
||||
### Set double quote style
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: 5
|
||||
c: 3.2
|
||||
e: true
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.. style="double"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: "cat"
|
||||
b: "5"
|
||||
c: "3.2"
|
||||
e: "true"
|
||||
```
|
||||
|
||||
### Set single quote style
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: 5
|
||||
c: 3.2
|
||||
e: true
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.. style="single"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: 'cat'
|
||||
b: '5'
|
||||
c: '3.2'
|
||||
e: 'true'
|
||||
```
|
||||
|
||||
### Set literal quote style
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: 5
|
||||
c: 3.2
|
||||
e: true
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.. style="literal"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: |-
|
||||
cat
|
||||
b: |-
|
||||
5
|
||||
c: |-
|
||||
3.2
|
||||
e: |-
|
||||
true
|
||||
```
|
||||
|
||||
### Set folded quote style
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: 5
|
||||
c: 3.2
|
||||
e: true
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.. style="folded"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: >-
|
||||
cat
|
||||
b: >-
|
||||
5
|
||||
c: >-
|
||||
3.2
|
||||
e: >-
|
||||
true
|
||||
```
|
||||
|
||||
### Set flow quote style
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: 5
|
||||
c: 3.2
|
||||
e: true
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.. style="flow"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
{a: cat, b: 5, c: 3.2, e: true}
|
||||
```
|
||||
|
||||
### Set empty (default) quote style
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: 5
|
||||
c: 3.2
|
||||
e: true
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.. style=""' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: cat
|
||||
b: 5
|
||||
c: 3.2
|
||||
e: true
|
||||
```
|
||||
|
||||
### Read style
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: thing
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.. | style' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
45
pkg/yqlib/doc/Tag Operator.md
Normal file
45
pkg/yqlib/doc/Tag Operator.md
Normal file
@@ -0,0 +1,45 @@
|
||||
The tag operator can be used to get or set the tag of ndoes (e.g. `!!str`, `!!int`, `!!bool`).
|
||||
## Examples
|
||||
### Get tag
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: 5
|
||||
c: 3.2
|
||||
e: true
|
||||
f: []
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.. | tag' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
!!map
|
||||
!!str
|
||||
!!int
|
||||
!!float
|
||||
!!bool
|
||||
!!seq
|
||||
```
|
||||
|
||||
### Convert numbers to strings
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: cat
|
||||
b: 5
|
||||
c: 3.2
|
||||
e: true
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '(.. | select(tag == "!!int")) tag= "!!str"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
a: cat
|
||||
b: "5"
|
||||
c: 3.2
|
||||
e: true
|
||||
```
|
||||
|
||||
353
pkg/yqlib/doc/Traverse Operator.md
Normal file
353
pkg/yqlib/doc/Traverse Operator.md
Normal file
@@ -0,0 +1,353 @@
|
||||
This is the simples (and perhaps most used) operator, it is used to navigate deeply into yaml structurse.
|
||||
## Examples
|
||||
### Simple map navigation
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
b: apple
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
b: apple
|
||||
```
|
||||
|
||||
### Splat
|
||||
Often used to pipe children into other operators
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- b: apple
|
||||
- c: banana
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.[]' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
b: apple
|
||||
c: banana
|
||||
```
|
||||
|
||||
### Children don't exist
|
||||
Nodes are added dynamically while traversing
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
c: banana
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a.b' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
null
|
||||
```
|
||||
|
||||
### Wildcard matching
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a:
|
||||
cat: apple
|
||||
mad: things
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a."*a*"' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
apple
|
||||
things
|
||||
```
|
||||
|
||||
### Aliases
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: &cat
|
||||
c: frog
|
||||
b: *cat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.b' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
*cat
|
||||
```
|
||||
|
||||
### Traversing aliases with splat
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: &cat
|
||||
c: frog
|
||||
b: *cat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.b.[]' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
frog
|
||||
```
|
||||
|
||||
### Traversing aliases explicitly
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: &cat
|
||||
c: frog
|
||||
b: *cat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.b.c' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
frog
|
||||
```
|
||||
|
||||
### Traversing arrays by index
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '[0]' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
1
|
||||
```
|
||||
|
||||
### Maps with numeric keys
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
2: cat
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '[2]' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
cat
|
||||
```
|
||||
|
||||
### Maps with non existing numeric keys
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: b
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '[0]' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
null
|
||||
```
|
||||
|
||||
### Traversing merge anchors
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
foo: &foo
|
||||
a: foo_a
|
||||
thing: foo_thing
|
||||
c: foo_c
|
||||
bar: &bar
|
||||
b: bar_b
|
||||
thing: bar_thing
|
||||
c: bar_c
|
||||
foobarList:
|
||||
b: foobarList_b
|
||||
!!merge <<:
|
||||
- *foo
|
||||
- *bar
|
||||
c: foobarList_c
|
||||
foobar:
|
||||
c: foobar_c
|
||||
!!merge <<: *foo
|
||||
thing: foobar_thing
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.foobar.a' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
foo_a
|
||||
```
|
||||
|
||||
### Traversing merge anchors with override
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
foo: &foo
|
||||
a: foo_a
|
||||
thing: foo_thing
|
||||
c: foo_c
|
||||
bar: &bar
|
||||
b: bar_b
|
||||
thing: bar_thing
|
||||
c: bar_c
|
||||
foobarList:
|
||||
b: foobarList_b
|
||||
!!merge <<:
|
||||
- *foo
|
||||
- *bar
|
||||
c: foobarList_c
|
||||
foobar:
|
||||
c: foobar_c
|
||||
!!merge <<: *foo
|
||||
thing: foobar_thing
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.foobar.c' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
foo_c
|
||||
```
|
||||
|
||||
### Traversing merge anchors with local override
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
foo: &foo
|
||||
a: foo_a
|
||||
thing: foo_thing
|
||||
c: foo_c
|
||||
bar: &bar
|
||||
b: bar_b
|
||||
thing: bar_thing
|
||||
c: bar_c
|
||||
foobarList:
|
||||
b: foobarList_b
|
||||
!!merge <<:
|
||||
- *foo
|
||||
- *bar
|
||||
c: foobarList_c
|
||||
foobar:
|
||||
c: foobar_c
|
||||
!!merge <<: *foo
|
||||
thing: foobar_thing
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.foobar.thing' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
foobar_thing
|
||||
```
|
||||
|
||||
### Splatting merge anchors
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
foo: &foo
|
||||
a: foo_a
|
||||
thing: foo_thing
|
||||
c: foo_c
|
||||
bar: &bar
|
||||
b: bar_b
|
||||
thing: bar_thing
|
||||
c: bar_c
|
||||
foobarList:
|
||||
b: foobarList_b
|
||||
!!merge <<:
|
||||
- *foo
|
||||
- *bar
|
||||
c: foobarList_c
|
||||
foobar:
|
||||
c: foobar_c
|
||||
!!merge <<: *foo
|
||||
thing: foobar_thing
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.foobar.[]' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
foo_c
|
||||
foo_a
|
||||
foobar_thing
|
||||
```
|
||||
|
||||
### Traversing merge anchor lists
|
||||
Note that the later merge anchors override previous
|
||||
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
foo: &foo
|
||||
a: foo_a
|
||||
thing: foo_thing
|
||||
c: foo_c
|
||||
bar: &bar
|
||||
b: bar_b
|
||||
thing: bar_thing
|
||||
c: bar_c
|
||||
foobarList:
|
||||
b: foobarList_b
|
||||
!!merge <<:
|
||||
- *foo
|
||||
- *bar
|
||||
c: foobarList_c
|
||||
foobar:
|
||||
c: foobar_c
|
||||
!!merge <<: *foo
|
||||
thing: foobar_thing
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.foobarList.thing' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
bar_thing
|
||||
```
|
||||
|
||||
### Splatting merge anchor lists
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
foo: &foo
|
||||
a: foo_a
|
||||
thing: foo_thing
|
||||
c: foo_c
|
||||
bar: &bar
|
||||
b: bar_b
|
||||
thing: bar_thing
|
||||
c: bar_c
|
||||
foobarList:
|
||||
b: foobarList_b
|
||||
!!merge <<:
|
||||
- *foo
|
||||
- *bar
|
||||
c: foobarList_c
|
||||
foobar:
|
||||
c: foobar_c
|
||||
!!merge <<: *foo
|
||||
thing: foobar_thing
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.foobarList.[]' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
bar_b
|
||||
foo_a
|
||||
bar_thing
|
||||
foobarList_c
|
||||
```
|
||||
|
||||
31
pkg/yqlib/doc/Union Operator.md
Normal file
31
pkg/yqlib/doc/Union Operator.md
Normal file
@@ -0,0 +1,31 @@
|
||||
This operator is used to combine different results together.
|
||||
## Examples
|
||||
### Combine scalars
|
||||
Running
|
||||
```bash
|
||||
yq eval --null-input '1, true, "cat"'
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
1
|
||||
true
|
||||
cat
|
||||
```
|
||||
|
||||
### Combine selected paths
|
||||
Given a sample.yml file of:
|
||||
```yaml
|
||||
a: fieldA
|
||||
b: fieldB
|
||||
c: fieldC
|
||||
```
|
||||
then
|
||||
```bash
|
||||
yq eval '.a, .c' sample.yml
|
||||
```
|
||||
will output
|
||||
```yaml
|
||||
fieldA
|
||||
fieldC
|
||||
```
|
||||
|
||||
7
pkg/yqlib/doc/headers/Assign Operator.md
Normal file
7
pkg/yqlib/doc/headers/Assign Operator.md
Normal file
@@ -0,0 +1,7 @@
|
||||
This operator is used to update node values. It can be used in either the:
|
||||
|
||||
### plain form: `=`
|
||||
Which will assign the LHS node values to the RHS node values. The RHS expression is run against the matching nodes in the pipeline.
|
||||
|
||||
### relative form: `|=`
|
||||
This will do a similar thing to the plain form, however, the RHS expression is run against _the LHS nodes_. This is useful for updating values based on old values, e.g. increment.
|
||||
4
pkg/yqlib/doc/headers/Collect into Array.md
Normal file
4
pkg/yqlib/doc/headers/Collect into Array.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# Collect into Array
|
||||
|
||||
This creates an array using the expression between the square brackets.
|
||||
|
||||
1
pkg/yqlib/doc/headers/Collect into Object.md
Normal file
1
pkg/yqlib/doc/headers/Collect into Object.md
Normal file
@@ -0,0 +1 @@
|
||||
This is used to construct objects (or maps). This can be used against existing yaml, or to create fresh yaml documents.
|
||||
1
pkg/yqlib/doc/headers/Comments Operator.md
Normal file
1
pkg/yqlib/doc/headers/Comments Operator.md
Normal file
@@ -0,0 +1 @@
|
||||
Use these comment operators to set or retrieve comments.
|
||||
1
pkg/yqlib/doc/headers/Delete Operator.md
Normal file
1
pkg/yqlib/doc/headers/Delete Operator.md
Normal file
@@ -0,0 +1 @@
|
||||
Deletes matching entries in maps or arrays.
|
||||
14
pkg/yqlib/doc/headers/Equals Operator.md
Normal file
14
pkg/yqlib/doc/headers/Equals Operator.md
Normal file
@@ -0,0 +1,14 @@
|
||||
## Equals Operator
|
||||
|
||||
This is a boolean operator that will return ```true``` if the LHS is equal to the RHS and ``false`` otherwise.
|
||||
|
||||
```
|
||||
.a == .b
|
||||
```
|
||||
|
||||
It is most often used with the select operator to find particular nodes:
|
||||
|
||||
```
|
||||
select(.a == .b)
|
||||
```
|
||||
|
||||
1
pkg/yqlib/doc/headers/Explode Operator.md
Normal file
1
pkg/yqlib/doc/headers/Explode Operator.md
Normal file
@@ -0,0 +1 @@
|
||||
Explodes (or dereferences) aliases and anchors.
|
||||
5
pkg/yqlib/doc/headers/Multiply Operator.md
Normal file
5
pkg/yqlib/doc/headers/Multiply Operator.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Like the multiple operator in `jq`, depending on the operands, this multiply operator will do different things. Currently only objects are supported, which have the effect of merging the RHS into the LHS.
|
||||
|
||||
Upcoming versions of `yq` will add support for other types of multiplication (numbers, strings).
|
||||
|
||||
Note that when merging objects, this operator returns the merged object (not the parent). This will be clearer in the examples below.
|
||||
1
pkg/yqlib/doc/headers/Not Operator.md
Normal file
1
pkg/yqlib/doc/headers/Not Operator.md
Normal file
@@ -0,0 +1 @@
|
||||
This is a boolean operator and will return `true` when given a `false` value (including null), and `false` otherwise.
|
||||
5
pkg/yqlib/doc/headers/Recursive Descent Operator.md
Normal file
5
pkg/yqlib/doc/headers/Recursive Descent Operator.md
Normal file
@@ -0,0 +1,5 @@
|
||||
This operator recursively matches all children nodes given of a particular element, including that node itself. This is most often used to apply a filter recursively against all matches, for instance to set the `style` of all nodes in a yaml doc:
|
||||
|
||||
```bash
|
||||
yq eval '.. style= "flow"' file.yaml
|
||||
```
|
||||
1
pkg/yqlib/doc/headers/Select Operator.md
Normal file
1
pkg/yqlib/doc/headers/Select Operator.md
Normal file
@@ -0,0 +1 @@
|
||||
Select is used to filter arrays and maps by a boolean expression.
|
||||
1
pkg/yqlib/doc/headers/Style Operator.md
Normal file
1
pkg/yqlib/doc/headers/Style Operator.md
Normal file
@@ -0,0 +1 @@
|
||||
The style operator can be used to get or set the style of nodes (e.g. string style, yaml style)
|
||||
1
pkg/yqlib/doc/headers/Tag Operator.md
Normal file
1
pkg/yqlib/doc/headers/Tag Operator.md
Normal file
@@ -0,0 +1 @@
|
||||
The tag operator can be used to get or set the tag of ndoes (e.g. `!!str`, `!!int`, `!!bool`).
|
||||
1
pkg/yqlib/doc/headers/Traverse Operator.md
Normal file
1
pkg/yqlib/doc/headers/Traverse Operator.md
Normal file
@@ -0,0 +1 @@
|
||||
This is the simples (and perhaps most used) operator, it is used to navigate deeply into yaml structurse.
|
||||
1
pkg/yqlib/doc/headers/Union Operator.md
Normal file
1
pkg/yqlib/doc/headers/Union Operator.md
Normal file
@@ -0,0 +1 @@
|
||||
This operator is used to combine different results together.
|
||||
20
pkg/yqlib/document_index_operator.go
Normal file
20
pkg/yqlib/document_index_operator.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func GetDocumentIndexOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||
var results = list.New()
|
||||
|
||||
for el := matchingNodes.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
node := &yaml.Node{Kind: yaml.ScalarNode, Value: fmt.Sprintf("%v", candidate.Document), Tag: "!!int"}
|
||||
scalar := &CandidateNode{Node: node, Document: candidate.Document, Path: candidate.Path}
|
||||
results.PushBack(scalar)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
41
pkg/yqlib/document_index_operator_test.go
Normal file
41
pkg/yqlib/document_index_operator_test.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var documentIndexScenarios = []expressionScenario{
|
||||
{
|
||||
description: "Retrieve a document index",
|
||||
document: "a: cat\n---\na: frog\n",
|
||||
expression: `.a | documentIndex`,
|
||||
expected: []string{
|
||||
"D0, P[a], (!!int)::0\n",
|
||||
"D1, P[a], (!!int)::1\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Filter by document index",
|
||||
document: "a: cat\n---\na: frog\n",
|
||||
expression: `select(. | documentIndex == 1)`,
|
||||
expected: []string{
|
||||
"D1, P[], (doc)::a: frog\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Print Document Index with matches",
|
||||
document: "a: cat\n---\na: frog\n",
|
||||
expression: `.a | ({"match": ., "doc": (. | documentIndex)})`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::match: cat\ndoc: 0\n",
|
||||
"D0, P[], (!!map)::match: frog\ndoc: 1\n",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestDocumentIndexScenarios(t *testing.T) {
|
||||
for _, tt := range documentIndexScenarios {
|
||||
testScenario(t, &tt)
|
||||
}
|
||||
documentScenarios(t, "Document Index Operator", documentIndexScenarios)
|
||||
}
|
||||
247
pkg/yqlib/encoder.go
Normal file
247
pkg/yqlib/encoder.go
Normal file
@@ -0,0 +1,247 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type Encoder interface {
|
||||
Encode(node *yaml.Node) error
|
||||
}
|
||||
|
||||
type yamlEncoder struct {
|
||||
destination io.Writer
|
||||
indent int
|
||||
colorise bool
|
||||
firstDoc bool
|
||||
}
|
||||
|
||||
func NewYamlEncoder(destination io.Writer, indent int, colorise bool) Encoder {
|
||||
if indent < 0 {
|
||||
indent = 0
|
||||
}
|
||||
return &yamlEncoder{destination, indent, colorise, true}
|
||||
}
|
||||
|
||||
func (ye *yamlEncoder) Encode(node *yaml.Node) error {
|
||||
|
||||
destination := ye.destination
|
||||
tempBuffer := bytes.NewBuffer(nil)
|
||||
if ye.colorise {
|
||||
destination = tempBuffer
|
||||
}
|
||||
|
||||
var encoder = yaml.NewEncoder(destination)
|
||||
|
||||
encoder.SetIndent(ye.indent)
|
||||
// TODO: work out if the first doc had a separator or not.
|
||||
if ye.firstDoc {
|
||||
ye.firstDoc = false
|
||||
} else if _, err := destination.Write([]byte("---\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := encoder.Encode(node); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ye.colorise {
|
||||
return ColorizeAndPrint(tempBuffer.Bytes(), ye.destination)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type jsonEncoder struct {
|
||||
encoder *json.Encoder
|
||||
}
|
||||
|
||||
func mapKeysToStrings(node *yaml.Node) {
|
||||
|
||||
if node.Kind == yaml.MappingNode {
|
||||
for index, child := range node.Content {
|
||||
if index%2 == 0 { // its a map key
|
||||
child.Tag = "!!str"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, child := range node.Content {
|
||||
mapKeysToStrings(child)
|
||||
}
|
||||
}
|
||||
|
||||
func NewJsonEncoder(destination io.Writer, indent int) Encoder {
|
||||
var encoder = json.NewEncoder(destination)
|
||||
var indentString = ""
|
||||
|
||||
for index := 0; index < indent; index++ {
|
||||
indentString = indentString + " "
|
||||
}
|
||||
encoder.SetIndent("", indentString)
|
||||
return &jsonEncoder{encoder}
|
||||
}
|
||||
|
||||
func (je *jsonEncoder) Encode(node *yaml.Node) error {
|
||||
var dataBucket orderedMap
|
||||
// firstly, convert all map keys to strings
|
||||
mapKeysToStrings(node)
|
||||
errorDecoding := node.Decode(&dataBucket)
|
||||
if errorDecoding != nil {
|
||||
return errorDecoding
|
||||
}
|
||||
return je.encoder.Encode(dataBucket)
|
||||
}
|
||||
|
||||
// orderedMap allows to marshal and unmarshal JSON and YAML values keeping the
|
||||
// order of keys and values in a map or an object.
|
||||
type orderedMap struct {
|
||||
// if this is an object, kv != nil. If this is not an object, kv == nil.
|
||||
kv []orderedMapKV
|
||||
altVal interface{}
|
||||
}
|
||||
|
||||
type orderedMapKV struct {
|
||||
K string
|
||||
V orderedMap
|
||||
}
|
||||
|
||||
func (o *orderedMap) UnmarshalJSON(data []byte) error {
|
||||
switch data[0] {
|
||||
case '{':
|
||||
// initialise so that even if the object is empty it is not nil
|
||||
o.kv = []orderedMapKV{}
|
||||
|
||||
// create decoder
|
||||
dec := json.NewDecoder(bytes.NewReader(data))
|
||||
_, err := dec.Token() // open object
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// cycle through k/v
|
||||
var tok json.Token
|
||||
for tok, err = dec.Token(); err != io.EOF; tok, err = dec.Token() {
|
||||
// we can expect two types: string or Delim. Delim automatically means
|
||||
// that it is the closing bracket of the object, whereas string means
|
||||
// that there is another key.
|
||||
if _, ok := tok.(json.Delim); ok {
|
||||
break
|
||||
}
|
||||
kv := orderedMapKV{
|
||||
K: tok.(string),
|
||||
}
|
||||
if err := dec.Decode(&kv.V); err != nil {
|
||||
return err
|
||||
}
|
||||
o.kv = append(o.kv, kv)
|
||||
}
|
||||
// unexpected error
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case '[':
|
||||
var arr []orderedMap
|
||||
return json.Unmarshal(data, &arr)
|
||||
}
|
||||
|
||||
return json.Unmarshal(data, &o.altVal)
|
||||
}
|
||||
|
||||
func (o orderedMap) MarshalJSON() ([]byte, error) {
|
||||
if o.kv == nil {
|
||||
return json.Marshal(o.altVal)
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
enc := json.NewEncoder(buf)
|
||||
buf.WriteByte('{')
|
||||
for idx, el := range o.kv {
|
||||
if err := enc.Encode(el.K); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf.WriteByte(':')
|
||||
if err := enc.Encode(el.V); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if idx != len(o.kv)-1 {
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
}
|
||||
buf.WriteByte('}')
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (o *orderedMap) UnmarshalYAML(node *yaml.Node) error {
|
||||
switch node.Kind {
|
||||
case yaml.DocumentNode:
|
||||
if len(node.Content) == 0 {
|
||||
return nil
|
||||
}
|
||||
return o.UnmarshalYAML(node.Content[0])
|
||||
case yaml.AliasNode:
|
||||
return o.UnmarshalYAML(node.Alias)
|
||||
case yaml.ScalarNode:
|
||||
return node.Decode(&o.altVal)
|
||||
case yaml.MappingNode:
|
||||
// set kv to non-nil
|
||||
o.kv = []orderedMapKV{}
|
||||
for i := 0; i < len(node.Content); i += 2 {
|
||||
var key string
|
||||
var val orderedMap
|
||||
if err := node.Content[i].Decode(&key); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := node.Content[i+1].Decode(&val); err != nil {
|
||||
return err
|
||||
}
|
||||
o.kv = append(o.kv, orderedMapKV{
|
||||
K: key,
|
||||
V: val,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
case yaml.SequenceNode:
|
||||
var res []orderedMap
|
||||
if err := node.Decode(&res); err != nil {
|
||||
return err
|
||||
}
|
||||
o.altVal = res
|
||||
o.kv = nil
|
||||
return nil
|
||||
case 0:
|
||||
// null
|
||||
o.kv = nil
|
||||
o.altVal = nil
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("orderedMap: invalid yaml node")
|
||||
}
|
||||
}
|
||||
|
||||
func (o *orderedMap) MarshalYAML() (interface{}, error) {
|
||||
// fast path: kv is nil, use altVal
|
||||
if o.kv == nil {
|
||||
return o.altVal, nil
|
||||
}
|
||||
content := make([]*yaml.Node, 0, len(o.kv)*2)
|
||||
for _, val := range o.kv {
|
||||
n := new(yaml.Node)
|
||||
if err := n.Encode(val.V); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content = append(content, &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!str",
|
||||
Value: val.K,
|
||||
}, n)
|
||||
}
|
||||
return &yaml.Node{
|
||||
Kind: yaml.MappingNode,
|
||||
Tag: "!!map",
|
||||
Content: content,
|
||||
}, nil
|
||||
}
|
||||
47
pkg/yqlib/encoder_test.go
Normal file
47
pkg/yqlib/encoder_test.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mikefarah/yq/v4/test"
|
||||
)
|
||||
|
||||
var sampleYaml = `zabbix: winner
|
||||
apple: great
|
||||
banana:
|
||||
- {cobra: kai, angus: bob}
|
||||
`
|
||||
|
||||
var expectedJson = `{
|
||||
"zabbix": "winner",
|
||||
"apple": "great",
|
||||
"banana": [
|
||||
{
|
||||
"cobra": "kai",
|
||||
"angus": "bob"
|
||||
}
|
||||
]
|
||||
}
|
||||
`
|
||||
|
||||
func TestJsonEncoderPreservesObjectOrder(t *testing.T) {
|
||||
var output bytes.Buffer
|
||||
writer := bufio.NewWriter(&output)
|
||||
|
||||
var jsonEncoder = NewJsonEncoder(writer, 2)
|
||||
inputs, err := readDocuments(strings.NewReader(sampleYaml), "sample.yml")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
node := inputs.Front().Value.(*CandidateNode).Node
|
||||
err = jsonEncoder.Encode(node)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
writer.Flush()
|
||||
test.AssertResult(t, expectedJson, output.String())
|
||||
|
||||
}
|
||||
174
pkg/yqlib/lib.go
Normal file
174
pkg/yqlib/lib.go
Normal file
@@ -0,0 +1,174 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"container/list"
|
||||
"fmt"
|
||||
|
||||
logging "gopkg.in/op/go-logging.v1"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type OperationType struct {
|
||||
Type string
|
||||
NumArgs uint // number of arguments to the op
|
||||
Precedence uint
|
||||
Handler OperatorHandler
|
||||
}
|
||||
|
||||
// operators TODO:
|
||||
// - get path operator (like doc index)
|
||||
// - get file index op (like doc index)
|
||||
// - get file name op (like doc index)
|
||||
// - write in place
|
||||
// - mergeAppend (merges and appends arrays)
|
||||
// - mergeEmpty (sets only if the document is empty, do I do that now?)
|
||||
// - compare ??
|
||||
// - validate ??
|
||||
// - exists
|
||||
|
||||
var Or = &OperationType{Type: "OR", NumArgs: 2, Precedence: 20, Handler: OrOperator}
|
||||
var And = &OperationType{Type: "AND", NumArgs: 2, Precedence: 20, Handler: AndOperator}
|
||||
|
||||
var Union = &OperationType{Type: "UNION", NumArgs: 2, Precedence: 10, Handler: UnionOperator}
|
||||
|
||||
var Assign = &OperationType{Type: "ASSIGN", NumArgs: 2, Precedence: 40, Handler: AssignUpdateOperator}
|
||||
|
||||
var AssignAttributes = &OperationType{Type: "ASSIGN_ATTRIBUTES", NumArgs: 2, Precedence: 40, Handler: AssignAttributesOperator}
|
||||
var AssignStyle = &OperationType{Type: "ASSIGN_STYLE", NumArgs: 2, Precedence: 40, Handler: AssignStyleOperator}
|
||||
var AssignTag = &OperationType{Type: "ASSIGN_TAG", NumArgs: 2, Precedence: 40, Handler: AssignTagOperator}
|
||||
var AssignComment = &OperationType{Type: "ASSIGN_COMMENT", NumArgs: 2, Precedence: 40, Handler: AssignCommentsOperator}
|
||||
|
||||
var Multiply = &OperationType{Type: "MULTIPLY", NumArgs: 2, Precedence: 40, Handler: MultiplyOperator}
|
||||
|
||||
var Equals = &OperationType{Type: "EQUALS", NumArgs: 2, Precedence: 40, Handler: EqualsOperator}
|
||||
var CreateMap = &OperationType{Type: "CREATE_MAP", NumArgs: 2, Precedence: 40, Handler: CreateMapOperator}
|
||||
var Pipe = &OperationType{Type: "PIPE", NumArgs: 2, Precedence: 45, Handler: PipeOperator}
|
||||
|
||||
var Length = &OperationType{Type: "LENGTH", NumArgs: 0, Precedence: 50, Handler: LengthOperator}
|
||||
var Collect = &OperationType{Type: "COLLECT", NumArgs: 0, Precedence: 50, Handler: CollectOperator}
|
||||
var GetStyle = &OperationType{Type: "GET_STYLE", NumArgs: 0, Precedence: 50, Handler: GetStyleOperator}
|
||||
var GetTag = &OperationType{Type: "GET_TAG", NumArgs: 0, Precedence: 50, Handler: GetTagOperator}
|
||||
var GetComment = &OperationType{Type: "GET_COMMENT", NumArgs: 0, Precedence: 50, Handler: GetCommentsOperator}
|
||||
var GetDocumentIndex = &OperationType{Type: "GET_DOCUMENT_INDEX", NumArgs: 0, Precedence: 50, Handler: GetDocumentIndexOperator}
|
||||
|
||||
var Explode = &OperationType{Type: "EXPLODE", NumArgs: 1, Precedence: 50, Handler: ExplodeOperator}
|
||||
|
||||
var CollectObject = &OperationType{Type: "COLLECT_OBJECT", NumArgs: 0, Precedence: 50, Handler: CollectObjectOperator}
|
||||
var TraversePath = &OperationType{Type: "TRAVERSE_PATH", NumArgs: 0, Precedence: 50, Handler: TraversePathOperator}
|
||||
|
||||
var DocumentFilter = &OperationType{Type: "DOCUMENT_FILTER", NumArgs: 0, Precedence: 50, Handler: TraversePathOperator}
|
||||
var SelfReference = &OperationType{Type: "SELF", NumArgs: 0, Precedence: 50, Handler: SelfOperator}
|
||||
var ValueOp = &OperationType{Type: "VALUE", NumArgs: 0, Precedence: 50, Handler: ValueOperator}
|
||||
var Not = &OperationType{Type: "NOT", NumArgs: 0, Precedence: 50, Handler: NotOperator}
|
||||
var Empty = &OperationType{Type: "EMPTY", NumArgs: 50, Handler: EmptyOperator}
|
||||
|
||||
var RecursiveDescent = &OperationType{Type: "RECURSIVE_DESCENT", NumArgs: 0, Precedence: 50, Handler: RecursiveDescentOperator}
|
||||
|
||||
var Select = &OperationType{Type: "SELECT", NumArgs: 1, Precedence: 50, Handler: SelectOperator}
|
||||
var DeleteChild = &OperationType{Type: "DELETE", NumArgs: 1, Precedence: 40, Handler: DeleteChildOperator}
|
||||
|
||||
// var Exists = &OperationType{Type: "Length", NumArgs: 2, Precedence: 35}
|
||||
// filters matches if they have the existing path
|
||||
|
||||
type Operation struct {
|
||||
OperationType *OperationType
|
||||
Value interface{}
|
||||
StringValue string
|
||||
CandidateNode *CandidateNode // used for Value Path elements
|
||||
Preferences interface{}
|
||||
}
|
||||
|
||||
func CreateValueOperation(value interface{}, stringValue string) *Operation {
|
||||
var node yaml.Node = yaml.Node{Kind: yaml.ScalarNode}
|
||||
node.Value = stringValue
|
||||
|
||||
switch value.(type) {
|
||||
case float32, float64:
|
||||
node.Tag = "!!float"
|
||||
case int, int64, int32:
|
||||
node.Tag = "!!int"
|
||||
case bool:
|
||||
node.Tag = "!!bool"
|
||||
case string:
|
||||
node.Tag = "!!str"
|
||||
case nil:
|
||||
node.Tag = "!!null"
|
||||
}
|
||||
|
||||
return &Operation{
|
||||
OperationType: ValueOp,
|
||||
Value: value,
|
||||
StringValue: stringValue,
|
||||
CandidateNode: &CandidateNode{Node: &node},
|
||||
}
|
||||
}
|
||||
|
||||
// debugging purposes only
|
||||
func (p *Operation) toString() string {
|
||||
if p.OperationType == TraversePath {
|
||||
return fmt.Sprintf("%v", p.Value)
|
||||
} else if p.OperationType == DocumentFilter {
|
||||
return fmt.Sprintf("d%v", p.Value)
|
||||
} else if p.OperationType == SelfReference {
|
||||
return "SELF"
|
||||
} else if p.OperationType == ValueOp {
|
||||
return fmt.Sprintf("%v (%T)", p.Value, p.Value)
|
||||
} else {
|
||||
return fmt.Sprintf("%v", p.OperationType.Type)
|
||||
}
|
||||
}
|
||||
|
||||
//use for debugging only
|
||||
func NodesToString(collection *list.List) string {
|
||||
if !log.IsEnabledFor(logging.DEBUG) {
|
||||
return ""
|
||||
}
|
||||
|
||||
result := ""
|
||||
for el := collection.Front(); el != nil; el = el.Next() {
|
||||
result = result + "\n" + NodeToString(el.Value.(*CandidateNode))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func NodeToString(node *CandidateNode) string {
|
||||
if !log.IsEnabledFor(logging.DEBUG) {
|
||||
return ""
|
||||
}
|
||||
value := node.Node
|
||||
if value == nil {
|
||||
return "-- nil --"
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
encoder := yaml.NewEncoder(buf)
|
||||
errorEncoding := encoder.Encode(value)
|
||||
if errorEncoding != nil {
|
||||
log.Error("Error debugging node, %v", errorEncoding.Error())
|
||||
}
|
||||
encoder.Close()
|
||||
tag := value.Tag
|
||||
if value.Kind == yaml.DocumentNode {
|
||||
tag = "doc"
|
||||
} else if value.Kind == yaml.AliasNode {
|
||||
tag = "alias"
|
||||
}
|
||||
return fmt.Sprintf(`D%v, P%v, (%v)::%v`, node.Document, node.Path, tag, buf.String())
|
||||
}
|
||||
|
||||
func KindString(kind yaml.Kind) string {
|
||||
switch kind {
|
||||
case yaml.ScalarNode:
|
||||
return "ScalarNode"
|
||||
case yaml.SequenceNode:
|
||||
return "SequenceNode"
|
||||
case yaml.MappingNode:
|
||||
return "MappingNode"
|
||||
case yaml.DocumentNode:
|
||||
return "DocumentNode"
|
||||
case yaml.AliasNode:
|
||||
return "AliasNode"
|
||||
default:
|
||||
return "unknown!"
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user