Fix handling of 'git@github.com:dart-lang/pub.git' style urls in git source (#3381)

diff --git a/lib/src/source/git.dart b/lib/src/source/git.dart
index 0d26283..44b3fee 100644
--- a/lib/src/source/git.dart
+++ b/lib/src/source/git.dart
@@ -641,6 +641,9 @@
   /// If the url was relative in the pubspec.yaml it will be resolved relative
   /// to the pubspec location, and stored here as an absolute file url, and
   /// [relative] will be true.
+  ///
+  /// This will not always parse as a [Uri] due the fact that `Uri.parse` does not allow strings of
+  /// the form: 'git@github.com:dart-lang/pub.git'.
   final String url;
 
   /// `true` if [url] was parsed from a relative url.
@@ -679,7 +682,7 @@
 
   @override
   String format() {
-    var result = '${p.prettyUri(url)} at '
+    var result = '${prettyUri(url)} at '
         '$ref';
     if (path != '.') result += ' in $path';
     return result;
@@ -715,6 +718,18 @@
 
   @override
   int get hashCode => Object.hash(url, ref, path);
+
+  // Similar in intend to [p.prettyUri] but does not fail if the input doesn't
+  // parse with [Uri.parse].
+  static String prettyUri(String url) {
+    // HACK: Working around the fact that `Uri.parse` does not allow strings of
+    // the form: 'git@github.com:dart-lang/pub.git'.
+    final parsedAsUri = Uri.tryParse(url);
+    if (parsedAsUri == null) {
+      return url;
+    }
+    return p.prettyUri(url);
+  }
 }
 
 class GitResolvedDescription extends ResolvedDescription {
@@ -727,7 +742,7 @@
 
   @override
   String format() {
-    var result = '${p.prettyUri(description.url)} at '
+    var result = '${GitDescription.prettyUri(description.url)} at '
         '${resolvedRef.substring(0, 6)}';
     if (description.path != '.') result += ' in ${description.path}';
     return result;
diff --git a/test/get/git/ssh_url_test.dart b/test/get/git/ssh_url_test.dart
new file mode 100644
index 0000000..e38f895
--- /dev/null
+++ b/test/get/git/ssh_url_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:pub/src/language_version.dart';
+
+import 'package:pub/src/source/git.dart';
+
+import 'package:test/test.dart';
+
+void main() {
+  // These tests are not integration tests because it seems to be hard to
+  // actually test this kind of urls locally. We would have to set up serving
+  // git over ssh.
+  //
+  // We could set up a local cache, and only test the '--offline' part of this.
+  // But for now we live with this.
+  test(
+      'Git description uris can be of the form git@github.com:dart-lang/pub.git',
+      () {
+    final description = GitDescription(
+      url: 'git@github.com:dart-lang/pub.git',
+      ref: 'main',
+      path: 'abc/',
+      containingDir: null,
+    );
+    expect(description.format(),
+        'git@github.com:dart-lang/pub.git at main in abc/');
+    expect(
+      description.serializeForPubspec(
+        containingDir: null,
+        languageVersion: LanguageVersion(2, 16),
+      ),
+      {
+        'url': 'git@github.com:dart-lang/pub.git',
+        'ref': 'main',
+        'path': 'abc/',
+      },
+    );
+    final resolvedDescription = GitResolvedDescription(
+        description, '7d48f902b0326fc2ce0615c20f1aab6c811fe55b');
+
+    expect(
+      resolvedDescription.format(),
+      'git@github.com:dart-lang/pub.git at 7d48f9 in abc/',
+    );
+    expect(
+      resolvedDescription.serializeForLockfile(containingDir: null),
+      {
+        'url': 'git@github.com:dart-lang/pub.git',
+        'ref': 'main',
+        'path': 'abc/',
+        'resolved-ref': '7d48f902b0326fc2ce0615c20f1aab6c811fe55b',
+      },
+    );
+  });
+}