organize gemini docs

pull/2714/head
Eric Windmill 4 weeks ago
parent 9801f24ac8
commit 0687f72005

@ -0,0 +1,36 @@
This workflow is performed periodically to maintain code health.
1. **Prepare the Log File:**
* Check if a `logs/freshness.md` file exists in the root of the
repository.
* If it does not exist, create it and add the following header:
```markdown
# Fresh Code Log
This file tracks sample projects that have not received meaningful code updates in over a year.
| Sample Name | Last Commit Author | Date of Last Commit | Lines of code updated |
|------------------------------------|--------------------|---------------------|-----------------------|
```
2. **Analyze Git History:**
* For each sample project in the monorepo:
* Use `git log` to find the most recent commit to a `.dart`
file within that sample's directory that was made by a
human (i.e., not a bot).
* **Example command for a sample in `sample_name/`:**
```bash
git log -1 --author='^(?!.*bot).*$' --pretty="format:%an,%ad" -- ./sample_name/**/*.dart
```
* Parse the output to get the author's name and the date of
the commit, and keep track of the number of lines of code
updated to .dart files in that commit.
3. **Log code update information:**
* Append a new line to table in the freshness log.
* **Example entry:**
```markdown
| my_awesome_sample | Jane Doe | Tue Aug 1 10:00:00 2024 | 10 lines of code
```
4. **Sort the table by most recent update in reverse chronological order.**

@ -0,0 +1,93 @@
You are an AI developer specializing in Dart and Flutter. Your primary
responsibility is to maintain this monorepo of sample projects,
ensuring they are up-to-date, clean, and well-organized.
This workflow is triggered when a new Flutter/Dart version is
released. Follow these steps precisely:
1. Prepare your environment:
* Switch to the `beta` branch and ensure it's up-to-date:
```bash
git checkout beta
git pull origin beta
```
* Switch your local Flutter SDK to the `beta` channel and upgrade:
```bash
flutter channel beta
flutter upgrade
```
2. Pre-Update Analysis from Blog Post (If Provided):
* The user may provide a URL to a blog post announcing the new
Flutter and Dart release.
* If a URL is provided, read the blog post to identify key
changes, new features, and updated best practices.
* Before proceeding with the steps below, apply the necessary
code modifications throughout the repository to adopt these new
features and best practices. For example, this might include
updating APIs, adopting new lint rules, or refactoring code to
use new language features.
3. Initial Setup:
* First, determine the precise Dart SDK version you will be
working with. Execute the command `flutter --version --machine`.
* Parse the JSON output to find the value of dartSdkVersion. You
will need the version number (e.g., 3.9.0). Let's call this
DART_VERSION.
* Next, read the pubspec.yaml file at the root of the monorepo.
* Parse the workspace section to get a list of all the relative
paths for the projects you need to process.
4. Process Each Project:
* Create a file called
`logs/YYYY-MM-DD_HH-MM-SS-release_update_log.txt`, but replace
YYYY-MM-DD_HH-MM-SS with the current date/time.
* Iterate through each project path you discovered in the
workspace.
* For each project, perform the following actions in its
directory. If any command returns output warnings, errors or info,
log the project path and the message in the log file, then move to
the next project.
5. Project-Specific Tasks:
* Update SDK Constraint:
* Read the project's pubspec.yaml file.
* Find the environment.sdk key.
* Update its value to ^DART_VERSION-0 (e.g., ^3.9.0-0).
* Save the modified pubspec.yaml file.
* Run Quality Checks:
* Run dart analyze --fatal-infos --fatal-warnings.
* Run dart format . to ensure the code is correctly formatted.
* Run Tests:
* Check if a test directory exists in the project.
* Exception: Do not run tests for the project named
material_3_demo.
* If a test directory exists (and it's not the excluded
project), run flutter test.
6. Fix issues:
* For each message in the
`logs/YYYY-MM-DD_HH-MM-SS-release_update_log.txt` file, attempt
to fix the problem. After 30 seconds of being unable to fix it,
move onto the next issue.
* If you fix the issue successfully, remove the message from the
log file.
* If you can't fix the issue, just leave the message in the log
file so the user can fix it.
7. Final Report:
* After processing all projects, generate a summary report.
* The report must include:
* The total number of projects processed.
* A list of projects that were updated and passed all checks
successfully.
* A list of projects that failed, specifying which command
failed for each.
8. Create Pull Request:
* After generating the report, create a pull request.
* Use the `gh` CLI tool for this purpose.
* The title of the pull request should be: `Prepare release for
Dart DART_VERSION / Flutter FLUTTER_VERSION`.
* The body of the pull request should contain the summary report
from the previous step.

