recce-nightly 0.61.0.20250409__py3-none-any.whl → 0.61.0.20250413__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of recce-nightly might be problematic. Click here for more details.

recce/VERSION CHANGED
@@ -1 +1 @@
1
- 0.61.0.20250409
1
+ 0.61.0.20250413
recce/data/404.html CHANGED
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-8a8709fe9d22c323.js"/><script src="/_next/static/chunks/38610ee6-24a85e2dfb424ddb.js" async=""></script><script src="/_next/static/chunks/783-784ce10322400a48.js" async=""></script><script src="/_next/static/chunks/main-app-cfd795a5fe58bf37.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>recce</title><meta name="description" content="Recce: Data validation toolkit for comprehensive PR review"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><script src="/_next/static/chunks/webpack-8a8709fe9d22c323.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:I[83798,[],\"\"]\n3:I[26375,[],\"\"]\n4:I[22587,[],\"\"]\na:I[114,[],\"\"]\n5:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n6:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\n7:{\"display\":\"inline-block\"}\n8:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\nb:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L1\",null,{\"buildId\":\"ynqWeF6GV-HrY-hgM_vm-\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"_not-found\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L2\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"children\":[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$5\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$6\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$7\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$8\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$L9\"],\"globalErrorComponent\":\"$a\",\"missingSlots\":\"$Wb\"}]\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"recce\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Recce: Data validation toolkit for comprehensive PR review\"}]]\n2:null\n"])</script></body></html>
1
+ <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-8a8709fe9d22c323.js"/><script src="/_next/static/chunks/38610ee6-24a85e2dfb424ddb.js" async=""></script><script src="/_next/static/chunks/783-784ce10322400a48.js" async=""></script><script src="/_next/static/chunks/main-app-cfd795a5fe58bf37.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>recce</title><meta name="description" content="Recce: Data validation toolkit for comprehensive PR review"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><script src="/_next/static/chunks/webpack-8a8709fe9d22c323.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:I[83798,[],\"\"]\n3:I[26375,[],\"\"]\n4:I[22587,[],\"\"]\na:I[114,[],\"\"]\n5:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n6:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\n7:{\"display\":\"inline-block\"}\n8:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\nb:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L1\",null,{\"buildId\":\"hD8g5-RYxHasL_ZuMPw1A\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"_not-found\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L2\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"children\":[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$5\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$6\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$7\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$8\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$L9\"],\"globalErrorComponent\":\"$a\",\"missingSlots\":\"$Wb\"}]\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"recce\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Recce: Data validation toolkit for comprehensive PR review\"}]]\n2:null\n"])</script></body></html>
recce/data/index.html CHANGED
@@ -24,4 +24,4 @@
24
24
  transparent 0%,
25
25
  #3182ce 50%,
26
26
  transparent 100%
