diff --git a/docs/docs/infrahubctl/infrahubctl-graphql.mdx b/docs/docs/infrahubctl/infrahubctl-graphql.mdx index e97d5216..143fc027 100644 --- a/docs/docs/infrahubctl/infrahubctl-graphql.mdx +++ b/docs/docs/infrahubctl/infrahubctl-graphql.mdx @@ -16,13 +16,21 @@ $ infrahubctl graphql [OPTIONS] COMMAND [ARGS]... **Commands**: -* `query-report`: Run a GraphQL query through... +* `query-report`: Report how Infrahub will interpret a... * `export-schema`: Export the GraphQL schema to a file. * `generate-return-types`: Create Pydantic Models for GraphQL query... ## `infrahubctl graphql query-report` -Run a GraphQL query through InfrahubGraphQLQueryReport and report its analysis. +Report how Infrahub will interpret a GraphQL query. + +Reports whether the query targets unique nodes, meaning every query it contains returns a +single object. Artifact and generator definitions use this to decide how much to regenerate +when data changes: when it is true, only the artifacts or generator instances of the objects +that changed are regenerated, and when it is false, all of them are. + +A query returns a single object when it filters on ids or hfid, or on every part of one +uniqueness constraint of the model, and the values it filters on are always provided. **Usage**: @@ -32,12 +40,12 @@ $ infrahubctl graphql query-report [OPTIONS] NAME **Arguments**: -* `NAME`: Name of the GraphQL query to analyze. [required] +* `NAME`: Name of the GraphQL query to analyze, as declared under queries in .infrahub.yml. [required] **Options**: * `--online`: Fetch the query from the Infrahub server (CoreGraphQLQuery by name) instead of reading it from the local .infrahub.yml file. -* `--branch TEXT`: Branch on which to run the report. +* `--branch TEXT`: Branch on which to run the report. Uniqueness constraints come from the schema, so the result can differ between branches. * `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml] * `--help`: Show this message and exit. diff --git a/infrahub_sdk/ctl/graphql.py b/infrahub_sdk/ctl/graphql.py index 37d55137..c46a893e 100644 --- a/infrahub_sdk/ctl/graphql.py +++ b/infrahub_sdk/ctl/graphql.py @@ -112,7 +112,9 @@ def callback() -> None: @app.command(name="query-report") @catch_exception(console=console) async def query_report( - name: str = typer.Argument(..., help="Name of the GraphQL query to analyze."), + name: str = typer.Argument( + ..., help="Name of the GraphQL query to analyze, as declared under queries in .infrahub.yml." + ), online: bool = typer.Option( False, "--online", @@ -121,10 +123,25 @@ async def query_report( "instead of reading it from the local .infrahub.yml file." ), ), - branch: str | None = typer.Option(None, help="Branch on which to run the report."), + branch: str | None = typer.Option( + None, + help=( + "Branch on which to run the report. Uniqueness constraints come from the schema, " + "so the result can differ between branches." + ), + ), _: str = CONFIG_PARAM, ) -> None: - """Run a GraphQL query through InfrahubGraphQLQueryReport and report its analysis.""" + """Report how Infrahub will interpret a GraphQL query. + + Reports whether the query targets unique nodes, meaning every query it contains returns a + single object. Artifact and generator definitions use this to decide how much to regenerate + when data changes: when it is true, only the artifacts or generator instances of the objects + that changed are regenerated, and when it is false, all of them are. + + A query returns a single object when it filters on ids or hfid, or on every part of one + uniqueness constraint of the model, and the values it filters on are always provided. + """ client = initialize_client(branch=branch) if online: diff --git a/pyproject.toml b/pyproject.toml index b8941b9a..f6fc3987 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -163,7 +163,7 @@ invalid-assignment = "ignore" # 1 violation in importer/json.py include = ["infrahub_sdk/node/node.py"] [tool.ty.overrides.rules] -invalid-argument-type = "ignore" # 9 violations - lines 776, 855, 859, 862 +invalid-argument-type = "ignore" # 8 violations [[tool.ty.overrides]] @@ -183,7 +183,6 @@ unused-ignore-comment = "ignore" # Clashes with mypy's type ignore comments include = ["tests/fixtures/**"] [tool.ty.overrides.rules] -invalid-argument-type = "ignore" # Test fixtures - dynamic mock data possibly-missing-attribute = "ignore" # Test fixtures use dynamic attributes # Test-specific overrides - tests have more lenient type checking @@ -231,9 +230,8 @@ include = [ ] [tool.ty.overrides.rules] -invalid-argument-type = "ignore" # 29 violations +invalid-argument-type = "ignore" # 25 violations invalid-assignment = "ignore" -no-matching-overload = "ignore" possibly-missing-attribute = "ignore" [[tool.ty.overrides]] @@ -276,7 +274,7 @@ disable_error_code = ["call-overload"] [[tool.mypy.overrides]] module = "infrahub_sdk.utils" -disable_error_code = ["arg-type", "attr-defined", "return-value", "union-attr"] +disable_error_code = ["attr-defined", "return-value", "union-attr"] [[tool.mypy.overrides]] # ``main.py`` intentionally narrows the ``attributes``/``relationships``/``choices`` fields inherited @@ -290,7 +288,7 @@ disable_error_code = ["assignment"] # The generated read models expose ``kind`` via ``@computed_field`` stacked on ``@property``. mypy # does not support decorators on top of ``@property`` and flags it, but pydantic requires this order. module = "infrahub_sdk.schema.generated.read" -disable_error_code = ["misc"] +disable_error_code = ["prop-decorator"] [tool.ruff] line-length = 120