@ -6,5 +6,6 @@
"mcp-server"
]
}
}
},
"contextFileName": "llm.md"
}

@ -4,7 +4,7 @@ version: 1.0.0+1
resolution: workspace
environment:
sdk: ^3.9.0-0
sdk: ^3.8.1-0
dependencies:
flutter:

@ -0,0 +1,3 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:

787
llm.md

@ -1,116 +1,683 @@
# Role: AI Monorepo Maintainer for Dart/Flutter Samples
You are an expert Dart and Flutter developer on the Flutter team at Google. Your code must adhere to this style guide.
You are an AI developer specializing in Dart and Flutter. Your primary responsibility is to maintain this monorepo of sample projects, ensuring they are up-to-date, clean, and well-organized. You will perform tasks related to SDK updates, sample deprecation, and code health monitoring.
---
## Core Philosophy
## Core Responsibilities
- **Optimize for readability**: Write code that is easy to understand and maintain
- **Write detailed documentation**: Every public API should be well-documented
- **Keep one source of truth**: Avoid duplicating state across your application
- **Design APIs from the developer's perspective**: Consider how the API will be used
- **Create useful error messages**: Error messages should guide developers toward solutions
- **Write tests first**: When fixing bugs, write failing tests first, then fix the bug
- **Avoid workarounds**: Take time to fix problems correctly rather than implementing temporary solutions
1. **SDK Release Updates:** Proactively update sample projects to be compatible with new releases of the Flutter and Dart SDKs.
2. **Sample Deprecation:** Archive and remove outdated or irrelevant sample projects as directed.
3. **Stale Code Identification:** Regularly scan the monorepo to identify and report code that has not been recently updated.
## Naming Conventions
---
### Identifier Types (Official Dart Guidelines)
## Workflows
### Workflow 1: Updating for a New SDK Release
This workflow is triggered when a new Flutter/Dart version is released. Follow the instructions in `release.md` to perform the update. A summary of the steps is below:
1. **Analyze Release Notes:**
* The user may provide a URL to the official release blog post. Read it carefully to understand breaking changes, new features, and migration guidelines. If no URL is provided, proceed to the next step.
2. **Prepare Your Environment:**
* Switch to the `beta` branch and ensure it's up-to-date:
```bash
git checkout beta
git pull origin beta
```
* Switch your local Flutter SDK to the `beta` channel and upgrade:
```bash
flutter channel beta
flutter upgrade
```
3. **Update Projects and Address Issues:**
* Follow the detailed steps in `release.md` to iterate through each project in the monorepo.
* For each project, you will:
* Update the SDK constraint in `pubspec.yaml`.
* Apply code changes based on the release notes (if provided).
* Run `dart analyze` and `dart format .` to identify and fix issues.
* Run `flutter test` to ensure correctness.
* Keep a log of any errors you cannot fix. If you are unable to resolve an issue for a project after a reasonable time, log it and move to the next one.
* **Note:** When updating for a new release, you can ignore `flutter pub outdated` warnings. As long as `pub get` completes successfully, it's okay.
4. **Create a Pull Request:**
* Once all projects are updated and the repository is in a clean state, create a pull request.
* Use the `gh` CLI to create the PR. The user will provide the necessary repository information if needed.
```bash
# Example:
gh pr create --title "feat: Update samples for Flutter X.Y.Z" --body "This PR updates all samples to be compatible with the latest Flutter beta release. All issues from the release tool have been addressed."
```
### Workflow 2: Deprecating a Sample Project
This workflow is triggered when a sample project is deemed obsolete.
1. **Identify the Target:**
* The user will specify the name of the sample project directory to be deleted.
2. **Check for Related Issues:**
* Search the repository's GitHub Issues for any open issues that mention the deletion or deprecation of the target sample. Note the issue number if you find one.
3. **Archive the Project:**
* Navigate to the parent directory of the sample project.
* Remove all files and subdirectories within the target directory.
```bash
# Example for a sample named 'old_sample'
rm -rf old_sample/*
```
4. **Create a Deprecation Notice:**
* In the now-empty directory, create a `README.md` file.
* Add a clear message explaining that the sample has been deprecated.
* If you found a related GitHub issue, link to it in the README.
* **Example `README.md` content:**
```markdown
# Sample Deprecated
This sample project has been deprecated and its contents have been removed. It is no longer maintained.
For more context, see issue #123.
```
### Workflow 3: Marking Stale Code
This workflow is performed periodically to maintain code health.
1. **Prepare the Log File:**
* Check if a `logs/stale_code.md` file exists in the root of the repository.
* If it does not exist, create it and add the following header:
```markdown
# Stale Code Log
This file tracks sample projects that have not received meaningful code updates in over a year.
| Sample Name | Last Commit Author | Date of Last Commit |
|------------------------------------|--------------------|---------------------|
```
2. **Analyze Git History:**
* For each sample project in the monorepo:
* Use `git log` to find the most recent commit to a `.dart` file within that sample's directory that was made by a human (i.e., not a bot).
* **Example command for a sample in `sample_name/`:**
```bash
git log -1 --author='^(?!.*bot).*$' --pretty="format:%an,%ad" -- ./sample_name/**/*.dart
```
* Parse the output to get the author's name and the date of the commit.
3. **Log Stale Code:**
* If the date of the last commit is more than one year ago, append a new row to the table in `stale_code.md`.
* **Example entry:**
```markdown
| my_awesome_sample | Jane Doe | Tue Aug 1 10:00:00 2024 |
```
#### UpperCamelCase
- **Classes**: `MyWidget`, `UserRepository`, `HttpClient`
- **Enum types**: `ButtonType`, `AnimationState`, `ConnectionState`
- **Typedefs**: `EventCallback`, `ValidatorFunction`
- **Type parameters**: `<T>`, `<K, V>`, `<TModel>`
- **Extensions**: `StringExtension`, `MyFancyList`, `SmartIterable`
#### lowerCamelCase
- **Variables**: `userName`, `isLoading`, `itemCount`
- **Parameters**: `onPressed`, `itemBuilder`, `scrollDirection`
- **Class members**: `_privateField`, `publicMethod`
- **Top-level functions**: `buildWidget`, `validateInput`
- **Constants**: `defaultPadding`, `maxRetries`, `pi` (prefer over SCREAMING_CAPS)
#### lowercase_with_underscores
- **Packages**: `my_package`, `http_client`
- **Directories**: `lib/widgets/custom`, `test/unit_tests`
- **Source files**: `user_profile_widget.dart`, `file_system.dart`
- **Import prefixes**: `import 'dart:math' as math;`, `import 'package:foo/foo.dart' as foo_lib;`
### Flutter-Specific Guidelines
- **Global constants**: Begin with prefix "k": `kDefaultTimeout`, `kMaxItems`
- **Avoid abbreviations**: Use `button` instead of `btn`, `number` instead of `num`
- **Acronyms**: Capitalize acronyms longer than two letters like regular words: `HttpClient` not `HTTPClient`
- **Unused parameters**: Use wildcards (`_`) for unused callback parameters
- **Private identifiers**: Use leading underscores only for truly private members
- **Avoid Hungarian notation**: Don't use prefix letters like `strName` or `intCount`
## Code Organization and Structure
### Import Ordering (Strict Dart Convention)
```dart
// 1. Dart core libraries (alphabetically)
import 'dart:async';
import 'dart:convert';
import 'dart:math';
// 2. Flutter and package imports (alphabetically)
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';
// 3. Relative imports (alphabetically)
import '../models/user.dart';
import '../widgets/custom_button.dart';
import 'user_repository.dart';
// 4. Exports (if any, in separate section)
export 'src/my_library.dart';
```
### Class Member Ordering (Flutter Team Convention)
```dart
class MyWidget extends StatefulWidget {
// 1. Constructors first
const MyWidget({
super.key,
required this.title,
this.isEnabled = true,
});
// 2. Public constants
static const double kDefaultHeight = 48.0;
// 3. Public fields
final String title;
final bool isEnabled;
// 4. Private constants
static const double _defaultPadding = 16.0;
// 5. Private fields
String? _cachedValue;
// 6. Getters and setters
bool get isDisabled => !isEnabled;
// 7. Public methods
@override
State<MyWidget> createState() => _MyWidgetState();
// 8. Private methods
void _updateCache() {
// Implementation
}
}
```
## Formatting and Style Rules
### Line Length and Basic Formatting
- **Always use `dart format`** for automatic code formatting
- **Prefer lines 80 characters or fewer** for better readability
- **Maximum 100 characters for comments** (Flutter team preference)
- **Always use curly braces** for all flow control statements
```dart
// Good - always use braces
if (condition) {
print('hello');
}
// Bad - missing braces
if (condition) print('hello');
```
### Function and Method Formatting
```dart
// Use "=>" for short functions and getters
String get displayName => '$firstName $lastName';
int get age => DateTime.now().year - birthYear;
// Use braces for longer functions
String formatUserName(String first, String last) {
if (first.isEmpty && last.isEmpty) {
return 'Anonymous';
}
return '$first $last'.trim();
}
```
### Dart-Specific Formatting Rules
- **Prefer `+=` over `++`** for increment operations: `counter += 1;`
- **Use collection literals** when possible: `<int>[]` instead of `List<int>()`
- **Adjacent string literals** for concatenation:
```dart
var longMessage = 'This is a very long message '
'that spans multiple lines.';
```
## Type Annotations and Safety
### Type Annotations (Required by Flutter Team)
```dart
// DO annotate return types on function declarations
String formatName(String first, String last) {
return '$first $last';
}
// DO annotate parameter types on function declarations
void updateUser(String id, Map<String, dynamic> data) {
// Implementation
}
// DO use explicit types for variables (avoid var/dynamic)
final List<User> users = [];
final Map<String, int> scores = {};
```
### Null Safety Best Practices
```dart
// DON'T explicitly initialize variables to null
String? name; // Good
String? name = null; // Bad
// DO use proper null-aware operators
final displayName = user?.name ?? 'Unknown';
// DO use late for non-nullable fields initialized later
class MyWidget extends StatefulWidget {
late final AnimationController controller;
}
```
### Future and Async Types
```dart
// DO use Future<void> for async functions that don't return values
Future<void> saveUser(User user) async {
await repository.save(user);
}
// DO prefer async/await over raw futures
Future<List<User>> loadUsers() async {
final response = await http.get('/api/users');
return parseUsers(response.body);
}
```
## Documentation Standards
### Documentation Comments (Dart Standard)
```dart
/// A custom button widget that provides enhanced styling and behavior.
///
/// This widget wraps Flutter's [ElevatedButton] and adds additional
/// functionality like loading states and custom styling.
///
/// The [onPressed] callback is called when the button is tapped.
/// Set [isEnabled] to false to disable the button.
///
/// Example usage:
/// ```dart
/// CustomButton(
/// onPressed: () => print('Pressed'),
/// child: Text('Click me'),
/// isEnabled: true,
/// )
/// ```
class CustomButton extends StatelessWidget {
/// Creates a custom button.
///
/// The [onPressed] and [child] parameters are required.
/// The [isEnabled] parameter defaults to true.
const CustomButton({
super.key,
required this.onPressed,
required this.child,
this.isEnabled = true,
});
/// Called when the button is pressed.
final VoidCallback? onPressed;
/// The widget to display inside the button.
final Widget child;
/// Whether the button is enabled for interaction.
final bool isEnabled;
}
```
### Method Documentation Requirements
```dart
/// Validates the given email address format.
///
/// Returns `true` if the [email] is valid according to RFC standards.
/// Returns `false` if the format is invalid.
///
/// Throws [ArgumentError] if [email] is null or empty.
///
/// Example:
/// ```dart
/// final isValid = validateEmail('user@example.com'); // true
/// ```
bool validateEmail(String email) {
if (email.isEmpty) {
throw ArgumentError('Email cannot be empty');
}
return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(email);
}
```
## Flutter-Specific Patterns
### Widget Construction
```dart
class CustomCard extends StatelessWidget {
const CustomCard({
super.key,
required this.title,
required this.content,
this.elevation = 2.0,
this.onTap,
});
final String title;
final Widget content;
final double elevation;
final VoidCallback? onTap;
@override
Widget build(BuildContext context) {
return Card(
elevation: elevation,
child: InkWell(
onTap: onTap,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8.0),
content,
],
),
),
),
);
}
}
```
### State Management Patterns
```dart
class CounterNotifier extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
void decrement() {
if (_count > 0) {
_count--;
notifyListeners();
}
}
void reset() {
_count = 0;
notifyListeners();
}
}
```
## String and Collection Best Practices
### String Interpolation and Formatting
```dart
// PREFER using interpolation to compose strings
final name = 'John Doe';
final age = 25;
final message = 'Hello, $name! You are $age years old.';
final calculation = 'Next year you will be ${age + 1}.';
// DO use adjacent strings for long literals
const longText = 'This is a very long text that '
'spans multiple lines for better '
'readability in the source code.';
```
### Collection Usage
```dart
// DO use collection literals
final List<String> names = [];
final Map<String, int> scores = {};
final Set<int> uniqueIds = {};
// DON'T use .length to check if empty
if (names.isEmpty) { // Good
print('No names');
}
if (names.length == 0) { // Bad
print('No names');
}
// DO use collection methods effectively
final activeUsers = users.where((user) => user.isActive).toList();
final userNames = users.map((user) => user.name).toList();
```
### Function References
```dart
// DON'T create lambdas when tear-offs work
final numbers = [1, 2, 3, 4, 5];
// Good - use tear-off
numbers.forEach(print);
// Bad - unnecessary lambda
numbers.forEach((number) {
print(number);
});
```
## Error Handling and Exceptions
### Meaningful Error Messages (Flutter Team Priority)
```dart
// Good: Specific and actionable
throw ArgumentError('Email must contain @ symbol');
throw StateError('Cannot call increment() after dispose()');
// Bad: Vague and unhelpful
throw ArgumentError('Invalid input');
throw Exception('Error occurred');
```
### Exception Handling Patterns
```dart
Future<User> fetchUser(String id) async {
try {
final response = await api.getUser(id);
return User.fromJson(response.data);
} on NetworkException catch (e) {
throw UserFetchException('Failed to fetch user: ${e.message}');
} on FormatException catch (e) {
throw UserParseException('Invalid user data format: ${e.message}');
} catch (e) {
throw UserFetchException('Unexpected error: ${e.toString()}');
}
}
```
## Testing Guidelines
### Widget Testing
```dart
testWidgets('CustomButton should call onPressed when tapped', (tester) async {
bool wasPressed = false;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: CustomButton(
onPressed: () => wasPressed = true,
child: const Text('Test Button'),
),
),
),
);
await tester.tap(find.byType(CustomButton));
await tester.pump();
expect(wasPressed, isTrue);
});
```
### Unit Testing Structure
```dart
group('UserRepository', () {
late UserRepository repository;
late MockApiClient mockApi;
setUp(() {
mockApi = MockApiClient();
repository = UserRepository(api: mockApi);
});
group('getUser', () {
test('should return user when valid ID provided', () async {
// Arrange
const userId = '123';
final expectedUser = User(id: userId, name: 'John');
when(() => mockApi.getUser(userId))
.thenAnswer((_) async => expectedUser.toJson());
// Act
final user = await repository.getUser(userId);
// Assert
expect(user.id, equals(userId));
expect(user.name, equals('John'));
});
test('should throw exception when user not found', () async {
// Arrange
const userId = 'invalid';
when(() => mockApi.getUser(userId))
.thenThrow(NotFoundException());
// Act & Assert
expect(
() => repository.getUser(userId),
throwsA(isA<UserNotFoundException>()),
);
});
});
});
```
## Advanced Dart Patterns
### Immutability and Data Classes
```dart
class User {
const User({
required this.id,
required this.name,
required this.email,
this.isActive = true,
});
final String id;
final String name;
final String email;
final bool isActive;
// Use copyWith for immutable updates
User copyWith({
String? id,
String? name,
String? email,
bool? isActive,
}) {
return User(
id: id ?? this.id,
name: name ?? this.name,
email: email ?? this.email,
isActive: isActive ?? this.isActive,
);
}
// Override equality
@override
bool operator ==(Object other) =>
other is User &&
runtimeType == other.runtimeType &&
id == other.id;
@override
int get hashCode => id.hashCode;
@override
String toString() => 'User(id: $id, name: $name, email: $email)';
}
```
### Enum Usage and Switch Statements
```dart
enum ConnectionState {
disconnected,
connecting,
connected,
error,
}
// Use switch without default to catch all cases
Widget buildConnectionIndicator(ConnectionState state) {
switch (state) {
case ConnectionState.disconnected:
return const Icon(Icons.wifi_off, color: Colors.grey);
case ConnectionState.connecting:
return const CircularProgressIndicator();
case ConnectionState.connected:
return const Icon(Icons.wifi, color: Colors.green);
case ConnectionState.error:
return const Icon(Icons.error, color: Colors.red);
}
}
```
### Effective Use of Assert
```dart
class Rectangle {
const Rectangle({
required this.width,
required this.height,
}) : assert(width > 0, 'Width must be positive'),
assert(height > 0, 'Height must be positive');
final double width;
final double height;
double get area {
assert(width > 0 && height > 0, 'Invalid rectangle dimensions');
return width * height;
}
}
```
## Performance and Best Practices
### Const Constructors and Optimization
```dart
// Use const constructors when possible
const EdgeInsets.all(16.0);
const SizedBox(height: 8.0);
// Create const widgets for better performance
class LoadingIndicator extends StatelessWidget {
const LoadingIndicator({super.key});
@override
Widget build(BuildContext context) {
return const Center(
child: CircularProgressIndicator(),
);
}
}
```
### Efficient Widget Building
```dart
class ProductList extends StatelessWidget {
const ProductList({
super.key,
required this.products,
});
final List<Product> products;
@override
Widget build(BuildContext context) {
// Don't do heavy computation in build method
return ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
final product = products[index];
return ProductTile(
key: ValueKey(product.id),
product: product,
);
},
);
}
}
```
## Anti-Patterns to Avoid
### Common Mistakes
```dart
// DON'T use double negatives
bool get isNotDisabled => !disabled; // Confusing
// DO use positive naming
bool get isEnabled => !disabled; // Clear
// DON'T use global state
var globalCounter = 0; // Avoid
// DO use proper state management
class CounterProvider extends ChangeNotifier {
int _counter = 0;
int get counter => _counter;
}
// DON'T create classes with only static members
class MathUtils {
static double pi = 3.14159;
static double circleArea(double radius) => pi * radius * radius;
}
// DO use top-level functions and constants
const double pi = 3.14159;
double circleArea(double radius) => pi * radius * radius;
// DON'T avoid using APIs as intended
class TimeSlot {
TimeSlot(this.start, this.end);
DateTime start;
DateTime end;
}
// DO follow API design principles
class TimeSlot {
const TimeSlot({
required this.start,
required this.end,
}) : assert(start.isBefore(end), 'Start must be before end');
final DateTime start;
final DateTime end;
}
```
## Tools and Development Workflow
### Required Tools
- **`dart format`**: Automatic code formatting (mandatory)
- **`dart analyze`**: Static analysis and linting
- **`flutter test`**: Run tests
- **IDE setup**: Configure your IDE to run these tools automatically
- **Pre-commit hooks**: Ensure code quality before commits
### Code Quality Checklist
- [ ] All code formatted with `dart format`
- [ ] No analyzer warnings or errors
- [ ] All public APIs documented with `///` comments
- [ ] Tests written for new functionality
- [ ] Error messages are specific and actionable
- [ ] Type annotations present on all public APIs
- [ ] Immutable objects used where appropriate
- [ ] Assert statements used to verify contracts
This unified style guide ensures consistency with both Flutter team practices and official Dart conventions, helping create maintainable, readable code that follows established patterns.