27
- );position:absolute;will-change:left;min-width:50%;-webkit-animation:animation-11lmxjq 1s ease infinite normal none running;animation:animation-11lmxjq 1s ease infinite normal none running;}@-webkit-keyframes animation-11lmxjq{0%{left:-40%;}100%{left:100%;}}@keyframes animation-11lmxjq{0%{left:-40%;}100%{left:100%;}}</style><div style="width:0%" data-indeterminate="" aria-valuemax="100" aria-valuemin="0" role="progressbar" class="css-h5ends"></div></div></div><div class="css-0"></div></div></div></div><span></span><span id="__chakra_env" hidden=""></span><script src="/_next/static/chunks/webpack-8a8709fe9d22c323.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/c9ecb46a4b21c126.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"2:I[83798,[],\"\"]\n4:I[49272,[],\"ClientPageRoot\"]\n5:I[12963,[\"266\",\"static/chunks/e24bf851-5db5db8459b0b291.js\",\"517\",\"static/chunks/c1ceaa8b-64142a5184f1b8b2.js\",\"678\",\"static/chunks/3998a672-63fc54b2b517ee2b.js\",\"509\",\"static/chunks/9746af58-527fd8cbd2d17eee.js\",\"648\",\"static/chunks/ce84277d-4bca7695ec1ada94.js\",\"989\",\"static/chunks/47d8844f-0516cea2ef568380.js\",\"147\",\"static/chunks/a30376cd-1ad5a3f522da896c.js\",\"995\",\"static/chunks/fee69bc6-1df8306af9d11293.js\",\"739\",\"static/chunks/7a8a3e83-dd26fafa0a7421e5.js\",\"283\",\"static/chunks/450c323b-b36e745822edebe2.js\",\"303\",\"static/chunks/36e1c10d-800596efe83e74a6.js\",\"22\",\"static/chunks/29e3cc0d-6e3b0cf904a6874d.js\",\"25\",\"static/chunks/b63b1b3f-fe714039749c1250.js\",\"355\",\"static/chunks/7f27ae6c-4ddea120696db611.js\",\"495\",\"static/chunks/6dc81886-9871b611a22bd997.js\",\"599\",\"static/chunks/c132bf7d-4cb4c4a123e27340.js\",\"971\",\"static/chunks/cd9f8d63-543677b0ef49da87.js\",\"269\",\"static/chunks/269-83bbdbcbd0cc1ddb.js\",\"931\",\"static/chunks/app/page-35403e208468490c.js\"],\"default\",1]\n6:I[26375,[],\"\"]\n7:I[22587,[],\"\"]\n9:I[114,[],\"\"]\na:[]\n0:[\"$\",\"$L2\",null,{\"buildId\":\"ynqWeF6GV-HrY-hgM_vm-\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"\"],\"initialTree\":[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"__PAGE__\",{},[[\"$L3\",[\"$\",\"$L4\",null,{\"props\":{\"params\":{},\"searchParams\":{}},\"Component\":\"$5\"}],[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/c9ecb46a4b21c126.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]]],null],null]},[[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"children\":[\"$\",\"$L6\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L7\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvet"])</script><script>self.__next_f.push([1,"ica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[null,\"$L8\"],\"globalErrorComponent\":\"$9\",\"missingSlots\":\"$Wa\"}]\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"recce\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Recce: Data validation toolkit for comprehensive PR review\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"32x32\"}]]\n3:null\n"])</script></body></html>
27
+ );position:absolute;will-change:left;min-width:50%;-webkit-animation:animation-11lmxjq 1s ease infinite normal none running;animation:animation-11lmxjq 1s ease infinite normal none running;}@-webkit-keyframes animation-11lmxjq{0%{left:-40%;}100%{left:100%;}}@keyframes animation-11lmxjq{0%{left:-40%;}100%{left:100%;}}</style><div style="width:0%" data-indeterminate="" aria-valuemax="100" aria-valuemin="0" role="progressbar" class="css-h5ends"></div></div></div><div class="css-0"></div></div></div></div><span></span><span id="__chakra_env" hidden=""></span><script src="/_next/static/chunks/webpack-8a8709fe9d22c323.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/c9ecb46a4b21c126.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"2:I[83798,[],\"\"]\n4:I[49272,[],\"ClientPageRoot\"]\n5:I[12963,[\"266\",\"static/chunks/e24bf851-5db5db8459b0b291.js\",\"517\",\"static/chunks/c1ceaa8b-64142a5184f1b8b2.js\",\"678\",\"static/chunks/3998a672-63fc54b2b517ee2b.js\",\"509\",\"static/chunks/9746af58-527fd8cbd2d17eee.js\",\"648\",\"static/chunks/ce84277d-4bca7695ec1ada94.js\",\"989\",\"static/chunks/47d8844f-0516cea2ef568380.js\",\"147\",\"static/chunks/a30376cd-1ad5a3f522da896c.js\",\"995\",\"static/chunks/fee69bc6-1df8306af9d11293.js\",\"739\",\"static/chunks/7a8a3e83-dd26fafa0a7421e5.js\",\"283\",\"static/chunks/450c323b-b36e745822edebe2.js\",\"303\",\"static/chunks/36e1c10d-800596efe83e74a6.js\",\"22\",\"static/chunks/29e3cc0d-6e3b0cf904a6874d.js\",\"25\",\"static/chunks/b63b1b3f-fe714039749c1250.js\",\"355\",\"static/chunks/7f27ae6c-4ddea120696db611.js\",\"495\",\"static/chunks/6dc81886-9871b611a22bd997.js\",\"599\",\"static/chunks/c132bf7d-4cb4c4a123e27340.js\",\"971\",\"static/chunks/cd9f8d63-543677b0ef49da87.js\",\"269\",\"static/chunks/269-83bbdbcbd0cc1ddb.js\",\"931\",\"static/chunks/app/page-35403e208468490c.js\"],\"default\",1]\n6:I[26375,[],\"\"]\n7:I[22587,[],\"\"]\n9:I[114,[],\"\"]\na:[]\n0:[\"$\",\"$L2\",null,{\"buildId\":\"hD8g5-RYxHasL_ZuMPw1A\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"\"],\"initialTree\":[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"__PAGE__\",{},[[\"$L3\",[\"$\",\"$L4\",null,{\"props\":{\"params\":{},\"searchParams\":{}},\"Component\":\"$5\"}],[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/c9ecb46a4b21c126.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]]],null],null]},[[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"children\":[\"$\",\"$L6\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L7\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvet"])</script><script>self.__next_f.push([1,"ica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[null,\"$L8\"],\"globalErrorComponent\":\"$9\",\"missingSlots\":\"$Wa\"}]\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"recce\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Recce: Data validation toolkit for comprehensive PR review\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"32x32\"}]]\n3:null\n"])</script></body></html>
recce/data/index.txt CHANGED
@@ -2,6 +2,6 @@
2
2
  3:I[12963,["266","static/chunks/e24bf851-5db5db8459b0b291.js","517","static/chunks/c1ceaa8b-64142a5184f1b8b2.js","678","static/chunks/3998a672-63fc54b2b517ee2b.js","509","static/chunks/9746af58-527fd8cbd2d17eee.js","648","static/chunks/ce84277d-4bca7695ec1ada94.js","989","static/chunks/47d8844f-0516cea2ef568380.js","147","static/chunks/a30376cd-1ad5a3f522da896c.js","995","static/chunks/fee69bc6-1df8306af9d11293.js","739","static/chunks/7a8a3e83-dd26fafa0a7421e5.js","283","static/chunks/450c323b-b36e745822edebe2.js","303","static/chunks/36e1c10d-800596efe83e74a6.js","22","static/chunks/29e3cc0d-6e3b0cf904a6874d.js","25","static/chunks/b63b1b3f-fe714039749c1250.js","355","static/chunks/7f27ae6c-4ddea120696db611.js","495","static/chunks/6dc81886-9871b611a22bd997.js","599","static/chunks/c132bf7d-4cb4c4a123e27340.js","971","static/chunks/cd9f8d63-543677b0ef49da87.js","269","static/chunks/269-83bbdbcbd0cc1ddb.js","931","static/chunks/app/page-35403e208468490c.js"],"default",1]
