Merge pull request #42 from dart-lang/allow-periods-in-package-names

allow periods in package names
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9de10b4..f481e20 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+#### 0.12.2+1
+  * Allow periods in package names (but can't end or begin with one).
+
 #### 0.12.2
   * Update to JS version
     [0.7.20](https://github.com/webcomponents/webcomponentsjs/tree/v0.7.20).
diff --git a/lib/build/script_compactor.dart b/lib/build/script_compactor.dart
index f177638..64fb318 100644
--- a/lib/build/script_compactor.dart
+++ b/lib/build/script_compactor.dart
@@ -229,7 +229,7 @@
 
 /// Generate a library name for an asset.
 String _libraryNameFor(AssetId id, BuildLogger logger, [int suffix]) {
-  if (id.package.contains(_invalidLibCharsRegex)) {
+  if (_isInvalidPackageName(id.package)) {
     logger.error('Invalid package name `${id.package}`. Package names should '
         'be valid dart identifiers, as indicated at '
         'https://www.dartlang.org/tools/pub/pubspec.html#name.');
@@ -262,6 +262,12 @@
   return path.url.relative(id.path, from: path.url.dirname(primaryInput.path));
 }
 
+bool _isInvalidPackageName(String name) {
+  return name.split('.').any((part) {
+    return part.isEmpty || part.contains(_invalidLibCharsRegex);
+  });
+}
+
 // Constant and final variables
 final _invalidLibCharsRegex = new RegExp('[^a-z0-9_]');
 final _numRegex = new RegExp('[0-9]');
diff --git a/pubspec.yaml b/pubspec.yaml
index 96fe7af..b78bb32 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: web_components
-version: 0.12.2
+version: 0.12.2+1
 author: Polymer.dart Authors <web-ui-dev@dartlang.org>
 homepage: https://github.com/dart-lang/web-components/
 description: >
diff --git a/test/build/script_compactor_test.dart b/test/build/script_compactor_test.dart
index a0c2ce3..7ffed81 100644
--- a/test/build/script_compactor_test.dart
+++ b/test/build/script_compactor_test.dart
@@ -209,6 +209,65 @@
     'valid dart identifiers, as indicated at '
     'https://www.dartlang.org/tools/pub/pubspec.html#name.'
   ], StringFormatter.noNewlinesOrSurroundingWhitespace);
+
+  testPhases('package names that start with a period are not allowed', phases, {
+    '.a|web/a.html': '''
+        <!DOCTYPE html><html><head></head><body>
+          <script type="application/dart" src="a.dart"></script>
+        </body></html>''',
+    '.a|web/a.dart': '''
+        library a.a;
+        main(){}''',
+  }, {}, [
+    'error: Invalid package name `.a`. Package names should be '
+    'valid dart identifiers, as indicated at '
+    'https://www.dartlang.org/tools/pub/pubspec.html#name.'
+  ], StringFormatter.noNewlinesOrSurroundingWhitespace);
+
+  testPhases('package names that end with a period are not allowed', phases, {
+    'a.|web/a.html': '''
+        <!DOCTYPE html><html><head></head><body>
+          <script type="application/dart" src="a.dart"></script>
+        </body></html>''',
+    'a.|web/a.dart': '''
+        library a.a;
+        main(){}''',
+  }, {}, [
+    'error: Invalid package name `a.`. Package names should be '
+    'valid dart identifiers, as indicated at '
+    'https://www.dartlang.org/tools/pub/pubspec.html#name.'
+  ], StringFormatter.noNewlinesOrSurroundingWhitespace);
+
+  testPhases('package names with double periods are not allowed', phases, {
+    'a..b|web/a.html': '''
+        <!DOCTYPE html><html><head></head><body>
+          <script type="application/dart" src="a.dart"></script>
+        </body></html>''',
+    'a..b|web/a.dart': '''
+        library a.a;
+        main(){}''',
+  }, {}, [
+    'error: Invalid package name `a..b`. Package names should be '
+    'valid dart identifiers, as indicated at '
+    'https://www.dartlang.org/tools/pub/pubspec.html#name.'
+  ], StringFormatter.noNewlinesOrSurroundingWhitespace);
+
+  testPhases('package names with internal periods are allowed', phases, {
+    'a.b|web/a.html': '''
+        <!DOCTYPE html><html><head></head><body>
+          <script type="application/dart" src="a.dart"></script>
+        </body></html>''',
+    'a.b|web/a.dart': '''
+        library a.b.a;
+        main(){}''',
+  }, {
+    'a.b|web/a.bootstrap.dart': '''
+      library a.b.web.a_bootstrap_dart;
+
+      import 'a.dart' as i0;
+
+      main() => i0.main();''',
+  }, [], StringFormatter.noNewlinesOrSurroundingWhitespace);
 }
 
 void codeExtractorTests() {