@ -1,78 +0,0 @@
You are an AI assistant that automates repository maintenance. Your
task is to create a release candidate for a monorepo containing
multiple Dart and Flutter projects. This involves updating the SDK
constraints for each project, running a series of quality checks,
and reporting the results.
Follow these steps precisely:
0. Pre-Update Analysis from Blog Post (If Provided):
* The user may provide a URL to a blog post announcing the new
Flutter and Dart release.
* If a URL is provided, read the blog post to identify key
changes, new features, and updated best practices.
* Before proceeding with the steps below, apply the necessary
code modifications throughout the repository to adopt these
new features and best practices. For example, this might
include updating APIs, adopting new lint rules, or
refactoring code to use new language features.
1. Initial Setup:
* First, determine the precise Dart SDK version you will be
working with. Execute the command `flutter --version --machine`.
* Parse the JSON output to find the value of dartSdkVersion.
You will need the version number (e.g., 3.9.0). Let's call
this DART_VERSION.
* Next, read the pubspec.yaml file at the root of the monorepo.
* Parse the workspace section to get a list of all the relative
paths for the projects you need to process.
2. Process Each Project:
* Create a file called `logs/YYYY-MM-DD_HH-MM-SS-release_update_log.txt`
* Iterate through each project path you discovered in the
workspace.
* For each project, perform the following actions in its
directory. If any command returns output warnings, errors or
info, log the project path and the message in the log file,
then move to the next project.
3. Project-Specific Tasks:
* Update SDK Constraint:
* Read the project's pubspec.yaml file.
* Find the environment.sdk key.
* Update its value to ^DART_VERSION-0 (e.g., ^3.9.0-0).
* Save the modified pubspec.yaml file.
* Run Quality Checks:
* Run dart analyze --fatal-infos --fatal-warnings.
* Run dart format . to ensure the code is correctly
formatted.
* Run Tests:
* Check if a test directory exists in the project.
* Exception: Do not run tests for the project named
material_3_demo.
* If a test directory exists (and it's not the excluded
project), run flutter test.
4. Fix issues:
* For each message in the `logs/YYYY-MM-DD_HH-MM-SS-release_update_log.txt` file, attempt
to fix the problem. After 30 seconds of being unable to fix
it, move onto the next issue.
* If you fix the issue successfully, remove the message from the
log file.
* If you can't fix the issue, just leave the message in the log
file so the user can fix it.
5. Final Report:
* After processing all projects, generate a summary report.
* The report must include:
* The total number of projects processed.
* A list of projects that were updated and passed all
checks successfully.
* A list of projects that failed, specifying which command
failed for each.
6. Create Pull Request:
* After generating the report, create a pull request.
* Use the `gh` CLI tool for this purpose.
* The title of the pull request should be: `Prepare release for Dart DART_VERSION / Flutter FLUTTER_VERSION`.
* The body of the pull request should contain the summary report from the previous step.
Loading…
Cancel
Save