3
3
  4:I[26375,[],""]
4
4
  5:I[22587,[],""]
5
- 0:["ynqWeF6GV-HrY-hgM_vm-",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/c9ecb46a4b21c126.css","precedence":"next","crossOrigin":"$undefined"}]]],null],null]},[[null,["$","html",null,{"lang":"en","children":["$","body",null,{"suppressHydrationWarning":true,"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]]
5
+ 0:["hD8g5-RYxHasL_ZuMPw1A",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/c9ecb46a4b21c126.css","precedence":"next","crossOrigin":"$undefined"}]]],null],null]},[[null,["$","html",null,{"lang":"en","children":["$","body",null,{"suppressHydrationWarning":true,"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]]
6
6
  6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"recce"}],["$","meta","3",{"name":"description","content":"Recce: Data validation toolkit for comprehensive PR review"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"32x32"}]]
7
7
  1:null
recce/util/breaking.py CHANGED
@@ -1,17 +1,65 @@
1
- from sqlglot.optimizer import optimize
1
+ from dataclasses import dataclass
2
+ from typing import Literal, Optional
2
3
 
4
+ import sqlglot.expressions as exp
5
+ from sqlglot import parse_one, diff, Dialect
6
+ from sqlglot.diff import Insert, Keep
7
+ from sqlglot.optimizer import optimize, traverse_scope, Scope
3
8
 
4
- def is_breaking_change(original_sql, modified_sql, dialect=None):
9
+ ChangeCategory = Literal['breaking', 'partial_breaking', 'non_breaking', 'unknown']
10
+ ColumnChangeStatus = Literal['added', 'removed', 'modified']
11
+ VALID_EXPRESSIONS = (
12
+ exp.Where,
13
+ exp.Join,
14
+ exp.Order,
15
+ exp.Group,
16
+ exp.Having,
17
+ exp.Limit,
18
+ exp.Offset,
19
+ exp.Window,
20
+ exp.Union,
21
+ exp.Intersect,
22
+ exp.Except,
23
+ exp.Merge,
24
+ exp.Delete,
25
+ exp.Update,
26
+ exp.Insert,
27
+ exp.Subquery,
28
+ )
29
+
30
+
31
+ @dataclass
32
+ class ChangeCategoryResult:
33
+ category: ChangeCategory
34
+ changed_columns: Optional[dict[str, ColumnChangeStatus]]
35
+
36
+ def __init__(
37
+ self,
38
+ category: ChangeCategory,
39
+ changed_columns: Optional[dict[str, ColumnChangeStatus]] = None
40
+ ):
41
+ self.category = category
42
+ self.changed_columns = changed_columns
43
+
44
+
45
+ CHANGE_CATEGORY_UNKNOWN = ChangeCategoryResult('unknown')
46
+ CHANGE_CATEGORY_BREAKING = ChangeCategoryResult('breaking')
47
+
48
+
49
+ def _debug(*args):
50
+ pass
51
+ # print(*args)
52
+
53
+
54
+ def is_breaking_change(old_sql, new_sql, dialect=None):
55
+ result = parse_change_category(old_sql, new_sql, old_schema=None, new_schema=None, dialect=dialect)
56
+ return result.category != 'non_breaking'
57
+
58
+
59
+ def _is_breaking_change(original_sql, modified_sql, dialect=None) -> bool:
5
60
  if original_sql == modified_sql:
6
61
  return False
7
62
 
