PageSourceSearch

https://www.openpolicyagent.org/assets/js/44dbb084.9fd5f2a8.js

js openpolicyagent.org collected 2026-09-24 08:29:53 UTC 5,513 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkopa_website=self.webpackChunkopa_website||[]).push([[18943],{28453:(e,n,o)=>{o.d(n,{R:()=>l,x:()=>i});var r=o(96540);const t={},s=r.createContext(t);function l(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),r.createElement(s.Provider,{value:n},e.children)}},59758:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>l,metadata:()=>r,toc:()=>a});const r=JSON.parse('{"id":"rules/bugs/redundant-loop-count","title":"redundant-loop-count","description":"Summary: Redundant count before loop","source":"@site/projects/regal/rules/bugs/redundant-loop-count.md","sourceDirName":"rules/bugs","slug":"/rules/bugs/redundant-loop-count","permalink":"/projects/regal/rules/bugs/redundant-loop-count","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"autoSidebar","previous":{"title":"redundant-existence-check","permalink":"/projects/regal/rules/bugs/redundant-existence-check"},"next":{"title":"rule-assigns-default","permalink":"/projects/regal/rules/bugs/rule-assigns-default"}}');var t=o(74848),s=o(28453);const l={},i="redundant-loop-count",c={},a=[{value:"Rationale",id:"rationale",level:2},{value:"Exceptions",id:"exceptions",level:2},{value:"<code>every</code> iteration",id:"every-iteration",level:3},{value:"Configuration Options",id:"configuration-options",level:2},{value:"Related Resources",id:"related-resources",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"redundant-loop-count",children:"redundant-loop-count"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Summary"}),": Redundant count before loop"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Category"}),": Bugs"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Avoid"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rego",children:"package policy\n\nallow if {\n    # redundant count and > comparison\n    count(input.user.roles) > 0\n    some role in input.user.roles\n    # .. do more with role ..\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Prefer"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rego",children:"package policy\n\nallow if {\n    some role in input.user.roles\n    # .. do more with role ..\n}\n"})}),"\n",(0,t.jsx)(n.h2,{id:"rationale",children:"Rationale"}),"\n",(0,t.jsx)(n.p,{children:"A loop that iterates over an empty collection evaluates to nothing, and counting the collection before the loop to\nensure it's not empty is therefore redundant."}),"\n",(0,t.jsx)(n.h2,{id:"exceptions",children:"Exceptions"}),"\n",(0,t.jsxs)(n.p,{children:["Note that this check is currently only performed on ",(0,t.jsx)(n.code,{children:"some"}),' loops, and not "ref-style" loops:']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rego",children:"package policy\n\nallow if {\n    # this won't be flagged\n    count(input.user.roles) > 0\n    role := input.user.roles[_]\n    # .. do more with role ..\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Another good reason to\n",(0,t.jsx)(n.a,{href:"https://www.openpolicyagent.org/projects/regal/rules/style/prefer-some-in-iteration",children:"prefer some .. in for iteration"}),"!"]}),"\n",(0,t.jsxs)(n.h3,{id:"every-iteration",children:[(0,t.jsx)(n.code,{children:"every"})," iteration"]}),"\n",(0,t.jsxs)(n.p,{children:["Counting to ensure a non-empty collection is used before ",(0,t.jsx)(n.code,{children:"every"})," loops may ",(0,t.jsx)(n.strong,{children:"not"})," be redundant, as ",(0,t.jsx)(n.code,{children:"every"})," evaluates\nto ",(0,t.jsx)(n.code,{children:"true"})," when an empty collection is passed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rego",children:"package policy\n\nallow if {\n    # every would otherwise be `true` on empty input.user.roles\n    # so this may be valid, depending on the outcome you expect\n    count(input.user.roles) > 0\n    every role in input.user.roles {\n        # .. do more with each role ..\n    }\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you want to have empty collections fail on ",(0,t.jsx)(n.code,{children:"every"})," conditions, do make sure to use ",(0,t.jsx)(n.code,{children:"count"}),"!"]}),"\n",(0,t.jsx)(n.h2,{id:"configuration-options",children:"Configuration Options"}),"\n",(0,t.jsx)(n.p,{children:"This linter rule provides the following configuration options:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'rules:\n  bugs:\n    redundant-loop-count:\n      # one of "error", "warning", "ignore"\n      level: error\n'})}),"\n",(0,t.jsx)(n.h2,{id:"related-resources",children:"Related Resources"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["GitHub: ",(0,t.jsx)(n.a,{href:"https://github.com/open-policy-agent/regal/blob/main/bundle/regal/rules/bugs/redundant-loop-count/redundant_loop_count.rego",children:"Source Code"})]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.