Fix bug with the `dt update-version` tool (#9793)
diff --git a/pubspec.lock b/pubspec.lock
index a2a5876..7629d2b 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -975,10 +975,10 @@
     dependency: transitive
     description:
       name: vm_service
-      sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
+      sha256: "046d3928e16fa4dc46e8350415661755ab759d9fc97fc21b5ab295f71e4f0499"
       url: "https://pub.dev"
     source: hosted
-    version: "15.0.2"
+    version: "15.1.0"
   vm_service_protos:
     dependency: transitive
     description:
diff --git a/tool/lib/commands/presubmit.dart b/tool/lib/commands/presubmit.dart
index c051803..6664880 100644
--- a/tool/lib/commands/presubmit.dart
+++ b/tool/lib/commands/presubmit.dart
@@ -65,7 +65,10 @@
         final pathsToFormat = _getPathsToFormat(p);
 
         final formatProcess = await pm.runProcess(
-          CliCommand.dart(['format', ...pathsToFormat], throwOnException: false),
+          CliCommand.dart([
+            'format',
+            ...pathsToFormat,
+          ], throwOnException: false),
           workingDirectory: p.packagePath,
         );
 
@@ -108,10 +111,12 @@
         final pathsToFormat = _getPathsToFormat(p);
 
         final formatProcess = await pm.runProcess(
-          CliCommand.dart(
-            ['format', '--output=none', '--set-exit-if-changed', ...pathsToFormat],
-            throwOnException: false,
-          ),
+          CliCommand.dart([
+            'format',
+            '--output=none',
+            '--set-exit-if-changed',
+            ...pathsToFormat,
+          ], throwOnException: false),
           workingDirectory: p.packagePath,
         );
 
diff --git a/tool/lib/commands/update_version.dart b/tool/lib/commands/update_version.dart
index 2891ba3..099be52 100644
--- a/tool/lib/commands/update_version.dart
+++ b/tool/lib/commands/update_version.dart
@@ -208,6 +208,25 @@
   return RegExp(r'-dev\.\d+').hasMatch(version);
 }
 
+String calculateNewVersion(String currentVersion, String type) {
+  switch (type) {
+    case 'release':
+      if (isDevVersion(currentVersion)) {
+        return stripPreReleases(currentVersion);
+      } else {
+        return incrementVersionByType(currentVersion, 'minor')!;
+      }
+    case 'dev':
+      return incrementDevVersion(currentVersion);
+    default:
+      final version = incrementVersionByType(currentVersion, type);
+      if (version == null) {
+        throw 'Failed to determine the newVersion.';
+      }
+      return version;
+  }
+}
+
 const pubspecVersionPrefix = 'version:';
 
 class ManualUpdateCommand extends Command {
@@ -326,23 +345,10 @@
     final type = argResults!['type'] as String;
     final isDryRun = argResults!['dry-run'] as bool;
     final currentVersion = versionFromPubspecFile();
-    String? newVersion;
     if (currentVersion == null) {
       throw 'Could not automatically determine current version.';
     }
-    switch (type) {
-      case 'release':
-        newVersion = stripPreReleases(currentVersion);
-        break;
-      case 'dev':
-        newVersion = incrementDevVersion(currentVersion);
-        break;
-      default:
-        newVersion = incrementVersionByType(currentVersion, type);
-        if (newVersion == null) {
-          throw 'Failed to determine the newVersion.';
-        }
-    }
+    final newVersion = calculateNewVersion(currentVersion, type);
     print('Bump version from $currentVersion to $newVersion');
 
     if (isDryRun) {
diff --git a/tool/test/update_version_test.dart b/tool/test/update_version_test.dart
new file mode 100644
index 0000000..68be52f
--- /dev/null
+++ b/tool/test/update_version_test.dart
@@ -0,0 +1,40 @@
+// Copyright 2026 The Flutter Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
+
+import 'package:devtools_tool/commands/update_version.dart';
+import 'package:test/test.dart';
+
+void main() {
+  group('calculateNewVersion', () {
+    test('release type strips pre-release when on dev version', () {
+      expect(calculateNewVersion('2.28.0-dev.0', 'release'), '2.28.0');
+      expect(calculateNewVersion('2.28.0-dev.5', 'release'), '2.28.0');
+    });
+
+    test('release type increments minor version when not on dev version', () {
+      expect(calculateNewVersion('2.28.0', 'release'), '2.29.0');
+      expect(calculateNewVersion('2.28.1', 'release'), '2.29.0');
+    });
+
+    test('dev type increments dev version', () {
+      expect(calculateNewVersion('1.2.3', 'dev'), '1.2.3-dev.0');
+      expect(calculateNewVersion('1.2.3-dev.4', 'dev'), '1.2.3-dev.5');
+    });
+
+    test('patch type increments patch version', () {
+      expect(calculateNewVersion('1.2.3', 'patch'), '1.2.4');
+      expect(calculateNewVersion('1.2.3-dev.4', 'patch'), '1.2.4');
+    });
+
+    test('minor type increments minor version', () {
+      expect(calculateNewVersion('1.2.3', 'minor'), '1.3.0');
+      expect(calculateNewVersion('1.2.3-dev.4', 'minor'), '1.3.0');
+    });
+
+    test('major type increments major version', () {
+      expect(calculateNewVersion('1.2.3', 'major'), '2.0.0');
+      expect(calculateNewVersion('1.2.3-dev.4', 'major'), '2.0.0');
+    });
+  });
+}
diff --git a/tool/test/validate_skills_test.dart b/tool/test/validate_skills_test.dart
index 7c50d63..1c44f8b 100644
--- a/tool/test/validate_skills_test.dart
+++ b/tool/test/validate_skills_test.dart
@@ -11,12 +11,13 @@
   test('Validate DevTools Skills', () async {
     final Level oldLevel = Logger.root.level;
     Logger.root.level = Level.ALL;
-    final StreamSubscription<LogRecord> subscription = Logger.root.onRecord.listen((record) {
-      print(record.message);
-    });
+    final StreamSubscription<LogRecord> subscription = Logger.root.onRecord
+        .listen((record) {
+          print(record.message);
+        });
 
     try {
-      // TODO(https://github.com/flutter/skills/issues/85): Update test 
+      // TODO(https://github.com/flutter/skills/issues/85): Update test
       // to use dart_skills_lint.yaml for config when available.
       final bool isValid = await validateSkills(
         skillDirPaths: ['../.agents/skills'],
@@ -26,7 +27,11 @@
           'check-trailing-whitespace': AnalysisSeverity.error,
         },
       );
-      expect(isValid, isTrue, reason: 'Skills validation failed. See above for details.');
+      expect(
+        isValid,
+        isTrue,
+        reason: 'Skills validation failed. See above for details.',
+      );
     } finally {
       Logger.root.level = oldLevel;
       await subscription.cancel();