8
- try:
9
- from sqlglot import parse_one, diff, Dialect
10
- from sqlglot.diff import Insert, Keep
11
- import sqlglot.expressions as exp
12
- except ImportError:
13
- return True
14
-
15
63
  try:
16
64
  dialect = Dialect.get(dialect)
17
65
 
@@ -38,25 +86,6 @@ def is_breaking_change(original_sql, modified_sql, dialect=None):
38
86
  e.expression for e in edits if isinstance(e, Insert)
39
87
  }
40
88
 
41
- VALID_EXPRESSIONS = (
42
- exp.Where,
43
- exp.Join,
44
- exp.Order,
45
- exp.Group,
46
- exp.Having,
47
- exp.Limit,
48
- exp.Offset,
49
- exp.Window,
50
- exp.Union,
51
- exp.Intersect,
52
- exp.Except,
53
- exp.Merge,
54
- exp.Delete,
55
- exp.Update,
56
- exp.Insert,
57
- exp.Subquery,
58
- )
59
-
60
89
  for edit in edits:
61
90
  if isinstance(edit, Insert):
62
91
  inserted_expr = edit.expression
@@ -76,3 +105,252 @@ def is_breaking_change(original_sql, modified_sql, dialect=None):
76
105
  return True
77
106
 
78
107
  return False
