Skip to content

Commit f1d5725

Browse files
feat(biome_graphql_analyze): implement useConsistentGraphqlDescriptions (#7672)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent b785a21 commit f1d5725

File tree

19 files changed

+585
-27
lines changed

19 files changed

+585
-27
lines changed

.changeset/chubby-bottles-lick.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
"@biomejs/biome": patch
3+
---
4+
5+
Added the nursery rule [`useConsistentGraphqlDescriptions`](https://biomejs.dev/linter/rules/use-consistent-graphql-descriptions/), requiring all descriptions to follow the same style (either block or inline) inside GraphQL files.
6+
7+
**Invalid:**
8+
9+
```graphql
10+
enum EnumValue {
11+
"this is a description"
12+
DEFAULT
13+
}
14+
```
15+
16+
**Valid:**
17+
18+
```graphql
19+
enum EnumValue {
20+
"""
21+
this is a description
22+
"""
23+
DEFAULT
24+
}
25+
```

crates/biome_configuration/src/analyzer/linter/rules.rs

Lines changed: 40 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/biome_diagnostics_categories/src/categories.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ define_categories! {
197197
"lint/nursery/useBiomeSuppressionComment": "https://biomejs.dev/linter/rules/use-biome-suppression-comment",
198198
"lint/nursery/useConsistentArrowReturn": "https://biomejs.dev/linter/rules/use-consistent-arrow-return",
199199
"lint/nursery/useConsistentObjectDefinition": "https://biomejs.dev/linter/rules/use-consistent-object-definition",
200+
"lint/nursery/useConsistentGraphqlDescriptions": "https://biomejs.dev/linter/rules/use-consistent-graphql-descriptions",
200201
"lint/nursery/useDeprecatedDate": "https://biomejs.dev/linter/rules/use-deprecated-date",
201202
"lint/nursery/useExhaustiveSwitchCases": "https://biomejs.dev/linter/rules/use-exhaustive-switch-cases",
202203
"lint/nursery/useExplicitFunctionReturnType": "https://biomejs.dev/linter/rules/use-explicit-type",

crates/biome_graphql_analyze/src/lint/nursery.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
55
use biome_analyze::declare_lint_group;
66
pub mod no_empty_source;
7+
pub mod use_consistent_graphql_descriptions;
78
pub mod use_deprecated_date;
8-
declare_lint_group! { pub Nursery { name : "nursery" , rules : [self :: no_empty_source :: NoEmptySource , self :: use_deprecated_date :: UseDeprecatedDate ,] } }
9+
declare_lint_group! { pub Nursery { name : "nursery" , rules : [self :: no_empty_source :: NoEmptySource , self :: use_consistent_graphql_descriptions :: UseConsistentGraphqlDescriptions , self :: use_deprecated_date :: UseDeprecatedDate ,] } }
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
use biome_analyze::{
2+
Ast, Rule, RuleDiagnostic, RuleSource, context::RuleContext, declare_lint_rule,
3+
};
4+
use biome_console::markup;
5+
use biome_graphql_syntax::GraphqlDescription;
6+
use biome_rowan::AstNode;
7+
use biome_rule_options::use_consistent_graphql_descriptions::{
8+
Style, UseConsistentGraphqlDescriptionsOptions,
9+
};
10+
11+
declare_lint_rule! {
12+
/// Require all descriptions to follow the same style (either block or inline) to maintain consistency and improve readability across the schema.
13+
///
14+
/// ## Examples
15+
///
16+
/// ### style: `block`
17+
///
18+
/// #### Invalid
19+
///
20+
/// ```graphql,expect_diagnostic
21+
/// enum EnumValue {
22+
/// "this is a description"
23+
/// DEFAULT
24+
/// }
25+
/// ```
26+
///
27+
/// #### Valid
28+
///
29+
/// ```graphql
30+
/// enum EnumValue {
31+
/// """
32+
/// this is a description
33+
/// """
34+
/// DEFAULT
35+
/// }
36+
/// ```
37+
///
38+
/// ## Options
39+
///
40+
/// ### `style`
41+
///
42+
/// This option will specify the description style.
43+
/// - `"block"`: Requires triple-quoted block descriptions (`"""..."""`)
44+
/// - `"inline"`: Requires single-quoted inline descriptions (`"..."`)
45+
///
46+
/// Default `"block"`
47+
///
48+
/// ```json,options
49+
/// {
50+
/// "options": {
51+
/// "style": "inline"
52+
/// }
53+
/// }
54+
/// ```
55+
///
56+
/// ```graphql,expect_diagnostic,use_options
57+
/// enum EnumValue {
58+
/// """
59+
/// this is a description
60+
/// """
61+
/// DEFAULT
62+
/// }
63+
/// ```
64+
///
65+
pub UseConsistentGraphqlDescriptions {
66+
version: "next",
67+
name: "useConsistentGraphqlDescriptions",
68+
language: "graphql",
69+
sources: &[RuleSource::EslintGraphql("description-style").same()],
70+
recommended: false,
71+
}
72+
}
73+
74+
impl Rule for UseConsistentGraphqlDescriptions {
75+
type Query = Ast<GraphqlDescription>;
76+
type State = ();
77+
type Signals = Option<Self::State>;
78+
type Options = UseConsistentGraphqlDescriptionsOptions;
79+
80+
fn run(ctx: &RuleContext<Self>) -> Option<Self::State> {
81+
let node = ctx.query();
82+
let style = ctx.options().style.unwrap_or_default();
83+
84+
let value = node.graphql_string_value().ok()?;
85+
86+
if style == Style::Block && !value.is_block() {
87+
return Some(());
88+
}
89+
90+
if style == Style::Inline && value.is_block() {
91+
return Some(());
92+
}
93+
94+
None
95+
}
96+
97+
fn diagnostic(ctx: &RuleContext<Self>, _state: &Self::State) -> Option<RuleDiagnostic> {
98+
let span = ctx.query().range();
99+
let style = ctx.options().style.unwrap_or_default();
100+
101+
Some(
102+
RuleDiagnostic::new(
103+
rule_category!(),
104+
span,
105+
markup! {
106+
"Unexpected "{if style == Style::Block { Style::Inline } else { Style::Block }}" description style."
107+
},
108+
)
109+
.note(markup! {
110+
"To stay consistent within the project, write the description "{style}" style."
111+
}),
112+
)
113+
}
114+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
enum EnumValue {
2+
"basic"
3+
BASIC
4+
"fluent"
5+
FLUENT
6+
"native"
7+
NATIVE
8+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
source: crates/biome_graphql_analyze/tests/spec_tests.rs
3+
expression: invalid.graphql
4+
---
5+
# Input
6+
```graphql
7+
enum EnumValue {
8+
"basic"
9+
BASIC
10+
"fluent"
11+
FLUENT
12+
"native"
13+
NATIVE
14+
}
15+
16+
```
17+
18+
# Diagnostics
19+
```
20+
invalid.graphql:2:2 lint/nursery/useConsistentGraphqlDescriptions ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
21+
22+
i Unexpected inline description style.
23+
24+
1 │ enum EnumValue {
25+
> 2"basic"
26+
^^^^^^^
27+
3BASIC
28+
4"fluent"
29+
30+
i To stay consistent within the project, write the description block style.
31+
32+
33+
```
34+
35+
```
36+
invalid.graphql:4:2 lint/nursery/useConsistentGraphqlDescriptions ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
37+
38+
i Unexpected inline description style.
39+
40+
2"basic"
41+
3BASIC
42+
> 4"fluent"
43+
^^^^^^^^
44+
5FLUENT
45+
6"native"
46+
47+
i To stay consistent within the project, write the description block style.
48+
49+
50+
```
51+
52+
```
53+
invalid.graphql:6:2 lint/nursery/useConsistentGraphqlDescriptions ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
54+
55+
i Unexpected inline description style.
56+
57+
4"fluent"
58+
5FLUENT
59+
> 6"native"
60+
^^^^^^^^
61+
7NATIVE
62+
8}
63+
64+
i To stay consistent within the project, write the description block style.
65+
66+
67+
```
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# should not generate diagnostics
2+
enum EnumValue {
3+
"""
4+
basic
5+
"""
6+
BASIC
7+
"""
8+
fluent
9+
"""
10+
FLUENT
11+
"""
12+
native
13+
"""
14+
NATIVE
15+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
source: crates/biome_graphql_analyze/tests/spec_tests.rs
3+
expression: valid.graphql
4+
---
5+
# Input
6+
```graphql
7+
# should not generate diagnostics
8+
enum EnumValue {
9+
"""
10+
basic
11+
"""
12+
BASIC
13+
"""
14+
fluent
15+
"""
16+
FLUENT
17+
"""
18+
native
19+
"""
20+
NATIVE
21+
}
22+
23+
```
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
enum EnumValue {
2+
"""
3+
basic
4+
"""
5+
BASIC
6+
"""
7+
fluent
8+
"""
9+
FLUENT
10+
"""
11+
native
12+
"""
13+
NATIVE
14+
}

0 commit comments

Comments
 (0)