Use caret syntax in environment recommendations (#3673)

Use ^-syntax if applicable when recommending constraints
diff --git a/lib/src/validator.dart b/lib/src/validator.dart
index cbf930f..e558772 100644
--- a/lib/src/validator.dart
+++ b/lib/src/validator.dart
@@ -105,7 +105,7 @@
         'Make sure your SDK constraint excludes old versions:\n'
         '\n'
         'environment:\n'
-        '  sdk: "$newSdkConstraint"');
+        '  sdk: "${newSdkConstraint.asCompatibleWithIfPossible()}"');
   }
 
   /// Returns whether [version1] and [version2] are pre-releases of the same version.
@@ -230,3 +230,16 @@
   ValidationContext(
       this.entrypoint, this.packageSize, this.serverUrl, this.files);
 }
+
+extension on VersionConstraint {
+  // Returns `this` expressed as [VersionConstraint.compatibleWith] if possible.
+  VersionConstraint asCompatibleWithIfPossible() {
+    final range = this;
+    if (range is! VersionRange) return this;
+    final min = range.min;
+    if (min == null) return this;
+    final asCompatibleWith = VersionConstraint.compatibleWith(min);
+    if (asCompatibleWith == this) return asCompatibleWith;
+    return this;
+  }
+}
diff --git a/test/testdata/goldens/directory_option_test/commands taking a --directory~-C parameter work.txt b/test/testdata/goldens/directory_option_test/commands taking a --directory~-C parameter work.txt
index 577a0a5..e133de4 100644
--- a/test/testdata/goldens/directory_option_test/commands taking a --directory~-C parameter work.txt
+++ b/test/testdata/goldens/directory_option_test/commands taking a --directory~-C parameter work.txt
@@ -113,7 +113,7 @@
 [STDERR]   Make sure your SDK constraint excludes old versions:
 [STDERR]   
 [STDERR]   environment:
-[STDERR]     sdk: ">=1.8.0 <2.0.0"
+[STDERR]     sdk: "^1.8.0"
 [STDERR] Sorry, your package is missing a requirement and can't be published yet.
 [STDERR] For more information, see: https://dart.dev/tools/pub/cmd/pub-lish.
 [EXIT CODE] 65
diff --git a/test/validator/dependency_test.dart b/test/validator/dependency_test.dart
index 81694dd..083cbcc 100644
--- a/test/validator/dependency_test.dart
+++ b/test/validator/dependency_test.dart
@@ -401,7 +401,7 @@
         ]).create();
 
         await expectValidationError(
-          '  sdk: ">=1.8.0 <2.0.0"',
+          '  sdk: "^1.8.0"',
           environment: {'_PUB_TEST_SDK_VERSION': '1.5.0'},
         );
       });
@@ -424,7 +424,7 @@
 
         await expectValidation(
           error: allOf(
-            contains('  sdk: ">=2.0.0 <3.0.0"'),
+            contains('  sdk: "^2.0.0"'),
             contains('  foo: any'),
           ),
           exitCode: DATA,
@@ -450,7 +450,7 @@
 
         await expectValidation(
           error: allOf([
-            contains('  sdk: ">=2.0.0 <3.0.0"'),
+            contains('  sdk: "^2.0.0"'),
             contains('  foo: any'),
           ]),
           environment: {'_PUB_TEST_SDK_VERSION': '1.24.0'},
@@ -479,7 +479,7 @@
         sdk: '>=1.18.0 <2.0.0',
       ).create();
 
-      await expectValidationError('sdk: ">=1.19.0 <2.0.0"', environment: {
+      await expectValidationError('sdk: "^1.19.0"', environment: {
         '_PUB_TEST_SDK_VERSION': '1.19.0',
         'FLUTTER_ROOT': path.join(d.sandbox, 'flutter'),
       });
@@ -493,7 +493,7 @@
       }).create();
 
       await expectValidationError(
-        'sdk: ">=1.19.0 <2.0.0"',
+        'sdk: "^1.19.0"',
         environment: {
           '_PUB_TEST_SDK_VERSION': '0.0.0',
           'FLUTTER_ROOT': path.join(d.sandbox, 'flutter'),
@@ -525,7 +525,7 @@
       }).create();
 
       await expectValidationError(
-        'sdk: ">=2.0.0 <3.0.0"',
+        'sdk: "^2.0.0"',
         environment: {'FUCHSIA_DART_SDK_ROOT': path.join(d.sandbox, 'fuchsia')},
       );
     });
diff --git a/test/validator/sdk_constraint_test.dart b/test/validator/sdk_constraint_test.dart
index 297b872..9f45748 100644
--- a/test/validator/sdk_constraint_test.dart
+++ b/test/validator/sdk_constraint_test.dart
@@ -109,7 +109,7 @@
         })
       ]).create();
       await expectValidation(sdkConstraint,
-          errors: anyElement(contains('">=1.19.0 <2.0.0"')));
+          errors: anyElement(contains('"^1.19.0"')));
     });
 
     test(
@@ -123,7 +123,7 @@
         })
       ]).create();
       await expectValidation(sdkConstraint,
-          errors: anyElement(contains('">=2.0.0 <3.0.0"')));
+          errors: anyElement(contains('"^2.0.0"')));
     });
 
     test('has a Fuchsia SDK constraint with no SDK constraint', () async {
@@ -135,7 +135,7 @@
         })
       ]).create();
       await expectValidation(sdkConstraint,
-          errors: anyElement(contains('">=2.0.0 <3.0.0"')));
+          errors: anyElement(contains('"^2.0.0"')));
     });
 
     test('depends on a pre-release sdk from a non-pre-release', () async {