108
+
109
+
110
+ def _diff_select_scope(
111
+ old_scope: Scope,
112
+ new_scope: Scope,
113
+ scope_changes_map: dict[Scope, ChangeCategoryResult]
114
+ ) -> ChangeCategoryResult:
115
+ assert old_scope.expression.key == 'select'
116
+ assert new_scope.expression.key == 'select'
117
+
118
+ result = ChangeCategoryResult('non_breaking')
119
+
120
+ # check if the upstream scopes is the same and not breaking
121
+ if old_scope.sources.keys() != new_scope.sources.keys():
122
+ return CHANGE_CATEGORY_BREAKING
123
+ for source_name, source in new_scope.sources.items():
124
+ if scope_changes_map.get(source) is not None:
125
+ change_category = scope_changes_map[source]
126
+ if change_category.category == 'breaking':
127
+ return CHANGE_CATEGORY_BREAKING
128
+
129
+ # check if non-select expressions are the same
130
+ old_select = old_scope.expression # type: exp.Select
131
+ new_select = new_scope.expression # type: exp.Select
132
+ for arg_key in old_select.args.keys() | new_select.args.keys():
133
+ if arg_key in ['expressions', 'with', 'from']:
134
+ continue
135
+
136
+ if old_select.args.get(arg_key) != new_select.args.get(arg_key):
137
+ return CHANGE_CATEGORY_BREAKING
138
+
139
+ def source_column_change_status(ref_column: exp.Column) -> Optional[ColumnChangeStatus]:
140
+ table_name = ref_column.table
141
+ column_name = ref_column.name
142
+ source = new_scope.sources.get(table_name, None) # type: exp.Table | Scope
143
+ if not isinstance(source, Scope):
144
+ return None
145
+
146
+ ref_change_category = scope_changes_map.get(source)
147
+ if ref_change_category is None:
148
+ return None
149
+
150
+ return ref_change_category.changed_columns.get(column_name)
151
+
152
+ # selects
153
+ old_column_map = {projection.alias_or_name: projection for projection in old_select.selects}
154
+ new_column_map = {projection.alias_or_name: projection for projection in new_select.selects}
155
+ changed_columns = {}
156
+ is_distinct = new_select.args.get('distinct') is not None
157
+
158
+ for column_name in (old_column_map.keys() | new_column_map.keys()):
159
+ def _has_udtf(expr: exp.Expression) -> bool:
160
+ return expr.find(exp.UDTF) is not None
161
+
162
+ def _has_aggregate(expr: exp.Expression) -> bool:
163
+ return expr.find(exp.AggFunc) is not None
164
+
165
+ old_column = old_column_map.get(column_name)
166
+ new_column = new_column_map.get(column_name)
167
+ if old_column is None:
168
+ if is_distinct:
169
+ return CHANGE_CATEGORY_BREAKING
170
+
171
+ if _has_udtf(new_column):
172
+ return CHANGE_CATEGORY_BREAKING
173
+
174
+ changed_columns[column_name] = 'added'
175
+ elif new_column is None:
176
+ if is_distinct:
177
+ return CHANGE_CATEGORY_BREAKING
178
+
179
+ if _has_udtf(old_column):
180
+ return CHANGE_CATEGORY_BREAKING
181
+
182
+ changed_columns[column_name] = 'removed'
183
+ result.category = 'partial_breaking'
184
+ elif old_column != new_column:
185
+ if is_distinct:
186
+ return CHANGE_CATEGORY_BREAKING
187
+
188
+ if _has_udtf(old_column) and _has_udtf(new_column):
189
+ return CHANGE_CATEGORY_BREAKING
190
+
191
+ if _has_aggregate(old_column) != _has_aggregate(new_column):
192
+ return CHANGE_CATEGORY_BREAKING
193
+
194
+ changed_columns[column_name] = 'modified'
195
+ result.category = 'partial_breaking'
196
+ else:
197
+ ref_columns = new_column.find_all(exp.Column)
198
+ for ref_column in ref_columns:
199
+ if source_column_change_status(ref_column) is not None:
200
+ if is_distinct:
201
+ return CHANGE_CATEGORY_BREAKING
202
+ if _has_udtf(new_column):
203
+ return CHANGE_CATEGORY_BREAKING
204
+
205
+ result.category = 'partial_breaking'
206
+ changed_columns[column_name] = 'modified'
207
+
208
+ def selected_column_change_status(ref_column: exp.Column) -> Optional[ColumnChangeStatus]:
209
+ column_name = ref_column.name
210
+ return changed_columns.get(column_name)
211
+
212
+ # joins clause: Reference the source columns
213
+ if new_select.args.get('joins'):
214
+ joins = new_select.args.get('joins')
215
+ for join in joins:
216
+ if isinstance(join, exp.Join):
217
+ for ref_column in join.find_all(exp.Column):
218
+ if source_column_change_status(ref_column) is not None:
219
+ return CHANGE_CATEGORY_BREAKING
220
+
221
+ # where clauses: Reference the source columns
222
+ if new_select.args.get('where'):
223
+ where = new_select.args.get('where')
224
+ if isinstance(where, exp.Where):
225
+ for ref_column in where.find_all(exp.Column):
226
+ if source_column_change_status(ref_column) is not None:
227
+ return CHANGE_CATEGORY_BREAKING
228
+
229
+ # group by clause: Reference the source columns, column index
230
+ if new_select.args.get('group'):
231
+ group = new_select.args.get('group')
232
+ if isinstance(group, exp.Group):
233
+ for ref_column in group.find_all(exp.Column):
234
+ if source_column_change_status(ref_column) is not None:
235
+ return CHANGE_CATEGORY_BREAKING
236
+
237
+ # having clause: Reference the source columns, selected columns
238
+ if new_select.args.get('having'):
239
+ having = new_select.args.get('having')
240
+ if isinstance(having, exp.Having):
241
+ for ref_column in having.find_all(exp.Column):
242
+ if source_column_change_status(ref_column) is not None:
243
+ return CHANGE_CATEGORY_BREAKING
244
+ if selected_column_change_status(ref_column) is not None:
245
+ return CHANGE_CATEGORY_BREAKING
246
+
247
+ # order by clause: Reference the source columns, selected columns, column index
248
+ if new_select.args.get('order'):
249
+ order = new_select.args.get('order')
250
+ if isinstance(order, exp.Order):
251
+ for ref_column in order.find_all(exp.Column):
252
+ if source_column_change_status(ref_column) is not None:
253
+ return CHANGE_CATEGORY_BREAKING
254
+ if selected_column_change_status(ref_column) is not None:
255
+ return CHANGE_CATEGORY_BREAKING
256
+
257
+ result.changed_columns = changed_columns
258
+ return result
259
+
260
+
261
+ def _diff_union_scope(
262
+ old_scope: Scope,
263
+ new_scope: Scope,
264
+ scope_changes_map: dict[Scope, ChangeCategoryResult]
265
+ ) -> ChangeCategoryResult:
266
+ assert old_scope.expression.key == 'union'
267
+ assert new_scope.expression.key == 'union'
268
+ assert len(old_scope.union_scopes) == len(new_scope.union_scopes)
269
+ assert new_scope.union_scopes is not None
270
+ assert len(new_scope.union_scopes) > 0
271
+
272
+ result = scope_changes_map.get(new_scope.union_scopes[0])
273
+ if result.category in ['breaking', 'unknown']:
274
+ return result
275
+
276
+ for sub_scope in new_scope.union_scopes[1:]:
277
+ result_right = scope_changes_map.get(sub_scope)
278
+ if result_right.category in ['breaking', 'unknown']:
279
+ return result_right
280
+ if result_right.category == 'partial_breaking':
281
+ result.category = 'partial_breaking'
282
+ for column_name, column_change_status in result_right.changed_columns.items():
283
+ result.changed_columns[column_name] = column_change_status
284
+
285
+ return result
286
+
287
+
288
+ def parse_change_category(
289
+ old_sql,
290
+ new_sql,
291
+ old_schema=None,
292
+ new_schema=None,
293
+ dialect=None,
294
+ optimizer_rules=None,
295
+ ) -> ChangeCategoryResult:
296
+ if old_sql == new_sql:
297
+ return ChangeCategoryResult('non_breaking')
298
+
299
+ try:
300
+ dialect = Dialect.get(dialect)
301
+
302
+ def _parse(sql, schema):
303
+ exp = parse_one(sql, dialect=dialect)
304
+ if schema:
305
+ try:
306
+ kwargs = {}
307
+ if optimizer_rules is not None:
308
+ kwargs["rules"] = optimizer_rules
309
+ exp = optimize(exp, schema=schema, dialect=dialect, **kwargs)
310
+ except Exception as e:
311
+ # cannot optimize, skip it.
312
+ _debug(e)
313
+ pass
314
+ return exp
315
+
316
+ old_exp = _parse(old_sql, old_schema)
317
+ new_exp = _parse(new_sql, new_schema)
318
+ except Exception as e:
319
+ _debug(e)
320
+ return CHANGE_CATEGORY_UNKNOWN
321
+
322
+ old_scopes = traverse_scope(old_exp)
323
+ new_scopes = traverse_scope(new_exp)
324
+ if len(old_scopes) != len(new_scopes):
325
+ return CHANGE_CATEGORY_BREAKING
326
+
327
+ scope_changes_map = {}
328
+ for old_scope, new_scope in zip(old_scopes, new_scopes):
329
+ if old_scope.expression.key != new_scope.expression.key:
330
+ scope_changes_map[new_scope] = CHANGE_CATEGORY_BREAKING
331
+ continue
332
+ if old_scope == new_scope:
333
+ scope_changes_map[new_scope] = ChangeCategoryResult('non_breaking')
334
+ continue
335
+
336
+ scope_type = old_scope.expression.key
337
+ if scope_type == 'select':
338
+ # CTE, Subquery, Root
339
+ result = _diff_select_scope(old_scope, new_scope, scope_changes_map)
340
+ elif scope_type == 'union':
341
+ # Union
342
+ result = _diff_union_scope(old_scope, new_scope, scope_changes_map)
343
+ else:
344
+ if old_scope.expression != new_scope.expression:
345
+ result = CHANGE_CATEGORY_BREAKING
346
+ else:
347
+ result = ChangeCategoryResult('non_breaking', changed_columns={})
348
+
349
+ if result.category == 'breaking' or result.category == 'unknown':
350
+ return result
351
+
352
+ scope_changes_map[new_scope] = result
353
+ if new_scope.is_root:
354
+ return result
355
+
356
+ return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: recce-nightly
3
- Version: 0.61.0.20250409
3
+ Version: 0.61.0.20250413
4
4
  Summary: Environment diff tool for dbt
