From c47da3d24ae14cf8faff59b9f123e1a43a801149 Mon Sep 17 00:00:00 2001
From: Natalie Weizenbaum <nweiz@google.com>
Date: Mon, 4 Jan 2016 17:56:54 -0800
Subject: [PATCH] Don't choke on dev transformers from path deps.

Closes #1369

R=rnystrom@google.com

Review URL: https://codereview.chromium.org//1556043006 .
---
 lib/src/pubspec.dart                          | 27 +++++++++++++---
 ...a_package_with_a_dev_transformer_test.dart | 32 +++++++++++++++++++
 2 files changed, 54 insertions(+), 5 deletions(-)
 create mode 100644 test/transformer/gets_and_upgrades_a_package_with_a_dev_transformer_test.dart

diff --git a/lib/src/pubspec.dart b/lib/src/pubspec.dart
index db55b4d5..74e9becd 100644
--- a/lib/src/pubspec.dart
+++ b/lib/src/pubspec.dart
@@ -190,11 +190,8 @@ class Pubspec {
         });
 
         var package = config.id.package;
-        if (package != name &&
-            !config.id.isBuiltInTransformer &&
-            !dependencies.any((ref) => ref.name == package) &&
-            !devDependencies.any((ref) => ref.name == package) &&
-            !dependencyOverrides.any((ref) => ref.name == package)) {
+        if (package != name && !config.id.isBuiltInTransformer &&
+            !_hasDependency(package)) {
           _error('"$package" is not a dependency.',
               libraryNode.span);
         }
@@ -207,6 +204,26 @@ class Pubspec {
   }
   List<Set<TransformerConfig>> _transformers;
 
+  /// Returns whether this pubspec has any kind of dependency on [package].
+  ///
+  /// This explicitly avoids calling [_parseDependencies] because parsing dev
+  /// dependencies can fail for a hosted package's pubspec (e.g. if that package
+  /// has a relative path dev dependency).
+  bool _hasDependency(String package) {
+    return [
+      'dependencies', 'dev_dependencies', 'dependency_overrides'
+    ].any((field) {
+      var map = fields[field];
+      if (map == null) return false;
+
+      if (map is! Map) {
+        _error('"$field" field must be a map.', fields.nodes[field].span);
+      }
+
+      return map.containsKey(package);
+    });
+  }
+
   /// The environment-related metadata.
   PubspecEnvironment get environment {
     if (_environment != null) return _environment;
diff --git a/test/transformer/gets_and_upgrades_a_package_with_a_dev_transformer_test.dart b/test/transformer/gets_and_upgrades_a_package_with_a_dev_transformer_test.dart
new file mode 100644
index 00000000..c47a226e
--- /dev/null
+++ b/test/transformer/gets_and_upgrades_a_package_with_a_dev_transformer_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS d.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:scheduled_test/scheduled_test.dart';
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+import '../serve/utils.dart';
+
+// Regression test for #1369.
+main() {
+  integration("gets and upgrades a package with a dev transformer", () {
+    servePackages((builder) {
+      builder.serveRealPackage('barback');
+
+      builder.serve('foo', '1.0.0', pubspec: {
+        'transformers': [
+          {'bar': {r'$include': 'test/**'}}
+        ],
+        'dev_dependencies': {
+          'bar': {'path': '../bar'}
+        }
+      });
+    });
+
+    d.appDir({'foo': '1.0.0'}).create();
+
+    // Check for the error message because pub didn't consider this error fatal.
+    pubGet(error: isEmpty, exitCode: 0);
+  });
+}
-- 
GitLab