Compare commits
983 Commits
lp-test-re
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
efc8e97d40 | ||
![]() |
ae0dfb3126 | ||
![]() |
cc01781c31 | ||
![]() |
5acd6984d0 | ||
![]() |
4e3c0d465a | ||
![]() |
266cde4510 | ||
![]() |
538d0b0b4f | ||
![]() |
6b9c19eceb | ||
![]() |
1490c6d3f0 | ||
![]() |
110ce01fce | ||
![]() |
d2964e7f0b | ||
![]() |
ccef1ab5e6 | ||
![]() |
d4177370f1 | ||
![]() |
f15fa27234 | ||
![]() |
84d701ffe5 | ||
![]() |
1012f37ffa | ||
![]() |
f18135cc24 | ||
![]() |
a8ad04a813 | ||
![]() |
c9b1950aa9 | ||
![]() |
cff5da40b3 | ||
![]() |
1dca1a1b3f | ||
![]() |
3b7ef14b40 | ||
![]() |
0a35748341 | ||
![]() |
e240ba5d73 | ||
![]() |
dd52d59602 | ||
![]() |
84ac3f2f9f | ||
![]() |
bfd616337b | ||
![]() |
cd6491db81 | ||
![]() |
1a1a60f52d | ||
![]() |
d41b77b623 | ||
![]() |
74068df10a | ||
![]() |
164b14aedc | ||
![]() |
2713aeaed6 | ||
![]() |
ef35f53a80 | ||
![]() |
c5bb992c80 | ||
![]() |
06ad3ace6f | ||
![]() |
bd332080f2 | ||
![]() |
1de188a9e5 | ||
![]() |
d4cbb1c40b | ||
![]() |
70168e8e61 | ||
![]() |
29af6f4517 | ||
![]() |
00d540f5ed | ||
![]() |
a02eec56d4 | ||
![]() |
7b234485eb | ||
![]() |
8e35213fbb | ||
![]() |
c83072239e | ||
![]() |
b16523921f | ||
![]() |
cdb05a081b | ||
![]() |
d17e141be3 | ||
![]() |
feaf726b3a | ||
![]() |
faeaec31d0 | ||
![]() |
f93da5854a | ||
![]() |
aa593087ba | ||
![]() |
5def9014ed | ||
![]() |
0b6c98a1f0 | ||
![]() |
e34bf94e7d | ||
![]() |
8d3cf1eee3 | ||
![]() |
45cc311cd2 | ||
![]() |
99086a587d | ||
![]() |
77af1ab66a | ||
![]() |
6cf7f45131 | ||
![]() |
982f059788 | ||
![]() |
dc98004888 | ||
![]() |
90a9b01d26 | ||
![]() |
ff68a34119 | ||
![]() |
6ca7dd2cc6 | ||
![]() |
06526591dd | ||
![]() |
91eadda5cf | ||
![]() |
e94e4d8143 | ||
![]() |
ea0dd90530 | ||
![]() |
87a178f05b | ||
![]() |
ec02230f32 | ||
![]() |
ca818ac21b | ||
![]() |
7cf7c53935 | ||
![]() |
96bd90a6a9 | ||
![]() |
85d974977b | ||
![]() |
1379adbc47 | ||
![]() |
66bae183f4 | ||
![]() |
e1ee16f500 | ||
![]() |
31e8111116 | ||
![]() |
ef9ace8117 | ||
![]() |
fd50acb2e3 | ||
![]() |
6edd31ee99 | ||
![]() |
26f042cc83 | ||
![]() |
6919fdfd79 | ||
![]() |
314d4b0ed2 | ||
![]() |
32d452498a | ||
![]() |
0360734651 | ||
![]() |
cb4497e15d | ||
![]() |
c008bdb1a8 | ||
![]() |
0b46bc20f9 | ||
![]() |
b294a06b26 | ||
![]() |
28e7cab961 | ||
![]() |
40b6cf5d12 | ||
![]() |
8ae7a510c0 | ||
![]() |
3c466262f6 | ||
![]() |
a9fc281e99 | ||
![]() |
a4428806a8 | ||
![]() |
152a2d8c47 | ||
![]() |
aa7f7e600d | ||
![]() |
a025ef5394 | ||
![]() |
3891361829 | ||
![]() |
c485ec3dc3 | ||
![]() |
f7e3f45cf3 | ||
![]() |
734c90357c | ||
![]() |
1dc3769b22 | ||
![]() |
c02b8cfead | ||
![]() |
7be11bd842 | ||
![]() |
3d015e3518 | ||
![]() |
697e49fc2c | ||
![]() |
0884cdba3c | ||
![]() |
99d5ce6339 | ||
![]() |
429661e018 | ||
![]() |
d608b6dedb | ||
![]() |
7c9aad50bf | ||
![]() |
693507a8ed | ||
![]() |
c7f2158161 | ||
![]() |
f284ff36ad | ||
![]() |
6507098d55 | ||
![]() |
5b2ef9ae42 | ||
![]() |
85743bd38f | ||
![]() |
0c99d2979a | ||
![]() |
13017974d0 | ||
![]() |
69a0045069 | ||
![]() |
c6cbb0a4bd | ||
![]() |
51dd4ca773 | ||
![]() |
b6559d9c46 | ||
![]() |
29c60e929f | ||
![]() |
db6114afab | ||
![]() |
d204203515 | ||
![]() |
dd3bb762aa | ||
![]() |
5b31409df5 | ||
![]() |
3c16fb5a55 | ||
![]() |
71238b6d5c | ||
![]() |
e7c5865c64 | ||
![]() |
c9e1585367 | ||
![]() |
805318ee1b | ||
![]() |
e9f98eab67 | ||
![]() |
b34a35ee48 | ||
![]() |
1f6f5da0e3 | ||
![]() |
8dc1c62edd | ||
![]() |
1ae4d71783 | ||
![]() |
e032cf53ea | ||
![]() |
8586551b59 | ||
![]() |
91feb0da97 | ||
![]() |
909d3d025a | ||
![]() |
d76bab68bd | ||
![]() |
3077f8ce6e | ||
![]() |
f0986b7056 | ||
![]() |
df5229c7be | ||
![]() |
c3d5e7ae01 | ||
![]() |
76ccee7856 | ||
![]() |
7cd779c09a | ||
![]() |
d63f01a9b1 | ||
![]() |
8b10fbcbb5 | ||
![]() |
8d2a7efa47 | ||
![]() |
afc4f2638a | ||
![]() |
1dc40b1a64 | ||
![]() |
99e38a9163 | ||
![]() |
1060d8a1b4 | ||
![]() |
67416c1eec | ||
![]() |
3cb75f0c8b | ||
![]() |
f191b1e114 | ||
![]() |
66586c5c75 | ||
![]() |
de3124561f | ||
![]() |
5e6349e3a1 | ||
![]() |
410a9972af | ||
![]() |
f16efb2b5c | ||
![]() |
753b21a566 | ||
![]() |
d8c3c03e56 | ||
![]() |
656f853238 | ||
![]() |
59fba4deac | ||
![]() |
972b0e39c2 | ||
![]() |
ea1ac05c78 | ||
![]() |
ba18ae7f08 | ||
![]() |
f26dc7084d | ||
![]() |
9d7de6d39d | ||
![]() |
fdf295d151 | ||
![]() |
f78837a2bc | ||
![]() |
c4ad5da103 | ||
![]() |
97ea439a11 | ||
![]() |
adae29df8e | ||
![]() |
60cddc7cc9 | ||
![]() |
ae4e0661ea | ||
![]() |
e769e586c9 | ||
![]() |
c046fc94c4 | ||
![]() |
9966f12d52 | ||
![]() |
13111e20e7 | ||
![]() |
3049db59e8 | ||
![]() |
e2133270e7 | ||
![]() |
a2320f1b8d | ||
![]() |
d22236c056 | ||
![]() |
818f168bf5 | ||
![]() |
601aff6915 | ||
![]() |
29db082484 | ||
![]() |
00213b7c50 | ||
![]() |
4a2fe22a72 | ||
![]() |
7475e42c29 | ||
![]() |
a16475c830 | ||
![]() |
e3a3a43170 | ||
![]() |
2619fbcace | ||
![]() |
4903879d09 | ||
![]() |
c79083491d | ||
![]() |
162d5baaf8 | ||
![]() |
19b9e223e1 | ||
![]() |
6ef35e2a8c | ||
![]() |
d9e29030ae | ||
![]() |
1f6167eb91 | ||
![]() |
d9a7e045e9 | ||
![]() |
36d247fb3b | ||
![]() |
c5efdf6797 | ||
![]() |
5be0d9daa7 | ||
![]() |
1a4f63cc4d | ||
![]() |
071e229c14 | ||
![]() |
fc7ed69d88 | ||
![]() |
c1a6b0f5f5 | ||
![]() |
c99ad72c75 | ||
![]() |
8c0356d55e | ||
![]() |
1e63f6a274 | ||
![]() |
7e54acfafa | ||
![]() |
14c80b84d0 | ||
![]() |
1168630c4e | ||
![]() |
be17e31527 | ||
![]() |
8471f3d8a4 | ||
![]() |
d873f6b135 | ||
![]() |
5e12d3beff | ||
![]() |
4bfe5a01d7 | ||
![]() |
2dc3a33c3b | ||
![]() |
4c6681ee65 | ||
![]() |
ec2258b717 | ||
![]() |
2b798c3265 | ||
![]() |
35c4205143 | ||
![]() |
8940eee53e | ||
![]() |
1e62d9fef8 | ||
![]() |
74c4f4c8db | ||
![]() |
8aadee1de1 | ||
![]() |
46eb087a63 | ||
![]() |
040c9dabef | ||
![]() |
11dd942825 | ||
![]() |
9a672e7951 | ||
![]() |
74ed1fa393 | ||
![]() |
bd7f201e23 | ||
![]() |
59e278c497 | ||
![]() |
2e155a926e | ||
![]() |
398cc98f7c | ||
![]() |
519c3bbd18 | ||
![]() |
9cdea89191 | ||
![]() |
8536b2730e | ||
![]() |
8f2f6bee31 | ||
![]() |
e39e8bb76d | ||
![]() |
4be8383d89 | ||
![]() |
444c238059 | ||
![]() |
efd18e59bf | ||
![]() |
4e15f3d653 | ||
![]() |
43247cd487 | ||
![]() |
a2aa406613 | ||
![]() |
383361a9e8 | ||
![]() |
dff46bdcfd | ||
![]() |
aa709674da | ||
![]() |
56cf51e747 | ||
![]() |
8db2c956de | ||
![]() |
e5a0528302 | ||
![]() |
330156276c | ||
![]() |
deac0761b1 | ||
![]() |
f96f4c8de7 | ||
![]() |
07d614dd5b | ||
![]() |
bb47c97c62 | ||
![]() |
434c3bf4df | ||
![]() |
98e58e1e76 | ||
![]() |
5adea709d2 | ||
![]() |
de50069607 | ||
![]() |
38ffd02fc3 | ||
![]() |
1d97909d90 | ||
![]() |
826213ed01 | ||
![]() |
5e18970336 | ||
![]() |
77c4627ffb | ||
![]() |
5e5c00550d | ||
![]() |
8558f5ea6f | ||
![]() |
f9cf7be4f3 | ||
![]() |
277554fc6b | ||
![]() |
70e2b8e427 | ||
![]() |
af2920e1a9 | ||
![]() |
5fb2c9dd39 | ||
![]() |
efa7462eae | ||
![]() |
741e23121b | ||
![]() |
c480f9a4b0 | ||
![]() |
a6f4f03031 | ||
![]() |
dd3cecfbc8 | ||
![]() |
cfa48bfefd | ||
![]() |
5675385d6b | ||
![]() |
62c1e322df | ||
![]() |
fb328a5d36 | ||
![]() |
0cc91b7983 | ||
![]() |
92e1462656 | ||
![]() |
52d0dfa648 | ||
![]() |
17fa0b539b | ||
![]() |
2bd1df5c66 | ||
![]() |
d1ee5fd369 | ||
![]() |
7bccb68f23 | ||
![]() |
11265c14c0 | ||
![]() |
8ab7b69c47 | ||
![]() |
23a50090fa | ||
![]() |
e0ab6ac55d | ||
![]() |
604db8c2c3 | ||
![]() |
485be38b87 | ||
![]() |
a007e43d9c | ||
![]() |
55c1242657 | ||
![]() |
b2b1cb99fe | ||
![]() |
25af4a84c2 | ||
![]() |
45f6278173 | ||
![]() |
fda9b1826d | ||
![]() |
7389f307e0 | ||
![]() |
00517107f6 | ||
![]() |
7779572735 | ||
![]() |
fef1801f40 | ||
![]() |
735dd9133f | ||
![]() |
0a7e283d1b | ||
![]() |
d04661341c | ||
![]() |
dc4e9af93c | ||
![]() |
c284c59986 | ||
![]() |
c20a09e86d | ||
![]() |
59d8084fe7 | ||
![]() |
87317d77c7 | ||
![]() |
f6ab7c9169 | ||
![]() |
7416540093 | ||
![]() |
bec1fbda8c | ||
![]() |
fecdd82012 | ||
![]() |
a624f2612f | ||
![]() |
dcec0bccbf | ||
![]() |
468053a319 | ||
![]() |
2e09e1da7d | ||
![]() |
e0f73e0d96 | ||
![]() |
81be66c490 | ||
![]() |
0b91d94617 | ||
![]() |
3138737f75 | ||
![]() |
40b87a4fde | ||
![]() |
8a98529945 | ||
![]() |
0eae5398e1 | ||
![]() |
5db83ed6c3 | ||
![]() |
1649129d22 | ||
![]() |
e950dfd676 | ||
![]() |
dd61f0e6c5 | ||
![]() |
5815d72fb9 | ||
![]() |
411255ad6a | ||
![]() |
e240c8e7e6 | ||
![]() |
b205453bab | ||
![]() |
9a83e984d0 | ||
![]() |
5d105088f2 | ||
![]() |
584dc78ee8 | ||
![]() |
91efb203e5 | ||
![]() |
5067b537e8 | ||
![]() |
c00516692e | ||
![]() |
f0b8295b12 | ||
![]() |
402a45849d | ||
![]() |
32948e319f | ||
![]() |
e0e9ecf750 | ||
![]() |
c383a324cd | ||
![]() |
14115715cd | ||
![]() |
99589d0af9 | ||
![]() |
40e39609de | ||
![]() |
831b770bfc | ||
![]() |
3fca2aa4b8 | ||
![]() |
402e3ea5ef | ||
![]() |
0b279b2bf2 | ||
![]() |
8d1152d450 | ||
![]() |
21cc3400bd | ||
![]() |
470973e6d1 | ||
![]() |
9592b44aa4 | ||
![]() |
03d5cf98e7 | ||
![]() |
c83d7bff84 | ||
![]() |
953f1f0315 | ||
![]() |
251db04bc0 | ||
![]() |
41e6f81392 | ||
![]() |
423514e941 | ||
![]() |
064a3a01dd | ||
![]() |
6c69789850 | ||
![]() |
19f97f60ba | ||
![]() |
9f98b3b50d | ||
![]() |
a0be31ce67 | ||
![]() |
f4690e5118 | ||
![]() |
007eef4362 | ||
![]() |
51b85e712b | ||
![]() |
1d3e50e6e2 | ||
![]() |
8093bf5e8a | ||
![]() |
64ab6905ed | ||
![]() |
cb5723187a | ||
![]() |
0f12c897a3 | ||
![]() |
a34b0af0cb | ||
![]() |
90bbc1c99e | ||
![]() |
a7bff601e5 | ||
![]() |
d870aef0b5 | ||
![]() |
25b5633b36 | ||
![]() |
c36fc7cc5f | ||
![]() |
78497b8212 | ||
![]() |
b2e18a89be | ||
![]() |
65c443e810 | ||
![]() |
06c42fd02c | ||
![]() |
0a28d7405a | ||
![]() |
a15cfd94e2 | ||
![]() |
8c81f74b33 | ||
![]() |
2c08a31abb | ||
![]() |
289e7cf5e9 | ||
![]() |
ee3e232e09 | ||
![]() |
ed65d9debb | ||
![]() |
d81f6652ed | ||
![]() |
e956bf1f91 | ||
![]() |
3763add872 | ||
![]() |
ad2abcee0b | ||
![]() |
b790268421 | ||
![]() |
65d1ffdb3c | ||
![]() |
f5651454a8 | ||
![]() |
81fc47e203 | ||
![]() |
ff687582bd | ||
![]() |
4dfe1364d7 | ||
![]() |
1b03c3fe91 | ||
![]() |
47956ba750 | ||
![]() |
2a2c8c536b | ||
![]() |
91873ea473 | ||
![]() |
4c937f7f7d | ||
![]() |
0093e1be20 | ||
![]() |
5b31725f81 | ||
![]() |
fd533682a3 | ||
![]() |
419edfbf30 | ||
![]() |
56018c314b | ||
![]() |
86ac8e6b42 | ||
![]() |
2268e54865 | ||
![]() |
7f3640afc5 | ||
![]() |
a8afb3842f | ||
![]() |
d662fdf017 | ||
![]() |
041d90ff38 | ||
![]() |
7f4817c401 | ||
![]() |
d93d542b81 | ||
![]() |
8beccff292 | ||
![]() |
3e93c74572 | ||
![]() |
823fcb14f6 | ||
![]() |
4b89a9dddf | ||
![]() |
a3028b8b58 | ||
![]() |
57b08f6343 | ||
![]() |
3dd031e4f9 | ||
![]() |
2d59cc5136 | ||
![]() |
b835eba04d | ||
![]() |
3d0af4f45c | ||
![]() |
11089511c6 | ||
![]() |
5cd49b86a1 | ||
![]() |
77701ebe4c | ||
![]() |
0da64f5961 | ||
![]() |
40d0b7b271 | ||
![]() |
2a643a107e | ||
![]() |
8f70320640 | ||
![]() |
d1b2fe3283 | ||
![]() |
3759f659ca | ||
![]() |
fa06fa27c0 | ||
![]() |
f4c4dd5a27 | ||
![]() |
0c48561495 | ||
![]() |
0c1d492146 | ||
![]() |
cfcc2e6ea9 | ||
![]() |
3837a175d3 | ||
![]() |
4d35623ab6 | ||
![]() |
fd1d376848 | ||
![]() |
44534bc94e | ||
![]() |
fab84d04b6 | ||
![]() |
5570d7f9ea | ||
![]() |
733ac96ca6 | ||
![]() |
82b94b9a0b | ||
![]() |
c24b9fb275 | ||
![]() |
33780b6d3a | ||
![]() |
a5e0c5cfd4 | ||
![]() |
cee0ff447c | ||
![]() |
625764e2d5 | ||
![]() |
2f448af0d6 | ||
![]() |
393206d32e | ||
![]() |
45732d5930 | ||
![]() |
62d7b0373d | ||
![]() |
8158b8b61a | ||
![]() |
b16a5e7ee9 | ||
![]() |
8dfa2ffff7 | ||
![]() |
2aec911a18 | ||
![]() |
b5f14301e9 | ||
![]() |
1b7f6144a2 | ||
![]() |
a3f71c447b | ||
![]() |
140a3f7882 | ||
![]() |
8b86eb6fa5 | ||
![]() |
9a5a951210 | ||
![]() |
491cce69f0 | ||
![]() |
c107b359b6 | ||
![]() |
4f920e9878 | ||
![]() |
fceead7e75 | ||
![]() |
2f262c1640 | ||
![]() |
d3a2169e4d | ||
![]() |
d7be1f6bef | ||
![]() |
50b13ef2d3 | ||
![]() |
d5cc1222f6 | ||
![]() |
7c3b887cf7 | ||
![]() |
978a22fe9f | ||
![]() |
5cbd4d8e7d | ||
![]() |
d162735cf0 | ||
![]() |
d071c05987 | ||
![]() |
dddd173056 | ||
![]() |
ec99a6030e | ||
![]() |
19df85c0ad | ||
![]() |
a724ef1a6c | ||
![]() |
51c5882cdf | ||
![]() |
62638f5d69 | ||
![]() |
bed254ea2a | ||
![]() |
12b17b7cb9 | ||
![]() |
61b056455b | ||
![]() |
1ab0a36784 | ||
![]() |
28068d773a | ||
![]() |
1a23b1f2e8 | ||
![]() |
0d9930a426 | ||
![]() |
dcf8ddd32f | ||
![]() |
af1e607df5 | ||
![]() |
83c2b28511 | ||
![]() |
ea81fee645 | ||
![]() |
23e23ae3f6 | ||
![]() |
21c3a62798 | ||
![]() |
f84f7cf441 | ||
![]() |
f77a5dac57 | ||
![]() |
0a6a411f69 | ||
![]() |
8dc86cc903 | ||
![]() |
985ef74f45 | ||
![]() |
3a3815b0fe | ||
![]() |
0cf1a57539 | ||
![]() |
d52173ec6a | ||
![]() |
38ddcd316a | ||
![]() |
686c4056dc | ||
![]() |
ebfa509965 | ||
![]() |
b7b99233f3 | ||
![]() |
b7cd8c2b52 | ||
![]() |
570e581908 | ||
![]() |
15e03eee8c | ||
![]() |
4f89ce8ce4 | ||
![]() |
5c2d48fba7 | ||
![]() |
9f6c27a71c | ||
![]() |
bd736b7577 | ||
![]() |
0374f31c59 | ||
![]() |
f327e68410 | ||
![]() |
835a5d06dc | ||
![]() |
529e1df1c1 | ||
![]() |
2e860fc97d | ||
![]() |
9bd080e121 | ||
![]() |
b25db7cb08 | ||
![]() |
56beae5b82 | ||
![]() |
63314e3911 | ||
![]() |
7a7be7c4bd | ||
![]() |
6f2e5547fe | ||
![]() |
9d6ad2f12a | ||
![]() |
98393f4646 | ||
![]() |
d40250bbb3 | ||
![]() |
2eaddf5008 | ||
![]() |
03dbb4c924 | ||
![]() |
be8c07a1a8 | ||
![]() |
724ad9d6da | ||
![]() |
f481234ef0 | ||
![]() |
13448127b0 | ||
![]() |
fa80770ef3 | ||
![]() |
3f4bf9b819 | ||
![]() |
9ebf8f0f27 | ||
![]() |
7a02f98ebb | ||
![]() |
8918ab28f6 | ||
![]() |
29b82f7b38 | ||
![]() |
b9b85c7a80 | ||
![]() |
f9b1835f76 | ||
![]() |
445399c3da | ||
![]() |
5316e07ae7 | ||
![]() |
b13845a1c6 | ||
![]() |
7f19e8f447 | ||
![]() |
96e7bf82fe | ||
![]() |
68ff6774bb | ||
![]() |
4f54acff6b | ||
![]() |
8fe5b5cbbc | ||
![]() |
3075db2122 | ||
![]() |
981a4f0006 | ||
![]() |
b8c12bb564 | ||
![]() |
0477c4de5a | ||
![]() |
43d210e20b | ||
![]() |
3b4cb204d8 | ||
![]() |
f29f356d22 | ||
![]() |
b73fda9cfd | ||
![]() |
1c0b287163 | ||
![]() |
f99253ea13 | ||
![]() |
6907a79131 | ||
![]() |
197d1a1c07 | ||
![]() |
1fe06fc59c | ||
![]() |
3ef5ea56ae | ||
![]() |
9492c8aa44 | ||
![]() |
8ae6c27693 | ||
![]() |
7ade001680 | ||
![]() |
8ba460243e | ||
![]() |
820bf725a2 | ||
![]() |
4172eb0c81 | ||
![]() |
b9bf820777 | ||
![]() |
d4c31580f3 | ||
![]() |
3ca5972d27 | ||
![]() |
a60b1725d4 | ||
![]() |
68078b45e6 | ||
![]() |
e30506c097 | ||
![]() |
6b75f53fc4 | ||
![]() |
206ec4612b | ||
![]() |
b4c3455f8d | ||
![]() |
c2ba1a4a64 | ||
![]() |
a8fe186b1c | ||
![]() |
82c24b65b4 | ||
![]() |
7a9bb0afce | ||
![]() |
9063075082 | ||
![]() |
5a801735f7 | ||
![]() |
9debaf87d1 | ||
![]() |
2a23d72c8f | ||
![]() |
77157c470c | ||
![]() |
839ddbc9e8 | ||
![]() |
da17c23d79 | ||
![]() |
d70c3c40c7 | ||
![]() |
492dae1d8b | ||
![]() |
3bd69c9c16 | ||
![]() |
765538f971 | ||
![]() |
3445da4ee7 | ||
![]() |
d9092bc2ba | ||
![]() |
a9b8a71b3e | ||
![]() |
7f75840e19 | ||
![]() |
58c6c084e6 | ||
![]() |
54b1d7ce0b | ||
![]() |
012e2c7a1b | ||
![]() |
402a706522 | ||
![]() |
596ee15301 | ||
![]() |
f5daf909c7 | ||
![]() |
529854b11a | ||
![]() |
f72b745f74 | ||
![]() |
6bba43c295 | ||
![]() |
5a30718c35 | ||
![]() |
1b050f1560 | ||
![]() |
034d2c3279 | ||
![]() |
aa0ed2a838 | ||
![]() |
4b412cd92c | ||
![]() |
a3a2e69a45 | ||
![]() |
0e30d8dfd4 | ||
![]() |
7e63801e76 | ||
![]() |
7c46fffb13 | ||
![]() |
48df9b93a9 | ||
![]() |
e0a2495a2b | ||
![]() |
3e3f54d821 | ||
![]() |
7dcdd7b23e | ||
![]() |
b49208bc08 | ||
![]() |
def99a20d4 | ||
![]() |
7021be3a27 | ||
![]() |
60187a8f6f | ||
![]() |
3dacb3feb1 | ||
![]() |
67c5dcc7ae | ||
![]() |
b01fb79cd4 | ||
![]() |
80f1eb37b6 | ||
![]() |
85f1fb28c3 | ||
![]() |
183f408fc5 | ||
![]() |
ee6d385e79 | ||
![]() |
55768bfc8d | ||
![]() |
a769db8a39 | ||
![]() |
ef51d76f5f | ||
![]() |
a2b0adf225 | ||
![]() |
24a24fb675 | ||
![]() |
8ccde7d777 | ||
![]() |
26945dcd6a | ||
![]() |
90d2d525d1 | ||
![]() |
59eb7e0eed | ||
![]() |
cd5d048296 | ||
![]() |
0b9b390141 | ||
![]() |
d0757e5066 | ||
![]() |
df884767da | ||
![]() |
fe6a4115ec | ||
![]() |
da7543e22a | ||
![]() |
21bf3f447a | ||
![]() |
e5ae27a560 | ||
![]() |
6baf583836 | ||
![]() |
5273746944 | ||
![]() |
c6798c124a | ||
![]() |
f9c89def36 | ||
![]() |
3d6e106cad | ||
![]() |
240f52fc71 | ||
![]() |
6bb5228540 | ||
![]() |
c3ed549e27 | ||
![]() |
f925c9dbe0 | ||
![]() |
57efd786fe | ||
![]() |
58f256f85c | ||
![]() |
22b1c621ad | ||
![]() |
2783df88dd | ||
![]() |
2427e0e717 | ||
![]() |
a50335221d | ||
![]() |
1cdcbab02e | ||
![]() |
1f0f2b7a8e | ||
![]() |
979c6d4b4a | ||
![]() |
fc207d97df | ||
![]() |
c375649262 | ||
![]() |
ebf22e3023 | ||
![]() |
d4d145e532 | ||
![]() |
4e782555ed | ||
![]() |
db883d16c1 | ||
![]() |
952c1cab7b | ||
![]() |
9d1862194c | ||
![]() |
689d02641d | ||
![]() |
78c452a5b4 | ||
![]() |
6eda7ba687 | ||
![]() |
26637d3f66 | ||
![]() |
8321a7d34f | ||
![]() |
70a41c4e0c | ||
![]() |
31b4765a6d | ||
![]() |
491c17525b | ||
![]() |
9e83cd8308 | ||
![]() |
c3dcea77c5 | ||
![]() |
101cfde7a8 | ||
![]() |
5eebca6f88 | ||
![]() |
772f64b083 | ||
![]() |
580a49a7f4 | ||
![]() |
a3eacd6c35 | ||
![]() |
7e7ce1af88 | ||
![]() |
1ec24bcaa5 | ||
![]() |
f47c7dfd34 | ||
![]() |
2338e5e5f1 | ||
![]() |
54c37571c0 | ||
![]() |
b2b19cb731 | ||
![]() |
504835d1bf | ||
![]() |
dc516927c6 | ||
![]() |
2ffd6bfed6 | ||
![]() |
4e4811e5fe | ||
![]() |
84c3e221a8 | ||
![]() |
7ded42f122 | ||
![]() |
5a76b11ae3 | ||
![]() |
f97718f4dd | ||
![]() |
87b52abefd | ||
![]() |
4e73a5c8a7 | ||
![]() |
8ca326e547 | ||
![]() |
266eb76601 | ||
![]() |
8552b794e1 | ||
![]() |
dfbe4baa5a | ||
![]() |
1c2ab2361a | ||
![]() |
e738a460ae | ||
![]() |
63be5d2666 | ||
![]() |
4e0e265d9e | ||
![]() |
e035587614 | ||
![]() |
3afafafcb9 | ||
![]() |
00eee176da | ||
![]() |
71fa9cb6d3 | ||
![]() |
997bd49f75 | ||
![]() |
62a8196ac9 | ||
![]() |
ed08720fc3 | ||
![]() |
2224a6e81d | ||
![]() |
b053b7cd6c | ||
![]() |
41f1111fdd | ||
![]() |
916a63f5ac | ||
![]() |
2742dcd14d | ||
![]() |
abe74fddcb | ||
![]() |
78333c73cb | ||
![]() |
d275c64a11 | ||
![]() |
10d639e557 | ||
![]() |
7b737d6c55 | ||
![]() |
e1ba8e5cdf | ||
![]() |
8291066716 | ||
![]() |
48a70a9e03 | ||
![]() |
f117aa19cd | ||
![]() |
11592f2fde | ||
![]() |
b0ec3215a1 | ||
![]() |
84cbbd8357 | ||
![]() |
388ed01384 | ||
![]() |
e3348463ae | ||
![]() |
8aef3f27bd | ||
![]() |
f05c4e61a3 | ||
![]() |
7ccfb7cb15 | ||
![]() |
749ada480b | ||
![]() |
047f1dcfae | ||
![]() |
e246641dfa | ||
![]() |
0905074604 | ||
![]() |
261d3151c7 | ||
![]() |
27f9347d7b | ||
![]() |
d16db2b7ef | ||
![]() |
8e037685f0 | ||
![]() |
106927beaf | ||
![]() |
c4511dd37f | ||
![]() |
40f97ef690 | ||
![]() |
cc9aeddb3d | ||
![]() |
74f661bb3e | ||
![]() |
dce07c6f35 | ||
![]() |
78f32ca6fe | ||
![]() |
f4259f2a28 | ||
![]() |
a36ad0a025 | ||
![]() |
d9b0dfabc0 | ||
![]() |
fcf0c89e3e | ||
![]() |
33e7a76421 | ||
![]() |
716a7aa85d | ||
![]() |
8f7fcf7047 | ||
![]() |
8630818ded | ||
![]() |
3fc71e1444 | ||
![]() |
afdfdf77d0 | ||
![]() |
c06926321c | ||
![]() |
f5d478e3e5 | ||
![]() |
c3c046ff3e | ||
![]() |
cea6f025f6 | ||
![]() |
d6ad5e3c48 | ||
![]() |
e2937173ac | ||
![]() |
96c5350187 | ||
![]() |
02d29a500a | ||
![]() |
d836e73941 | ||
![]() |
b2a890068d | ||
![]() |
6882a6b33d | ||
![]() |
475b188cb3 | ||
![]() |
64a4f6648f | ||
![]() |
fc82f5ce69 | ||
![]() |
61c47c4571 | ||
![]() |
0f722e6d0b | ||
![]() |
0f8af61051 | ||
![]() |
efe0f45239 | ||
![]() |
1fb5ee760b | ||
![]() |
1447906551 | ||
![]() |
f3bd1c7b1c | ||
![]() |
a05bc3b14e | ||
![]() |
d5f68da6f8 | ||
![]() |
b59e3ad55b | ||
![]() |
25adcc6daa | ||
![]() |
458d45228a | ||
![]() |
430ebc0ad0 | ||
![]() |
fdeb110671 | ||
![]() |
9864ab02c0 | ||
![]() |
d8cc228277 | ||
![]() |
ef9d012edb | ||
![]() |
bb9b39d640 | ||
![]() |
e10f73edac | ||
![]() |
f7e4334515 | ||
![]() |
ca50289cd6 | ||
![]() |
32a8fb8116 | ||
![]() |
d9e8af8a8e | ||
![]() |
0c666c6b55 | ||
![]() |
fd10c121eb | ||
![]() |
4b834646d1 | ||
![]() |
abcf7a1edf | ||
![]() |
81a624d470 | ||
![]() |
9dd0010557 | ||
![]() |
ff3ef0a22d | ||
![]() |
d173dfb031 | ||
![]() |
a9dbd9f246 | ||
![]() |
b70eb0aed1 | ||
![]() |
d255072981 | ||
![]() |
915b23ebab | ||
![]() |
4261aba65f | ||
![]() |
68dc61f469 | ||
![]() |
bd44ac7802 | ||
![]() |
31b0e03754 | ||
![]() |
893fe62bcc | ||
![]() |
90b9c2a573 | ||
![]() |
b9ef7c27f0 | ||
![]() |
1505b7a8ea | ||
![]() |
e6561ec95b | ||
![]() |
ec76b66ed2 | ||
![]() |
f39f18d8d1 | ||
![]() |
a20a45637b | ||
![]() |
07577d88cb | ||
![]() |
d7aa28defe | ||
![]() |
ce16b3dca3 | ||
![]() |
fa88deb297 | ||
![]() |
cb1c486082 | ||
![]() |
276f177af9 | ||
![]() |
f033cba397 | ||
![]() |
f19a1f3eb4 | ||
![]() |
8d1e860b94 | ||
![]() |
36a30348a8 | ||
![]() |
c0e5eaec21 | ||
![]() |
0314fe7cf3 | ||
![]() |
1f8bb90e65 | ||
![]() |
96a10a4174 | ||
![]() |
140e595134 | ||
![]() |
3bee3faeb1 | ||
![]() |
7ef77a2844 | ||
![]() |
c66ba75bfa | ||
![]() |
02e39c6adc | ||
![]() |
debd0a0325 | ||
![]() |
c3aa4b07c5 | ||
![]() |
4c378e9766 | ||
![]() |
26cd1ce79c | ||
![]() |
8ed869228a | ||
![]() |
7566122a45 | ||
![]() |
c0a5024363 | ||
![]() |
0f8222f73b | ||
![]() |
91afce33c6 | ||
![]() |
62870a2202 | ||
![]() |
cf35ea3595 | ||
![]() |
7d64c96a75 | ||
![]() |
41422bc2cb | ||
![]() |
ac0dfabb00 | ||
![]() |
dd70d2cc44 | ||
![]() |
d6aa1d587c | ||
![]() |
e0ff22ed4a | ||
![]() |
86f9ff0887 | ||
![]() |
a159128a47 | ||
![]() |
648f7419da | ||
![]() |
636eef0dec | ||
![]() |
159dc46592 | ||
![]() |
6c682d56c9 | ||
![]() |
9a6bc1829d | ||
![]() |
78a79f452a | ||
![]() |
4d8a4567d6 | ||
![]() |
3f0b1782e7 | ||
![]() |
ebf084f5fc | ||
![]() |
fc29625b72 | ||
![]() |
b0681b9064 | ||
![]() |
d0e28a6c60 | ||
![]() |
4bcb4b6389 | ||
![]() |
071824716a | ||
![]() |
58cd0e7058 | ||
![]() |
3e9e0e28e6 | ||
![]() |
205aca197b | ||
![]() |
91d7b8b085 | ||
![]() |
8e7e803159 | ||
![]() |
242d61bf1a | ||
![]() |
2b5c305a6d | ||
![]() |
f581a56ea2 | ||
![]() |
f34e144d7b | ||
![]() |
3155d0ef12 | ||
![]() |
cb625f7ae0 | ||
![]() |
ed6892753e | ||
![]() |
e5db843a67 | ||
![]() |
5e1cf4332d | ||
![]() |
20820a610d | ||
![]() |
0202d981cd | ||
![]() |
5281ff503a | ||
![]() |
59ca94a495 | ||
![]() |
913b735952 | ||
![]() |
e08427bcf6 | ||
![]() |
d8c45777df | ||
![]() |
4a50193c56 | ||
![]() |
d9da9fbcd4 | ||
![]() |
87a08b5b89 | ||
![]() |
61855ffd1b | ||
![]() |
09ac17157d | ||
![]() |
4b2ab1f46d | ||
![]() |
0fd7e2c4b0 | ||
![]() |
782cae5eca | ||
![]() |
f740f91b5e | ||
![]() |
9c0b794d64 | ||
![]() |
8774e596aa | ||
![]() |
6bc94bea01 | ||
![]() |
1c285ade7a | ||
![]() |
8bfe3b7de1 | ||
![]() |
6caddcf0f7 | ||
![]() |
9a14e95675 | ||
![]() |
f744e90452 | ||
![]() |
72febdb507 | ||
![]() |
8a20fdca5e | ||
![]() |
abec878530 | ||
![]() |
750708a20a | ||
![]() |
6c2f002e21 | ||
![]() |
c8d61cbd00 | ||
![]() |
21c1778258 | ||
![]() |
39f2903c9b | ||
![]() |
2cf7447245 | ||
![]() |
fee05d9f21 | ||
![]() |
adc791cf2b | ||
![]() |
ec95fec7a9 | ||
![]() |
7e2174bd6f | ||
![]() |
ba9bab2a5e | ||
![]() |
c61e87ceda | ||
![]() |
56beff2e4d | ||
![]() |
818dd102d8 | ||
![]() |
75bbd8eb2d | ||
![]() |
8ceaab02f4 | ||
![]() |
90f15e5811 | ||
![]() |
2d06669565 | ||
![]() |
7a7c79e39d | ||
![]() |
81b87b7b36 | ||
![]() |
629afcca90 | ||
![]() |
bb109c9a31 | ||
![]() |
bed74da521 | ||
![]() |
1afa0580c4 | ||
![]() |
9b486fd862 | ||
![]() |
5bff87abb4 | ||
![]() |
22edb27f8d | ||
![]() |
0dd59d889a | ||
![]() |
7437d7c63f | ||
![]() |
cc4f916e89 | ||
![]() |
c6e5b8ba59 | ||
![]() |
ec2ce29386 | ||
![]() |
45b84689ad | ||
![]() |
3b54c6ea30 | ||
![]() |
7210a9e34f | ||
![]() |
9e18e895bc | ||
![]() |
9ba40b9a47 | ||
![]() |
3b36897ed7 | ||
![]() |
834d5a0579 | ||
![]() |
43f5ea875a | ||
![]() |
e5c64bafa8 |
@ -1,4 +1,4 @@
|
||||
load("github.com/SonarSource/cirrus-modules@v2", "load_features")
|
||||
load("github.com/SonarSource/cirrus-modules@v3", "load_features")
|
||||
|
||||
def main(ctx):
|
||||
return load_features(ctx)
|
||||
|
41
.cirrus.yml
41
.cirrus.yml
@ -25,7 +25,7 @@ container_definition: &CONTAINER_DEFINITION
|
||||
|
||||
setup_sonar_scanner: &SETUP_SONAR_SCANNER
|
||||
setup_sonar_scanner_script:
|
||||
- apt update -y && apt upgrade -y && apt update -y && apt install -y unzip
|
||||
- apt update -y && apt upgrade -y && apt update -y && apt install -y unzip
|
||||
- curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
|
||||
- unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
|
||||
|
||||
@ -38,9 +38,7 @@ tooling_tests_task:
|
||||
env:
|
||||
PYTHONPATH: .
|
||||
install_dependencies_script:
|
||||
- cd rspec-tools
|
||||
- pipenv install --dev
|
||||
- pipenv run pip install pytest pytest-cov
|
||||
- ci/install_rspec_tools_dependencies.sh
|
||||
tests_script:
|
||||
- bash ci/fetch_branches.sh
|
||||
- cd rspec-tools
|
||||
@ -77,15 +75,6 @@ frontend_tests_task:
|
||||
- cd frontend
|
||||
- sonar-scanner
|
||||
|
||||
validate_metadata_task:
|
||||
eks_container:
|
||||
<<: *CONTAINER_DEFINITION
|
||||
dockerfile: ci/Dockerfile
|
||||
cpu: 1
|
||||
memory: 2G
|
||||
metadata_tests_script:
|
||||
- ./ci/validate_metadata.sh
|
||||
|
||||
validate_ci_tests_task:
|
||||
skip: "!changesInclude('ci_tests/**', 'ci/**')"
|
||||
eks_container:
|
||||
@ -96,17 +85,22 @@ validate_ci_tests_task:
|
||||
ci_tests_script:
|
||||
- ./ci_tests/asciidoc_validation/run_tests.sh
|
||||
|
||||
validate_asciidoc_task:
|
||||
validate_rules_task:
|
||||
eks_container:
|
||||
<<: *CONTAINER_DEFINITION
|
||||
dockerfile: ci/Dockerfile
|
||||
cpu: 1
|
||||
memory: 2G
|
||||
asciidoc_tests_script:
|
||||
metadata_validation_script:
|
||||
- ./ci/validate_metadata.sh
|
||||
file_extensions_validation_script:
|
||||
- ./ci/validate_file_extensions.sh
|
||||
asciidoc_validation_script:
|
||||
- ./ci/validate_asciidoc.sh
|
||||
|
||||
validate_links_task:
|
||||
timeout_in: 120m
|
||||
execution_lock: RSPEC_validate_links
|
||||
eks_container:
|
||||
<<: *CONTAINER_DEFINITION
|
||||
dockerfile: ci/Dockerfile
|
||||
@ -117,31 +111,20 @@ validate_links_task:
|
||||
LINK_CACHE_PATH: /root/link-probing-history.cache
|
||||
cache_download_script:
|
||||
- bash ci/cirrus-cache.sh download ${LINK_CACHE_NAME} ${LINK_CACHE_PATH}
|
||||
tests_script:
|
||||
- md5sum /root/link-probing-history.cache/link_probes.history || true
|
||||
tests_script:
|
||||
- ./ci/validate_links.sh ${LINK_CACHE_PATH}
|
||||
- md5sum /root/link-probing-history.cache/link_probes.history
|
||||
always:
|
||||
cache_upload_script:
|
||||
- md5sum /root/link-probing-history.cache/link_probes.history || true
|
||||
- bash ci/cirrus-cache.sh upload ${LINK_CACHE_NAME} ${LINK_CACHE_PATH}
|
||||
|
||||
validate_file_extensions_task:
|
||||
eks_container:
|
||||
<<: *CONTAINER_DEFINITION
|
||||
dockerfile: ci/Dockerfile
|
||||
cpu: 1
|
||||
memory: 2G
|
||||
file_extension_tests_script:
|
||||
- bash ./ci/validate_file_extensions.sh
|
||||
|
||||
all_required_checks_task:
|
||||
depends_on:
|
||||
- tooling_tests
|
||||
- frontend_tests
|
||||
- validate_metadata
|
||||
- validate_asciidoc
|
||||
- validate_rules
|
||||
- validate_ci_tests
|
||||
- validate_file_extensions
|
||||
eks_container:
|
||||
<<: *CONTAINER_DEFINITION
|
||||
dockerfile: ci/Dockerfile
|
||||
|
16
.devcontainer/devcontainer.json
Normal file
16
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"build": {
|
||||
"dockerfile": "../ci/Dockerfile"
|
||||
},
|
||||
// https://code.visualstudio.com/docs/devcontainers/create-dev-container#_rebuild
|
||||
"postCreateCommand": ".devcontainer/finalize-container.sh",
|
||||
"waitFor": "postCreateCommand",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-python.python",
|
||||
"asciidoctor.asciidoctor-vscode"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
7
.devcontainer/finalize-container.sh
Executable file
7
.devcontainer/finalize-container.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TOP_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)/..
|
||||
|
||||
$TOP_DIR/ci/install_rspec_tools_dependencies.sh
|
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@ -1 +1 @@
|
||||
.github/CODEOWNERS @sonarsource/analysis-cfamily-squad
|
||||
.github/CODEOWNERS @sonarsource/quality-cfamily-squad
|
||||
|
9
.github/pull_request_template.md
vendored
9
.github/pull_request_template.md
vendored
@ -1,3 +1,12 @@
|
||||
<!--
|
||||
Jira Automation:
|
||||
|
||||
* Mention existing issue in the PR title to move it around automatically.
|
||||
* Mention existing issue in the PR description and a sub-task will be created for you to track this rspec PR separately.
|
||||
|
||||
No issue is created by default.
|
||||
-->
|
||||
|
||||
## Review
|
||||
|
||||
A dedicated reviewer checked the rule description successfully for:
|
||||
|
28
.github/workflows/PullRequestClosed.yml
vendored
Normal file
28
.github/workflows/PullRequestClosed.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Pull Request Closed
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
|
||||
jobs:
|
||||
PullRequestMerged_job:
|
||||
name: Pull Request Merged
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
pull-requests: read
|
||||
# For external PR, ticket should be moved manually
|
||||
if: |
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
steps:
|
||||
- id: secrets
|
||||
uses: SonarSource/vault-action-wrapper@v3
|
||||
with:
|
||||
secrets: |
|
||||
development/kv/data/jira user | JIRA_USER;
|
||||
development/kv/data/jira token | JIRA_TOKEN;
|
||||
- uses: sonarsource/gh-action-lt-backlog/PullRequestClosed@v2
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
jira-user: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_USER }}
|
||||
jira-token: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_TOKEN }}
|
28
.github/workflows/PullRequestCreated.yml
vendored
Normal file
28
.github/workflows/PullRequestCreated.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Pull Request Created
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: ["opened"]
|
||||
|
||||
jobs:
|
||||
PullRequestCreated_job:
|
||||
name: Pull Request Created
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
# For external PR, ticket should be created manually
|
||||
if: |
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
steps:
|
||||
- id: secrets
|
||||
uses: SonarSource/vault-action-wrapper@v3
|
||||
with:
|
||||
secrets: |
|
||||
development/github/token/{REPO_OWNER_NAME_DASH}-jira token | GITHUB_TOKEN;
|
||||
development/kv/data/jira user | JIRA_USER;
|
||||
development/kv/data/jira token | JIRA_TOKEN;
|
||||
- uses: sonarsource/gh-action-lt-backlog/PullRequestCreated@v2
|
||||
with:
|
||||
github-token: ${{ fromJSON(steps.secrets.outputs.vault).GITHUB_TOKEN }}
|
||||
jira-user: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_USER }}
|
||||
jira-token: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_TOKEN }}
|
28
.github/workflows/RequestReview.yml
vendored
Normal file
28
.github/workflows/RequestReview.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Request review
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: ["review_requested"]
|
||||
|
||||
jobs:
|
||||
RequestReview_job:
|
||||
name: Request review
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
# For external PR, ticket should be moved manually
|
||||
if: |
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
steps:
|
||||
- id: secrets
|
||||
uses: SonarSource/vault-action-wrapper@v3
|
||||
with:
|
||||
secrets: |
|
||||
development/github/token/{REPO_OWNER_NAME_DASH}-jira token | GITHUB_TOKEN;
|
||||
development/kv/data/jira user | JIRA_USER;
|
||||
development/kv/data/jira token | JIRA_TOKEN;
|
||||
- uses: sonarsource/gh-action-lt-backlog/RequestReview@v2
|
||||
with:
|
||||
github-token: ${{ fromJSON(steps.secrets.outputs.vault).GITHUB_TOKEN }}
|
||||
jira-user: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_USER }}
|
||||
jira-token: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_TOKEN }}
|
30
.github/workflows/SubmitReview.yml
vendored
Normal file
30
.github/workflows/SubmitReview.yml
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
name: Submit Review
|
||||
|
||||
on:
|
||||
pull_request_review:
|
||||
types: [submitted]
|
||||
|
||||
jobs:
|
||||
SubmitReview_job:
|
||||
name: Submit Review
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
pull-requests: read
|
||||
# For external PR, ticket should be moved manually
|
||||
if: |
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
&& (github.event.review.state == 'changes_requested'
|
||||
|| github.event.review.state == 'approved')
|
||||
steps:
|
||||
- id: secrets
|
||||
uses: SonarSource/vault-action-wrapper@v3
|
||||
with:
|
||||
secrets: |
|
||||
development/kv/data/jira user | JIRA_USER;
|
||||
development/kv/data/jira token | JIRA_TOKEN;
|
||||
- uses: sonarsource/gh-action-lt-backlog/SubmitReview@v2
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
jira-user: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_USER }}
|
||||
jira-token: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_TOKEN }}
|
3
.github/workflows/add_language.yml
vendored
3
.github/workflows/add_language.yml
vendored
@ -15,6 +15,9 @@ on:
|
||||
jobs:
|
||||
add_language_to_rule:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
3
.github/workflows/create_new_rspec.yml
vendored
3
.github/workflows/create_new_rspec.yml
vendored
@ -12,6 +12,9 @@ on:
|
||||
jobs:
|
||||
create_new_rule:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -7,7 +7,7 @@ on:
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: read # Get the list and metadata of open new-rule PRs
|
||||
contents: write # Get the contents of open new-rule PRs, the 'master'; write to 'gh-pages' branch
|
||||
|
101
.github/workflows/update_coverage.yml
vendored
101
.github/workflows/update_coverage.yml
vendored
@ -2,20 +2,34 @@ name: Update rule coverage
|
||||
on:
|
||||
schedule:
|
||||
- cron: '17 2 * * *'
|
||||
workflow_dispatch: # When manually triggered from a non-default branch, the results will not be pushed
|
||||
|
||||
jobs:
|
||||
update_coverage:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write # required by SonarSource/vault-action-wrapper
|
||||
contents: write
|
||||
actions: write # required by andymckay/cancel-action
|
||||
env:
|
||||
TMP_BRANCH: temporary/coverage_update
|
||||
|
||||
steps:
|
||||
- name: 'get secrets'
|
||||
id: secrets
|
||||
uses: SonarSource/vault-action-wrapper@v3
|
||||
with:
|
||||
secrets: |
|
||||
development/github/token/SonarSource-rspec-coverage token | coverage_github_token;
|
||||
development/kv/data/slack token | slack_token;
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: true
|
||||
ref: master
|
||||
fetch-depth: 0
|
||||
path: 'rspec'
|
||||
token: ${{ secrets.COVERAGE_GITHUB_TOKEN }}
|
||||
token: ${{ fromJSON(steps.secrets.outputs.vault).coverage_github_token }}
|
||||
ref: 'master'
|
||||
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
@ -31,7 +45,7 @@ jobs:
|
||||
|
||||
- name: 'Regenerate coverage information'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.COVERAGE_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).coverage_github_token }}
|
||||
id: gen-coverage
|
||||
working-directory: 'rspec/rspec-tools'
|
||||
run: |
|
||||
@ -59,44 +73,67 @@ jobs:
|
||||
git commit -m "update coverage information"
|
||||
git push --force-with-lease origin $TMP_BRANCH
|
||||
|
||||
- name: 'Wait for CI to succeed'
|
||||
if: steps.gen-coverage.outputs.new_coverage == 'true'
|
||||
uses: fountainhead/action-wait-for-check@v1.0.0
|
||||
id: wait-for-build
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
checkName: all_required_checks
|
||||
ref: ${{ env.TMP_BRANCH }}
|
||||
timeoutSeconds: 2400
|
||||
intervalSeconds: 30
|
||||
- name: 'Create a PR'
|
||||
id: create-github-pr
|
||||
working-directory: 'rspec'
|
||||
env:
|
||||
GH_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).coverage_github_token }}
|
||||
run: |
|
||||
PR_URL=$(gh pr create --head ${{ env.TMP_BRANCH }} --title "Update coverage information" --body "" --label "rspec system")
|
||||
gh pr merge $PR_URL
|
||||
|
||||
- name: 'Push the updated coverage to master'
|
||||
if: |
|
||||
steps.gen-coverage.outputs.new_coverage == 'true' &&
|
||||
steps.wait-for-build.outputs.conclusion == 'success'
|
||||
- name: 'Wait until the PR is merged'
|
||||
id: wait-for-pr-to-merge
|
||||
env:
|
||||
GH_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).coverage_github_token }}
|
||||
working-directory: 'rspec'
|
||||
run: |
|
||||
git checkout master
|
||||
git merge $TMP_BRANCH
|
||||
git push origin master
|
||||
set -ueo pipefail
|
||||
|
||||
- name: 'Delete the temporary branch'
|
||||
if: always() && steps.create-temp-branch.conclusion == 'success'
|
||||
uses: dawidd6/action-delete-branch@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN}}
|
||||
branches: ${{ env.TMP_BRANCH}}
|
||||
# Implicitly referring to the PR corresponding to current branch
|
||||
|
||||
- name: 'Fail if the change breaks CI'
|
||||
if: |
|
||||
steps.gen-coverage.outputs.new_coverage == 'true' &&
|
||||
steps.wait-for-build.outputs.conclusion != 'success'
|
||||
run: exit 1
|
||||
# Set timeout (20 minutes in seconds)
|
||||
TIMEOUT=1200 # seconds
|
||||
START_TIME=$(date +%s)
|
||||
INTERVAL=20 # seconds
|
||||
|
||||
while true; do
|
||||
# Check if the PR is merged
|
||||
PR_STATE=$(gh pr view --json state,mergedAt -q '.state')
|
||||
MERGED_AT=$(gh pr view --json state,mergedAt -q '.mergedAt')
|
||||
|
||||
if [[ "${PR_STATE}" == "MERGED" ]]; then
|
||||
echo "PR merged at: $MERGED_AT"
|
||||
exit 0
|
||||
fi
|
||||
echo "PR state is ${PR_STATE}"
|
||||
|
||||
# Check for timeout
|
||||
CURRENT_TIME=$(date +%s)
|
||||
ELAPSED_TIME=$((CURRENT_TIME - START_TIME))
|
||||
|
||||
if [[ "${ELAPSED_TIME}" -gt "${TIMEOUT}" ]]; then
|
||||
echo "Timeout waiting for PR to merge."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Wait for $INTERVAL seconds before checking again
|
||||
sleep "$INTERVAL"
|
||||
done
|
||||
|
||||
- name: 'Close PR and delete branch upon failure to merge'
|
||||
if: ${{ failure() }}
|
||||
env:
|
||||
GH_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).coverage_github_token }}
|
||||
working-directory: 'rspec'
|
||||
run: |
|
||||
PR_URL=$(gh pr view --json url --jq '.url')
|
||||
gh pr close "$PR_URL" --delete-branch
|
||||
|
||||
- name: 'Notify on slack about the failure'
|
||||
if: ${{ failure() }}
|
||||
env:
|
||||
SLACK_API_TOKEN: ${{ secrets.SLACK_API_TOKEN }}
|
||||
SLACK_API_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).slack_token }}
|
||||
working-directory: 'rspec/rspec-tools'
|
||||
run: |
|
||||
pipenv run rspec-tools notify-failure-on-slack \
|
||||
|
5
.github/workflows/update_quickfix_status.yml
vendored
5
.github/workflows/update_quickfix_status.yml
vendored
@ -25,7 +25,10 @@ on:
|
||||
jobs:
|
||||
update_quickfix_status:
|
||||
name: Update quick fix status
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,6 +10,7 @@
|
||||
# generated files
|
||||
/rules/**/*.html
|
||||
/frontend/public/rules
|
||||
rspec-tools/link_probes.history
|
||||
|
||||
# compiled files
|
||||
*.out
|
||||
|
275
LICENSE
275
LICENSE
@ -1,165 +1,184 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
SONAR Source-Available License v1.0
|
||||
Last Updated November 13, 2024
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
1. DEFINITIONS
|
||||
|
||||
"Agreement" means this Sonar Source-Available License v1.0
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
"Competing" means marketing a product or service as a substitute for the
|
||||
functionality or value of SonarQube. A product or service may compete regardless
|
||||
of how it is designed or deployed. For example, a product or service may compete
|
||||
even if it provides its functionality via any kind of interface (including
|
||||
services, libraries, or plug-ins), even if it is ported to a different platform
|
||||
or programming language, and even if it is provided free of charge.
|
||||
|
||||
0. Additional Definitions.
|
||||
"Contribution" means:
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
a) in the case of the initial Contributor, the initial content Distributed under
|
||||
this Agreement, and
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
b) in the case of each subsequent Contributor:
|
||||
i) changes to the Program, and
|
||||
ii) additions to the Program;
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
where such changes and/or additions to the Program originate from and are
|
||||
Distributed by that particular Contributor. A Contribution "originates" from a
|
||||
Contributor if it was added to the Program by such Contributor itself or anyone
|
||||
acting on such Contributor's behalf. Contributions do not include changes or
|
||||
additions to the Program that are not Modified Works.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
"Contributor" means any person or entity that Distributes the Program.
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
"Derivative Works" shall mean any work, whether in Source Code or other form,
|
||||
that is based on (or derived from) the Program and for which the editorial
|
||||
revisions, annotations, elaborations, or other modifications represent, as a
|
||||
whole, an original work of authorship.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
"Distribute" means the acts of a) distributing or b) making available in any
|
||||
manner that enables the transfer of a copy.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
"Licensed Patents" mean patent claims licensable by a Contributor that are
|
||||
necessarily infringed by the use or sale of its Contribution alone or when
|
||||
combined with the Program.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
"Modified Works" shall mean any work in Source Code or other form that results
|
||||
from an addition to, deletion from, or modification of the contents of the
|
||||
Program, including, for purposes of clarity, any new file in Source Code form
|
||||
that contains any contents of the Program. Modified Works shall not include
|
||||
works that contain only declarations, interfaces, types, classes, structures, or
|
||||
files of the Program solely in each case in order to link to, bind by name, or
|
||||
subclass the Program or Modified Works thereof.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
"Non-competitive Purpose" means any purpose except for (a) providing to others
|
||||
any product or service that includes or offers the same or substantially similar
|
||||
functionality as SonarQube, (b) Competing with SonarQube, and/or (c) employing,
|
||||
using, or engaging artificial intelligence technology that is not part of the
|
||||
Program to ingest, interpret, analyze, train on, or interact with the data
|
||||
provided by the Program, or to engage with the Program in any manner.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
"Notices" means any legal statements or attributions included with the Program,
|
||||
including, without limitation, statements concerning copyright, patent,
|
||||
trademark, disclaimers of warranty, or limitations of liability
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
"Program" means the Contributions Distributed in accordance with this Agreement.
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
"Recipient" means anyone who receives the Program under this Agreement,
|
||||
including Contributors.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
"SonarQube" means an open-source or commercial edition of software offered by
|
||||
SonarSource that is branded "SonarQube".
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
"SonarSource" means SonarSource SA, a Swiss company registered in Switzerland
|
||||
under UID No. CHE-114.587.664.
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
"Source Code" means the form of a Program preferred for making modifications,
|
||||
including but not limited to software source code, documentation source, and
|
||||
configuration files.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
2. GRANT OF RIGHTS
|
||||
|
||||
4. Combined Works.
|
||||
a) Subject to the terms of this Agreement, each Contributor hereby grants
|
||||
Recipient a non-exclusive, worldwide, royalty-free copyright license, for any
|
||||
Non-competitive Purpose, to reproduce, prepare Derivative Works of, publicly
|
||||
display, publicly perform, Distribute and sublicense the Contribution of such
|
||||
Contributor, if any, and such Derivative Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
b) Subject to the terms of this Agreement, each Contributor hereby grants
|
||||
Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed
|
||||
Patents, for any Non-competitive Purpose, to make, use, sell, offer to sell,
|
||||
import, and otherwise transfer the Contribution of such Contributor, if any, in
|
||||
Source Code or other form. This patent license shall apply to the combination of
|
||||
the Contribution and the Program if, at the time the Contribution is added by
|
||||
the Contributor, such addition of the Contribution causes such combination to be
|
||||
covered by the Licensed Patents. The patent license shall not apply to any other
|
||||
combinations that include the Contribution.
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
c) Recipient understands that although each Contributor grants the licenses to
|
||||
its Contributions set forth herein, no assurances are provided by any
|
||||
Contributor that the Program does not infringe the patent or other intellectual
|
||||
property rights of any other entity. Each Contributor disclaims any liability to
|
||||
Recipient for claims brought by any other entity based on infringement of
|
||||
intellectual property rights or otherwise. As a condition to exercising the
|
||||
rights and licenses granted hereunder, each Recipient hereby assumes sole
|
||||
responsibility to secure any other intellectual property rights needed, if any.
|
||||
For example, if a third-party patent license is required to allow Recipient to
|
||||
Distribute the Program, it is Recipient's responsibility to acquire that license
|
||||
before distributing the Program.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
d) Each Contributor represents that to its knowledge it has sufficient copyright
|
||||
rights in its Contribution, if any, to grant the copyright license set forth in
|
||||
this Agreement.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
3. REQUIREMENTS
|
||||
|
||||
d) Do one of the following:
|
||||
3.1 If a Contributor Distributes the Program in any form, then the Program must
|
||||
also be made available as Source Code, in accordance with section 3.2, and the
|
||||
Contributor must accompany the Program with a statement that the Source Code for
|
||||
the Program is available under this Agreement, and inform Recipients how to
|
||||
obtain it in a reasonable manner on or through a medium customarily used for
|
||||
software exchange; and
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
3.2 When the Program is Distributed as Source Code:
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
a) it must be made available under this Agreement, and
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
b) a copy of this Agreement must be included with each copy of the Program.
|
||||
|
||||
5. Combined Libraries.
|
||||
3.3 Contributors may not remove or alter any Notices contained within the
|
||||
Program from any copy of the Program which they Distribute, provided that
|
||||
Contributors may add their own appropriate Notices.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
4. NO WARRANTY
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
|
||||
OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
|
||||
responsible for determining the appropriateness of using and distributing the
|
||||
Program and assumes all risks associated with its exercise of rights under this
|
||||
Agreement, including but not limited to the risks and costs of program errors,
|
||||
compliance with applicable laws, damage to or loss of data, programs or
|
||||
equipment, and unavailability or interruption of operations.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
5. DISCLAIMER OF LIABILITY
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
|
||||
THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
6. GENERAL
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
If any provision of this Agreement is invalid or unenforceable under applicable
|
||||
law, it shall not affect the validity or enforceability of the remainder of the
|
||||
terms of this Agreement, and without further action by the parties hereto, such
|
||||
provision shall be reformed to the minimum extent necessary to make such
|
||||
provision valid and enforceable.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
If Recipient institutes patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Program itself
|
||||
(excluding combinations of the Program with other software or hardware)
|
||||
infringes such Recipient’s patent(s), then such Recipient’s rights granted under
|
||||
Section 2(b) shall terminate as of the date such litigation is filed.
|
||||
|
||||
All Recipient’s rights under this Agreement shall terminate if it fails to
|
||||
comply with any of the material terms or conditions of this Agreement and does
|
||||
not cure such failure in a reasonable period of time after becoming aware of
|
||||
such noncompliance. If all Recipient’s rights under this Agreement terminate,
|
||||
Recipient agrees to cease use and distribution of the Program as soon as
|
||||
reasonably practicable. However, Recipient’s obligations under this Agreement
|
||||
and any licenses granted by Recipient relating to the Program shall continue and
|
||||
survive.
|
||||
|
||||
Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives
|
||||
no rights or licenses to the intellectual property of any Contributor under this
|
||||
Agreement, whether expressly, by implication, estoppel, or otherwise. All rights
|
||||
in the Program not expressly granted under this Agreement are reserved. Nothing
|
||||
in this Agreement is intended to be enforceable by any entity that is not a
|
||||
Contributor or Recipient. No third-party beneficiary rights are created under
|
||||
this Agreement.
|
||||
|
@ -8,6 +8,8 @@ This repository contains the specification of every static-analysis rule availab
|
||||
|
||||
It also contains rules which have been dropped and rules which will one day be implemented.
|
||||
|
||||
The content of this repository is covered by the link:LICENSE[SONAR Source-Available License v1.0].
|
||||
|
||||
== Rules directory structure
|
||||
|
||||
* https://github.com/SonarSource/rspec/tree/master/rules[rules] directory: contains every specified rule.
|
||||
|
@ -6,38 +6,38 @@ ACTION=${1}
|
||||
CACHE_NAME=${2}
|
||||
PATH_TO_CACHE=${3}
|
||||
|
||||
CACHE_KEY=${CACHE_NAME}
|
||||
DEFAULT_CACHE_KEY=${CACHE_NAME}
|
||||
CACHE_URL="http://${CIRRUS_HTTP_CACHE_HOST}/${CACHE_NAME}"
|
||||
|
||||
CACHE_URL=http://${CIRRUS_HTTP_CACHE_HOST}/${CACHE_KEY}
|
||||
|
||||
TMP_PATH=/tmp/tmp-cache.tgz
|
||||
TMP_PATH="/tmp/tmp-cache.tgz"
|
||||
|
||||
case "${ACTION}" in
|
||||
|
||||
download)
|
||||
echo "Download cache with key ${CACHE_KEY}"
|
||||
|
||||
echo " -> try ${CACHE_URL}"
|
||||
curl -sfSL -o ${TMP_PATH} ${CACHE_URL} || {
|
||||
echo "Cache download failed";
|
||||
exit 0;
|
||||
echo "Download cache with key ${CACHE_NAME} from ${CACHE_URL}"
|
||||
curl --silent --show-error --fail --location --output "${TMP_PATH}" "${CACHE_URL}" || {
|
||||
echo "Cache download failed" >&2
|
||||
exit 0
|
||||
}
|
||||
du -hs ${TMP_PATH}
|
||||
tar -Pxzf ${TMP_PATH}
|
||||
rm ${TMP_PATH}
|
||||
du -hs "${TMP_PATH}"
|
||||
tar -Pxzf "${TMP_PATH}"
|
||||
rm "${TMP_PATH}"
|
||||
;;
|
||||
|
||||
upload)
|
||||
echo "Upload cache to ${CACHE_URL}"
|
||||
tar -Pczf ${TMP_PATH} ${PATH_TO_CACHE}
|
||||
du -hs ${TMP_PATH}
|
||||
curl -s -X POST --data-binary @${TMP_PATH} ${CACHE_URL}
|
||||
tar -Pczf "${TMP_PATH}" "${PATH_TO_CACHE}"
|
||||
du -hs "${TMP_PATH}"
|
||||
curl --silent --show-error -X POST --data-binary "@${TMP_PATH}" "${CACHE_URL}" || {
|
||||
echo "Cache upload failed" >&2
|
||||
exit 0
|
||||
}
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unexpected cache ACTION: ${ACTION}"
|
||||
echo "Unexpected cache ACTION: ${ACTION}" >&2
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
echo "Cache ${ACTION}ed succeeded."
|
||||
|
7
ci/install_rspec_tools_dependencies.sh
Executable file
7
ci/install_rspec_tools_dependencies.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
cd rspec-tools
|
||||
pipenv install --dev
|
||||
pipenv run pip install pytest pytest-cov
|
0
ci/validate_file_extensions.sh
Normal file → Executable file
0
ci/validate_file_extensions.sh
Normal file → Executable file
@ -13,17 +13,20 @@ else
|
||||
git diff --name-only "${base}" -- rules/ | # Get all the changes in rules
|
||||
sed -Ee 's#(rules/S[0-9]+)/.*#\1#' | # extract the rule directories
|
||||
sort -u | # deduplicate
|
||||
while IFS= read -r rule; do [[ -d "$rule" ]] && echo "$rule" || true; done | # filter non-deleted rules
|
||||
while IFS= read -r rule; do if [[ -d "$rule" ]]; then echo "$rule"; fi done | # filter out deleted rules
|
||||
sed 's#rules/##' | # get rule ids
|
||||
mapfile -t affected_rules # store them in the `affected_rules` array
|
||||
echo "Validating ${affected_rules[@]}"
|
||||
echo "Validating ${affected_rules[*]}"
|
||||
fi
|
||||
|
||||
printf '\n\n\n'
|
||||
|
||||
# Validate metadata
|
||||
if [[ "${#affected_rules[@]}" -gt 0 ]]
|
||||
then
|
||||
cd rspec-tools
|
||||
pipenv install
|
||||
printf '\n\n\n'
|
||||
pipenv run rspec-tools validate-rules-metadata "${affected_rules[@]}"
|
||||
else
|
||||
echo "No rule changed or added"
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
== In the RSPEC
|
||||
|
||||
The rule status (`/status` in the metadata) should be set to `deprecated`.
|
||||
The rule status (`/status` in the metadata) should be set to `deprecated`, and its tags should be removed. If the rule is in `SonarWay`, it should be removed from this profile.
|
||||
|
||||
Optionally, `/extra/replacementRules` can list the rules that replace this rule.
|
||||
|
||||
|
@ -271,6 +271,24 @@ tsql:: use `sql`
|
||||
|
||||
In case no language is appropriate for a code block (for example shared examples between multiple languages), you can use `text` as the language.
|
||||
|
||||
=== Comments within code blocks
|
||||
|
||||
Colon (`:`) should be used as separator between `Noncompliant`/`Compliant` comments and the text explanation that follows, if any.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
int X = 2; // Noncompliant: variable should be in lowercase
|
||||
----
|
||||
|
||||
|
||||
When referencing a name within a comment in a code example, use double quotes to make it clear it refers to an existing element in the code.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
int i = 0;
|
||||
cout << noexcept(++i); // Noncompliant: "i" is not incremented
|
||||
----
|
||||
|
||||
=== Diff view
|
||||
|
||||
Additionally, you can also use two attributes to let the products know your code examples should be highlighted with a diff view when possible
|
||||
|
@ -1,3 +1,4 @@
|
||||
// Ansible
|
||||
// C#
|
||||
* ASP.NET
|
||||
* ASP.NET Core
|
||||
@ -8,6 +9,7 @@
|
||||
* Dapper
|
||||
* BouncyCastle
|
||||
* Jwt.Net
|
||||
* Blazor
|
||||
// C-Family
|
||||
* Botan
|
||||
* CryptoPP
|
||||
@ -25,6 +27,7 @@
|
||||
* libxml2
|
||||
// Java
|
||||
* Android
|
||||
* Android WebView
|
||||
* Apache Commons
|
||||
* Apache Commons
|
||||
* Apache Commons Email
|
||||
@ -40,21 +43,32 @@
|
||||
* Java EE
|
||||
* Java JWT
|
||||
* Java SE
|
||||
* Java JDBC API
|
||||
* Java I/O API
|
||||
* Jdom2
|
||||
* JSP
|
||||
* Legacy Mongo Java API
|
||||
* OkHttp
|
||||
* Realm
|
||||
* Apache HttpClient
|
||||
* Couchbase
|
||||
* SAX
|
||||
* Servlet
|
||||
* Spring
|
||||
* Spring Data MongoDB
|
||||
* Spring Data Cassandra
|
||||
* Spring Data Redis
|
||||
* Spring Data Neo4j
|
||||
* SQLCipher
|
||||
* Thymeleaf
|
||||
// JS
|
||||
* Jasmine
|
||||
* Jest
|
||||
* Flow.js
|
||||
* Node.js
|
||||
* Express.js
|
||||
* SSH2
|
||||
* Mocha
|
||||
* MongoDB
|
||||
* Mongoose
|
||||
* Sequelize
|
||||
@ -69,6 +83,7 @@
|
||||
* TypeScript
|
||||
* PropTypes
|
||||
* JSX
|
||||
* Electron
|
||||
// PHP
|
||||
* Core PHP
|
||||
* Guzzle
|
||||
@ -83,6 +98,7 @@
|
||||
* Argon2-cffi
|
||||
* Bcrypt
|
||||
* Cryptodome
|
||||
* databases
|
||||
* Django
|
||||
* Django Templates
|
||||
* FastAPI
|
||||
@ -103,6 +119,7 @@
|
||||
* python-ldap
|
||||
* Python SQLite
|
||||
* Python Standard Library
|
||||
* PyTorch
|
||||
* PyYAML
|
||||
* Requests
|
||||
* Scrypt
|
||||
@ -110,6 +127,7 @@
|
||||
* SignXML
|
||||
* SQLAlchemy
|
||||
* ssl
|
||||
* TensorFlow
|
||||
// Docker
|
||||
* Wget
|
||||
// Cloudformation
|
||||
@ -135,7 +153,7 @@
|
||||
* CryptoSwift
|
||||
* IDZSwiftCommonCrypto
|
||||
// Azure resource manager
|
||||
* ARM templates
|
||||
* JSON templates
|
||||
* Bicep
|
||||
// PL/SQL
|
||||
* DBMS_CRYPTO
|
||||
@ -143,3 +161,5 @@
|
||||
* Go Standard Library
|
||||
// Kubernetes
|
||||
* Helm
|
||||
// Kotlin
|
||||
Jetpack Compose
|
||||
|
@ -45,6 +45,7 @@ When web pages have massively long names like "Java™ Platform, Standard Editio
|
||||
* AWS blog - https://aws.amazon.com/blogs
|
||||
* Azure Documentation - https://learn.microsoft.com/en-us/azure/?product=popular
|
||||
* CERT - https://wiki.sei.cmu.edu/confluence/display/seccode
|
||||
* Clippy Lints - https://rust-lang.github.io/rust-clippy/master/index.html
|
||||
* {cpp} reference - https://en.cppreference.com/w/
|
||||
* {cpp} Core Guidelines - https://github.com/isocpp/CppCoreGuidelines/blob/e49158a/CppCoreGuidelines.md
|
||||
* CVE - https://cve.mitre.org
|
||||
|
@ -40,6 +40,6 @@ You can update the quickfix field using this GitHub Workflow: https://github.com
|
||||
|
||||
The code field is an object that contains information related to the clean code taxonomy. It is an object with two required properties:
|
||||
|
||||
* `impacts`: A nested object that is treated as a mapping from a software quality to a level (`"LOW"`, `"MEDIUM"` or `"HIGH"`). Note that at least one software quality has to be specified. The current list of allowed software qualities is `"MAINTAINABILITY"`, `"RELIABILITY"` and `"SECURITY"`.
|
||||
* `impacts`: A nested object that is treated as a mapping from a software quality to a level (`"INFO"`, `"LOW"`, `"MEDIUM"`, `"HIGH"` or `"BLOCKER"`). Note that at least one software quality has to be specified. The current list of allowed software qualities is `"MAINTAINABILITY"`, `"RELIABILITY"` and `"SECURITY"`.
|
||||
|
||||
* `attribute`: A single clean code attribute that the rule aims to achieve. This has to be one of the following values: `"FORMATTED"`, `"CONVENTIONAL"`, `"IDENTIFIABLE"`, `"CLEAR"`, `"LOGICAL"`, `"COMPLETE"`, `"EFFICIENT"`, `"FOCUSED"`, `"DISTINCT"`, `"MODULAR"`, `"TESTED"`, `"LAWFUL"`, `"TRUSTWORTHY"`, `"RESPECTFUL"`.
|
||||
|
@ -109,3 +109,17 @@ Use it when referencing variable names, file names, tokens, and all kinds of spe
|
||||
Write:: Compiling source file `src/generic_file.py` breaks an `assert` call in pytest framework.
|
||||
Avoid:: Compiling source file "src/generic_file.py" breaks an `assert` call in `pytest` framework.
|
||||
|
||||
== Referencing elements from the code
|
||||
|
||||
When referencing elements from the code within a normal sentence, use the `backticks` (```) to format it. This includes variable names, function names, class names, and so on.
|
||||
|
||||
When referencing the same elements within a comment in a code block, surrpond it with double quotes.
|
||||
[source,cpp]
|
||||
----
|
||||
int i = 0;
|
||||
// Write
|
||||
cout << noexcept(++i); // Noncompliant, "i" is not incremented -> Double quotes
|
||||
// Avoid
|
||||
cout << noexcept(++i); // Noncompliant, i is not incremented -> No quotes
|
||||
cout << noexcept(++i); // Noncompliant, `i` is not incremented -> Backticks
|
||||
----
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -149,6 +149,7 @@ const languageToJiraProject = new Map(Object.entries({
|
||||
'ABAP': 'SONARABAP',
|
||||
'AZURE_RESOURCE_MANAGER': 'SONARIAC',
|
||||
'CFAMILY': 'CPP',
|
||||
'DART': 'DART',
|
||||
'DOCKER': 'SONARIAC',
|
||||
'JAVA': 'SONARJAVA',
|
||||
'JCL': 'SONARJCL',
|
||||
@ -157,38 +158,42 @@ const languageToJiraProject = new Map(Object.entries({
|
||||
'HTML': 'SONARHTML',
|
||||
'PHP': 'SONARPHP',
|
||||
'PLI': 'SONARPLI',
|
||||
'PLSQL': 'SONARPLSQL',
|
||||
'PLSQL': 'PLSQL',
|
||||
'RPG': 'SONARRPG',
|
||||
'APEX': 'SONARSLANG',
|
||||
'RUBY': 'SONARSLANG',
|
||||
'APEX': 'SONARAPEX',
|
||||
'RUBY': 'SONARRUBY',
|
||||
'RUST': 'SKUNK',
|
||||
'KOTLIN': 'SONARKT',
|
||||
'SCALA': 'SONARSLANG',
|
||||
'GO': 'SONARSLANG',
|
||||
'SECRETS': 'SECRETS',
|
||||
'SCALA': 'SONARSCALA',
|
||||
'GO': 'SONARGO',
|
||||
'SECRETS': 'SONARTEXT',
|
||||
'SWIFT': 'SONARSWIFT',
|
||||
'TSQL': 'SONARTSQL',
|
||||
'VB6': 'SONARVBSIX',
|
||||
'TSQL': 'TSQL',
|
||||
'VB6': 'VB6',
|
||||
'XML': 'SONARXML',
|
||||
'CLOUDFORMATION': 'SONARIAC',
|
||||
'TERRAFORM': 'SONARIAC',
|
||||
'KUBERNETES': 'SONARIAC',
|
||||
'TEXT': 'SONARTEXT',
|
||||
'ANSIBLE': 'SONARIAC',
|
||||
}));
|
||||
|
||||
const languageToGithubProject = new Map(Object.entries({
|
||||
'ABAP': 'sonar-abap',
|
||||
'AZURE_RESOURCE_MANAGER': 'sonar-iac',
|
||||
'CSHARP': 'sonar-dotnet',
|
||||
'DART': 'sonar-dart',
|
||||
'DOCKER': 'sonar-iac',
|
||||
'VBNET': 'sonar-dotnet',
|
||||
'JAVASCRIPT': 'SonarJS',
|
||||
'TYPESCRIPT': 'SonarJS',
|
||||
'SWIFT': 'sonar-swift',
|
||||
'KOTLIN': 'sonar-kotlin',
|
||||
'GO': 'slang-enterprise',
|
||||
'SCALA': 'slang-enterprise',
|
||||
'RUBY': 'slang-enterprise',
|
||||
'APEX': 'slang-enterprise',
|
||||
'GO': 'sonar-go',
|
||||
'SCALA': 'sonar-scala',
|
||||
'RUBY': 'sonar-ruby',
|
||||
'RUST': 'sonar-rust',
|
||||
'APEX': 'sonar-apex',
|
||||
'HTML': 'sonar-html',
|
||||
'COBOL': 'sonar-cobol',
|
||||
'VB6': 'sonar-vb',
|
||||
@ -207,8 +212,9 @@ const languageToGithubProject = new Map(Object.entries({
|
||||
'CLOUDFORMATION': 'sonar-iac',
|
||||
'TERRAFORM': 'sonar-iac',
|
||||
'KUBERNETES': 'sonar-iac',
|
||||
'SECRETS': 'sonar-secrets',
|
||||
'SECRETS': 'sonar-text',
|
||||
'TEXT': 'sonar-text',
|
||||
'ANSIBLE': 'sonar-iac-enterprise',
|
||||
}));
|
||||
|
||||
function ticketsAndImplementationPRsLinks(ruleNumber: string, title: string, language?: string) {
|
||||
@ -314,7 +320,7 @@ function usePageMetadata(ruleid: string, language: string, classes: UsedStyles):
|
||||
|
||||
if (coverage !== 'Not Covered') {
|
||||
prUrl = undefined;
|
||||
branch = 'master';
|
||||
branch = 'master';
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -31,7 +31,7 @@ export async function process_incomplete_rspecs(tmpRepoDir: string,
|
||||
const repo = await (() => {
|
||||
if (!fs.existsSync(path.join(tmpRepoDir, '.git'))) {
|
||||
if (process.env.GITHUB_TOKEN) {
|
||||
return Git.Clone.clone('https://' + process.env.GITHUB_TOKEN + '@github.com/SonarSource/rspec/', tmpRepoDir);
|
||||
return Git.Clone.clone(`https://${process.env.GITHUB_TOKEN}@github.com/SonarSource/rspec/`, tmpRepoDir);
|
||||
} else {
|
||||
return Git.Clone.clone('https://github.com/SonarSource/rspec/', tmpRepoDir);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ const languageToSonarpedia = new Map<string, string[]>(Object.entries({
|
||||
'cfamily': ['CPP', 'C', 'OBJC'],
|
||||
'cobol': ['COBOL'],
|
||||
'csharp': ['CSH'],
|
||||
'dart': ['DART'],
|
||||
'docker': ['DOCKER'],
|
||||
'vbnet': ['VBNET'],
|
||||
'css': ['CSS'],
|
||||
@ -26,6 +27,7 @@ const languageToSonarpedia = new Map<string, string[]>(Object.entries({
|
||||
'plsql': ['PLSQL'],
|
||||
'python': ['PY'],
|
||||
'rpg': ['RPG'],
|
||||
'rust': ['RUST'],
|
||||
'secrets': ['SECRETS'],
|
||||
'swift': ['SWIFT'],
|
||||
'tsql': ['TSQL'],
|
||||
@ -36,7 +38,8 @@ const languageToSonarpedia = new Map<string, string[]>(Object.entries({
|
||||
'cloudformation': ['CLOUDFORMATION'],
|
||||
'terraform': ['TERRAFORM'],
|
||||
'kubernetes': ['KUBERNETES'],
|
||||
'text': ['TEXT']
|
||||
'text': ['TEXT'],
|
||||
'ansible': ['ANSIBLE']
|
||||
}));
|
||||
|
||||
export function useRuleCoverage() {
|
||||
|
@ -55,5 +55,5 @@ In order to generate an HTML file from the ASCIIdoc, you can use [asciidoctor](h
|
||||
|
||||
[source,sh]
|
||||
----
|
||||
$ asciidoctor -e rule.adoc
|
||||
$ asciidoctor rule.adoc
|
||||
----
|
||||
|
@ -0,0 +1,56 @@
|
||||
{
|
||||
"title": "SECRET_TYPE should not be disclosed",
|
||||
"type": "VULNERABILITY",
|
||||
"code": {
|
||||
"impacts": {
|
||||
"SECURITY": "BLOCKER"
|
||||
},
|
||||
"attribute": "TRUSTWORTHY"
|
||||
},
|
||||
"status": "beta",
|
||||
"remediation": {
|
||||
"func": "Constant\/Issue",
|
||||
"constantCost": "30min"
|
||||
},
|
||||
"tags": [
|
||||
"cwe",
|
||||
"cert"
|
||||
],
|
||||
"defaultSeverity": "Blocker",
|
||||
"ruleSpecification": "RSPEC-${RSPEC_ID}",
|
||||
"sqKey": "S${RSPEC_ID}",
|
||||
"scope": "All",
|
||||
"securityStandards": {
|
||||
"CWE": [
|
||||
798,
|
||||
259
|
||||
],
|
||||
"OWASP": [
|
||||
"A3"
|
||||
],
|
||||
"CERT": [
|
||||
"MSC03-J."
|
||||
],
|
||||
"OWASP Top 10 2021": [
|
||||
"A7"
|
||||
],
|
||||
"PCI DSS 3.2": [
|
||||
"6.5.10"
|
||||
],
|
||||
"PCI DSS 4.0": [
|
||||
"6.2.4"
|
||||
],
|
||||
"ASVS 4.0": [
|
||||
"2.10.4",
|
||||
"3.5.2",
|
||||
"6.4.1"
|
||||
],
|
||||
"STIG ASD_V5R3": [
|
||||
"V-222642"
|
||||
]
|
||||
},
|
||||
"defaultQualityProfiles": [
|
||||
"Sonar way"
|
||||
],
|
||||
"quickfix": "unknown"
|
||||
}
|
123
rspec-tools/rspec_template/single_language/secrets/rule.adoc
Normal file
123
rspec-tools/rspec_template/single_language/secrets/rule.adoc
Normal file
@ -0,0 +1,123 @@
|
||||
:example_env: ENV_VAR_NAME
|
||||
:example_name: java-property-name
|
||||
:example_secret: example_secret_value
|
||||
|
||||
// Set value that can be used to refer to the type of secret in, for example:
|
||||
// "An attacker can use this {secret_type} to ..."
|
||||
// Commonly used values: access token, api key, application secret, application key or consumer key, service password, OAuth token, deployment password
|
||||
:secret_type: secret
|
||||
|
||||
include::../../../shared_content/secrets/description.adoc[]
|
||||
|
||||
== Why is this an issue?
|
||||
|
||||
include::../../../shared_content/secrets/rationale.adoc[]
|
||||
|
||||
=== What is the potential impact?
|
||||
|
||||
// Optional: Give a general description of the secret and what it's used for.
|
||||
|
||||
include::../../../shared_content/secrets/impact/generic_impact.adoc[]
|
||||
|
||||
// Uncomment the following line, if specifying detailed impacts from below (also make sure to have new lines around the uncommented includes):
|
||||
// include::../../../shared_content/secrets/impact/specific_impact_intro.adoc[]
|
||||
|
||||
// Secret may allow hosting arbitrary files
|
||||
// include::../../../shared_content/secrets/impact/malware_distribution.adoc[]
|
||||
|
||||
// Secret may allow accessing or compromising sensitive data
|
||||
// include::../../../shared_content/secrets/impact/data_compromise.adoc[]
|
||||
|
||||
// Secret may allow uploading artifacts to services used elsewhere in the supply chain
|
||||
// This is specific for code and artifact repositories
|
||||
// include::../../../shared_content/secrets/impact/supply_chain_attack.adoc[]
|
||||
|
||||
// Secret may be used to trigger workflows
|
||||
// This is webhook-specific
|
||||
// include::../../../shared_content/secrets/impact/codeless_vulnerability_chaining.adoc[]
|
||||
|
||||
// OAuth tokens may allow accessing 3rd party services
|
||||
// include::../../../shared_content/secrets/impact/oauth_token_compromise.adoc[]
|
||||
|
||||
// Mailing service compromise may allow sending spam, which may result in account termination
|
||||
// include::../../../shared_content/secrets/impact/suspicious_activities_termination.adoc[]
|
||||
|
||||
// Sensitive information leak / identity impersonation, e.g., through leaked signing secret
|
||||
// include::../../../shared_content/secrets/impact/security_downgrade.adoc[]
|
||||
|
||||
// Audit trail discrepancies
|
||||
// include::../../../shared_content/secrets/impact/non_repudiation.adoc[]
|
||||
|
||||
// Package repository secrets may allow access to source code etc.
|
||||
// include::../../../shared_content/secrets/impact/source_code_compromise.adoc[]
|
||||
|
||||
// Spamming automated calls may cause large bills and rate limited service access
|
||||
// include::../../../shared_content/secrets/impact/exceed_rate_limits.adoc[]
|
||||
|
||||
// For blockchain specific tokens
|
||||
// include::../../../shared_content/secrets/impact/blockchain_data_exposure.adoc[]
|
||||
|
||||
// Specific for banking / financial transaction tokens, causing financial loss
|
||||
// include::../../../shared_content/secrets/impact/banking_financial_loss.adoc[]
|
||||
|
||||
// Secret can be used to send spam or phish users
|
||||
// include::../../../shared_content/secrets/impact/phishing.adoc[]
|
||||
|
||||
// Secret may allow modifying application data (object stores etc.)
|
||||
// include::../../../shared_content/secrets/impact/data_modification.adoc[]
|
||||
|
||||
// Specific to services that are used to share PII (personal infos, chat logs, ..)
|
||||
// include::../../../shared_content/secrets/impact/personal_data_compromise.adoc[]
|
||||
|
||||
// Secret may allow accessing financial data, like CC information or confidential financial reports
|
||||
// include::../../../shared_content/secrets/impact/disclosure_of_financial_data.adoc[]
|
||||
|
||||
// Secret may allow occurring financial losses through 3rd party API usage
|
||||
// include::../../../shared_content/secrets/impact/financial_loss.adoc[]
|
||||
|
||||
// Secret may be used to modify dashboards to corrupt shown data
|
||||
// Requires setting service_name variable
|
||||
// :service_name: secret service
|
||||
// include::../../../shared_content/secrets/impact/dataviz_takeover.adoc[]
|
||||
|
||||
// Secret is related to IaaS providers and can be used to change DNS, launch VMs, etc.
|
||||
// Requires setting service_name variable
|
||||
// :service_name: secret service
|
||||
// include::../../../shared_content/secrets/impact/infrastructure_takeover.adoc[]
|
||||
|
||||
== How to fix it
|
||||
|
||||
// 1. Revoke leaked secrets
|
||||
|
||||
include::../../../shared_content/secrets/fix/revoke.adoc[]
|
||||
|
||||
// 2. Analyze recent use to identify misuse
|
||||
|
||||
include::../../../shared_content/secrets/fix/recent_use.adoc[]
|
||||
|
||||
// 3. Use a secret vault in the future
|
||||
|
||||
include::../../../shared_content/secrets/fix/vault.adoc[]
|
||||
|
||||
// 4. Never hard-code secrets
|
||||
|
||||
include::../../../shared_content/secrets/fix/default.adoc[]
|
||||
|
||||
// OAuth PKCE is very specific to OAuth 2.0
|
||||
// include::../../../shared_content/secrets/fix/oauth_pkce.adoc[]
|
||||
|
||||
=== Code examples
|
||||
|
||||
include::../../../shared_content/secrets/examples.adoc[]
|
||||
|
||||
//=== How does this work?
|
||||
|
||||
//=== Pitfalls
|
||||
|
||||
//=== Going the extra mile
|
||||
|
||||
== Resources
|
||||
|
||||
include::../../../shared_content/secrets/resources/standards.adoc[]
|
||||
|
||||
//=== Benchmarks
|
@ -1,21 +1,28 @@
|
||||
import os,io
|
||||
import re
|
||||
import requests
|
||||
import json
|
||||
import random
|
||||
import datetime
|
||||
from bs4 import BeautifulSoup
|
||||
from socket import timeout
|
||||
import json
|
||||
import pathlib
|
||||
import random
|
||||
import socket
|
||||
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
TOLERABLE_LINK_DOWNTIME = datetime.timedelta(days=7)
|
||||
LINK_PROBES_HISTORY_FILE = './link_probes.history'
|
||||
PROBING_COOLDOWN = datetime.timedelta(days=1)
|
||||
PROBING_SPREAD = 100 # minutes
|
||||
PROBING_COOLDOWN = datetime.timedelta(days=2)
|
||||
PROBING_SPREAD = 60 * 24 # in minutes, 1 day
|
||||
link_probes_history = {}
|
||||
|
||||
# These links consistently fail in CI, but work-on-my-machine
|
||||
EXCEPTIONS = [
|
||||
EXCEPTION_PREFIXES = [
|
||||
# It seems the server certificate was renewed on 2nd of August 2024.
|
||||
# The server is sending only its certificate, without including the
|
||||
# Intermediate certificate used to issue the server cert. Because of that
|
||||
# some application are not able to verify the complete chain of trust.
|
||||
"https://wiki.sei.cmu.edu/",
|
||||
# The CI reports 403 on drupal.org while it works locally.
|
||||
# Maybe the CI's IP is blocklisted...
|
||||
"https://www.drupal.org/",
|
||||
]
|
||||
|
||||
def show_files(filenames):
|
||||
@ -65,7 +72,7 @@ def live_url(url: str, timeout=5):
|
||||
req = requests.Request('GET', url, headers = {'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="90"',
|
||||
'sec-ch-ua-mobile': '?0',
|
||||
'Upgrade-Insecure-Requests': '1',
|
||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 GLS/100.10.9939.100',
|
||||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
|
||||
'Sec-Fetch-Site':'none',
|
||||
'Sec-Fetch-Mode':'navigate',
|
||||
@ -94,13 +101,13 @@ def live_url(url: str, timeout=5):
|
||||
print(f"ERROR: Too many redirects: {rr}")
|
||||
return False
|
||||
except requests.Timeout as t:
|
||||
print(f"ERROR: timeout ", t)
|
||||
print(f"ERROR: Request timeout {t}")
|
||||
return False
|
||||
except timeout as t:
|
||||
print(f"ERROR: timeout ", t)
|
||||
except socket.timeout as t:
|
||||
print(f"ERROR: Socket timeout {t}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"ERROR: ", e)
|
||||
print(f"ERROR: {e}")
|
||||
return False
|
||||
|
||||
def findurl_in_html(filename,urls):
|
||||
@ -145,20 +152,51 @@ def get_all_links_from_htmls(dir):
|
||||
print("All html files crawled")
|
||||
return urls
|
||||
|
||||
def probe_links(urls):
|
||||
def url_is_exception(url: str) -> bool:
|
||||
return any(
|
||||
url.startswith(e) for e in EXCEPTION_PREFIXES
|
||||
)
|
||||
|
||||
def probe_links(urls: dict) -> bool:
|
||||
errors = []
|
||||
link_cache_exception = 0
|
||||
link_cache_hit = 0
|
||||
link_cache_miss = 0
|
||||
print("Testing links")
|
||||
for url in urls:
|
||||
print(f"{url} in {len(urls[url])} files")
|
||||
if url in EXCEPTIONS:
|
||||
link_count = len(urls)
|
||||
for idx, url in enumerate(urls):
|
||||
print(f"[{idx+1}/{link_count}] {url} in {len(urls[url])} files")
|
||||
if url_is_exception(url):
|
||||
link_cache_exception += 1
|
||||
print("skip as an exception")
|
||||
elif url_was_reached_recently(url):
|
||||
link_cache_hit += 1
|
||||
print("skip probing because it was reached recently")
|
||||
elif live_url(url, timeout=5):
|
||||
link_cache_miss += 1
|
||||
rejuvenate_url(url)
|
||||
elif url_is_long_dead(url):
|
||||
link_cache_miss += 1
|
||||
errors.append(url)
|
||||
return errors
|
||||
else:
|
||||
link_cache_miss += 1
|
||||
|
||||
confirmed_errors = confirm_errors(errors, urls)
|
||||
|
||||
print(f"\n\n\n{'=' * 80}\n\n\n")
|
||||
if confirmed_errors:
|
||||
report_errors(confirmed_errors, urls)
|
||||
print(f"{len(confirmed_errors)}/{len(urls)} links are dead, see above ^^ the list and the related files\n\n")
|
||||
print("Cache statistics:")
|
||||
print(f"\t{link_cache_hit=}")
|
||||
print(f"\t{link_cache_miss=}")
|
||||
link_cache_hit_ratio = (link_cache_hit) / (link_cache_hit + link_cache_miss)
|
||||
print(f"\t{link_cache_hit_ratio:03.2%} hits")
|
||||
print(f"\t{link_cache_exception=}")
|
||||
print(f"\n\n\n{'=' * 80}\n\n\n")
|
||||
|
||||
success = len(confirmed_errors) == 0
|
||||
return success
|
||||
|
||||
def confirm_errors(presumed_errors, urls):
|
||||
confirmed_errors = []
|
||||
@ -180,16 +218,9 @@ def report_errors(errors, urls):
|
||||
def check_html_links(dir):
|
||||
load_url_probing_history()
|
||||
urls = get_all_links_from_htmls(dir)
|
||||
errors = probe_links(urls)
|
||||
exit_code = 0
|
||||
if errors:
|
||||
confirmed_errors = confirm_errors(errors, urls)
|
||||
if confirmed_errors:
|
||||
report_errors(confirmed_errors, urls)
|
||||
print(f"{len(confirmed_errors)}/{len(urls)} links are dead, see above ^^ the list and the related files")
|
||||
exit_code = 1
|
||||
if exit_code == 0:
|
||||
success = probe_links(urls)
|
||||
if success:
|
||||
print(f"All {len(urls)} links are good")
|
||||
save_url_probing_history()
|
||||
exit(exit_code)
|
||||
exit(0 if success else 1)
|
||||
|
||||
|
@ -1,14 +1,43 @@
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import collections
|
||||
from git import Repo
|
||||
from git import Git
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from rspec_tools.utils import (load_json, pushd)
|
||||
from git import Git, Repo
|
||||
from rspec_tools.utils import load_json, pushd
|
||||
|
||||
REPOS = ['sonar-abap','sonar-cpp','sonar-cobol','sonar-dotnet','sonar-css','sonar-flex','slang-enterprise','sonar-java','SonarJS','sonar-php','sonar-pli','sonar-plsql','sonar-python','sonar-rpg','sonar-swift','sonar-text','sonar-tsql','sonar-vb','sonar-html','sonar-xml','sonar-kotlin', 'sonar-secrets', 'sonar-security', 'sonar-dataflow-bug-detection', 'sonar-iac']
|
||||
REPOS = [
|
||||
'sonar-abap',
|
||||
'sonar-apex',
|
||||
'sonar-architecture',
|
||||
'sonar-cobol',
|
||||
'sonar-cpp',
|
||||
'sonar-dart',
|
||||
'sonar-dataflow-bug-detection',
|
||||
'sonar-dotnet-enterprise',
|
||||
'sonar-flex',
|
||||
'sonar-go-enterprise',
|
||||
'sonar-html',
|
||||
'sonar-iac-enterprise',
|
||||
'sonar-java',
|
||||
'SonarJS',
|
||||
'sonar-kotlin',
|
||||
'sonar-php',
|
||||
'sonar-pli',
|
||||
'sonar-plsql',
|
||||
'sonar-python-enterprise',
|
||||
'sonar-rpg',
|
||||
'sonar-ruby',
|
||||
'sonar-scala',
|
||||
'sonar-security',
|
||||
'sonar-swift',
|
||||
'sonar-text-enterprise',
|
||||
'sonar-tsql',
|
||||
'sonar-vb',
|
||||
'sonar-xml'
|
||||
]
|
||||
|
||||
CANONICAL_NAMES = {
|
||||
'CLOUD_FORMATION': 'CLOUDFORMATION',
|
||||
@ -17,14 +46,14 @@ CANONICAL_NAMES = {
|
||||
'WEB': 'HTML'
|
||||
}
|
||||
|
||||
|
||||
RULES_FILENAME = 'covered_rules.json'
|
||||
|
||||
|
||||
def get_rule_id(filename):
|
||||
rule_id = filename[:-5]
|
||||
if '_' in rule_id:
|
||||
return rule_id[:rule_id.find('_')]
|
||||
else:
|
||||
return rule_id
|
||||
return rule_id.removesuffix('_abap').removesuffix('_java')
|
||||
|
||||
|
||||
def compatible_languages(rule, languages_from_sonarpedia):
|
||||
'''
|
||||
@ -43,7 +72,7 @@ def get_implemented_rules(path, languages_from_sonarpedia):
|
||||
for lang in languages_from_sonarpedia:
|
||||
implemented_rules[lang] = []
|
||||
for filename in os.listdir(path):
|
||||
if filename.endswith(".json") and not filename.startswith("Sonar_way"):
|
||||
if filename.endswith(".json") and 'profile' not in filename:
|
||||
rule = load_json(os.path.join(path, filename))
|
||||
rule_id = get_rule_id(filename)
|
||||
for language in compatible_languages(rule, languages_from_sonarpedia):
|
||||
@ -155,17 +184,29 @@ def checkout_repo(repo):
|
||||
git_url=f"https://github.com/SonarSource/{repo}"
|
||||
token=os.getenv('GITHUB_TOKEN')
|
||||
if token:
|
||||
git_url=f"https://{token}@github.com/SonarSource/{repo}"
|
||||
git_url=f"https://oauth2:{token}@github.com/SonarSource/{repo}"
|
||||
if not os.path.exists(repo):
|
||||
return Repo.clone_from(git_url, repo)
|
||||
else:
|
||||
return Repo(repo)
|
||||
|
||||
|
||||
VERSION_RE = re.compile(r'\d[\d\.]+')
|
||||
def is_version_tag(name):
|
||||
return bool(re.fullmatch(VERSION_RE, name))
|
||||
|
||||
|
||||
def comparable_version(key):
|
||||
if not is_version_tag(key):
|
||||
return [0]
|
||||
return list(map(int, key.split('.')))
|
||||
|
||||
|
||||
def collect_coverage_for_all_versions(repo, coverage):
|
||||
git_repo = checkout_repo(repo)
|
||||
tags = git_repo.tags
|
||||
tags.sort(key = lambda t: t.commit.committed_date)
|
||||
versions = [tag.name for tag in tags if '-' not in tag.name]
|
||||
versions = [tag.name for tag in tags if is_version_tag(tag.name)]
|
||||
versions.sort(key = comparable_version)
|
||||
for version in versions:
|
||||
collect_coverage_for_version(repo, git_repo, version, coverage)
|
||||
collect_coverage_for_version(repo, git_repo, 'master', coverage)
|
||||
|
@ -95,7 +95,7 @@ class RuleCreator:
|
||||
if rule_item.is_file():
|
||||
template_content = rule_item.read_text()
|
||||
lang = LANG_TO_SOURCE[language]
|
||||
final_content = template_content.replace('[source,text]', f'[source,{lang}]')
|
||||
final_content = template_content.replace('[source,text', f'[source,{lang}')
|
||||
rule_item.write_text(final_content)
|
||||
|
||||
def _fill_multi_lang_template_files(self, rule_dir: Path, rule_number: int, languages: Iterable[str]):
|
||||
@ -113,7 +113,9 @@ class RuleCreator:
|
||||
|
||||
def _fill_single_lang_template_files(self, rule_dir: Path, rule_number: int, language: str):
|
||||
common_template = self.TEMPLATE_PATH / 'single_language' / 'common'
|
||||
lang_specific_template = self.TEMPLATE_PATH / 'single_language' / 'language_specific'
|
||||
lang_specific_template = self.TEMPLATE_PATH / 'single_language' / language
|
||||
if not Path(lang_specific_template).exists():
|
||||
lang_specific_template = self.TEMPLATE_PATH / 'single_language' / 'language_specific'
|
||||
copy_directory_content(common_template, rule_dir)
|
||||
|
||||
lang_dir = rule_dir /language
|
||||
|
@ -16,9 +16,10 @@ LANG_TO_LABEL = {'abap': 'abap',
|
||||
'cobol': 'cobol',
|
||||
'csharp': 'dotnet',
|
||||
'css': 'css',
|
||||
'dart': 'dart',
|
||||
'docker': 'iac',
|
||||
'flex': 'flex',
|
||||
'go': 'slang',
|
||||
'go': 'go',
|
||||
'html': 'html',
|
||||
'java': 'java',
|
||||
'javascript': 'jsts',
|
||||
@ -39,6 +40,7 @@ LANG_TO_LABEL = {'abap': 'abap',
|
||||
'tsql': 'tsql',
|
||||
'vb6': 'vb6',
|
||||
'vbnet': 'dotnet',
|
||||
'ansible': 'iac',
|
||||
'cloudformation': 'iac',
|
||||
'terraform': 'iac',
|
||||
'kubernetes': 'iac',
|
||||
@ -52,6 +54,7 @@ LANG_TO_SOURCE = {
|
||||
'cloudformation': 'yaml',
|
||||
'csharp': 'csharp',
|
||||
'css': 'css',
|
||||
'dart': 'dart',
|
||||
'docker': 'docker',
|
||||
'go': 'go',
|
||||
'html': 'html',
|
||||
@ -74,6 +77,7 @@ LANG_TO_SOURCE = {
|
||||
'c': 'c',
|
||||
'objectivec': 'objectivec',
|
||||
'vb': 'vb',
|
||||
'ansible': 'yaml',
|
||||
# these languages are not supported by highlight.js as the moment:
|
||||
'apex': 'apex',
|
||||
'azureresourcemanager': 'bicep',
|
||||
|
@ -1,6 +1,6 @@
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Final, Dict, List
|
||||
from typing import Dict, Final, List, Union
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
from rspec_tools.errors import RuleValidationError
|
||||
@ -78,15 +78,26 @@ def intersection(list1, list2):
|
||||
def difference(list1, list2):
|
||||
return list(set(list1) - set(list2))
|
||||
|
||||
def validate_titles_are_not_misclassified_as_subtitles(rule_language: LanguageSpecificRule, subtitles: list[str], allowed_h2_sections: list[str]):
|
||||
# TODO This does not validate "How to fix it" section for frameworks as the section names are a bit special.
|
||||
misclassified = intersection(subtitles, allowed_h2_sections)
|
||||
if misclassified:
|
||||
misclassified.sort()
|
||||
misclassified_str = ', '.join(misclassified)
|
||||
raise RuleValidationError(f'Rule {rule_language.id} has some sections misclassified. Ensure there are not too many `=` in the asciidoc file for: {misclassified_str}')
|
||||
|
||||
def validate_section_names(rule_language: LanguageSpecificRule):
|
||||
"""Validates all h2-level section names"""
|
||||
def get_titles(level: Union[str, list[str]]) -> list[str]:
|
||||
return list(map(lambda x: x.text.strip(), rule_language.description.find_all(level)))
|
||||
|
||||
descr = rule_language.description
|
||||
h2_titles = list(map(lambda x: x.text.strip(), descr.find_all('h2')))
|
||||
|
||||
h2_titles = get_titles('h2')
|
||||
subtitles = get_titles(['h3', 'h4', 'h5', 'h6'])
|
||||
allowed_h2_sections = list(MANDATORY_SECTIONS) + list(OPTIONAL_SECTIONS.keys())
|
||||
validate_titles_are_not_misclassified_as_subtitles(rule_language, subtitles, allowed_h2_sections)
|
||||
validate_duplications(h2_titles, rule_language)
|
||||
|
||||
education_titles = intersection(h2_titles, list(MANDATORY_SECTIONS) + list(OPTIONAL_SECTIONS.keys()))
|
||||
education_titles = intersection(h2_titles, allowed_h2_sections)
|
||||
if education_titles:
|
||||
# Using the education format.
|
||||
validate_how_to_fix_it_sections_names(rule_language, h2_titles)
|
||||
@ -234,7 +245,7 @@ def validate_security_standard_links(rule_language: LanguageSpecificRule):
|
||||
# Avoid raising mismatch issues on deprecated or closed rules
|
||||
if metadata.get('status') != 'ready':
|
||||
return
|
||||
|
||||
|
||||
security_standards_metadata = metadata.get('securityStandards', {})
|
||||
for standard in SECURITY_STANDARD_URL.keys():
|
||||
|
||||
@ -244,7 +255,7 @@ def validate_security_standard_links(rule_language: LanguageSpecificRule):
|
||||
extra_links = difference(links_mapping, metadata_mapping)
|
||||
if len(extra_links) > 0:
|
||||
raise RuleValidationError(f'Rule {rule_language.id} has a mismatch for the {standard} security standards. Remove links from the Resources/See section ({extra_links}) or fix the rule metadata')
|
||||
|
||||
|
||||
missing_links = difference(metadata_mapping, links_mapping)
|
||||
if len(missing_links) > 0:
|
||||
raise RuleValidationError(f'Rule {rule_language.id} has a mismatch for the {standard} security standards. Add links to the Resources/See section ({missing_links}) or fix the rule metadata')
|
||||
|
@ -156,6 +156,15 @@
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"OWASP Mobile Top 10 2024": {
|
||||
"type": "array",
|
||||
"minItems": 0,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"pattern": "^M([1-9]|10)$"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"PCI DSS 3.2": {
|
||||
"type": "array",
|
||||
"minItems": 0,
|
||||
@ -219,7 +228,7 @@
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"STIG ASD 2023-06-08": {
|
||||
"STIG ASD_V5R3": {
|
||||
"type": "array",
|
||||
"minItems": 0,
|
||||
"items": {
|
||||
@ -267,15 +276,15 @@
|
||||
"properties": {
|
||||
"MAINTAINABILITY": {
|
||||
"type": "string",
|
||||
"enum": ["LOW", "MEDIUM", "HIGH"]
|
||||
"enum": ["INFO", "LOW", "MEDIUM", "HIGH", "BLOCKER"]
|
||||
},
|
||||
"RELIABILITY": {
|
||||
"type": "string",
|
||||
"enum": ["LOW", "MEDIUM", "HIGH"]
|
||||
"enum": ["INFO", "LOW", "MEDIUM", "HIGH", "BLOCKER"]
|
||||
},
|
||||
"SECURITY": {
|
||||
"type": "string",
|
||||
"enum": ["LOW", "MEDIUM", "HIGH"]
|
||||
"enum": ["INFO", "LOW", "MEDIUM", "HIGH", "BLOCKER"]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"title": "Function names should comply with a naming convention",
|
||||
"defaultQualityProfiles": [
|
||||
|
||||
]
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
== Why is this an issue?
|
||||
|
||||
=== How to fix it
|
||||
|
||||
=== Resources
|
457
rspec-tools/tests/resources/invalid-rules/S100/php/rule.html
Normal file
457
rspec-tools/tests/resources/invalid-rules/S100/php/rule.html
Normal file
@ -0,0 +1,457 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.8">
|
||||
<title>Why is this an issue?</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
|
||||
<style>
|
||||
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
|
||||
/* Uncomment @import statement below to use as custom stylesheet */
|
||||
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
|
||||
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
|
||||
audio,canvas,video{display:inline-block}
|
||||
audio:not([controls]){display:none;height:0}
|
||||
script{display:none!important}
|
||||
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
|
||||
a{background:transparent}
|
||||
a:focus{outline:thin dotted}
|
||||
a:active,a:hover{outline:0}
|
||||
h1{font-size:2em;margin:.67em 0}
|
||||
abbr[title]{border-bottom:1px dotted}
|
||||
b,strong{font-weight:bold}
|
||||
dfn{font-style:italic}
|
||||
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
|
||||
mark{background:#ff0;color:#000}
|
||||
code,kbd,pre,samp{font-family:monospace;font-size:1em}
|
||||
pre{white-space:pre-wrap}
|
||||
q{quotes:"\201C" "\201D" "\2018" "\2019"}
|
||||
small{font-size:80%}
|
||||
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
|
||||
sup{top:-.5em}
|
||||
sub{bottom:-.25em}
|
||||
img{border:0}
|
||||
svg:not(:root){overflow:hidden}
|
||||
figure{margin:0}
|
||||
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
|
||||
legend{border:0;padding:0}
|
||||
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
|
||||
button,input{line-height:normal}
|
||||
button,select{text-transform:none}
|
||||
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
|
||||
button[disabled],html input[disabled]{cursor:default}
|
||||
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
|
||||
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
|
||||
textarea{overflow:auto;vertical-align:top}
|
||||
table{border-collapse:collapse;border-spacing:0}
|
||||
*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
html,body{font-size:100%}
|
||||
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
|
||||
a:hover{cursor:pointer}
|
||||
img,object,embed{max-width:100%;height:auto}
|
||||
object,embed{height:100%}
|
||||
img{-ms-interpolation-mode:bicubic}
|
||||
.left{float:left!important}
|
||||
.right{float:right!important}
|
||||
.text-left{text-align:left!important}
|
||||
.text-right{text-align:right!important}
|
||||
.text-center{text-align:center!important}
|
||||
.text-justify{text-align:justify!important}
|
||||
.hide{display:none}
|
||||
img,object,svg{display:inline-block;vertical-align:middle}
|
||||
textarea{height:auto;min-height:50px}
|
||||
select{width:100%}
|
||||
.center{margin-left:auto;margin-right:auto}
|
||||
.stretch{width:100%}
|
||||
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
|
||||
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
|
||||
a{color:#2156a5;text-decoration:underline;line-height:inherit}
|
||||
a:hover,a:focus{color:#1d4b8f}
|
||||
a img{border:none}
|
||||
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
|
||||
p aside{font-size:.875em;line-height:1.35;font-style:italic}
|
||||
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
|
||||
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
|
||||
h1{font-size:2.125em}
|
||||
h2{font-size:1.6875em}
|
||||
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
|
||||
h4,h5{font-size:1.125em}
|
||||
h6{font-size:1em}
|
||||
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
|
||||
em,i{font-style:italic;line-height:inherit}
|
||||
strong,b{font-weight:bold;line-height:inherit}
|
||||
small{font-size:60%;line-height:inherit}
|
||||
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
|
||||
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
|
||||
ul,ol{margin-left:1.5em}
|
||||
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
|
||||
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
|
||||
ul.square{list-style-type:square}
|
||||
ul.circle{list-style-type:circle}
|
||||
ul.disc{list-style-type:disc}
|
||||
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
|
||||
dl dt{margin-bottom:.3125em;font-weight:bold}
|
||||
dl dd{margin-bottom:1.25em}
|
||||
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
|
||||
abbr{text-transform:none}
|
||||
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
|
||||
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
|
||||
blockquote cite::before{content:"\2014 \0020"}
|
||||
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
|
||||
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
|
||||
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
|
||||
h1{font-size:2.75em}
|
||||
h2{font-size:2.3125em}
|
||||
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
|
||||
h4{font-size:1.4375em}}
|
||||
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
|
||||
table thead,table tfoot{background:#f7f8f7}
|
||||
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
|
||||
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
|
||||
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
|
||||
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
|
||||
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
|
||||
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
|
||||
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
|
||||
.clearfix::after,.float-group::after{clear:both}
|
||||
*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
|
||||
*:not(pre)>code.nobreak{word-wrap:normal}
|
||||
*:not(pre)>code.nowrap{white-space:nowrap}
|
||||
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
|
||||
em em{font-style:normal}
|
||||
strong strong{font-weight:400}
|
||||
.keyseq{color:rgba(51,51,51,.8)}
|
||||
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
|
||||
.keyseq kbd:first-child{margin-left:0}
|
||||
.keyseq kbd:last-child{margin-right:0}
|
||||
.menuseq,.menuref{color:#000}
|
||||
.menuseq b:not(.caret),.menuref{font-weight:inherit}
|
||||
.menuseq{word-spacing:-.02em}
|
||||
.menuseq b.caret{font-size:1.25em;line-height:.8}
|
||||
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
|
||||
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
|
||||
b.button::before{content:"[";padding:0 3px 0 2px}
|
||||
b.button::after{content:"]";padding:0 2px 0 3px}
|
||||
p a>code:hover{color:rgba(0,0,0,.9)}
|
||||
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
|
||||
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
|
||||
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
|
||||
#content{margin-top:1.25em}
|
||||
#content::before{content:none}
|
||||
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
|
||||
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
|
||||
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
|
||||
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
|
||||
#header .details span:first-child{margin-left:-.125em}
|
||||
#header .details span.email a{color:rgba(0,0,0,.85)}
|
||||
#header .details br{display:none}
|
||||
#header .details br+span::before{content:"\00a0\2013\00a0"}
|
||||
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
|
||||
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
|
||||
#header #revnumber{text-transform:capitalize}
|
||||
#header #revnumber::after{content:"\00a0"}
|
||||
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
|
||||
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
|
||||
#toc>ul{margin-left:.125em}
|
||||
#toc ul.sectlevel0>li>a{font-style:italic}
|
||||
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
|
||||
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
|
||||
#toc li{line-height:1.3334;margin-top:.3334em}
|
||||
#toc a{text-decoration:none}
|
||||
#toc a:active{text-decoration:underline}
|
||||
#toctitle{color:#7a2518;font-size:1.2em}
|
||||
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
|
||||
body.toc2{padding-left:15em;padding-right:0}
|
||||
#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
|
||||
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
|
||||
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
|
||||
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
|
||||
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
|
||||
body.toc2.toc-right{padding-left:0;padding-right:15em}
|
||||
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
|
||||
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
|
||||
#toc.toc2{width:20em}
|
||||
#toc.toc2 #toctitle{font-size:1.375em}
|
||||
#toc.toc2>ul{font-size:.95em}
|
||||
#toc.toc2 ul ul{padding-left:1.25em}
|
||||
body.toc2.toc-right{padding-left:0;padding-right:20em}}
|
||||
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
|
||||
#content #toc>:first-child{margin-top:0}
|
||||
#content #toc>:last-child{margin-bottom:0}
|
||||
#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
|
||||
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
|
||||
#content{margin-bottom:.625em}
|
||||
.sect1{padding-bottom:.625em}
|
||||
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
|
||||
.sect1{padding-bottom:1.25em}}
|
||||
.sect1:last-child{padding-bottom:0}
|
||||
.sect1+.sect1{border-top:1px solid #e7e7e9}
|
||||
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
|
||||
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
|
||||
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
|
||||
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
|
||||
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
|
||||
.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
|
||||
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
|
||||
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
|
||||
.paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
|
||||
table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
|
||||
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
|
||||
.admonitionblock>table td.icon{text-align:center;width:80px}
|
||||
.admonitionblock>table td.icon img{max-width:none}
|
||||
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
|
||||
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6)}
|
||||
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
|
||||
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
|
||||
.exampleblock>.content>:first-child{margin-top:0}
|
||||
.exampleblock>.content>:last-child{margin-bottom:0}
|
||||
.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
|
||||
.sidebarblock>:first-child{margin-top:0}
|
||||
.sidebarblock>:last-child{margin-bottom:0}
|
||||
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
|
||||
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
|
||||
.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
|
||||
.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
|
||||
.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;overflow-x:auto;padding:1em;font-size:.8125em}
|
||||
@media screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
|
||||
@media screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
|
||||
.literalblock pre.nowrap,.literalblock pre.nowrap pre,.listingblock pre.nowrap,.listingblock pre.nowrap pre{white-space:pre;word-wrap:normal}
|
||||
.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
|
||||
.listingblock pre.highlightjs{padding:0}
|
||||
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
|
||||
.listingblock pre.prettyprint{border-width:0}
|
||||
.listingblock>.content{position:relative}
|
||||
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
|
||||
.listingblock:hover code[data-lang]::before{display:block}
|
||||
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:#999}
|
||||
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
|
||||
table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
|
||||
table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
|
||||
table.pyhltable td.code{padding-left:.75em;padding-right:0}
|
||||
pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #dddddf}
|
||||
pre.pygments .lineno{display:inline-block;margin-right:.25em}
|
||||
table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
|
||||
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
|
||||
.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
|
||||
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
|
||||
.quoteblock blockquote{margin:0;padding:0;border:0}
|
||||
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
|
||||
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
|
||||
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
|
||||
.verseblock{margin:0 1em 1.25em}
|
||||
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
|
||||
.verseblock pre strong{font-weight:400}
|
||||
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
|
||||
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
|
||||
.quoteblock .attribution br,.verseblock .attribution br{display:none}
|
||||
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
|
||||
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
|
||||
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
|
||||
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
|
||||
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
|
||||
.quoteblock.excerpt,.quoteblock .quoteblock{margin:0 0 1.25em;padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
|
||||
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
|
||||
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
|
||||
table.tableblock{max-width:100%;border-collapse:separate}
|
||||
p.tableblock:last-child{margin-bottom:0}
|
||||
td.tableblock>.content{margin-bottom:-1.25em}
|
||||
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
|
||||
table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}
|
||||
table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}
|
||||
table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}
|
||||
table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px}
|
||||
table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0}
|
||||
table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}
|
||||
table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}
|
||||
table.frame-all{border-width:1px}
|
||||
table.frame-sides{border-width:0 1px}
|
||||
table.frame-topbot,table.frame-ends{border-width:1px 0}
|
||||
table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd){background:#f8f8f7}
|
||||
table.stripes-none tr,table.stripes-odd tr:nth-of-type(even){background:none}
|
||||
th.halign-left,td.halign-left{text-align:left}
|
||||
th.halign-right,td.halign-right{text-align:right}
|
||||
th.halign-center,td.halign-center{text-align:center}
|
||||
th.valign-top,td.valign-top{vertical-align:top}
|
||||
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
|
||||
th.valign-middle,td.valign-middle{vertical-align:middle}
|
||||
table thead th,table tfoot th{font-weight:bold}
|
||||
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
|
||||
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
|
||||
p.tableblock>code:only-child{background:none;padding:0}
|
||||
p.tableblock{font-size:1em}
|
||||
td>div.verse{white-space:pre}
|
||||
ol{margin-left:1.75em}
|
||||
ul li ol{margin-left:1.5em}
|
||||
dl dd{margin-left:1.125em}
|
||||
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
|
||||
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
|
||||
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
|
||||
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
|
||||
ul.unstyled,ol.unstyled{margin-left:0}
|
||||
ul.checklist{margin-left:.625em}
|
||||
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
|
||||
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
|
||||
ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
|
||||
ul.inline>li{margin-left:1.25em}
|
||||
.unstyled dl dt{font-weight:400;font-style:normal}
|
||||
ol.arabic{list-style-type:decimal}
|
||||
ol.decimal{list-style-type:decimal-leading-zero}
|
||||
ol.loweralpha{list-style-type:lower-alpha}
|
||||
ol.upperalpha{list-style-type:upper-alpha}
|
||||
ol.lowerroman{list-style-type:lower-roman}
|
||||
ol.upperroman{list-style-type:upper-roman}
|
||||
ol.lowergreek{list-style-type:lower-greek}
|
||||
.hdlist>table,.colist>table{border:0;background:none}
|
||||
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
|
||||
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
|
||||
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
|
||||
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
|
||||
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
|
||||
.colist td:not([class]):first-child img{max-width:none}
|
||||
.colist td:not([class]):last-child{padding:.25em 0}
|
||||
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
|
||||
.imageblock.left{margin:.25em .625em 1.25em 0}
|
||||
.imageblock.right{margin:.25em 0 1.25em .625em}
|
||||
.imageblock>.title{margin-bottom:0}
|
||||
.imageblock.thumb,.imageblock.th{border-width:6px}
|
||||
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
|
||||
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
|
||||
.image.left{margin-right:.625em}
|
||||
.image.right{margin-left:.625em}
|
||||
a.image{text-decoration:none;display:inline-block}
|
||||
a.image object{pointer-events:none}
|
||||
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
|
||||
sup.footnote a,sup.footnoteref a{text-decoration:none}
|
||||
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
|
||||
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
|
||||
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
|
||||
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
|
||||
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
|
||||
#footnotes .footnote:last-of-type{margin-bottom:0}
|
||||
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
|
||||
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
|
||||
.gist .file-data>table td.line-data{width:99%}
|
||||
div.unbreakable{page-break-inside:avoid}
|
||||
.big{font-size:larger}
|
||||
.small{font-size:smaller}
|
||||
.underline{text-decoration:underline}
|
||||
.overline{text-decoration:overline}
|
||||
.line-through{text-decoration:line-through}
|
||||
.aqua{color:#00bfbf}
|
||||
.aqua-background{background-color:#00fafa}
|
||||
.black{color:#000}
|
||||
.black-background{background-color:#000}
|
||||
.blue{color:#0000bf}
|
||||
.blue-background{background-color:#0000fa}
|
||||
.fuchsia{color:#bf00bf}
|
||||
.fuchsia-background{background-color:#fa00fa}
|
||||
.gray{color:#606060}
|
||||
.gray-background{background-color:#7d7d7d}
|
||||
.green{color:#006000}
|
||||
.green-background{background-color:#007d00}
|
||||
.lime{color:#00bf00}
|
||||
.lime-background{background-color:#00fa00}
|
||||
.maroon{color:#600000}
|
||||
.maroon-background{background-color:#7d0000}
|
||||
.navy{color:#000060}
|
||||
.navy-background{background-color:#00007d}
|
||||
.olive{color:#606000}
|
||||
.olive-background{background-color:#7d7d00}
|
||||
.purple{color:#600060}
|
||||
.purple-background{background-color:#7d007d}
|
||||
.red{color:#bf0000}
|
||||
.red-background{background-color:#fa0000}
|
||||
.silver{color:#909090}
|
||||
.silver-background{background-color:#bcbcbc}
|
||||
.teal{color:#006060}
|
||||
.teal-background{background-color:#007d7d}
|
||||
.white{color:#bfbfbf}
|
||||
.white-background{background-color:#fafafa}
|
||||
.yellow{color:#bfbf00}
|
||||
.yellow-background{background-color:#fafa00}
|
||||
span.icon>.fa{cursor:default}
|
||||
a span.icon>.fa{cursor:inherit}
|
||||
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
|
||||
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
|
||||
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
|
||||
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
|
||||
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
|
||||
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
|
||||
.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
|
||||
.conum[data-value] *{color:#fff!important}
|
||||
.conum[data-value]+b{display:none}
|
||||
.conum[data-value]::after{content:attr(data-value)}
|
||||
pre .conum[data-value]{position:relative;top:-.125em}
|
||||
b.conum *{color:inherit!important}
|
||||
.conum:not([data-value]):empty{display:none}
|
||||
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
|
||||
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
|
||||
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
|
||||
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
|
||||
p{margin-bottom:1.25rem}
|
||||
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
|
||||
.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
|
||||
.print-only{display:none!important}
|
||||
@page{margin:1.25cm .75cm}
|
||||
@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
|
||||
html{font-size:80%}
|
||||
a{color:inherit!important;text-decoration:underline!important}
|
||||
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
|
||||
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
|
||||
abbr[title]::after{content:" (" attr(title) ")"}
|
||||
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
|
||||
thead{display:table-header-group}
|
||||
svg{max-width:100%}
|
||||
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
|
||||
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
|
||||
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
|
||||
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
|
||||
body.book #header{text-align:center}
|
||||
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
|
||||
body.book #header .details{border:0!important;display:block;padding:0!important}
|
||||
body.book #header .details span:first-child{margin-left:0!important}
|
||||
body.book #header .details br{display:block}
|
||||
body.book #header .details br+span::before{content:none!important}
|
||||
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
|
||||
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
|
||||
.listingblock code[data-lang]::before{display:block}
|
||||
#footer{padding:0 .9375em}
|
||||
.hide-on-print{display:none!important}
|
||||
.print-only{display:block!important}
|
||||
.hide-for-print{display:none!important}
|
||||
.show-for-print{display:inherit!important}}
|
||||
@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
|
||||
.sect1{padding:0!important}
|
||||
.sect1+.sect1{border:0}
|
||||
#footer{background:none}
|
||||
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
|
||||
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
|
||||
</style>
|
||||
</head>
|
||||
<body class="article">
|
||||
<div id="header">
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_why_is_this_an_issue">Why is this an issue?</h2>
|
||||
<div class="sectionbody">
|
||||
<div class="sect2">
|
||||
<h3 id="_how_to_fix_it">How to fix it</h3>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_resources">Resources</h3>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2024-10-10 12:53:12 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -43,10 +43,13 @@ def test_create_new_multi_lang_rule_branch(rule_creator: RuleCreator, mock_git_r
|
||||
for lang_item in lang_root.glob('**/*'):
|
||||
if lang_item.is_file():
|
||||
expected_content = lang_item.read_text().replace('${RSPEC_ID}', str(rule_number))
|
||||
expected_content = expected_content.replace('[source,text]', f'[source,{LANG_TO_SOURCE[os.path.basename(lang)]}]')
|
||||
expected_content = expected_content.replace('[source,text', f'[source,{LANG_TO_SOURCE[os.path.basename(lang)]}')
|
||||
relative_path = lang_item.relative_to(lang_root)
|
||||
actual_content = rule_dir.joinpath(lang, relative_path).read_text()
|
||||
assert actual_content == expected_content
|
||||
if lang_item.suffix == '.adoc':
|
||||
assert 'source,text' not in actual_content
|
||||
assert LANG_TO_SOURCE[os.path.basename(lang)] in actual_content
|
||||
|
||||
|
||||
def test_create_new_single_lang_rule_branch(rule_creator: RuleCreator, mock_git_rspec_repo: Repo):
|
||||
@ -75,10 +78,13 @@ def test_create_new_single_lang_rule_branch(rule_creator: RuleCreator, mock_git_
|
||||
if lang_item.is_file():
|
||||
expected_content = lang_item.read_text().replace('${RSPEC_ID}', str(rule_number))
|
||||
dir_name = os.path.basename(lang)
|
||||
expected_content = expected_content.replace('[source,text]', f'[source,{LANG_TO_SOURCE[dir_name]}]')
|
||||
expected_content = expected_content.replace('[source,text', f'[source,{LANG_TO_SOURCE[dir_name]}')
|
||||
relative_path = lang_item.relative_to(lang_root)
|
||||
actual_content = rule_dir.joinpath(lang, relative_path).read_text()
|
||||
assert actual_content == expected_content
|
||||
if lang_item.suffix == '.adoc':
|
||||
assert 'source,text' not in actual_content
|
||||
assert LANG_TO_SOURCE[dir_name] in actual_content
|
||||
|
||||
|
||||
def test_create_new_rule_pull_request(rule_creator: RuleCreator):
|
||||
@ -138,10 +144,13 @@ def test_add_lang_singlelang_nonconventional_rule_create_branch(rule_creator: Ru
|
||||
for lang_item in lang_root.glob('**/*'):
|
||||
if lang_item.is_file():
|
||||
expected_content = lang_item.read_text().replace('${RSPEC_ID}', str(rule_number))
|
||||
expected_content = expected_content.replace('[source,text]', f'[source,{LANG_TO_SOURCE[language]}]')
|
||||
expected_content = expected_content.replace('[source,text', f'[source,{LANG_TO_SOURCE[language]}')
|
||||
relative_path = lang_item.relative_to(lang_root)
|
||||
actual_content = rule_dir.joinpath(language, relative_path).read_text()
|
||||
assert actual_content == expected_content
|
||||
if lang_item.suffix == '.adoc':
|
||||
assert 'source,text' not in actual_content
|
||||
assert LANG_TO_SOURCE[language] in actual_content
|
||||
|
||||
|
||||
def test_add_lang_singlelang_conventional_rule_create_branch(rule_creator: RuleCreator, mock_git_rspec_repo: Repo):
|
||||
@ -186,10 +195,13 @@ def test_add_lang_multilang_rule_create_branch(rule_creator: RuleCreator, mock_g
|
||||
for lang_item in lang_root.glob('**/*'):
|
||||
if lang_item.is_file():
|
||||
expected_content = lang_item.read_text().replace('${RSPEC_ID}', str(rule_number))
|
||||
expected_content = expected_content.replace('[source,text]', f'[source,{LANG_TO_SOURCE[language]}]')
|
||||
expected_content = expected_content.replace('[source,text', f'[source,{LANG_TO_SOURCE[language]}')
|
||||
relative_path = lang_item.relative_to(lang_root)
|
||||
actual_content = rule_dir.joinpath(language, relative_path).read_text()
|
||||
assert actual_content == expected_content
|
||||
if lang_item.suffix == '.adoc':
|
||||
assert 'source,text' not in actual_content
|
||||
assert LANG_TO_SOURCE[language] in actual_content
|
||||
|
||||
|
||||
@patch('rspec_tools.create_rule.RuleCreator')
|
||||
|
@ -39,6 +39,11 @@ def test_unexpected_section_fails_validation(invalid_rule):
|
||||
with pytest.raises(RuleValidationError, match=fr'^Rule {rule.id} has an unconventional header "Invalid header"'):
|
||||
validate_section_names(rule)
|
||||
|
||||
def test_sections_with_wrong_level_fails_validation(invalid_rule):
|
||||
rule = invalid_rule('S100', 'php')
|
||||
with pytest.raises(RuleValidationError, match=fr'^Rule {rule.id} has some sections misclassified. Ensure there are not too many `=` in the asciidoc file for: How to fix it, Resources'):
|
||||
validate_section_names(rule)
|
||||
|
||||
def test_valid_section_levels_passes_validation(rule_language):
|
||||
'''Check that description with correct formatting is considered valid.'''
|
||||
validate_section_levels(rule_language('S100', 'cfamily'))
|
||||
|
@ -82,7 +82,7 @@ def test_rule_with_invalid_impacts(invalid_rules: RulesRepository):
|
||||
|
||||
def test_rule_with_invalid_impact_level(invalid_rules: RulesRepository):
|
||||
s506 = invalid_rules.get_rule('S506')
|
||||
with pytest.raises(RuleValidationError, match=re.escape("Rule S506 failed validation for these reasons:\n - Rule scala:S506 has invalid metadata in MAINTAINABILITY: 'INVALID' is not one of ['LOW', 'MEDIUM', 'HIGH']")):
|
||||
with pytest.raises(RuleValidationError, match=re.escape("Rule S506 failed validation for these reasons:\n - Rule scala:S506 has invalid metadata in MAINTAINABILITY: 'INVALID' is not one of ['INFO', 'LOW', 'MEDIUM', 'HIGH', 'BLOCKER']")):
|
||||
validate_rule_metadata(s506)
|
||||
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
{
|
||||
"title": "Method names should comply with a naming convention"
|
||||
"title": "Method names should comply with a naming convention",
|
||||
"scope": "Main"
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
{
|
||||
"title": "Function and method names should comply with a naming convention",
|
||||
"defaultQualityProfiles": [],
|
||||
"scope": "Main"
|
||||
}
|
||||
"scope": "Main",
|
||||
"compatibleLanguages": [
|
||||
"js",
|
||||
"ts"
|
||||
]
|
||||
}
|
@ -2,7 +2,7 @@ include::../rule.adoc[]
|
||||
|
||||
For example, with the default provided regular expression ``++^[a-z][a-zA-Z0-9]*$++``, the function:
|
||||
|
||||
[source,php]
|
||||
[source,php,diff-id=1,diff-type=noncompliant]
|
||||
----
|
||||
function DoSomething(){ // Noncompliant
|
||||
// ...
|
||||
@ -11,13 +11,31 @@ function DoSomething(){ // Noncompliant
|
||||
|
||||
should be renamed to
|
||||
|
||||
[source,php]
|
||||
[source,php,diff-id=1,diff-type=compliant]
|
||||
----
|
||||
function doSomething(){
|
||||
// ...
|
||||
}
|
||||
----
|
||||
|
||||
In case the Drupal framework is detected and the default regex is not replaced, it will follow the PHP coding standards for Drupal.
|
||||
|
||||
[source,php,diff-id=2,diff-type=noncompliant]
|
||||
----
|
||||
function doSomething(){ // Noncompliant
|
||||
// ...
|
||||
}
|
||||
----
|
||||
|
||||
should be renamed to
|
||||
|
||||
[source,php,diff-id=2,diff-type=compliant]
|
||||
----
|
||||
function do_something(){
|
||||
// ...
|
||||
}
|
||||
----
|
||||
|
||||
=== Exceptions
|
||||
|
||||
Methods with an ``++@inheritdoc++`` annotation, as well as magic methods (``++__construct()++``, ``++__destruct()++``, ``++__call()++``, ``++__callStatic()++``, ``++__get()++``, ``++__set()++``, ``++__isset()++``, ``++__unset()++``, ``++__sleep()++``, ``++__wakeup()++``, ``++__toString()++``, ``++__invoke()++``, ``++__set_state()++``, ``++__clone()++``, ``++__debugInfo()++``) are ignored.
|
||||
@ -34,6 +52,10 @@ function __destruct(){...} // Compliant by exception
|
||||
function myFunc(){...} // Compliant by exception
|
||||
----
|
||||
|
||||
== References
|
||||
|
||||
* https://www.drupal.org/docs/develop/standards/php/php-coding-standards#s-functions-and-variables[Drupal - Naming Conventions - Functions and variables]
|
||||
|
||||
ifdef::env-github,rspecator-view[]
|
||||
|
||||
'''
|
||||
|
@ -1,13 +1,12 @@
|
||||
== Why is this an issue?
|
||||
|
||||
A using directive makes names from another namespace available in the current scope. It should only be used when those names do not create an ambiguity with other names, otherwise, it is better to fully qualify the names you want to use.
|
||||
A using-directive (e.g., `using namespace std;`) makes names from another namespace available in the current scope. It should only be used when those names do not create an ambiguity with other names. Otherwise, it is better to fully qualify the names you want to use.
|
||||
|
||||
The effect of using-directives inside a function body ceases at the end of the current scope. However, when the using-directives are at the global or namespace scope, their effects propagate to the rest of the scope.
|
||||
|
||||
When you write a header file, you don't know from which context it will be included. Therefore, if this header contains using directives, you cannot be sure that they will not create ambiguities in that context. Those ambiguities could lead to compilation failures or, worse, to a different function being selected by overload resolution depending on the order of inclusion of headers.
|
||||
|
||||
|
||||
A using declaration behaves in the same way but only for one name. Because of their much narrower scope, this rule does not apply to using declarations.
|
||||
When you write a header file, you don't know from which contexts it will be included. Therefore, if this header contains using-directives at the global or namespace scope, you cannot be sure that they will not create ambiguities in some of the including contexts. Those ambiguities could lead to compilation failures or, worse, to a different function being selected by overload resolution depending on the order of inclusion of headers.
|
||||
|
||||
This rule will raise an issue on using-directives in header files.
|
||||
|
||||
=== Noncompliant code example
|
||||
|
||||
@ -52,12 +51,21 @@ void m2 ( )
|
||||
|
||||
=== Exceptions
|
||||
|
||||
The issue only happens if the using directive is at global scope or at namespace scope. If is is inside a function body, it will cease to be in effect at the end of the current scope, and will not propagate to the users of the header file.
|
||||
Using-declarations (e.g., `using std::cout;`) behave in the same way but only for one name. This rule does not apply to them because their scope is much narrower.
|
||||
|
||||
Additionally, since it isn't easy to fully qualify the content of the `std::literals` and `std::placeholders` namespaces, this rule doesn't raise violations for using-directives that target these namespaces or their sub-namespaces, such as ``++std::literals::chrono_literals++``.
|
||||
|
||||
== Resources
|
||||
|
||||
=== Documentation
|
||||
|
||||
* {cpp} reference - https://en.cppreference.com/w/cpp/language/namespace#Using-directives[using-directives]
|
||||
|
||||
|
||||
=== External coding guidelines
|
||||
|
||||
* MISRA {cpp}:2008, 7-3-6 - using-directives and using-declarations (excluding class scope or function scope using-declarations) shall not be used in header files.
|
||||
|
||||
* {cpp} Core Guidelines - https://github.com/isocpp/CppCoreGuidelines/blob/e49158a/CppCoreGuidelines.md#sf7-dont-write-using-namespace-at-global-scope-in-a-header-file[SF.7: Don't write `using namespace` at global scope in a header file]
|
||||
|
||||
|
||||
|
56
rules/S101/dart/rule.adoc
Normal file
56
rules/S101/dart/rule.adoc
Normal file
@ -0,0 +1,56 @@
|
||||
== Why is this an issue?
|
||||
|
||||
Shared naming conventions allow teams to collaborate efficiently. In Dart, the convention is that all type names should be in camel-case starting with a capital letter (aka Pascal case).
|
||||
|
||||
This rule raises an issue when a class name does not comply with this convention.
|
||||
|
||||
== How to fix it
|
||||
|
||||
=== Code examples
|
||||
|
||||
==== Noncompliant code example
|
||||
|
||||
[source,dart]
|
||||
----
|
||||
class My_Class { } // Noncompliant: contains a dash
|
||||
class myClass { } // Noncompliant: starts with a lowercase
|
||||
class myclass { } // Noncompliant: all in lowercase
|
||||
----
|
||||
|
||||
==== Compliant solution
|
||||
|
||||
[source,dart]
|
||||
----
|
||||
class MyClass { }
|
||||
----
|
||||
|
||||
== Resources
|
||||
|
||||
* Dart Docs - https://dart.dev/tools/linter-rules/camel_case_types[Dart Linter rule - camel_case_types]
|
||||
|
||||
=== Related rules
|
||||
|
||||
* S7046 - Extension identifiers should comply with a naming convention
|
||||
* S7075 - Non-constant names should comply with a naming convention
|
||||
|
||||
ifdef::env-github,rspecator-view[]
|
||||
|
||||
'''
|
||||
== Implementation Specification
|
||||
(visible only on this page)
|
||||
|
||||
=== Message
|
||||
|
||||
* The type name '<typeName>' isn't an UpperCamelCase identifier.
|
||||
|
||||
=== Highlighting
|
||||
|
||||
The type name (without generic parameters, or representation type declaration).
|
||||
|
||||
'''
|
||||
== Comments And Links
|
||||
(visible only on this page)
|
||||
|
||||
include::../comments-and-links.adoc[]
|
||||
|
||||
endif::env-github,rspecator-view[]
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
|
||||
"scope": "Main"
|
||||
}
|
||||
|
@ -2,5 +2,9 @@
|
||||
"defaultQualityProfiles": [
|
||||
"Sonar way"
|
||||
],
|
||||
"scope": "Main"
|
||||
}
|
||||
"scope": "Main",
|
||||
"compatibleLanguages": [
|
||||
"js",
|
||||
"ts"
|
||||
]
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
|
||||
"scope": "Main"
|
||||
}
|
||||
|
@ -2,5 +2,9 @@
|
||||
"scope": "Main",
|
||||
"defaultQualityProfiles": [],
|
||||
"status": "deprecated",
|
||||
"tags": []
|
||||
}
|
||||
"tags": [],
|
||||
"compatibleLanguages": [
|
||||
"js",
|
||||
"ts"
|
||||
]
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
"type": "CODE_SMELL",
|
||||
"code": {
|
||||
"impacts": {
|
||||
"MAINTAINABILITY": "HIGH"
|
||||
"MAINTAINABILITY": "BLOCKER"
|
||||
},
|
||||
"attribute": "CLEAR"
|
||||
},
|
||||
@ -17,19 +17,13 @@
|
||||
"based-on-misra"
|
||||
],
|
||||
"extra": {
|
||||
"replacementRules": [
|
||||
|
||||
],
|
||||
"legacyKeys": [
|
||||
|
||||
]
|
||||
"replacementRules": [],
|
||||
"legacyKeys": []
|
||||
},
|
||||
"defaultSeverity": "Blocker",
|
||||
"ruleSpecification": "RSPEC-1032",
|
||||
"sqKey": "S1032",
|
||||
"scope": "Main",
|
||||
"defaultQualityProfiles": [
|
||||
|
||||
],
|
||||
"defaultQualityProfiles": [],
|
||||
"quickfix": "unknown"
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
"type": "CODE_SMELL",
|
||||
"code": {
|
||||
"impacts": {
|
||||
"MAINTAINABILITY": "HIGH"
|
||||
"MAINTAINABILITY": "BLOCKER"
|
||||
},
|
||||
"attribute": "CLEAR"
|
||||
},
|
||||
@ -19,12 +19,8 @@
|
||||
"pitfall"
|
||||
],
|
||||
"extra": {
|
||||
"replacementRules": [
|
||||
|
||||
],
|
||||
"legacyKeys": [
|
||||
|
||||
]
|
||||
"replacementRules": [],
|
||||
"legacyKeys": []
|
||||
},
|
||||
"defaultSeverity": "Blocker",
|
||||
"ruleSpecification": "RSPEC-1036",
|
||||
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
|
||||
"scope": "Main"
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
{
|
||||
"scope": "Main"
|
||||
}
|
||||
"scope": "Main",
|
||||
"compatibleLanguages": [
|
||||
"js",
|
||||
"ts"
|
||||
]
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
{
|
||||
"title": "All \"except\" blocks should be able to catch exceptions"
|
||||
"title": "All \"except\" blocks should be able to catch exceptions",
|
||||
"tags": [
|
||||
"suspicious"
|
||||
]
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"title": "Finalizers should not throw exceptions",
|
||||
"code": {
|
||||
"impacts": {
|
||||
"RELIABILITY": "HIGH"
|
||||
"RELIABILITY": "BLOCKER"
|
||||
},
|
||||
"attribute": "LOGICAL"
|
||||
},
|
||||
|
@ -2,7 +2,7 @@
|
||||
"title": "Finalize method should not throw exceptions",
|
||||
"code": {
|
||||
"impacts": {
|
||||
"RELIABILITY": "HIGH"
|
||||
"RELIABILITY": "BLOCKER"
|
||||
},
|
||||
"attribute": "LOGICAL"
|
||||
},
|
||||
|
@ -18,8 +18,8 @@ void foo () // no exceptions specified
|
||||
throw ( 21 ); // anything can be thrown
|
||||
}
|
||||
|
||||
void goo ( ) throw ( Exception )
|
||||
{
|
||||
void goo ( ) throw ( Exception )
|
||||
{
|
||||
foo ( ); // Noncompliant; an int could be thrown
|
||||
}
|
||||
----
|
||||
@ -34,8 +34,8 @@ void foo () // no exceptions specified
|
||||
throw ( 21 ); // this is legal; anything can be thrown
|
||||
}
|
||||
|
||||
void goo ( ) throw ( Exception, int )
|
||||
{
|
||||
void goo ( ) throw ( Exception, int )
|
||||
{
|
||||
foo ( );
|
||||
}
|
||||
----
|
||||
@ -45,7 +45,6 @@ void goo ( ) throw ( Exception, int )
|
||||
|
||||
* MISRA {cpp}:2008, 15-5-2
|
||||
* CWE - https://cwe.mitre.org/data/definitions/391[CWE-391 - Unchecked Error Condition]
|
||||
* https://www.securecoding.cert.org/confluence/x/EADTAQ[CERT, ERR55-CPP.] - Honor exception specifications
|
||||
|
||||
|
||||
ifdef::env-github,rspecator-view[]
|
||||
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
|
||||
"scope": "Main"
|
||||
}
|
||||
|
@ -2,5 +2,9 @@
|
||||
"scope": "Main",
|
||||
"defaultQualityProfiles": [],
|
||||
"status": "deprecated",
|
||||
"tags": []
|
||||
}
|
||||
"tags": [],
|
||||
"compatibleLanguages": [
|
||||
"js",
|
||||
"ts"
|
||||
]
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
"type": "BUG",
|
||||
"code": {
|
||||
"impacts": {
|
||||
"RELIABILITY": "HIGH"
|
||||
"RELIABILITY": "BLOCKER"
|
||||
},
|
||||
"attribute": "COMPLETE"
|
||||
},
|
||||
|
@ -3,7 +3,7 @@
|
||||
"type": "BUG",
|
||||
"code": {
|
||||
"impacts": {
|
||||
"RELIABILITY": "HIGH"
|
||||
"RELIABILITY": "BLOCKER"
|
||||
},
|
||||
"attribute": "LOGICAL"
|
||||
},
|
||||
@ -12,13 +12,9 @@
|
||||
"func": "Constant\/Issue",
|
||||
"constantCost": "30min"
|
||||
},
|
||||
"tags": [
|
||||
|
||||
],
|
||||
"tags": [],
|
||||
"extra": {
|
||||
"replacementRules": [
|
||||
|
||||
],
|
||||
"replacementRules": [],
|
||||
"legacyKeys": [
|
||||
"PipelinedFunctionsWithoutPipeRow"
|
||||
]
|
||||
|
5
rules/S106/dart/metadata.json
Normal file
5
rules/S106/dart/metadata.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"defaultQualityProfiles": [
|
||||
|
||||
]
|
||||
}
|
84
rules/S106/dart/rule.adoc
Normal file
84
rules/S106/dart/rule.adoc
Normal file
@ -0,0 +1,84 @@
|
||||
:language_std_outputs: print
|
||||
|
||||
== Why is this an issue?
|
||||
|
||||
include::../description.adoc[]
|
||||
|
||||
If you are using Flutter, you can use `debugPrint` or surround print calls with a check for `kDebugMode`.
|
||||
|
||||
=== Code examples
|
||||
|
||||
==== Noncompliant code example
|
||||
|
||||
[source,dart]
|
||||
----
|
||||
void doSomething(int x) {
|
||||
// ...
|
||||
print('debug: $x');
|
||||
// ...
|
||||
}
|
||||
----
|
||||
|
||||
==== Compliant solution
|
||||
|
||||
[source,dart]
|
||||
----
|
||||
void doSomething(int x) {
|
||||
// ...
|
||||
debugPrint('debug: $x');
|
||||
// ...
|
||||
}
|
||||
----
|
||||
|
||||
or
|
||||
|
||||
[source,dart]
|
||||
----
|
||||
void doSomething(int x) {
|
||||
// ...
|
||||
if (kDebugMode) {
|
||||
print('debug: $x');
|
||||
}
|
||||
// ...
|
||||
}
|
||||
----
|
||||
|
||||
or
|
||||
|
||||
[source,dart]
|
||||
----
|
||||
void doSomething(int x) {
|
||||
// ...
|
||||
log('log: $x');
|
||||
// ...
|
||||
}
|
||||
----
|
||||
|
||||
== Resources
|
||||
|
||||
* OWASP - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/[Top 10 2021 Category A9 - Security Logging and Monitoring Failures]
|
||||
* OWASP - https://owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure[Top 10 2017 Category A3 - Sensitive Data Exposure]
|
||||
* Dart Docs - https://dart.dev/tools/linter-rules/avoid_print[Dart Linter rule - avoid_print]
|
||||
* Flutter API Docs - https://api.flutter.dev/flutter/foundation/kDebugMode-constant.html[kDebugMode top-level constant]
|
||||
|
||||
ifdef::env-github,rspecator-view[]
|
||||
|
||||
'''
|
||||
== Implementation Specification
|
||||
(visible only on this page)
|
||||
|
||||
=== Message
|
||||
|
||||
* Don't invoke 'print' in production code.
|
||||
|
||||
=== Highlighting
|
||||
|
||||
The identifier of the `print` method, without argument list.
|
||||
|
||||
'''
|
||||
== Comments And Links
|
||||
(visible only on this page)
|
||||
|
||||
include::../comments-and-links.adoc[]
|
||||
|
||||
endif::env-github,rspecator-view[]
|
@ -3,7 +3,9 @@
|
||||
"bad-practice",
|
||||
"user-experience"
|
||||
],
|
||||
"defaultQualityProfiles": [
|
||||
|
||||
"defaultQualityProfiles": [],
|
||||
"compatibleLanguages": [
|
||||
"js",
|
||||
"ts"
|
||||
]
|
||||
}
|
||||
}
|
7
rules/S106/rust/metadata.json
Normal file
7
rules/S106/rust/metadata.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"defaultQualityProfiles": [],
|
||||
"tags": [
|
||||
"bad-practice",
|
||||
"clippy"
|
||||
]
|
||||
}
|
39
rules/S106/rust/rule.adoc
Normal file
39
rules/S106/rust/rule.adoc
Normal file
@ -0,0 +1,39 @@
|
||||
:language_std_outputs: print!, println!
|
||||
|
||||
== Why is this an issue?
|
||||
|
||||
include::../description.adoc[]
|
||||
|
||||
=== Code examples
|
||||
|
||||
==== Noncompliant code example
|
||||
|
||||
[source,rust,diff-id=1,diff-type=noncompliant]
|
||||
----
|
||||
fn do_something() {
|
||||
println!("my message"); // Noncompliant, output directly to stdout without a logger
|
||||
}
|
||||
----
|
||||
|
||||
==== Compliant solution
|
||||
|
||||
[source,rust,diff-id=1,diff-type=compliant]
|
||||
----
|
||||
use log::{info, LevelFilter};
|
||||
use simple_logger::SimpleLogger;
|
||||
|
||||
fn do_something() {
|
||||
SimpleLogger::new().with_level(LevelFilter::Info).init().unwrap();
|
||||
// ...
|
||||
info!("my message"); // Compliant, output via logger
|
||||
// ...
|
||||
}
|
||||
----
|
||||
|
||||
== Resources
|
||||
|
||||
=== Documentation
|
||||
|
||||
* Clippy Lints - https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout
|
||||
* OWASP - https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/[Top 10 2021 Category A9 - Security Logging and Monitoring Failures]
|
||||
* OWASP - https://owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure[Top 10 2017 Category A3 - Sensitive Data Exposure]
|
3
rules/S1065/dart/metadata.json
Normal file
3
rules/S1065/dart/metadata.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
|
||||
}
|
57
rules/S1065/dart/rule.adoc
Normal file
57
rules/S1065/dart/rule.adoc
Normal file
@ -0,0 +1,57 @@
|
||||
== Why is this an issue?
|
||||
|
||||
include::../description.adoc[]
|
||||
|
||||
=== Noncompliant code example
|
||||
|
||||
[source,dart,diff-id=1,diff-type=noncompliant]
|
||||
----
|
||||
void foo() {
|
||||
outer: //label is not used.
|
||||
for(int i = 0; i < 10; i++) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
=== Compliant solution
|
||||
|
||||
[source,dart,diff-id=1,diff-type=compliant]
|
||||
----
|
||||
void foo() {
|
||||
for(int i = 0; i < 10; i++) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
== Resources
|
||||
|
||||
=== Documentation
|
||||
|
||||
* CERT - https://wiki.sei.cmu.edu/confluence/x/5dUxBQ[CERT, MSC12-C.] - Detect and remove code that has no effect or is never executed
|
||||
* Dart Docs - https://dart.dev/tools/diagnostic-messages?utm_source=dartdev&utm_medium=redir&utm_id=diagcode&utm_content=unnecessary_cast#unused_label[Dart Linter rule - unused_label]
|
||||
|
||||
ifdef::env-github,rspecator-view[]
|
||||
|
||||
'''
|
||||
== Implementation Specification
|
||||
(visible only on this page)
|
||||
|
||||
=== Message
|
||||
|
||||
* The label '<labelName>' isn't used.
|
||||
|
||||
`<labelName>` doesn't include the semicolon.
|
||||
|
||||
=== Highlighting
|
||||
|
||||
The label name, including the semicolon.
|
||||
|
||||
'''
|
||||
== Comments And Links
|
||||
(visible only on this page)
|
||||
|
||||
include::../comments-and-links.adoc[]
|
||||
|
||||
endif::env-github,rspecator-view[]
|
@ -7,5 +7,6 @@
|
||||
"CERT": [
|
||||
"MSC12-C."
|
||||
]
|
||||
}
|
||||
},
|
||||
"scope": "Main"
|
||||
}
|
||||
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"defaultQualityProfiles": [],
|
||||
"scope": "Main"
|
||||
}
|
||||
"scope": "Main",
|
||||
"compatibleLanguages": [
|
||||
"js",
|
||||
"ts"
|
||||
]
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
|
||||
"scope": "Main"
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
{
|
||||
"scope": "Main"
|
||||
}
|
||||
"scope": "Main",
|
||||
"compatibleLanguages": [
|
||||
"js",
|
||||
"ts"
|
||||
]
|
||||
}
|
3
rules/S1068/dart/metadata.json
Normal file
3
rules/S1068/dart/metadata.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
|
||||
}
|
22
rules/S1068/dart/rule.adoc
Normal file
22
rules/S1068/dart/rule.adoc
Normal file
@ -0,0 +1,22 @@
|
||||
== Why is this an issue?
|
||||
|
||||
include::../description.adoc[]
|
||||
|
||||
[source,dart]
|
||||
----
|
||||
class MyClass {
|
||||
final String _str; // Noncompliant, _str private field is never read
|
||||
|
||||
C(this._str);
|
||||
}
|
||||
----
|
||||
|
||||
== How to fix it
|
||||
|
||||
If the field isn't needed, then remove it.
|
||||
|
||||
If the field was intended to be used, then add the missing code.
|
||||
|
||||
== Resources
|
||||
|
||||
* https://dart.dev/tools/diagnostic-messages?utm_source=dartdev&utm_medium=redir&utm_id=diagcode&utm_content=unnecessary_cast#unused_field[Dart compiler diagnostic - unused field]
|
@ -1,4 +1,8 @@
|
||||
{
|
||||
"title": "Unused private class members should be removed",
|
||||
"quickfix": "covered"
|
||||
"title": "Unused private class members should be removed",
|
||||
"quickfix": "covered",
|
||||
"compatibleLanguages": [
|
||||
"js",
|
||||
"ts"
|
||||
]
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
"type": "CODE_SMELL",
|
||||
"code": {
|
||||
"impacts": {
|
||||
"MAINTAINABILITY": "HIGH"
|
||||
"MAINTAINABILITY": "BLOCKER"
|
||||
},
|
||||
"attribute": "CONVENTIONAL"
|
||||
},
|
||||
@ -17,12 +17,8 @@
|
||||
"sql"
|
||||
],
|
||||
"extra": {
|
||||
"replacementRules": [
|
||||
|
||||
],
|
||||
"legacyKeys": [
|
||||
|
||||
]
|
||||
"replacementRules": [],
|
||||
"legacyKeys": []
|
||||
},
|
||||
"defaultSeverity": "Blocker",
|
||||
"ruleSpecification": "RSPEC-1069",
|
||||
|
3
rules/S107/dart/metadata.json
Normal file
3
rules/S107/dart/metadata.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
|
||||
}
|
6
rules/S107/dart/noncompliant.adoc
Normal file
6
rules/S107/dart/noncompliant.adoc
Normal file
@ -0,0 +1,6 @@
|
||||
[source,dart]
|
||||
----
|
||||
void setCoordinates(int x1, int y1, int z1, int x2, int y2, int z2) { // Noncompliant
|
||||
// ...
|
||||
}
|
||||
----
|
21
rules/S107/dart/rule.adoc
Normal file
21
rules/S107/dart/rule.adoc
Normal file
@ -0,0 +1,21 @@
|
||||
:language: dart
|
||||
|
||||
include::../rule.adoc[]
|
||||
|
||||
ifdef::env-github,rspecator-view[]
|
||||
|
||||
'''
|
||||
== Implementation Specification
|
||||
(visible only on this page)
|
||||
|
||||
include::../message.adoc[]
|
||||
|
||||
include::../parameters.adoc[]
|
||||
|
||||
'''
|
||||
== Comments And Links
|
||||
(visible only on this page)
|
||||
|
||||
include::../comments-and-links.adoc[]
|
||||
|
||||
endif::env-github,rspecator-view[]
|
11
rules/S107/dart/split-example.adoc
Normal file
11
rules/S107/dart/split-example.adoc
Normal file
@ -0,0 +1,11 @@
|
||||
[source,dart]
|
||||
----
|
||||
// Each function does a part of what the original setCoordinates function was doing, so confusion risks are lower
|
||||
void setOrigin(int x, int y, int z) {
|
||||
// ...
|
||||
}
|
||||
|
||||
void setSize(int width, int height, int depth) {
|
||||
// ...
|
||||
}
|
||||
----
|
13
rules/S107/dart/struct-example.adoc
Normal file
13
rules/S107/dart/struct-example.adoc
Normal file
@ -0,0 +1,13 @@
|
||||
[source,dart]
|
||||
----
|
||||
class Point { // In geometry, Point is a logical structure to group data
|
||||
int x;
|
||||
int y;
|
||||
|
||||
Point(this.x, this.y);
|
||||
}
|
||||
|
||||
void setCoordinates(Point p1, Point p2) {
|
||||
// ...
|
||||
}
|
||||
----
|
@ -1,3 +1,4 @@
|
||||
{
|
||||
"title": "Methods should not have too many parameters"
|
||||
"title": "Methods should not have too many parameters",
|
||||
"scope": "Main"
|
||||
}
|
||||
|
@ -2,5 +2,9 @@
|
||||
"defaultQualityProfiles": [
|
||||
"Sonar way"
|
||||
],
|
||||
"scope": "Main"
|
||||
}
|
||||
"scope": "Main",
|
||||
"compatibleLanguages": [
|
||||
"js",
|
||||
"ts"
|
||||
]
|
||||
}
|
6
rules/S107/rust/metadata.json
Normal file
6
rules/S107/rust/metadata.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"tags": [
|
||||
"brain-overload",
|
||||
"clippy"
|
||||
]
|
||||
}
|
6
rules/S107/rust/noncompliant.adoc
Normal file
6
rules/S107/rust/noncompliant.adoc
Normal file
@ -0,0 +1,6 @@
|
||||
[source,rust]
|
||||
----
|
||||
fn set_coordinates(x1: i32, y1: i32, z1: i32, x2: i32, y2: i32, z2: i32) { // Noncompliant
|
||||
// ...
|
||||
}
|
||||
----
|
27
rules/S107/rust/rule.adoc
Normal file
27
rules/S107/rust/rule.adoc
Normal file
@ -0,0 +1,27 @@
|
||||
:language: rust
|
||||
|
||||
include::../rule.adoc[]
|
||||
|
||||
== Resources
|
||||
|
||||
=== Documentation
|
||||
|
||||
* Clippy Lints - https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments
|
||||
|
||||
ifdef::env-github,rspecator-view[]
|
||||
|
||||
'''
|
||||
== Implementation Specification
|
||||
(visible only on this page)
|
||||
|
||||
include::../message.adoc[]
|
||||
|
||||
include::../parameters.adoc[]
|
||||
|
||||
'''
|
||||
== Comments And Links
|
||||
(visible only on this page)
|
||||
|
||||
include::../comments-and-links.adoc[]
|
||||
|
||||
endif::env-github,rspecator-view[]
|
11
rules/S107/rust/split-example.adoc
Normal file
11
rules/S107/rust/split-example.adoc
Normal file
@ -0,0 +1,11 @@
|
||||
[source,rust]
|
||||
----
|
||||
// Each function does a part of what the original setCoordinates function was doing, so confusion risks are lower
|
||||
fn set_origin(x: i32, y: i32, z: i32) {
|
||||
// ...
|
||||
}
|
||||
|
||||
fn set_size(width: i32, height: i32, depth: i32) {
|
||||
// ...
|
||||
}
|
||||
----
|
17
rules/S107/rust/struct-example.adoc
Normal file
17
rules/S107/rust/struct-example.adoc
Normal file
@ -0,0 +1,17 @@
|
||||
[source,rust]
|
||||
----
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
impl Point {
|
||||
fn new(x: i32, y: i32) -> Point {
|
||||
Point { x, y }
|
||||
}
|
||||
}
|
||||
|
||||
fn set_coordinates(p1: &mut Point, p2: &Point) {
|
||||
// ...
|
||||
}
|
||||
----
|
@ -3,7 +3,7 @@
|
||||
"type": "BUG",
|
||||
"code": {
|
||||
"impacts": {
|
||||
"RELIABILITY": "HIGH"
|
||||
"RELIABILITY": "BLOCKER"
|
||||
},
|
||||
"attribute": "COMPLETE"
|
||||
},
|
||||
@ -12,13 +12,9 @@
|
||||
"func": "Constant\/Issue",
|
||||
"constantCost": "1h"
|
||||
},
|
||||
"tags": [
|
||||
|
||||
],
|
||||
"tags": [],
|
||||
"extra": {
|
||||
"replacementRules": [
|
||||
|
||||
],
|
||||
"replacementRules": [],
|
||||
"legacyKeys": [
|
||||
"ForallStatementShouldUseSaveExceptionsClause"
|
||||
]
|
||||
|
@ -1,5 +1,13 @@
|
||||
include::../description.adoc[]
|
||||
|
||||
=== Exceptions
|
||||
|
||||
This rule does not raise an issue when:
|
||||
|
||||
* A constant path is relative and contains at most two parts.
|
||||
* A constant path is used in an annotation
|
||||
* A path is annotated
|
||||
|
||||
== How to fix it
|
||||
|
||||
=== Code examples
|
||||
@ -9,6 +17,8 @@ include::../description.adoc[]
|
||||
[source,java,diff-id=1,diff-type=noncompliant]
|
||||
----
|
||||
public class Foo {
|
||||
public static final String FRIENDS_ENDPOINT = "/user/friends"; // Compliant path is relative and has only two parts
|
||||
|
||||
public Collection<User> listUsers() {
|
||||
File userList = new File("/home/mylogin/Dev/users.txt"); // Noncompliant
|
||||
Collection<User> users = parse(userList);
|
||||
@ -38,6 +48,24 @@ public class Foo {
|
||||
}
|
||||
----
|
||||
|
||||
Exceptions examples:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
public class Foo {
|
||||
public static final String FRIENDS_ENDPOINT = "/user/friends"; // Compliant path is relative and has only two parts
|
||||
|
||||
public static final String ACCOUNT = "/account/group/list.html"; // Compliant path is used in an annotation
|
||||
|
||||
@Value("${base.url}" + ACCOUNT)
|
||||
private String groupUrl;
|
||||
|
||||
@MyAnnotation()
|
||||
String path = "/default/url/for/site"; // Compliant path is annotated
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
ifdef::env-github,rspecator-view[]
|
||||
|
||||
'''
|
||||
|
@ -3,5 +3,9 @@
|
||||
"accessibility",
|
||||
"wcag2-a",
|
||||
"react"
|
||||
],
|
||||
"compatibleLanguages": [
|
||||
"js",
|
||||
"ts"
|
||||
]
|
||||
}
|
||||
}
|
@ -46,7 +46,7 @@
|
||||
"14.1.2",
|
||||
"5.4.1"
|
||||
],
|
||||
"STIG ASD 2023-06-08": [
|
||||
"STIG ASD_V5R3": [
|
||||
"V-222612"
|
||||
]
|
||||
},
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user