5
5
  Home-page: https://github.com/InfuseAI/recce
6
6
  Author: InfuseAI Dev Team
@@ -1,4 +1,4 @@
1
- recce/VERSION,sha256=encjeSrPrHOGjhbFoG9cocKXOSiWbVxgztGXQ6XHkac,16
1
+ recce/VERSION,sha256=ATqr7dmhW0FY6iYXPWy8hd0aqv2ZtiV8e1g0t_rKPlo,16
2
2
  recce/__init__.py,sha256=e0lFWHcmyw6LDA9ZVRJUToPe7ApnJjPTCylw4aBowto,2392
3
3
  recce/artifact.py,sha256=a7P1cXd6lglEZF2OYeNvsEg9ME-ocJo5oPU4VZVeaz0,6586
4
4
  recce/cli.py,sha256=Tsm4X-5KADwVeYuvvQzAkWIkIoWhpQvHsp9aCcp5caY,34251
@@ -23,10 +23,10 @@ recce/apis/check_api.py,sha256=S4OYx3vR5iezo1vnWpk56JUZiprAr9UgYcz-HEIsROs,6211
23
23
  recce/apis/check_func.py,sha256=onhGppZ7LDrVmipHaXZI-WaTVRFZDwb2oQhbYe0tSXY,4316
24
24
  recce/apis/run_api.py,sha256=FdNFWt7JrPbCv2CQkswbsaw5gZNGesjQBi749jbQtK0,3326
25
25
  recce/apis/run_func.py,sha256=zxxRo9_VdvSMeDbzQnBgVo5_msOmauiVF4XJTe-hvOg,7179
26
- recce/data/404.html,sha256=KgTDfRf-UBpeB26Q5kx99nIf_c3xdKLbvTPjEMVWIgA,6204
26
+ recce/data/404.html,sha256=OE0AGW769Bzysa3DFb7deke1m9hGhUwTbkKBC0y50sg,6204
27
27
  recce/data/favicon.ico,sha256=B2mBumUOnzvUrXrqNkrc5QfdDXjzEXRcWkWur0fJ6sM,2565
28
- recce/data/index.html,sha256=alfZvpz4zrZc-LxR8zhnc8DNDdvlbFOIkQIQZywDCjk,38922
29
- recce/data/index.txt,sha256=CQUJKA40ddYdwkDzfrjaRS-0V9hLkBQ2Xb_y3v87IDY,3283
28
+ recce/data/index.html,sha256=XRUgJC6fjPOmsUmc4DEOv3sVNdeg7tRxwakgzGPvPNc,38922
29
+ recce/data/index.txt,sha256=sbmpq8ybTulXmh5tNZEqWJN_4W21A1HfG8WpkJPSkTk,3283
30
30
  recce/data/_next/static/chunks/269-83bbdbcbd0cc1ddb.js,sha256=UhRJXQY7HhZP1MVqjK8tt8UzhXWNABSlzugwDiaE5mg,1256384
