diff --git a/CHANGELOG.md b/CHANGELOG.md index 17a64fb3..85bccf7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # CHANGELOG +## 0.2.4 +- Improved layout of `server-appengine`. + ## 0.2.3+1 - fixed an issue with the Polymer template diff --git a/README.md b/README.md index 3c42a1e7..4c08fc28 100644 --- a/README.md +++ b/README.md @@ -27,25 +27,32 @@ Requirements: To install: - $> pub global activate stagehand +```console +> pub global activate stagehand +``` -To update: +To update, run activate again: - # activate stagehand again - $> pub global activate stagehand +```console +> pub global activate stagehand +``` ## Usage Stagehand will generate a project skeleton into the current directory. As an example, here is how you create a package with Stagehand: - $> mkdir fancy_project - $> cd fancy_project - $> stagehand package-simple +```console +> mkdir fancy_project +> cd fancy_project +> stagehand package-simple +``` And to list all of the project templates: - $> stagehand +```console +> stagehand +``` ## Goals diff --git a/lib/generators/console_full_data.dart b/lib/generators/console_full_data.dart index f53bc15b..7b8f18f2 100644 --- a/lib/generators/console_full_data.dart +++ b/lib/generators/console_full_data.dart @@ -2,7 +2,7 @@ // All rights reserved. Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -List data = [ +const List data = const [ ".gitignore", "text", """LmJ1aWxkbG9nCi5EU19TdG9yZQouaWRlYQoucGFja2FnZXMKLnB1Yi8KYnVpbGQvCnBhY2thZ2Vz diff --git a/lib/generators/console_simple_data.dart b/lib/generators/console_simple_data.dart index 7dfac358..f169b94f 100644 --- a/lib/generators/console_simple_data.dart +++ b/lib/generators/console_simple_data.dart @@ -2,7 +2,7 @@ // All rights reserved. Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -List data = [ +const List data = const [ "bin/main.dart", "text", "bWFpbihMaXN0PFN0cmluZz4gYXJncykgewogIHByaW50KCdIZWxsbyB3b3JsZCEnKTsKfQo=", diff --git a/lib/generators/package_simple_data.dart b/lib/generators/package_simple_data.dart index 66b40a58..7e80219f 100644 --- a/lib/generators/package_simple_data.dart +++ b/lib/generators/package_simple_data.dart @@ -2,7 +2,7 @@ // All rights reserved. Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -List data = [ +const List data = const [ ".gitignore", "text", """LmJ1aWxkbG9nCi5EU19TdG9yZQouaWRlYQoucGFja2FnZXMKLnB1Yi8KYnVpbGQvCnBhY2thZ2Vz diff --git a/lib/generators/server_appengine_data.dart b/lib/generators/server_appengine_data.dart index f555ab26..0057aa04 100644 --- a/lib/generators/server_appengine_data.dart +++ b/lib/generators/server_appengine_data.dart @@ -2,7 +2,7 @@ // All rights reserved. Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -List data = [ +const List data = const [ ".gitignore", "text", """LmJ1aWxkbG9nCi5EU19TdG9yZQouaWRlYQoucGFja2FnZXMKLnB1Yi8KYnVpbGQvCnBhY2thZ2Vz @@ -129,36 +129,37 @@ bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKbGlicmFyeSB7 e3Byb2plY3ROYW1lfX0ubWVtY2FjaGU7CgppbXBvcnQgJ2RhcnQ6YXN5bmMnOwppbXBvcnQgJ2Rh cnQ6aW8nOwoKaW1wb3J0ICdwYWNrYWdlOmFwcGVuZ2luZS9hcHBlbmdpbmUuZGFydCc7Cgpjb25z dCBTdHJpbmcgREVGQVVMVF9LRVkgPSAnaGVsbG8nOwpib29sIGNhY2hlSW5pdGlhbGl6ZWQgPSBm -YWxzZTsKCi8vLyBJbml0aWFsaXplIHRoZSBjYWNoZS4KRnV0dXJlIGluaXRpYWxpemUoKSB7CiAg -Ly8gSWYgdGhlIGNhY2hlIGlzIGFscmVhZHkgaW5pdGlhbGl6ZWQsIGp1c3QgcmV0dXJuLgogIGlm -IChjYWNoZUluaXRpYWxpemVkKSB7CiAgICByZXR1cm4gbmV3IEZ1dHVyZS52YWx1ZSgpOwogIH0K -CiAgLy8gVGhlIEFwcEVuZ2luZSBlbnZpcm9ubWVudCBoYXMgYSBwcmVjb25maWd1cmVkICdjb250 -ZXh0JyB3aGljaCBwcm92aWRlcwogIC8vIGF1dGhvcml6ZWQgYWNjZXNzIHRvIHRoZSBkZWZhdWx0 -IGFwaSBzZXJ2aWNlcy4KICB2YXIgbWVtY2FjaGUgPSBjb250ZXh0LnNlcnZpY2VzLm1lbWNhY2hl -OwoKICAvLyBJbml0aWFsaXplIHRoZSBjYWNoZSBhbmQgc2V0IHRoZSBkZWZhdWx0IHZhbHVlLgog -IHJldHVybiBtZW1jYWNoZS5jbGVhcigpCiAgICAgIC50aGVuKChfKSA9PiBtZW1jYWNoZS5zZXQo -REVGQVVMVF9LRVksICd0aGVyZSEnKSkKICAgICAgLnRoZW4oKF8pID0+IGNhY2hlSW5pdGlhbGl6 -ZWQgPSB0cnVlKTsKfQoKLy8vIENsZWFycyB0aGUgY2FjaGUgYW5kIHJlc2V0cyB0aGUgZGVmYXVs -dC4KRnV0dXJlIGNsZWFyKCkgewogIGNhY2hlSW5pdGlhbGl6ZWQgPSBmYWxzZTsKICByZXR1cm4g -aW5pdGlhbGl6ZSgpOwp9CgovLy8gSGVscGVyIG1ldGhvZCB0byB3cml0ZSBhIHNldCBvZiBrZXkv -dmFsdWUgcGFpcnMgdG8gdGhlIG1lbWNhY2hlLgp2b2lkIHdyaXRlKEh0dHBSZXNwb25zZSByZXNw -b25zZSwgTWFwPFN0cmluZywgU3RyaW5nPiB2YWx1ZU1hcCkgewogIHZhciBtZW1jYWNoZSA9IGNv -bnRleHQuc2VydmljZXMubWVtY2FjaGU7CiAgRnV0dXJlLmZvckVhY2godmFsdWVNYXAua2V5cywg -KGtleSkgewogICAgdmFyIHZhbHVlID0gdmFsdWVNYXBba2V5XTsKICAgIHJldHVybiBtZW1jYWNo -ZS5zZXQoa2V5LCB2YWx1ZSkKICAgICAgICAudGhlbigoXykgPT4gcmVzcG9uc2Uud3JpdGVsbign -IiR7a2V5fSI6ICIke3ZhbHVlfSInKSk7CiAgfSkud2hlbkNvbXBsZXRlKHJlc3BvbnNlLmNsb3Nl -KTsKfQoKLy8vIEhlbHBlciBtZXRob2QgdG8gcmVhZCBhIHNldCBvZiB2YWx1ZXMgZnJvbSB0aGUg -bWVtY2FjaGUuCnZvaWQgcmVhZChIdHRwUmVzcG9uc2UgcmVzcG9uc2UsIEl0ZXJhYmxlPFN0cmlu -Zz4ga2V5cykgewogIHZhciBtZW1jYWNoZSA9IGNvbnRleHQuc2VydmljZXMubWVtY2FjaGU7CiAg -RnV0dXJlLmZvckVhY2goa2V5cywgKGtleSkgPT4gbWVtY2FjaGUuZ2V0KGtleSkKICAgICAgLnRo -ZW4oKHZhbHVlKSA9PiByZXNwb25zZS53cml0ZWxuKCciJHtrZXl9IjogIiR7dmFsdWV9IicpKQog -ICAgICAuY2F0Y2hFcnJvcigoXykgPT4gcmVzcG9uc2Uud3JpdGVsbignIiR7a2V5fSI6IHZhbHVl -IG5vdCBmb3VuZCEnKSkpCiAgICAud2hlbkNvbXBsZXRlKHJlc3BvbnNlLmNsb3NlKTsKfQo=""", +YWxzZTsKCi8vLyBJbml0aWFsaXplIHRoZSBjYWNoZS4KRnV0dXJlIGluaXRpYWxpemUoKSBhc3lu +YyB7CiAgLy8gSWYgdGhlIGNhY2hlIGlzIGFscmVhZHkgaW5pdGlhbGl6ZWQsIGp1c3QgcmV0dXJu +LgogIGlmIChjYWNoZUluaXRpYWxpemVkKSByZXR1cm47CgogIC8vIFRoZSBBcHBFbmdpbmUgZW52 +aXJvbm1lbnQgaGFzIGEgcHJlY29uZmlndXJlZCAnY29udGV4dCcgd2hpY2ggcHJvdmlkZXMKICAv +LyBhdXRob3JpemVkIGFjY2VzcyB0byB0aGUgZGVmYXVsdCBhcGkgc2VydmljZXMuCiAgdmFyIG1l +bWNhY2hlID0gY29udGV4dC5zZXJ2aWNlcy5tZW1jYWNoZTsKCiAgLy8gSW5pdGlhbGl6ZSB0aGUg +Y2FjaGUgYW5kIHNldCB0aGUgZGVmYXVsdCB2YWx1ZS4KICBhd2FpdCBtZW1jYWNoZS5jbGVhcigp +OwogIGF3YWl0IG1lbWNhY2hlLnNldChERUZBVUxUX0tFWSwgJ3RoZXJlIScpOwogIGNhY2hlSW5p +dGlhbGl6ZWQgPSB0cnVlOwp9CgovLy8gQ2xlYXJzIHRoZSBjYWNoZSBhbmQgcmVzZXRzIHRoZSBk +ZWZhdWx0LgpGdXR1cmUgY2xlYXIoKSBhc3luYyB7CiAgY2FjaGVJbml0aWFsaXplZCA9IGZhbHNl +OwogIGF3YWl0IGluaXRpYWxpemUoKTsKfQoKLy8vIEhlbHBlciBtZXRob2QgdG8gd3JpdGUgYSBz +ZXQgb2Yga2V5L3ZhbHVlIHBhaXJzIHRvIHRoZSBtZW1jYWNoZS4Kdm9pZCB3cml0ZShIdHRwUmVz +cG9uc2UgcmVzcG9uc2UsIE1hcDxTdHJpbmcsIFN0cmluZz4gdmFsdWVNYXApIHsKICB2YXIgbWVt +Y2FjaGUgPSBjb250ZXh0LnNlcnZpY2VzLm1lbWNhY2hlOwogIEZ1dHVyZS5mb3JFYWNoKHZhbHVl +TWFwLmtleXMsIChrZXkpIHsKICAgIHZhciB2YWx1ZSA9IHZhbHVlTWFwW2tleV07CiAgICByZXR1 +cm4gbWVtY2FjaGUKICAgICAgICAuc2V0KGtleSwgdmFsdWUpCiAgICAgICAgLnRoZW4oKF8pID0+ +IHJlc3BvbnNlLndyaXRlbG4oJyIke2tleX0iOiAiJHt2YWx1ZX0iJykpOwogIH0pLndoZW5Db21w +bGV0ZShyZXNwb25zZS5jbG9zZSk7Cn0KCi8vLyBIZWxwZXIgbWV0aG9kIHRvIHJlYWQgYSBzZXQg +b2YgdmFsdWVzIGZyb20gdGhlIG1lbWNhY2hlLgp2b2lkIHJlYWQoSHR0cFJlc3BvbnNlIHJlc3Bv +bnNlLCBJdGVyYWJsZTxTdHJpbmc+IGtleXMpIHsKICB2YXIgbWVtY2FjaGUgPSBjb250ZXh0LnNl +cnZpY2VzLm1lbWNhY2hlOwogIEZ1dHVyZQogICAgICAuZm9yRWFjaCgKICAgICAgICAgIGtleXMs +CiAgICAgICAgICAoa2V5KSA9PiBtZW1jYWNoZQogICAgICAgICAgICAgIC5nZXQoa2V5KQogICAg +ICAgICAgICAgIC50aGVuKCh2YWx1ZSkgPT4gcmVzcG9uc2Uud3JpdGVsbignIiR7a2V5fSI6ICIk +e3ZhbHVlfSInKSkKICAgICAgICAgICAgICAuY2F0Y2hFcnJvcigKICAgICAgICAgICAgICAgICAg +KF8pID0+IHJlc3BvbnNlLndyaXRlbG4oJyIke2tleX0iOiB2YWx1ZSBub3QgZm91bmQhJykpKQog +ICAgICAud2hlbkNvbXBsZXRlKHJlc3BvbnNlLmNsb3NlKTsKfQo=""", "pubspec.yaml", "text", """bmFtZToge3twcm9qZWN0TmFtZX19CnZlcnNpb246IDAuMC4xCmRlc2NyaXB0aW9uOiBBIHNpbXBs ZSBBcHAgRW5naW5lIGFwcGxpY2F0aW9uLgojYXV0aG9yOiB7e2F1dGhvcn19IDxlbWFpbEBleGFt cGxlLmNvbT4KI2hvbWVwYWdlOiBodHRwczovL3d3dy5leGFtcGxlLmNvbQoKZW52aXJvbm1lbnQ6 -CiAgc2RrOiAnPj0xLjUuMCA8Mi4wLjAnCgpkZXBlbmRlbmNpZXM6CiAgYXBwZW5naW5lOiAnPj0w +CiAgc2RrOiAnPj0xLjkuMCA8Mi4wLjAnCgpkZXBlbmRlbmNpZXM6CiAgYXBwZW5naW5lOiAnPj0w LjMuMCA8MC40LjAnCg==""" ]; diff --git a/lib/generators/server_shelf_data.dart b/lib/generators/server_shelf_data.dart index a7ca88fd..524c0caa 100644 --- a/lib/generators/server_shelf_data.dart +++ b/lib/generators/server_shelf_data.dart @@ -2,7 +2,7 @@ // All rights reserved. Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -List data = [ +const List data = const [ ".gitignore", "text", """LmJ1aWxkbG9nCi5EU19TdG9yZQouaWRlYQoucGFja2FnZXMKLnB1Yi8KYnVpbGQvCnBhY2thZ2Vz diff --git a/lib/generators/web_polymer_data.dart b/lib/generators/web_polymer_data.dart index ae54954a..1f24b52c 100644 --- a/lib/generators/web_polymer_data.dart +++ b/lib/generators/web_polymer_data.dart @@ -2,7 +2,7 @@ // All rights reserved. Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -List data = [ +const List data = const [ ".gitignore", "text", """LmJ1aWxkbG9nCi5EU19TdG9yZQouaWRlYQoucGFja2FnZXMKLnB1Yi8KYnVpbGQvCnBhY2thZ2Vz diff --git a/lib/generators/web_simple_data.dart b/lib/generators/web_simple_data.dart index b3e9085e..d914eef4 100644 --- a/lib/generators/web_simple_data.dart +++ b/lib/generators/web_simple_data.dart @@ -2,7 +2,7 @@ // All rights reserved. Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -List data = [ +const List data = const [ ".gitignore", "text", """LmJ1aWxkbG9nCi5EU19TdG9yZQouaWRlYQoucGFja2FnZXMKLnB1Yi8KYnVpbGQvCnBhY2thZ2Vz diff --git a/templates/server-appengine/lib/memcache.dart b/templates/server-appengine/lib/memcache.dart index f343064c..aeb58052 100644 --- a/templates/server-appengine/lib/memcache.dart +++ b/templates/server-appengine/lib/memcache.dart @@ -12,26 +12,24 @@ const String DEFAULT_KEY = 'hello'; bool cacheInitialized = false; /// Initialize the cache. -Future initialize() { +Future initialize() async { // If the cache is already initialized, just return. - if (cacheInitialized) { - return new Future.value(); - } + if (cacheInitialized) return; // The AppEngine environment has a preconfigured 'context' which provides // authorized access to the default api services. var memcache = context.services.memcache; // Initialize the cache and set the default value. - return memcache.clear() - .then((_) => memcache.set(DEFAULT_KEY, 'there!')) - .then((_) => cacheInitialized = true); + await memcache.clear(); + await memcache.set(DEFAULT_KEY, 'there!'); + cacheInitialized = true; } /// Clears the cache and resets the default. -Future clear() { +Future clear() async { cacheInitialized = false; - return initialize(); + await initialize(); } /// Helper method to write a set of key/value pairs to the memcache. @@ -39,7 +37,8 @@ void write(HttpResponse response, Map valueMap) { var memcache = context.services.memcache; Future.forEach(valueMap.keys, (key) { var value = valueMap[key]; - return memcache.set(key, value) + return memcache + .set(key, value) .then((_) => response.writeln('"${key}": "${value}"')); }).whenComplete(response.close); } @@ -47,8 +46,13 @@ void write(HttpResponse response, Map valueMap) { /// Helper method to read a set of values from the memcache. void read(HttpResponse response, Iterable keys) { var memcache = context.services.memcache; - Future.forEach(keys, (key) => memcache.get(key) - .then((value) => response.writeln('"${key}": "${value}"')) - .catchError((_) => response.writeln('"${key}": value not found!'))) - .whenComplete(response.close); + Future + .forEach( + keys, + (key) => memcache + .get(key) + .then((value) => response.writeln('"${key}": "${value}"')) + .catchError( + (_) => response.writeln('"${key}": value not found!'))) + .whenComplete(response.close); } diff --git a/templates/server-appengine/pubspec.yaml b/templates/server-appengine/pubspec.yaml index b4ba0296..260abc43 100644 --- a/templates/server-appengine/pubspec.yaml +++ b/templates/server-appengine/pubspec.yaml @@ -5,7 +5,7 @@ description: A simple App Engine application. #homepage: https://www.example.com environment: - sdk: '>=1.5.0 <2.0.0' + sdk: '>=1.9.0 <2.0.0' dependencies: appengine: '>=0.3.0 <0.4.0' diff --git a/test/validate_templates.dart b/test/validate_templates.dart index 5b9b9294..6f39f90c 100644 --- a/test/validate_templates.dart +++ b/test/validate_templates.dart @@ -9,7 +9,7 @@ library stagehand.test.validate_templates; import 'dart:io'; -import 'package:grinder/grinder.dart'; +import 'package:grinder/grinder.dart' hide fail; import 'package:path/path.dart' as path; import 'package:stagehand/stagehand.dart' as stagehand; import 'package:test/test.dart'; @@ -44,7 +44,7 @@ void _testGenerator(stagehand.Generator generator, Directory tempDir) { var pubspecFile = new File(pubspecPath); if (!pubspecFile.existsSync()) { - throw 'A pubspec much be defined!'; + fail('A pubspec much be defined!'); } Pub.get(runOptions: new RunOptions(workingDirectory: tempDir.path)); diff --git a/tool/grind.dart b/tool/grind.dart index 8d43e3ee..17534070 100644 --- a/tool/grind.dart +++ b/tool/grind.dart @@ -60,18 +60,14 @@ test() => new TestRunner().testAsync(files: 'test/validate_templates.dart'); void _concatenateFiles(Directory src, File target) { log('Creating ${target.path}'); - List results = []; - - _traverse(src, '', results); - - String str = results.map((s) => ' ${_toStr(s)}').join(',\n'); + String str = _traverse(src, '').map((s) => ' ${_toStr(s)}').join(',\n'); target.writeAsStringSync(""" // Copyright (c) 2014, Google Inc. 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. -List data = [ +const List data = const [ ${str} ]; """); @@ -85,27 +81,22 @@ String _toStr(String s) { } } -void _traverse(Directory dir, String root, List results) { +Iterable _traverse(Directory dir, String root) sync* { var files = _listSync(dir, recursive: false, followLinks: false); for (FileSystemEntity entity in files) { - String name = path.basename(entity.path); - if (entity is Link) continue; + String name = path.basename(entity.path); if (name == 'pubspec.lock') continue; if (name.startsWith('.') && name != '.gitignore') continue; if (entity is Directory) { - _traverse(entity, '${root}${name}/', results); + yield* _traverse(entity, '${root}${name}/'); } else { - File file = entity; - String fileType = _isBinaryFile(name) ? 'binary' : 'text'; - String data = CryptoUtils.bytesToBase64(file.readAsBytesSync(), + yield '${root}${name}'; + yield _isBinaryFile(name) ? 'binary' : 'text'; + yield BASE64.encode((entity as File).readAsBytesSync(), addLineSeparator: true); - - results.add('${root}${name}'); - results.add(fileType); - results.add(data); } } }