diff --git a/README.md b/README.md
index 09038a7a..62332634 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[](https://nokycucwgzweensacwfy.supabase.co/functions/v1/get_project_url?projectId=211)
-Flutter/Dart lints configuration based on software engineering industry standards (ISO/IEC, NIST) and best practices.
+Flutter/Dart lints configuration based on software engineering industry standards (ISO/IEC, NIST) and best practices, developed and maintained by [Solid Software](https://solid.software).
# Documentation
@@ -66,3 +66,24 @@ To indicate that your project is using Solid Lints, you can use the following ba
```markdown
[](https://pub.dev/packages/solid_lints)
```
+
+---
+
+## Maintained by Solid Software
+
+Developed and maintained by **[Solid Software](https://solid.software)** – a top Flutter agency and official Flutter consultants focused on best engineering practices.
+
+### Why Solid Software?
+
+- **Creators of [Solid Lints](https://lints.solid.software)** – Flutter and Dart lint rules based on software industry standards (ISO/IEC, NIST).
+- **Guardrails for AI Development** – Solid Lints keeps AI-assisted Flutter and Dart code clean, consistent, and strictly compliant with engineering standards.
+- **Full-Cycle Engineering** – from architecture and development to launch, scaling, and long-term support.
+
+
+
+
+ **Planning to launch a startup with Flutter?**
+
+ [🚀 Hire our Flutter team](https://solid.software/#solid-footer) • [Explore our open-source tools](https://pub.dev/publishers/solid.software/packages)
+
+
diff --git a/doc/docusaurus/docs/1_rulesets/main.md b/doc/docusaurus/docs/1_rulesets/main.md
index 0a3d8cf5..df60c8ac 100644
--- a/doc/docusaurus/docs/1_rulesets/main.md
+++ b/doc/docusaurus/docs/1_rulesets/main.md
@@ -1,4 +1,12 @@
---
+title: Main Rule Set
+description: 'Pre-configured Dart and Flutter lint rules for static analysis of application code based on NIST and Code Complete standards.'
+keywords:
+ - main ruleset
+ - solid_lints
+ - dart analysis
+ - flutter lint rules
+ - static analysis
sidebar_label: Main
sidebar_position: 1
---
diff --git a/doc/docusaurus/docs/1_rulesets/test.md b/doc/docusaurus/docs/1_rulesets/test.md
index 8120df3e..df2fe99a 100644
--- a/doc/docusaurus/docs/1_rulesets/test.md
+++ b/doc/docusaurus/docs/1_rulesets/test.md
@@ -1,4 +1,12 @@
---
+title: Test Rule Set
+description: 'Pre-configured Dart and Flutter lint rules tailored specifically for unit and automated test suites.'
+keywords:
+ - test ruleset
+ - solid_lints
+ - dart test linter
+ - flutter test rules
+ - unit testing
sidebar_label: Test
sidebar_position: 2
---
diff --git a/doc/docusaurus/docs/3_other_notable_packages.md b/doc/docusaurus/docs/3_other_notable_packages.md
index db0a8b94..51f10519 100644
--- a/doc/docusaurus/docs/3_other_notable_packages.md
+++ b/doc/docusaurus/docs/3_other_notable_packages.md
@@ -1,4 +1,12 @@
---
+title: Other Notable Packages
+description: 'Recommended Dart and Flutter packages that complement solid_lints for dead code detection, cognitive complexity, and architectural quality.'
+keywords:
+ - dart packages
+ - undead
+ - cognitive_complexity
+ - code quality
+ - solid_lints
sidebar_label: Other notable packages
sidebar_position: 3
---
diff --git a/doc/docusaurus/docusaurus.config.js b/doc/docusaurus/docusaurus.config.js
index 3a913ee4..081c6266 100644
--- a/doc/docusaurus/docusaurus.config.js
+++ b/doc/docusaurus/docusaurus.config.js
@@ -7,7 +7,9 @@ const darkCodeTheme = themes.oneDark;
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'solid_lints',
- tagline: 'An opinionated set of lint rules based on industry standards.',
+ tagline:
+ 'An opinionated set of lint rules based on industry standards, ' +
+ 'maintained by Solid Software, a top Flutter agency.',
url: 'https://lints.solid.software',
baseUrl: '/',
onBrokenLinks: 'throw',
@@ -18,6 +20,46 @@ const config = {
deploymentBranch: 'web-docs-deployment',
trailingSlash: false,
staticDirectories: ['static'],
+ i18n: {
+ defaultLocale: 'en',
+ locales: ['en'],
+ },
+ headTags: [
+ {
+ tagName: 'script',
+ attributes: {
+ type: 'application/ld+json',
+ },
+ innerHTML: JSON.stringify({
+ '@context': 'https://schema.org',
+ '@type': 'SoftwareApplication',
+ name: 'solid_lints',
+ url: 'https://lints.solid.software',
+ description:
+ 'Dart and Flutter lint rules based on software industry ' +
+ 'standards, maintained by Solid Software, a top Flutter agency.',
+ applicationCategory: 'DeveloperApplication',
+ operatingSystem: 'Windows, macOS, Linux',
+ license:
+ 'https://github.com/solid-software/solid_lints/blob/master/LICENSE',
+ codeRepository: 'https://github.com/solid-software/solid_lints',
+ sameAs: [
+ 'https://github.com/solid-software/solid_lints',
+ 'https://pub.dev/packages/solid_lints',
+ ],
+ offers: {
+ '@type': 'Offer',
+ price: '0',
+ priceCurrency: 'USD',
+ },
+ author: {
+ '@type': 'Organization',
+ name: 'Solid Software',
+ url: 'https://solid.software',
+ },
+ }),
+ },
+ ],
plugins: [
[
require.resolve("@easyops-cn/docusaurus-search-local"),
@@ -50,6 +92,23 @@ const config = {
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
+ metadata: [
+ {
+ name: 'keywords',
+ content:
+ 'solid lints, dart linter, flutter lint rules, static analysis, ' +
+ 'code quality, AI code quality, AI guardrails, solid software, ' +
+ 'top flutter agency, flutter consultants',
+ },
+ {name: 'author', content: 'Solid Software'},
+ {property: 'og:type', content: 'website'},
+ {
+ property: 'og:description',
+ content:
+ 'Dart and Flutter lint rules based on software industry ' +
+ 'standards, maintained by Solid Software, a top Flutter agency.',
+ },
+ ],
tableOfContents: {
minHeadingLevel: 2,
maxHeadingLevel: 6,
@@ -67,6 +126,11 @@ const config = {
position: 'left',
label: 'Docs',
},
+ {
+ href: 'https://solid.software',
+ label: 'Solid Software',
+ position: 'right',
+ },
{
href: 'https://github.com/solid-software/solid_lints',
label: 'GitHub',
@@ -81,6 +145,14 @@ const config = {
label: 'Docs',
to: '/docs/intro',
},
+ {
+ label: 'Solid Software',
+ href: 'https://solid.software',
+ },
+ {
+ label: 'pub.dev',
+ href: 'https://pub.dev/packages/solid_lints',
+ },
{
label: 'GitHub',
href: 'https://github.com/solid-software/solid_lints',
diff --git a/doc/docusaurus/package.json b/doc/docusaurus/package.json
index 81f2d586..d56ccf5e 100644
--- a/doc/docusaurus/package.json
+++ b/doc/docusaurus/package.json
@@ -1,7 +1,7 @@
{
"name": "docusaurus",
"version": "0.0.0",
- "homepage": "https://solid-software.github.io/solid_lints/",
+ "homepage": "https://lints.solid.software",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
diff --git a/doc/docusaurus/src/pages/index.tsx b/doc/docusaurus/src/pages/index.tsx
index 15c846ab..da59d406 100644
--- a/doc/docusaurus/src/pages/index.tsx
+++ b/doc/docusaurus/src/pages/index.tsx
@@ -25,7 +25,11 @@ export default function Home(): JSX.Element {
return (
+ description={
+ 'Dart and Flutter lint rules based on software industry ' +
+ 'standards, developed and maintained by Solid Software, ' +
+ 'a top Flutter agency.'
+ }>
{() => }
diff --git a/doc/docusaurus/static/llms.txt b/doc/docusaurus/static/llms.txt
new file mode 100644
index 00000000..af5d35ec
--- /dev/null
+++ b/doc/docusaurus/static/llms.txt
@@ -0,0 +1,71 @@
+# solid_lints
+
+> An opinionated set of lint rules and metrics for Dart and Flutter based on software engineering industry standards and best practices, developed and maintained by [Solid Software](https://solid.software), a top Flutter agency.
+
+Quickstart setup:
+
+Add `solid_lints` to `pubspec.yaml`:
+```bash
+dart pub add dev:solid_lints
+```
+
+Or manually in `pubspec.yaml`:
+```yaml
+dev_dependencies:
+ solid_lints: ^1.0.0 # Replace with latest version
+```
+
+Enable the plugin in `analysis_options.yaml`:
+```yaml
+include: package:solid_lints/analysis_options.yaml
+
+plugins:
+ solid_lints: ^1.0.0 # Replace with latest version
+```
+
+## Documentation
+- [Introduction](https://lints.solid.software/docs/intro): Setup guide, installation, and configuration overview
+- [Main Ruleset](https://lints.solid.software/docs/rulesets/main): Standard analysis ruleset for production application code
+- [Test Ruleset](https://lints.solid.software/docs/rulesets/test): Specialized ruleset tailored for unit and widget test files
+- [Other Notable Packages](https://lints.solid.software/docs/other_notable_packages): Complementary packages for dead code analysis, cognitive complexity, and duplicate detection
+
+## Custom Lint Rules
+- [avoid_debug_print_in_release](https://lints.solid.software/docs/custom_lints/avoid_debug_print_in_release): Forbids calling debugPrint in production code
+- [avoid_duplicate_code](https://lints.solid.software/docs/custom_lints/avoid_duplicate_code): Detects and prevents duplicate code fragments and patterns
+- [avoid_final_with_getter](https://lints.solid.software/docs/custom_lints/avoid_final_with_getter): Forbids redundant private final fields with public getters
+- [avoid_global_state](https://lints.solid.software/docs/custom_lints/avoid_global_state): Avoids mutable top-level and static variables
+- [avoid_late_keyword](https://lints.solid.software/docs/custom_lints/avoid_late_keyword): Forbids the late keyword to prevent LateInitializationError
+- [avoid_non_null_assertion](https://lints.solid.software/docs/custom_lints/avoid_non_null_assertion): Discourages the bang (!) operator in favor of proper null handling
+- [avoid_returning_widgets](https://lints.solid.software/docs/custom_lints/avoid_returning_widgets): Encourages dedicated Widget classes over widget-returning helper methods
+- [avoid_similar_names](https://lints.solid.software/docs/custom_lints/avoid_similar_names): Warns when identifiers in the same scope have confusingly similar names
+- [avoid_unnecessary_return_variable](https://lints.solid.software/docs/custom_lints/avoid_unnecessary_return_variable): Prevents intermediate variables immediately returned
+- [avoid_unnecessary_setstate](https://lints.solid.software/docs/custom_lints/avoid_unnecessary_setstate): Warns against synchronous setState calls in lifecycle hooks or build
+- [avoid_unnecessary_type_assertions](https://lints.solid.software/docs/custom_lints/avoid_unnecessary_type_assertions): Flags redundant is checks and whereType calls
+- [avoid_unrelated_type_assertions](https://lints.solid.software/docs/custom_lints/avoid_unrelated_type_assertions): Warns about unrelated is type checks whose result is always constant
+- [avoid_unused_parameters](https://lints.solid.software/docs/custom_lints/avoid_unused_parameters): Detects unused parameters in functions, constructors, and methods
+- [avoid_using_api](https://lints.solid.software/docs/custom_lints/avoid_using_api): Configurable rule to restrict deprecated or discouraged classes and APIs
+- [cyclomatic_complexity](https://lints.solid.software/docs/custom_lints/cyclomatic_complexity): Calculates and limits cyclomatic complexity of functions and methods
+- [double_literal_format](https://lints.solid.software/docs/custom_lints/double_literal_format): Enforces consistent formatting of floating-point number literals
+- [feature_envy](https://lints.solid.software/docs/custom_lints/feature_envy): Warns when a method accesses external class members more than its own
+- [function_lines_of_code](https://lints.solid.software/docs/custom_lints/function_lines_of_code): Monitors and limits source lines of code per function body
+- [member_ordering](https://lints.solid.software/docs/custom_lints/member_ordering): Enforces configurable ordering conventions for class members
+- [named_parameters_ordering](https://lints.solid.software/docs/custom_lints/named_parameters_ordering): Enforces specific ordering conventions for named parameters
+- [newline_before_return](https://lints.solid.software/docs/custom_lints/newline_before_return): Requires an empty line preceding return statements in code blocks
+- [no_empty_block](https://lints.solid.software/docs/custom_lints/no_empty_block): Disallows empty code blocks unless explicitly commented or catch handlers
+- [no_equal_then_else](https://lints.solid.software/docs/custom_lints/no_equal_then_else): Warns when if-else branches contain identical execution bodies
+- [no_magic_number](https://lints.solid.software/docs/custom_lints/no_magic_number): Forbids unexplained raw numeric literals outside named constants
+- [number_of_parameters](https://lints.solid.software/docs/custom_lints/number_of_parameters): Limits maximum allowed number of parameters per function or constructor
+- [prefer_conditional_expressions](https://lints.solid.software/docs/custom_lints/prefer_conditional_expressions): Recommends ternary operators instead of verbose if-else assignment blocks
+- [prefer_early_return](https://lints.solid.software/docs/custom_lints/prefer_early_return): Encourages guard clauses and early returns to reduce nesting
+- [prefer_first](https://lints.solid.software/docs/custom_lints/prefer_first): Suggests using iterable.first instead of [0] or elementAt(0)
+- [prefer_last](https://lints.solid.software/docs/custom_lints/prefer_last): Suggests using iterable.last instead of index-by-length
+- [prefer_match_file_name](https://lints.solid.software/docs/custom_lints/prefer_match_file_name): Checks that the file name matches the primary declared class or element
+- [proper_super_calls](https://lints.solid.software/docs/custom_lints/proper_super_calls): Ensures correct super invocation order in initState and dispose methods
+- [use_descriptive_names_for_type_parameters](https://lints.solid.software/docs/custom_lints/use_descriptive_names_for_type_parameters): Requires clear generic type parameter names when three or more are present
+- [use_nearest_context](https://lints.solid.software/docs/custom_lints/use_nearest_context): Ensures BuildContext is retrieved from the nearest available widget scope
+
+## Optional
+- [undead](https://pub.dev/packages/undead): Deterministic reachability and dead code analysis for Dart and Flutter
+- [cognitive_complexity](https://pub.dev/packages/cognitive_complexity): Cognitive complexity calculation and data-flow analysis tools
+- [ciach](https://pub.dev/packages/ciach): Architecture and module boundary enforcement for layered Flutter projects
+- [dedupe](https://pub.dev/packages/dedupe): CLI tool and algorithms for detecting duplicate Dart code blocks
diff --git a/doc/docusaurus/static/robots.txt b/doc/docusaurus/static/robots.txt
new file mode 100644
index 00000000..127dea07
--- /dev/null
+++ b/doc/docusaurus/static/robots.txt
@@ -0,0 +1,4 @@
+User-agent: *
+Allow: /
+
+Sitemap: https://lints.solid.software/sitemap.xml
diff --git a/lib/src/lints/avoid_late_keyword/avoid_late_keyword_rule.dart b/lib/src/lints/avoid_late_keyword/avoid_late_keyword_rule.dart
index 04522c54..05afd588 100644
--- a/lib/src/lints/avoid_late_keyword/avoid_late_keyword_rule.dart
+++ b/lib/src/lints/avoid_late_keyword/avoid_late_keyword_rule.dart
@@ -5,8 +5,6 @@ import 'package:solid_lints/src/lints/avoid_late_keyword/models/avoid_late_keywo
import 'package:solid_lints/src/lints/avoid_late_keyword/visitors/avoid_late_keyword_visitor.dart';
import 'package:solid_lints/src/models/solid_lint_rule.dart';
-/// Avoid `late` keyword
-///
/// Using `late` disables compile time safety for what would else be a nullable
/// variable. Instead, a runtime check is made, which may throw an unexpected
/// exception for an uninitialized variable.
diff --git a/lib/src/lints/avoid_similar_names/avoid_similar_names_rule.dart b/lib/src/lints/avoid_similar_names/avoid_similar_names_rule.dart
index 58140dab..dff18e52 100644
--- a/lib/src/lints/avoid_similar_names/avoid_similar_names_rule.dart
+++ b/lib/src/lints/avoid_similar_names/avoid_similar_names_rule.dart
@@ -4,8 +4,6 @@ import 'package:analyzer/error/error.dart';
import 'package:solid_lints/src/lints/avoid_similar_names/visitors/avoid_similar_names_visitor.dart';
import 'package:solid_lints/src/models/solid_lint_rule.dart';
-/// Avoid similar names
-///
/// Warns about variables or parameters that have confusingly similar names
/// within the same function scope (e.g., using numeric suffixes or
/// single-letter modifiers like `someClass1` and `someClass2`).
diff --git a/lib/src/lints/avoid_unrelated_type_assertions/avoid_unrelated_type_assertions_rule.dart b/lib/src/lints/avoid_unrelated_type_assertions/avoid_unrelated_type_assertions_rule.dart
index fa1709b8..07565e92 100644
--- a/lib/src/lints/avoid_unrelated_type_assertions/avoid_unrelated_type_assertions_rule.dart
+++ b/lib/src/lints/avoid_unrelated_type_assertions/avoid_unrelated_type_assertions_rule.dart
@@ -5,7 +5,7 @@ import 'package:analyzer/error/error.dart';
import 'package:solid_lints/src/lints/avoid_unrelated_type_assertions/visitors/avoid_unrelated_type_assertions_visitor.dart';
/// A `avoid_unrelated_type_assertions` rule which
-/// warns about unnecessary usage of `as` operator
+/// warns about unnecessary usage of `as` operator.
class AvoidUnrelatedTypeAssertionsRule extends AnalysisRule {
/// The lint rule name. Must be public to generate docs.
static const lintName = 'avoid_unrelated_type_assertions';
diff --git a/lib/src/lints/newline_before_return/newline_before_return_rule.dart b/lib/src/lints/newline_before_return/newline_before_return_rule.dart
index 5614cd62..350bf4b1 100644
--- a/lib/src/lints/newline_before_return/newline_before_return_rule.dart
+++ b/lib/src/lints/newline_before_return/newline_before_return_rule.dart
@@ -29,7 +29,7 @@ import 'package:solid_lints/src/lints/newline_before_return/visitors/newline_bef
// Inspired by ESLint (https://eslint.org/docs/rules/newline-before-return)
-/// Warns about missing newline before return in a code block
+/// Warns about missing newline before return in a code block.
///
/// ### Example
///
diff --git a/lib/src/lints/no_magic_number/no_magic_number_rule.dart b/lib/src/lints/no_magic_number/no_magic_number_rule.dart
index 7dd3d79d..c879cc0e 100644
--- a/lib/src/lints/no_magic_number/no_magic_number_rule.dart
+++ b/lib/src/lints/no_magic_number/no_magic_number_rule.dart
@@ -5,7 +5,7 @@ import 'package:solid_lints/src/lints/no_magic_number/models/no_magic_number_par
import 'package:solid_lints/src/lints/no_magic_number/visitors/no_magic_number_rule_visitor.dart';
import 'package:solid_lints/src/models/solid_lint_rule.dart';
-/// A `no_magic_number` rule which forbids having numbers without variable
+/// A `no_magic_number` rule which forbids having numbers without variable.
///
/// There is a number of exceptions, where number literals are allowed:
/// - Collection literals;
diff --git a/lib/src/lints/prefer_conditional_expressions/prefer_conditional_expressions_rule.dart b/lib/src/lints/prefer_conditional_expressions/prefer_conditional_expressions_rule.dart
index 75372939..8ab9dce9 100644
--- a/lib/src/lints/prefer_conditional_expressions/prefer_conditional_expressions_rule.dart
+++ b/lib/src/lints/prefer_conditional_expressions/prefer_conditional_expressions_rule.dart
@@ -10,7 +10,7 @@ import 'package:solid_lints/src/models/solid_lint_rule.dart';
// Inspired by TSLint (https://palantir.github.io/tslint/rules/prefer-conditional-expression/)
/// Highlights simple "if" statements that can be replaced with conditional
-/// expressions
+/// expressions.
///
/// ### Example config:
///
diff --git a/lib/src/utils/docs_parser/output_formatters/docusaurus_formatter.dart b/lib/src/utils/docs_parser/output_formatters/docusaurus_formatter.dart
index bab004af..338b6881 100644
--- a/lib/src/utils/docs_parser/output_formatters/docusaurus_formatter.dart
+++ b/lib/src/utils/docs_parser/output_formatters/docusaurus_formatter.dart
@@ -4,18 +4,26 @@ import 'package:path/path.dart';
import 'package:solid_lints/src/utils/docs_parser/models/rule_doc.dart';
import 'package:solid_lints/src/utils/docs_parser/output_formatters/markdown_formatter.dart';
import 'package:solid_lints/src/utils/docs_parser/output_formatters/rules_documentation_formatter.dart';
+import 'package:solid_lints/src/utils/docs_parser/utils/rule_description_extractor.dart';
import 'package:yaml/yaml.dart';
/// Formatter that generates markdown files for every separate rule
class DocusaurusFormatter implements RulesDocumentationFormatter {
- static const _introFileMetadata = '''
----
-sidebar_label: Overview
-sidebar_position: 0
----
-
-
-''';
+ static const _introFileMetadata =
+ '---\n'
+ 'title: Overview\n'
+ "description: 'Official documentation for solid_lints, an opinionated "
+ "set of Dart and Flutter lint rules maintained by Solid Software.'\n"
+ 'keywords:\n'
+ ' - solid_lints\n'
+ ' - dart lint rules\n'
+ ' - flutter linter\n'
+ ' - static analysis\n'
+ ' - code quality\n'
+ ' - solid software\n'
+ 'sidebar_label: Overview\n'
+ 'sidebar_position: 0\n'
+ '---\n\n';
static const _latestVersionPlaceholder = '';
static final _markdownFormatter = MarkdownFormatter();
@@ -62,12 +70,36 @@ sidebar_position: 0
return null;
}
- void _createMarkdownFileForRule(RuleDoc rule) =>
- File(join(_outputDirectory.path, '${rule.name}.md')).writeAsStringSync(
- _markdownFormatter.formatRuleToMarkdown(
- rule,
- includeName: false,
- parametersAsList: false,
- ),
- );
+ void _createMarkdownFileForRule(RuleDoc rule) {
+ final frontmatter = _formatRuleFrontmatter(rule);
+ final markdown = _markdownFormatter.formatRuleToMarkdown(
+ rule,
+ includeName: false,
+ parametersAsList: false,
+ );
+
+ File(
+ join(_outputDirectory.path, '${rule.name}.md'),
+ ).writeAsStringSync('$frontmatter$markdown');
+ }
+
+ String _formatRuleFrontmatter(RuleDoc rule) {
+ final description = RuleDescriptionExtractor.extract(
+ rule,
+ ).replaceAll("'", "''");
+
+ return '''
+---
+title: ${rule.name}
+description: '$description'
+keywords:
+ - ${rule.name}
+ - solid_lints
+ - dart lint
+ - flutter linter
+ - static analysis
+---
+
+''';
+ }
}
diff --git a/lib/src/utils/docs_parser/utils/rule_description_extractor.dart b/lib/src/utils/docs_parser/utils/rule_description_extractor.dart
new file mode 100644
index 00000000..7e9aa495
--- /dev/null
+++ b/lib/src/utils/docs_parser/utils/rule_description_extractor.dart
@@ -0,0 +1,32 @@
+import 'package:solid_lints/src/utils/docs_parser/models/rule_doc.dart';
+
+/// Extracts and sanitizes concise descriptions from rule documentation.
+abstract final class RuleDescriptionExtractor {
+ static final _firstParagraphEndPattern = RegExp(
+ r'(?:\n\s*\n|^\s*(?:#|```|[-*]\s|See more here:))',
+ multiLine: true,
+ );
+ static final _whitespacePattern = RegExp(r'\s+');
+ static final _firstSentencePattern = RegExp(
+ r'^.*?\.(?:\s+(?=[A-Z])|$)',
+ dotAll: true,
+ );
+
+ /// Extracts and formats a concise description from [rule] documentation.
+ static String extract(RuleDoc rule) {
+ final doc = rule.doc.trim();
+ final end = _firstParagraphEndPattern.firstMatch(doc)?.start;
+ final paragraph = (end != null ? doc.substring(0, end) : doc)
+ .replaceAll(_whitespacePattern, ' ')
+ .trim();
+
+ if (paragraph.isEmpty) {
+ return 'Lint rule ${rule.name} for Dart and Flutter.';
+ }
+
+ final sentence =
+ _firstSentencePattern.firstMatch(paragraph)?[0]?.trim() ?? paragraph;
+
+ return sentence.replaceAll('`', '');
+ }
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index 5a016948..8e3bed37 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,8 +3,10 @@ description:
Lints for Dart and Flutter based on software industry standards and best
practices.
version: 1.0.0
-homepage: https://github.com/solid-software/solid_lints/
-documentation: https://solid-software.github.io/solid_lints/docs/intro
+homepage: https://lints.solid.software
+repository: https://github.com/solid-software/solid_lints
+issue_tracker: https://github.com/solid-software/solid_lints/issues
+documentation: https://lints.solid.software/docs/intro
topics: [lints, linter, lint, analysis, analyzer]
platforms:
android:
diff --git a/test/src/utils/docs_parser/utils/rule_description_extractor_test.dart b/test/src/utils/docs_parser/utils/rule_description_extractor_test.dart
new file mode 100644
index 00000000..a61374c7
--- /dev/null
+++ b/test/src/utils/docs_parser/utils/rule_description_extractor_test.dart
@@ -0,0 +1,93 @@
+import 'package:solid_lints/src/utils/docs_parser/models/rule_doc.dart';
+import 'package:solid_lints/src/utils/docs_parser/utils/rule_description_extractor.dart';
+import 'package:test/test.dart';
+
+void main() {
+ group('RuleDescriptionExtractor', () {
+ RuleDoc createRule({required String name, required String doc}) =>
+ RuleDoc(name: name, doc: doc, parameters: const []);
+
+ group('extract', () {
+ test('returns default fallback when doc is empty', () {
+ final rule = createRule(name: 'my_rule', doc: '');
+
+ final result = RuleDescriptionExtractor.extract(rule);
+
+ expect(result, 'Lint rule my_rule for Dart and Flutter.');
+ });
+
+ test(
+ 'returns default fallback when doc starts with markdown heading',
+ () {
+ final rule = createRule(
+ name: 'my_rule',
+ doc: '### Example config:\n```yaml\n```',
+ );
+
+ final result = RuleDescriptionExtractor.extract(rule);
+
+ expect(result, 'Lint rule my_rule for Dart and Flutter.');
+ },
+ );
+
+ test('extracts single paragraph description', () {
+ final rule = createRule(
+ name: 'my_rule',
+ doc: 'A comprehensive lint rule description.',
+ );
+
+ final result = RuleDescriptionExtractor.extract(rule);
+
+ expect(result, 'A comprehensive lint rule description.');
+ });
+
+ test('extracts only the first sentence when paragraph has multiple '
+ 'sentences', () {
+ final rule = createRule(
+ name: 'avoid_late',
+ doc:
+ 'Using `late` disables compile time safety. '
+ 'Instead, a runtime check is made.\n\n'
+ '### Example',
+ );
+
+ final result = RuleDescriptionExtractor.extract(rule);
+
+ expect(result, 'Using late disables compile time safety.');
+ });
+
+ test('removes backticks from description', () {
+ final rule = createRule(
+ name: 'rule_with_backticks',
+ doc:
+ 'This is a description with `code`.\n\n'
+ '### Example config:\n```yaml\n```',
+ );
+
+ final result = RuleDescriptionExtractor.extract(rule);
+
+ expect(result, 'This is a description with code.');
+ });
+
+ test('stops before code blocks, lists, and reference markers', () {
+ final ruleWithList = createRule(
+ name: 'list_rule',
+ doc: 'Description line.\n- bullet item',
+ );
+ expect(
+ RuleDescriptionExtractor.extract(ruleWithList),
+ 'Description line.',
+ );
+
+ final ruleWithSeeMore = createRule(
+ name: 'see_more_rule',
+ doc: 'Description line.\nSee more here: https://example.com',
+ );
+ expect(
+ RuleDescriptionExtractor.extract(ruleWithSeeMore),
+ 'Description line.',
+ );
+ });
+ });
+ });
+}