31
31
  recce/data/_next/static/chunks/29e3cc0d-6e3b0cf904a6874d.js,sha256=coxMNraKHS7chq4l2N3jRs77qfhaOYkEn-wjYI52ej8,700
32
32
  recce/data/_next/static/chunks/36e1c10d-800596efe83e74a6.js,sha256=rC1wLoI7fYSVwOWQwrjC5-HQes_Kvprg-KDb_o9gls4,7796
@@ -58,6 +58,8 @@ recce/data/_next/static/chunks/app/_not-found/page-76f691066176b63a.js,sha256=b4
58
58
  recce/data/_next/static/chunks/pages/_app-9f1049bbd7b90455.js,sha256=3qJYhzjjCOPEx_LpkPPeUwsHVlK_m7fXhaY8MR-H2_U,283
59
59
  recce/data/_next/static/chunks/pages/_error-71ed60313c005df1.js,sha256=_4EzYhelkRLMqFXsYponnqJ0h47TCnyzV5SYROuaORw,250
60
60
  recce/data/_next/static/css/c9ecb46a4b21c126.css,sha256=JbGypR8aDNuZavNvH6dhPtSbMVSCsy0ycPrz_6XkiVc,21925
61
+ recce/data/_next/static/hD8g5-RYxHasL_ZuMPw1A/_buildManifest.js,sha256=uZT3XnlZkFx7KBidsNMR-Gbjt_cu1ARQkVwXbzxPlIs,224
62
+ recce/data/_next/static/hD8g5-RYxHasL_ZuMPw1A/_ssgManifest.js,sha256=Z49s4suAsf5y_GfnQSvm4qtq2ggxEbZPfEDTXjy6XgA,80
61
63
  recce/data/_next/static/media/montserrat-cyrillic-800-normal.22628180.woff2,sha256=P5Sx5PNkdTlDYzAdulW_OPRfMokDLi6XTpmS8KJSRoI,11148
62
64
  recce/data/_next/static/media/montserrat-cyrillic-800-normal.31d693bb.woff,sha256=ITxULbMzWscxwUi_v3GpzTSYVWlwq_z9fpEvAkEvHJw,11020
63
65
  recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.7e2c1e62.woff,sha256=6J3PqBk_hOFVM8PpfZeSfwZQumQd6LTPPjnaVha2KQ0,12672
@@ -68,8 +70,6 @@ recce/data/_next/static/media/montserrat-latin-ext-800-normal.013b84f9.woff2,sha
68
70
  recce/data/_next/static/media/montserrat-latin-ext-800-normal.aff52ab0.woff,sha256=IaGLu1tg0bPED9SLQjsK_VdkG3_RCq82GBmSP56xNFU,41956
69
71
  recce/data/_next/static/media/montserrat-vietnamese-800-normal.5f21869b.woff,sha256=9ke3AivSl-ihV218s2s9NyJS8t0ETKDdqIK4rJWiPl0,7544
70
72
  recce/data/_next/static/media/montserrat-vietnamese-800-normal.c0035377.woff2,sha256=bnmP7vEVe-4gLSDBsmKqD-SATv6-Pg-pxnTpSj7BCeI,7948
71
- recce/data/_next/static/ynqWeF6GV-HrY-hgM_vm-/_buildManifest.js,sha256=uZT3XnlZkFx7KBidsNMR-Gbjt_cu1ARQkVwXbzxPlIs,224
72
- recce/data/_next/static/ynqWeF6GV-HrY-hgM_vm-/_ssgManifest.js,sha256=Z49s4suAsf5y_GfnQSvm4qtq2ggxEbZPfEDTXjy6XgA,80
73
73
  recce/data/imgs/feedback/thumbs-down.png,sha256=q9KVIbaZku1TWkYHuleYlO-b6HsTApYh3St5xNHMGMg,10695
74
74
  recce/data/imgs/feedback/thumbs-up.png,sha256=VF3BH8bmYEqcSsMDJO57xMqW4t6crCXUXaMlOPgI_OE,10556
75
75
  recce/data/logo/recce-logo-white.png,sha256=y3re8iEucJnMUkAkRS2CjWHTlOydyvgWdWjuQKcXDbk,46923
@@ -94,7 +94,7 @@ recce/tasks/schema.py,sha256=28mmZni0AU1bLfptt7Np3ddKhQ5XZsrtYINonQ2OQOo,2274
94
94
  recce/tasks/top_k.py,sha256=E-V2p2St2W1RXa4cQMUYagHpja5rWj_mcPLtvJ3fKfI,5522
