From b23c073be5373d21eb1fd5eb6612a2f1bf06a921 Mon Sep 17 00:00:00 2001 From: Eric Windmill Date: Fri, 1 Aug 2025 13:16:18 -0400 Subject: [PATCH] checkin --- CHANGELOG.md | 32 -- analysis_defaults/lib/flutter.yaml | 2 +- compass_app/server/analysis_options.yaml | 31 -- llm_prompt.md | 15 - tool/release.dart | 512 +++++++++++------------ tool/release_cleanup.sh | 267 ------------ workspace.md | 27 +- 7 files changed, 267 insertions(+), 619 deletions(-) delete mode 100644 CHANGELOG.md delete mode 100644 compass_app/server/analysis_options.yaml delete mode 100755 tool/release_cleanup.sh diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 7d8e5b733..000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,32 +0,0 @@ -# Changelog - -The purpose of this changelog is to track the freshness of samples and which -samples reflect *current best practices*. It describes **human-made, significant -** changes made to the repository or samples in the repository. - -While all samples in this repository build and run, some of them were written -long ago, and no longer reflect what we want developers to learn. For example, -samples should have been refactored when Dart 3 released to include patterns and -records, where appropriate. - -* **DO include:** - * The addition of new samples. - * The removal of existing samples. - * Considerable refactoring of any given sample. - -* **DO NOT include:** - * Simple changes that reflect minor version bumps in Flutter. For example, - in a recent Flutter update, `Color.red` became `Color.r`. - * Dependency updates. - * Bug fixes. - * Any changes made to simply 'keep the lights on'. - -# Log - -| DATE (YYYY-MM-DD) | Sample(s) | author | Changes | -|-------------------|-------------------|--------------|-----------------------------------------------| -| NEXT GOES HERE | | | | -| | | | | -| 2024-12-04 | N/A - repo change | ericwindmill | Added changelog | -| 2024-11-27 | fake_sample | ericwindmill | Refactored fake_sample to use Dart 3 features | -| 2020-04-17 | fake_sample | ericwindmill | Created fake_sample | diff --git a/analysis_defaults/lib/flutter.yaml b/analysis_defaults/lib/flutter.yaml index c7262e3a3..34ab6e19b 100644 --- a/analysis_defaults/lib/flutter.yaml +++ b/analysis_defaults/lib/flutter.yaml @@ -2,7 +2,7 @@ include: package:flutter_lints/flutter.yaml formatter: trailing_commas: preserve - page_width: 75 + page_width: 79 analyzer: language: diff --git a/compass_app/server/analysis_options.yaml b/compass_app/server/analysis_options.yaml deleted file mode 100644 index 08418910f..000000000 --- a/compass_app/server/analysis_options.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# This file configures the static analysis results for your project (errors, -# warnings, and lints). -# -# This enables the 'recommended' set of lints from `package:lints`. -# This set helps identify many issues that may lead to problems when running -# or consuming Dart code, and enforces writing Dart using a single, idiomatic -# style and format. -# -# If you want a smaller set of lints you can change this to specify -# 'package:lints/core.yaml'. These are just the most critical lints -# (the recommended set includes the core lints). -# The core lints are also what is used by pub.dev for scoring packages. - -include: package:analysis_defaults/flutter.yaml - - -# Uncomment the following section to specify additional rules. - -# linter: -# rules: -# - camel_case_types - -# analyzer: -# exclude: -# - path/to/excluded/files/** - -# For more information about the core and recommended set of lints, see -# https://dart.dev/go/core-lints - -# For additional information about configuring this file, see -# https://dart.dev/guides/language/analysis-options diff --git a/llm_prompt.md b/llm_prompt.md index 37bd8ce88..4cb8f7e54 100644 --- a/llm_prompt.md +++ b/llm_prompt.md @@ -47,18 +47,3 @@ You are an AI assistant tasked with keeping a repository of Flutter projects up- Please proceed with this task. - -Next: - -- Run the CLI command `flutter channel beta` to ensure the Flutter SDK on my machine is using the latest beta -- Run the CI running the bash file @/tool/flutter_ci_script_stable.sh - - When there's a non-0 response, attempt to fix the issue. - - -- remove samples and replace with a README -- Update script to look into sub-directories. Because some projects are themselves mono repos. -- Make sure this is in every pubspec yaml - analysis_defaults: - path: ../analysis_defaults - -- shouldn't run flutter-test unless theirs a test dir \ No newline at end of file diff --git a/tool/release.dart b/tool/release.dart index d0300d5c1..ba21c5438 100644 --- a/tool/release.dart +++ b/tool/release.dart @@ -8,322 +8,307 @@ import 'package:yaml_edit/yaml_edit.dart'; const String logDir = 'logs'; -late File _logFile; - void main(List arguments) async { - final parser = ArgParser() - ..addFlag('dry-run', - negatable: false, - help: - 'Prints the commands that would be executed, but does not run them.'); - final argResults = parser.parse(arguments); - final isDryRun = argResults['dry-run'] as bool; - - setupLogging(); - - log( - styleBold - .wrap('Flutter Monorepo Update Script Started: ${DateTime.now()}')!, - stdout); - log(blue.wrap('Log file: ${_logFile.path}')!, stdout); - - if (isDryRun) { - log(yellow.wrap('--- DRY RUN MODE ---')!, stdout); - } + final runner = ReleaseScriptRunner(); + await runner.run(arguments); +} - if (!await isFlutterInstalled()) { - log(red.wrap('Flutter is not installed or not in PATH')!, stderr); - exit(1); - } +class ReleaseScriptRunner { + late final File _logFile; + bool _isDryRun = false; - // log(styleBold.wrap('\n=========================================')!, stdout); - // log(styleBold.wrap('Upgrading Flutter SDK')!, stdout); - // log(styleBold.wrap('=========================================')!, stdout); - - // final (didFlutterUpgrade, _) = - // await runCommand('flutter', ['upgrade'], isDryRun: isDryRun); - - // if (!didFlutterUpgrade) { - // log(red.wrap('Failed to upgrade Flutter SDK')!, stderr); - // exit(1); - // } - - // log(styleBold.wrap('\n=========================================')!, stdout); - // log(styleBold.wrap('Resolving workspace dependencies')!, stdout); - // log(styleBold.wrap('=========================================')!, stdout); - - // final (didPubUpgrade, _) = - // await runCommand('flutter', ['pub', 'upgrade'], isDryRun: isDryRun); - // if (!didPubUpgrade) { - // log(red.wrap('Failed to upgrade workspace dependencies'), stderr); - // exit(1); - // } - - // final (didPubGet, _) = - // await runCommand('flutter', ['pub', 'get'], isDryRun: isDryRun); - // if (!didPubGet) { - // log(red.wrap('Failed to get workspace dependencies'), stderr); - // exit(1); - // } - - final dartVersion = await getDartVersion(); - if (dartVersion == null) { - log(red.wrap('Failed to get Dart SDK version.'), stderr); - exit(1); - } - log(blue.wrap('Using Dart SDK version: $dartVersion'), stdout); + Future run(List arguments) async { + final parser = ArgParser() + ..addFlag('dry-run', + negatable: false, + help: + 'Prints the commands that would be executed, but does not run them.'); + final argResults = parser.parse(arguments); + _isDryRun = argResults['dry-run'] as bool; + + _setupLogging(); - final packages = await getWorkspacePackages(); - if (packages.isEmpty) { - log(yellow.wrap('No packages found in the root pubspec.yaml workspace.'), + log( + styleBold + .wrap('Flutter Monorepo Update Script Started: ${DateTime.now()}'), stdout); - exit(0); - } + log(blue.wrap('Log file: ${_logFile.path}')!, stdout); - log( - blue.wrap( - 'Found ${packages.length} Flutter project(s): ${packages.join(', ')}'), - stdout); + if (_isDryRun) { + log(yellow.wrap('--- DRY RUN MODE ---')!, stdout); + } - final failedProjects = []; - for (final packagePath in packages) { - final success = await processProject(packagePath, dartVersion, isDryRun); - if (!success) { - failedProjects.add(packagePath); + if (!await _isFlutterInstalled()) { + log(red.wrap('Flutter is not installed or not in PATH')!, stderr); + exit(1); } - } - printSummary(packages.length, failedProjects); + final dartVersion = await _getDartVersion(); + if (dartVersion == null) { + log(red.wrap('Failed to get Dart SDK version.'), stderr); + exit(1); + } + log(blue.wrap('Using Dart SDK version: $dartVersion'), stdout); - log( - styleBold.wrap( - '\nFlutter Monorepo Update Script Completed: ${DateTime.now()}'), - stdout); + final packages = await _getWorkspacePackages(); + if (packages.isEmpty) { + log(yellow.wrap('No packages found in the root pubspec.yaml workspace.'), + stdout); + exit(0); + } - if (failedProjects.isNotEmpty) { - exit(1); - } -} + log( + blue.wrap( + 'Found ${packages.length} Flutter project(s): ${packages.join(', ')}'), + stdout); -void setupLogging() { - final logsDir = Directory(logDir); - if (!logsDir.existsSync()) { - logsDir.createSync(recursive: true); - } - final timestamp = DateTime.now().toIso8601String().replaceAll(':', '-'); - _logFile = File(p.join(logDir, 'release_logs_$timestamp.log')); -} + final failedProjects = []; + for (final packagePath in packages) { + final success = await _processProject(packagePath, dartVersion); + if (!success) { + failedProjects.add(packagePath); + } + } -void log(String? message, IOSink sink) { - if (message == null) return; - sink.writeln(message); -} + _printSummary(packages.length, failedProjects); -void logToFile(String? message) { - if (message == null) return; - _logFile.writeAsStringSync( - '\n${stripAnsiCodes(message)}', - mode: FileMode.append, - ); -} + log( + styleBold.wrap( + '\nFlutter Monorepo Update Script Completed: ${DateTime.now()}'), + stdout); -Future isFlutterInstalled() async { - try { - final result = await Process.run('flutter', ['--version']); - return result.exitCode == 0; - } catch (e) { - return false; + if (failedProjects.isNotEmpty) { + exit(1); + } } -} -Future getDartVersion() async { - try { - final result = await Process.run('flutter', ['--version', '--machine']); - if (result.exitCode == 0) { - final json = loadYaml(result.stdout as String) as YamlMap; - final fullDartVersion = json['dartSdkVersion'] as String?; - if (fullDartVersion != null) { - return fullDartVersion.split(' ').first; - } - return null; + void _setupLogging() { + final logsDir = Directory(logDir); + if (!logsDir.existsSync()) { + logsDir.createSync(recursive: true); } - } catch (e) { - log(red.wrap('Error getting Dart SDK version: $e'), stderr); + final timestamp = DateTime.now().toIso8601String().replaceAll(':', '-'); + _logFile = File(p.join(logDir, 'release_logs_$timestamp.log')); } - return null; -} -Future> getWorkspacePackages() async { - final rootPubspec = File('pubspec.yaml'); - if (!rootPubspec.existsSync()) { - log(red.wrap('Root pubspec.yaml not found!'), stderr); - return []; + void log(String? message, IOSink sink) { + if (message == null) return; + sink.writeln(message); } - try { - final content = await rootPubspec.readAsString(); - final yaml = loadYaml(content) as YamlMap; - final workspace = yaml['workspace'] as YamlList?; - if (workspace != null) { - return workspace.nodes.map((node) => node.value as String).toList(); - } - } catch (e) { - log(red.wrap('Error reading workspace packages: $e'), stderr); + void logToFile(String? message) { + if (message == null) return; + _logFile.writeAsStringSync( + '\n${_stripAnsiCodes(message)}', + mode: FileMode.append, + ); } - return []; -} - -Future processProject( - String projectPath, String dartVersion, bool isDryRun) async { - final projectName = p.basename(projectPath); - final projectDir = Directory(projectPath); - final issues = []; - if (!projectDir.existsSync()) { - log(red.wrap('Project directory not found: $projectPath'), stderr); - return false; + Future _isFlutterInstalled() async { + try { + final result = await Process.run('flutter', ['--version']); + return result.exitCode == 0; + } catch (e) { + return false; + } } - // For stdout - log(styleBold.wrap('\n========================================='), stdout); - log(styleBold.wrap('Processing project: $projectName'), stdout); - log(styleBold.wrap('=========================================')!, stdout); - - log(blue.wrap('Updating SDK constraints to use Dart $dartVersion'), stdout); - if (!isDryRun) { - if (!await updateSdkConstraints(projectPath, dartVersion)) { - log(red.wrap('Failed to update SDK constraints for $projectName'), - stderr); - return false; + Future _getDartVersion() async { + try { + final result = await Process.run('flutter', ['--version', '--machine']); + if (result.exitCode == 0) { + final json = loadYaml(result.stdout as String) as YamlMap; + final fullDartVersion = json['dartSdkVersion'] as String?; + if (fullDartVersion != null) { + return fullDartVersion.split(' ').first; + } + return null; + } + } catch (e) { + log(red.wrap('Error getting Dart SDK version: $e'), stderr); } + return null; } - final commands = [ - Command('dart analyze', 'Running dart analyze...', 'dart', - ['analyze', '--fatal-infos', '--fatal-warnings']), - Command('dart format', 'Running dart format...', 'dart', ['format', '.']), - ]; + Future> _getWorkspacePackages() async { + final rootPubspec = File('pubspec.yaml'); + if (!rootPubspec.existsSync()) { + log(red.wrap('Root pubspec.yaml not found!'), stderr); + return []; + } - final testDir = Directory(p.join(projectPath, 'test')); - if (projectName != 'material_3_demo' && testDir.existsSync()) { - commands - .add(Command('flutter test', 'Running tests...', 'flutter', ['test'])); + try { + final content = await rootPubspec.readAsString(); + final yaml = loadYaml(content) as YamlMap; + final workspace = yaml['workspace'] as YamlList?; + if (workspace != null) { + return workspace.nodes.map((node) => node.value as String).toList(); + } + } catch (e) { + log(red.wrap('Error reading workspace packages: $e'), stderr); + } + return []; } - for (final command in commands) { - log(blue.wrap(command.description), stdout); + Future _processProject(String projectPath, String dartVersion) async { + final projectName = p.basename(projectPath); + final projectDir = Directory(projectPath); + final issues = []; - final (didPass, output) = await runCommand( - command.executable, - command.arguments, - workingDirectory: projectPath, - isDryRun: isDryRun, - ); + if (!projectDir.existsSync()) { + log(red.wrap('Project directory not found: $projectPath'), stderr); + return false; + } - if (!didPass) { - log(red.wrap('${command.displayName} failed for $projectName'), stderr); + log(styleBold.wrap('\n========================================='), stdout); + log(styleBold.wrap('Processing project: $projectName'), stdout); + log(styleBold.wrap('=========================================')!, stdout); - if (command.displayName == 'pub upgrade' || - command.displayName == 'pub get' && - output.contains('Failed to update packages.')) { - issues.add(output); + log(blue.wrap('Updating SDK constraints to use Dart $dartVersion'), stdout); + if (!_isDryRun) { + if (!await _updateSdkConstraints(projectPath, dartVersion)) { + log(red.wrap('Failed to update SDK constraints for $projectName'), + stderr); + return false; } + } - if (command.displayName == 'dart analyze' && - output.contains('issue found.') || - output.contains('issues found.')) { - issues.add(output); - } + final commands = [ + Command('dart analyze', 'Running dart analyze...', 'dart', + ['analyze', '--fatal-infos', '--fatal-warnings']), + Command('dart format', 'Running dart format...', 'dart', ['format', '.']), + ]; + + final testDir = Directory(p.join(projectPath, 'test')); + if (projectName != 'material_3_demo' && testDir.existsSync()) { + commands.add( + Command('flutter test', 'Running tests...', 'flutter', ['test'])); + } - if (command.displayName == 'flutter test' && - !output.contains('All tests passed!')) { - issues.add(output); + for (final command in commands) { + log(blue.wrap(command.description), stdout); + + final (didPass, output) = await _runCommand( + command.executable, + command.arguments, + workingDirectory: projectPath, + ); + + if (!didPass) { + log(red.wrap('${command.displayName} failed for $projectName'), stderr); + + if (command.displayName == 'pub upgrade' || + command.displayName == 'pub get' && + output.contains('Failed to update packages.')) { + issues.add(output); + } + + if (command.displayName == 'dart analyze' && + output.contains('issue found.') || + output.contains('issues found.')) { + issues.add(output); + } + + if (command.displayName == 'flutter test' && + !output.contains('All tests passed!')) { + issues.add(output); + } } } - } - if (issues.isNotEmpty) { - logToFile('- Issues found in $projectName'); - for (final issue in issues) { - if (isOnlyWhitespace(issue)) continue; - logToFile('-- $issue'); + if (issues.isNotEmpty) { + logToFile('- Issues found in $projectName'); + for (final issue in issues) { + if (_isOnlyWhitespace(issue)) continue; + logToFile('-- $issue'); + } } + + log(green.wrap('Successfully processed $projectName'), stdout); + return true; } - log(green.wrap('Successfully processed $projectName'), stdout); - return true; -} + Future _updateSdkConstraints( + String projectDir, String versionString) async { + final pubspecFile = File(p.join(projectDir, 'pubspec.yaml')); + if (!pubspecFile.existsSync()) { + log(red.wrap('pubspec.yaml not found in $projectDir'), stderr); + return false; + } -Future updateSdkConstraints( - String projectDir, String versionString) async { - final pubspecFile = File(p.join(projectDir, 'pubspec.yaml')); - if (!pubspecFile.existsSync()) { - log(red.wrap('pubspec.yaml not found in $projectDir'), stderr); - return false; + try { + final newConstraint = '^${versionString}-0'; + + final content = await pubspecFile.readAsString(); + final editor = YamlEditor(content); + editor.update(['environment', 'sdk'], newConstraint); + + await pubspecFile.writeAsString(editor.toString()); + log( + blue.wrap( + 'Updated Dart SDK constraint in $projectDir to: $newConstraint'), + stdout); + return true; + } catch (e) { + log(red.wrap('Failed to update SDK constraint in $projectDir: $e'), + stderr); + return false; + } } - try { - final newConstraint = '^${versionString}-0'; - - final content = await pubspecFile.readAsString(); - final editor = YamlEditor(content); - editor.update(['environment', 'sdk'], newConstraint); + Future<(bool, String)> _runCommand(String executable, List arguments, + {String? workingDirectory}) async { + final commandString = '$executable ${arguments.join(' ')}'; + if (_isDryRun) { + log( + yellow.wrap( + ' [DRY RUN] Would execute: `$commandString` in `${workingDirectory ?? '.'}`'), + stdout); + return (true, ''); + } - await pubspecFile.writeAsString(editor.toString()); - log( - blue.wrap( - 'Updated Dart SDK constraint in $projectDir to: $newConstraint'), - stdout); - return true; - } catch (e) { - log(red.wrap('Failed to update SDK constraint in $projectDir: $e'), stderr); - return false; - } -} + final process = await Process.start(executable, arguments, + workingDirectory: workingDirectory, runInShell: true); -Future<(bool, String)> runCommand(String executable, List arguments, - {String? workingDirectory, bool isDryRun = false}) async { - final commandString = '$executable ${arguments.join(' ')}'; - if (isDryRun) { - log( - yellow.wrap( - ' [DRY RUN] Would execute: `$commandString` in `${workingDirectory ?? '.'}`'), - stdout); - return (true, ''); - } + StringBuffer output = StringBuffer(''); - final process = await Process.start(executable, arguments, - workingDirectory: workingDirectory, runInShell: true); + final stdoutFuture = + process.stdout.transform(SystemEncoding().decoder).forEach((line) { + log(line, stdout); + if (!_isOnlyWhitespace(line)) output.writeln('${line.trim().padLeft(2)}'); + }); - StringBuffer output = StringBuffer(''); + final stderrFuture = + process.stderr.transform(SystemEncoding().decoder).forEach((line) { + log(red.wrap(line), stderr); + if (!_isOnlyWhitespace(line)) output.writeln('${line.trim().padLeft(2)}'); + }); - final stdoutFuture = - process.stdout.transform(SystemEncoding().decoder).forEach((line) { - log(line, stdout); - if (!isOnlyWhitespace(line)) output.writeln('${line.trim().padLeft(2)}'); - }); + await Future.wait([stdoutFuture, stderrFuture]); - final stderrFuture = - process.stderr.transform(SystemEncoding().decoder).forEach((line) { - log(red.wrap(line), stderr); - if (!isOnlyWhitespace(line)) output.writeln('${line.trim().padLeft(2)}'); - }); + return (await process.exitCode == 0, output.toString()); + } - await Future.wait([stdoutFuture, stderrFuture]); + void _printSummary(int total, List failed) { + log(styleBold.wrap('\n=========================================')!, stdout); + log(styleBold.wrap('Update Summary')!, stdout); + log(styleBold.wrap('=========================================')!, stdout); + log(blue.wrap('Total projects processed: $total'), stdout); + log(green.wrap('Successful: ${total - failed.length}'), stdout); - return (await process.exitCode == 0, output.toString()); -} + if (failed.isNotEmpty) { + log(red.wrap('Failed: ${failed.length}'), stderr); + log(red.wrap('Failed projects: ${failed.join(', ')}'), stderr); + } + } -void printSummary(int total, List failed) { - log(styleBold.wrap('\n=========================================')!, stdout); - log(styleBold.wrap('Update Summary')!, stdout); - log(styleBold.wrap('=========================================')!, stdout); - log(blue.wrap('Total projects processed: $total'), stdout); - log(green.wrap('Successful: ${total - failed.length}'), stdout); + String _stripAnsiCodes(String text) { + final ansiRegex = RegExp(r'\x1B\[[0-?]*[ -/]*[@-~]'); + return text.replaceAll(ansiRegex, ''); + } - if (failed.isNotEmpty) { - log(red.wrap('Failed: ${failed.length}'), stderr); - log(red.wrap('Failed projects: ${failed.join(', ')}'), stderr); + bool _isOnlyWhitespace(String text) { + return text.trim().isEmpty; } } @@ -335,12 +320,3 @@ class Command { Command(this.displayName, this.description, this.executable, this.arguments); } - -String stripAnsiCodes(String text) { - final ansiRegex = RegExp(r'\x1B\[[0-?]*[ -/]*[@-~]'); - return text.replaceAll(ansiRegex, ''); -} - -bool isOnlyWhitespace(String text) { - return text.trim().isEmpty; -} diff --git a/tool/release_cleanup.sh b/tool/release_cleanup.sh deleted file mode 100755 index aeea28c02..000000000 --- a/tool/release_cleanup.sh +++ /dev/null @@ -1,267 +0,0 @@ -#!/bin/bash - -set -e - -# Configuration -LOGS_DIR="logs" -LOG_FILE="$LOGS_DIR/flutter_update_$(date +%Y-%m-%d_%H-%M-%S).log" -TEMP_LOG="/tmp/flutter_temp_$$.log" - -# Create logs directory if it doesn't exist -mkdir -p "$LOGS_DIR" - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# Logging function -log() { - echo -e "$1" | tee -a "$LOG_FILE" -} - -log_error() { - echo -e "${RED}ERROR: $1${NC}" | tee -a "$LOG_FILE" -} - -log_warning() { - echo -e "${YELLOW}WARNING: $1${NC}" | tee -a "$LOG_FILE" -} - -log_info() { - echo -e "${BLUE}INFO: $1${NC}" | tee -a "$LOG_FILE" -} - -# Function to check if directory is a Flutter project -is_flutter_project() { - local dir="$1" - [[ -f "$dir/pubspec.yaml" ]] && grep -q "flutter:" "$dir/pubspec.yaml" -} - -# Function to get current Flutter version -get_flutter_version() { - flutter --version --machine | grep '"frameworkVersion"' | cut -d'"' -f4 -} - -# Function to update SDK constraints in pubspec.yaml -update_sdk_constraints() { - local project_dir="$1" - local current_version="$2" - local pubspec="pubspec.yaml" - - if [[ ! -f "$pubspec" ]]; then - log_error "pubspec.yaml not found in $project_dir" - return 1 - fi - - # Extract major and minor version numbers - local major=$(echo "$current_version" | cut -d'.' -f1) - local minor=$(echo "$current_version" | cut -d'.' -f2) - local next_major=$((major + 1)) - - # Create SDK constraint string - local sdk_constraint=">=$current_version <$next_major.0.0" - - # Update only the Dart SDK constraint under environment: section - # This specifically targets the sdk: line under environment: and not flutter dependencies - if grep -A5 "^environment:" "$pubspec" | grep -q "sdk:"; then - # Use perl to update only the environment sdk constraint - perl -i -pe ' - BEGIN { $in_env = 0; } - if (/^environment:/) { $in_env = 1; } - elsif (/^\w/ && !/^\s/) { $in_env = 0; } - if ($in_env && /(\s+sdk:\s*)['\''"]?[^'\''"]*['\''"]?/) { - s/(\s+sdk:\s*)['\''"]?[^'\''"]*['\''"]?/$1'\'''"$sdk_constraint"'\''/; - } - ' "$pubspec" - log_info "Updated Dart SDK constraint in $project_dir to: $sdk_constraint" - else - log_warning "No Dart SDK constraint found under environment: in $project_dir/pubspec.yaml" - return 1 - fi -} - -# Function to process a single Flutter project -process_project() { - local project_dir="$1" - local project_name=$(basename "$project_dir") - - log "" - log "=========================================" - log "Processing project: $project_name" - log "=========================================" - - cd "$project_dir" - - # Get current Flutter version for SDK constraints - local flutter_version - flutter_version=$(get_flutter_version) - if [[ $? -ne 0 ]]; then - log_error "Failed to get Flutter version for $project_name" - return 1 - fi - - # Update SDK constraints - log_info "Updating SDK constraints to use Flutter $flutter_version" - if ! update_sdk_constraints "$project_dir" "$flutter_version"; then - log_error "Failed to update SDK constraints for $project_name" - return 1 - fi - - # Update dependencies - log_info "Updating dependencies..." - if ! flutter pub upgrade > "$TEMP_LOG" 2>&1; then - log_error "Failed to upgrade dependencies for $project_name" - cat "$TEMP_LOG" >> "$LOG_FILE" - return 1 - fi - - # Run pub get - log_info "Running pub get..." - if ! flutter pub get > "$TEMP_LOG" 2>&1; then - log_error "Failed to run pub get for $project_name" - cat "$TEMP_LOG" >> "$LOG_FILE" - return 1 - fi - - # Run dart analyze and capture output - log_info "Running dart analyze..." - if ! dart analyze > "$TEMP_LOG" 2>&1; then - local exit_code=$? - log_error "Dart analyze found issues in $project_name (exit code: $exit_code)" - - # Filter and log only errors, warnings, and infos (not success messages) - if grep -E "(error|warning|info):" "$TEMP_LOG" > /dev/null; then - log "Analyze results for $project_name:" - grep -E "(error|warning|info):" "$TEMP_LOG" >> "$LOG_FILE" - fi - - # Check if there are fatal errors (errors that would prevent compilation) - if grep -E "^error:" "$TEMP_LOG" > /dev/null; then - log_error "Fatal errors found in $project_name, skipping further processing" - return 1 - fi - else - # Even on success, check for warnings and infos - if grep -E "(warning|info):" "$TEMP_LOG" > /dev/null; then - log "Analyze results for $project_name:" - grep -E "(warning|info):" "$TEMP_LOG" >> "$LOG_FILE" - fi - fi - - # Run dart format - log_info "Running dart format..." - if ! dart format . > "$TEMP_LOG" 2>&1; then - log_error "Failed to format code for $project_name" - cat "$TEMP_LOG" >> "$LOG_FILE" - # Continue anyway, formatting errors are not fatal - fi - - # Run tests - log_info "Running tests..." - if ! flutter test > "$TEMP_LOG" 2>&1; then - local exit_code=$? - log_error "Tests failed for $project_name (exit code: $exit_code)" - - # Log test failures - if grep -E "(FAILED|ERROR|Exception)" "$TEMP_LOG" > /dev/null; then - log "Test failures for $project_name:" - grep -E "(FAILED|ERROR|Exception)" "$TEMP_LOG" >> "$LOG_FILE" - fi - - return 1 - fi - - log_info "Successfully processed $project_name" - return 0 -} - -# Main execution -main() { - local original_dir="$PWD" - log "Flutter Monorepo Update Script Started: $(date)" - log "Log file: $LOG_FILE" - - # Check if Flutter is installed - if ! command -v flutter &> /dev/null; then - log_error "Flutter is not installed or not in PATH" - exit 1 - fi - - # Upgrade Flutter SDK - log "" - log "=========================================" - log "Upgrading Flutter SDK" - log "=========================================" - - if ! flutter upgrade > "$TEMP_LOG" 2>&1; then - log_error "Failed to upgrade Flutter SDK" - cat "$TEMP_LOG" >> "$LOG_FILE" - exit 1 - fi - - local flutter_version - flutter_version=$(get_flutter_version) - log_info "Flutter upgraded to version: $flutter_version" - - # Find all Flutter projects in the current directory - local projects=() - for dir in */; do - if [[ -d "$dir" ]] && is_flutter_project "$dir"; then - projects+=("$dir") - fi - done - - if [[ ${#projects[@]} -eq 0 ]]; then - log_warning "No Flutter projects found in the current directory" - exit 0 - fi - - log_info "Found ${#projects[@]} Flutter project(s): ${projects[*]}" - - # Process each project - local success_count=0 - local failure_count=0 - local failed_projects=() - - for project in "${projects[@]}"; do - if process_project "$project"; then - ((success_count++)) - else - ((failure_count++)) - failed_projects+=("$(basename "$project")") - fi - - # Return to root directory - cd "$original_dir" - done - - # Summary - log "" - log "=========================================" - log "Update Summary" - log "=========================================" - log_info "Total projects processed: ${#projects[@]}" - log_info "Successful: $success_count" - - if [[ $failure_count -gt 0 ]]; then - log_error "Failed: $failure_count" - log_error "Failed projects: ${failed_projects[*]}" - fi - - log "" - log "Flutter Monorepo Update Script Completed: $(date)" - - # Cleanup - rm -f "$TEMP_LOG" - - # Exit with error code if any projects failed - if [[ $failure_count -gt 0 ]]; then - exit 1 - fi -} - -# Run main function -main "$@" \ No newline at end of file diff --git a/workspace.md b/workspace.md index 7c5e1dbf7..f906c5ed7 100644 --- a/workspace.md +++ b/workspace.md @@ -1,8 +1,25 @@ -You are a Dart developer that maintains this monorepo of Flutter sample projects. +You are a Dart developer that maintains this monorepo of sample projects. These are the tasks you need to do when necessary: + +- Update for release of a new version of flutter/dart + - Read the release blog posts at (USER WILL PROVIDE) + - In the repository, checkout the "beta" git branch and make sure its up to date + - Make sure the local flutter SDK is pointing to the beta channel + - Run 'tool/release.dart', which will create a log file. + - Read the log file and address any issues it describes. + - Use the gh cli to make a PR + +- Delete samples and replace with a README + - Remove all files within a sample project directory. + - Create a README and explain that the project is deprecated. + - Look at issues on (USER WILL PROVIDE LINK TO GITHUB ISSUES) + - If there are any open issues that describe deleting this sample, link to it in the README + +- Mark stale code + - Create a 'stale_code.md' file if it doesn't exist. + - For each sample, look at the git logs and find the most recent commit to a .dart file in sample made by a real person. + - If that commit was more than one year ago, log it by appending to the stale code log 'sample name, git user name, date of last commit' + - + -- Read https://dart.dev/tools/pub/workspaces -- Create a gloabl pubspec.yaml and populate it -- Determine 5 packages in this repository that could easily be migrated to workspaces. -- Migrate those 5 packages.