95
95
  recce/tasks/valuediff.py,sha256=7GcSy7emPSLXjqcJomJ5aK9V8Eamo864ln-iOyNnW5A,15118
96
96
  recce/util/__init__.py,sha256=0lcJectK7Z7k9h0EaYCcv4Bgw2PN03OdJoxb3tbV5j8,37
97
- recce/util/breaking.py,sha256=GnUHuk1xm1pEKu8u8kZx4rGhy1BQvUrD8oTSNTNMOq8,2052
97
+ recce/util/breaking.py,sha256=jo3kkrzKSAcoaH_vs6Lc7hv1-QOnA8TXIAn1Kja8lyE,12489
98
98
  recce/util/cache.py,sha256=QB6wzxe0M3jNTwP0M27Ys8F2hF-oda4-LyXXG9THuZQ,646
99
99
  recce/util/cll.py,sha256=fEh13utsobam6fEqyDRXvtxUqXfqZRN-rlTxXXK7NDI,12206
100
100
  recce/util/io.py,sha256=uMBpJBKKOUPHTBgntkVkuaVUkY8grDIlA8ORCtFLE5E,3372
@@ -104,7 +104,7 @@ recce/util/pydantic_model.py,sha256=KumKuyCjbTzEMsKLE4-b-eZfp0gLhYDdmVtw1-hxiJw,
104
104
  recce/util/recce_cloud.py,sha256=pR0TrtK3s617vmHn-19pvA4jpRZz0k5YUuGlpFYoarE,7094
105
105
  recce/util/singleton.py,sha256=l2Q31ulDNCMJCuzUIGNXuvniHdGg6EMg80mrW48-97w,643
106
106
  recce/yaml/__init__.py,sha256=489WHH9pAPf68gx04qifA0AmexIopJona3EPWxGxa-Y,1296
107
- recce_nightly-0.61.0.20250409.dist-info/licenses/LICENSE,sha256=CQjjMy9aYPhfe8xG_bcpIfKtNkdxLZ5IOb8oPygtUhY,11343
107
+ recce_nightly-0.61.0.20250413.dist-info/licenses/LICENSE,sha256=CQjjMy9aYPhfe8xG_bcpIfKtNkdxLZ5IOb8oPygtUhY,11343
108
108
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
109
  tests/test_cli.py,sha256=tEQJVT8TbrAOPkIqkVJR6e2k-4dGJZMQVdsYC4DSQAE,5613
110
110
  tests/test_config.py,sha256=FM55tG0Yaqu8x9l6EiJtFJDUu6F2n96vW4_xbX3O7DY,1579
@@ -132,8 +132,8 @@ tests/tasks/test_row_count.py,sha256=hjrKP1u2aZ9V0EWb0WGXDz4-V2kYaiNeiJ_Mqin8BPg
132
132
  tests/tasks/test_schema.py,sha256=02guW2UXwUW3Ts8x27KjdL6V9fVatGlx8XFEEcVq3bU,2810
133
133
  tests/tasks/test_top_k.py,sha256=hqYWSd9xE1GU0wgvpgKeLHbPVd5CABYcTJvgA49JRyA,1707
134
134
  tests/tasks/test_valuediff.py,sha256=_z1Ci4ba4lFSWwbj7cbKBRtWqLgV_1HIZGqQlEFl61o,1863
135
- recce_nightly-0.61.0.20250409.dist-info/METADATA,sha256=skwtIL4fiIHuGx4wDmcstCzBybzz60H9Pu_Yvc2McEU,13240
136
- recce_nightly-0.61.0.20250409.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
137
- recce_nightly-0.61.0.20250409.dist-info/entry_points.txt,sha256=oqoY_IiwIqXbgrIsPnlqUqao2eiIeP2dprowkOlmeyg,40
138
- recce_nightly-0.61.0.20250409.dist-info/top_level.txt,sha256=6PKGVpf75idP0C6KEaldDzzZUauIxNu1ZDstau1pI4I,12
139
- recce_nightly-0.61.0.20250409.dist-info/RECORD,,
135
+ recce_nightly-0.61.0.20250413.dist-info/METADATA,sha256=hid5zh-TqJnT2_nk4it9w6_Scb3taedtfkd_grA4dYw,13240
136
+ recce_nightly-0.61.0.20250413.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
137
+ recce_nightly-0.61.0.20250413.dist-info/entry_points.txt,sha256=oqoY_IiwIqXbgrIsPnlqUqao2eiIeP2dprowkOlmeyg,40
138
+ recce_nightly-0.61.0.20250413.dist-info/top_level.txt,sha256=6PKGVpf75idP0C6KEaldDzzZUauIxNu1ZDstau1pI4I,12
139
+ recce_nightly-0.61.0.20250413.dist-info/RECORD,,