| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library googleapis_generator.package_configuration; | 5 library googleapis_generator.package_configuration; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 | 9 |
| 10 import 'package:discoveryapis_generator/discoveryapis_generator.dart'; | 10 import 'package:discoveryapis_generator/discoveryapis_generator.dart'; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 | 22 |
| 23 Package(this.name, this.apis, this.pubspec, this.readme, this.license, | 23 Package(this.name, this.apis, this.pubspec, this.readme, this.license, |
| 24 this.changelog); | 24 this.changelog); |
| 25 } | 25 } |
| 26 | 26 |
| 27 /** | 27 /** |
| 28 * Configuration of a set of packages generated from a set of APIs exposed by | 28 * Configuration of a set of packages generated from a set of APIs exposed by |
| 29 * a Discovery Service. | 29 * a Discovery Service. |
| 30 */ | 30 */ |
| 31 class DiscoveryPackagesConfiguration { | 31 class DiscoveryPackagesConfiguration { |
| 32 String configFile; |
| 33 Map yaml; |
| 32 Map<String, Package> packages = {}; | 34 Map<String, Package> packages = {}; |
| 33 Iterable<String> excessApis; | 35 Iterable<String> excessApis; |
| 34 Iterable<String> missingApis; | 36 Iterable<String> missingApis; |
| 35 | 37 |
| 36 /** | 38 /** |
| 37 * Create a new discovery packages configuration. | 39 * Create a new discovery packages configuration. |
| 38 * | 40 * |
| 39 * [config] is the path to the YAML configuration file. | 41 * [config] is the path to the YAML configuration file. |
| 40 * | 42 * |
| 41 * [allApis] is the list of all supported APIs returned by the Discovery | 43 * [allApis] is the list of all supported APIs returned by the Discovery |
| (...skipping 25 matching lines...) Expand all Loading... |
| 67 * - adexchangebuyer:v1 | 69 * - adexchangebuyer:v1 |
| 68 * | 70 * |
| 69 * Each package to build is listed under the key `packages:`. | 71 * Each package to build is listed under the key `packages:`. |
| 70 * | 72 * |
| 71 * The key `skipped_apis` is used to list APIs returned buy the Discovery | 73 * The key `skipped_apis` is used to list APIs returned buy the Discovery |
| 72 * Service but is not part of any generated packages. | 74 * Service but is not part of any generated packages. |
| 73 * | 75 * |
| 74 * The file names for the content of readme and license files are resolved | 76 * The file names for the content of readme and license files are resolved |
| 75 * relative to the configuration file. | 77 * relative to the configuration file. |
| 76 */ | 78 */ |
| 77 DiscoveryPackagesConfiguration( | 79 DiscoveryPackagesConfiguration(this.configFile) { |
| 78 String configFile, List<DirectoryListItems> allApis) { | 80 yaml = loadYaml(new File(configFile).readAsStringSync()); |
| 79 var configYaml = new File(configFile).readAsStringSync(); | 81 } |
| 80 var yaml = loadYaml(configYaml); | 82 |
| 81 packages = _packagesFromYaml(yaml['packages'], configFile, allApis); | 83 /** |
| 82 var knownApis = _calculateKnownApis(packages, | 84 * Downloads discovery documents from the configuration. |
| 83 _listFromYaml(yaml['skipped_apis'])); | 85 * |
| 84 missingApis = _calculateMissingApis(knownApis, allApis); | 86 * [discoveryDocsDir] is the directory where all the downloaded discovery |
| 85 excessApis = _calculateExcessApis(knownApis, allApis); | 87 * documents are stored. |
| 88 */ |
| 89 Future download(String discoveryDocsDir, |
| 90 List<DirectoryListItems> items) async { |
| 91 // Delete all downloaded discovery documents. |
| 92 var dir = new Directory(discoveryDocsDir); |
| 93 if (dir.existsSync()) dir.deleteSync(recursive: true); |
| 94 |
| 95 // Get all rest discovery documents & initialize this object. |
| 96 List<RestDescription> allApis = await fetchDiscoveryDocuments(); |
| 97 _initialize(allApis); |
| 98 |
| 99 // Download the discovery documents for the packages to build |
| 100 // (only the APIs we're interested in). |
| 101 var futures = []; |
| 102 packages.forEach((name, package) { |
| 103 futures.add(downloadDiscoveryDocuments('$discoveryDocsDir/$name', |
| 104 ids: package.apis)); |
| 105 }); |
| 106 |
| 107 return Future.wait(futures).then((List<List<RestDescription>> results) { |
| 108 _initialize(results.expand((result) => result).toList()); |
| 109 }); |
| 86 } | 110 } |
| 87 | 111 |
| 88 /** | 112 /** |
| 89 * Generate packages from the configuration. | 113 * Generate packages from the configuration. |
| 90 * | 114 * |
| 91 * [discoveryDocsDir] is the directory where all the downloaded discovery | 115 * [discoveryDocsDir] is the directory where all the downloaded discovery |
| 92 * documents are stored. | 116 * documents are stored. |
| 93 * | 117 * |
| 94 * [generatedApisDir] is the directory where the packages are generated. | 118 * [generatedApisDir] is the directory where the packages are generated. |
| 95 * Each package is generated in a sub-directory. | 119 * Each package is generated in a sub-directory. |
| 96 */ | 120 */ |
| 97 Future generate(String discoveryDocsDir, String generatedApisDir) { | 121 void generate(String discoveryDocsDir, String generatedApisDir) { |
| 98 // Delete all downloaded discovery documents. | 122 // Delete all downloaded discovery documents. |
| 99 var dir = new Directory(discoveryDocsDir); | 123 var dir = new Directory(discoveryDocsDir); |
| 100 if (dir.existsSync()) dir.deleteSync(recursive: true); | 124 if (!dir.existsSync()) { |
| 125 throw new Exception( |
| 126 'Error: The given `$discoveryDocsDir` directory does not exist.'); |
| 127 } |
| 101 | 128 |
| 102 // Download the discovery documents for the packages to build. | 129 // Load discovery documents from disc & initialize this object. |
| 103 var futures = []; | 130 List<RestDescription> allApis = []; |
| 104 packages.forEach((name, package) { | 131 yaml['packages'].forEach((Map package) { |
| 105 futures.add(downloadDiscoveryDocuments('$discoveryDocsDir/$name', | 132 package.forEach((String name, _) { |
| 106 ids: package.apis)); | 133 allApis.addAll(loadDiscoveryDocuments('$discoveryDocsDir/$name')); |
| 107 }); | |
| 108 | |
| 109 return Future.wait(futures).then((_) { | |
| 110 packages.forEach((name, package) { | |
| 111 generateAllLibraries('$discoveryDocsDir/$name', | |
| 112 '$generatedApisDir/$name', | |
| 113 package.pubspec); | |
| 114 new File('$generatedApisDir/$name/README.md') | |
| 115 .writeAsStringSync(package.readme); | |
| 116 if (package.license != null) { | |
| 117 new File('$generatedApisDir/$name/LICENSE') | |
| 118 .writeAsStringSync(package.license); | |
| 119 } | |
| 120 if (package.changelog != null) { | |
| 121 new File('$generatedApisDir/$name/CHANGELOG.md') | |
| 122 .writeAsStringSync(package.changelog); | |
| 123 } | |
| 124 }); | 134 }); |
| 125 }); | 135 }); |
| 136 _initialize(allApis); |
| 137 |
| 138 // Generate packages. |
| 139 packages.forEach((name, package) { |
| 140 generateAllLibraries('$discoveryDocsDir/$name', |
| 141 '$generatedApisDir/$name', |
| 142 package.pubspec); |
| 143 new File('$generatedApisDir/$name/README.md') |
| 144 .writeAsStringSync(package.readme); |
| 145 if (package.license != null) { |
| 146 new File('$generatedApisDir/$name/LICENSE') |
| 147 .writeAsStringSync(package.license); |
| 148 } |
| 149 if (package.changelog != null) { |
| 150 new File('$generatedApisDir/$name/CHANGELOG.md') |
| 151 .writeAsStringSync(package.changelog); |
| 152 } |
| 153 }); |
| 154 } |
| 155 |
| 156 /** |
| 157 * Initializes the missingApis/excessApis/packages properties from a list |
| 158 * of [RestDescription]s. |
| 159 */ |
| 160 void _initialize(List<RestDescription> allApis) { |
| 161 packages = _packagesFromYaml(yaml['packages'], configFile, allApis); |
| 162 var knownApis = _calculateKnownApis(packages, |
| 163 _listFromYaml(yaml['skipped_apis'])); |
| 164 missingApis = _calculateMissingApis(knownApis, allApis); |
| 165 excessApis = _calculateExcessApis(knownApis, allApis); |
| 126 } | 166 } |
| 127 | 167 |
| 128 // Return empty list for YAML null value. | 168 // Return empty list for YAML null value. |
| 129 static List _listFromYaml(value) => value != null ? value : []; | 169 static List _listFromYaml(value) => value != null ? value : []; |
| 130 | 170 |
| 131 static String _generateReadme( | 171 static String _generateReadme( |
| 132 String readmeFile, List<DirectoryListItems> items) { | 172 String readmeFile, List<RestDescription> items) { |
| 133 var sb = new StringBuffer(); | 173 var sb = new StringBuffer(); |
| 134 if (readmeFile != null) { | 174 if (readmeFile != null) { |
| 135 sb.write(new File(readmeFile).readAsStringSync()); | 175 sb.write(new File(readmeFile).readAsStringSync()); |
| 136 } | 176 } |
| 137 sb.writeln(''' | 177 sb.writeln(''' |
| 138 | 178 |
| 139 ## Available Google APIs | 179 ## Available Google APIs |
| 140 | 180 |
| 141 The following is a list of APIs that are currently available inside this | 181 The following is a list of APIs that are currently available inside this |
| 142 package. | 182 package. |
| 143 '''); | 183 '''); |
| 144 for (DirectoryListItems item in items) { | 184 for (RestDescription item in items) { |
| 145 sb.write("#### "); | 185 sb.write("#### "); |
| 146 if (item.icons != null && item.icons.x16 != null) { | 186 if (item.icons != null && item.icons.x16 != null) { |
| 147 sb.write(" "); | 187 sb.write(" "); |
| 148 } | 188 } |
| 149 sb..writeln('${item.title} - ${item.name} ${item.version}') | 189 sb..writeln('${item.title} - ${item.name} ${item.version}') |
| 150 ..writeln() | 190 ..writeln() |
| 151 ..writeln('${item.description}') | 191 ..writeln('${item.description}') |
| 152 ..writeln(); | 192 ..writeln(); |
| 153 if (item.documentationLink != null) { | 193 if (item.documentationLink != null) { |
| 154 sb.writeln( | 194 sb.writeln( |
| 155 'Official API documentation: ${item.documentationLink}'); | 195 'Official API documentation: ${item.documentationLink}'); |
| 156 sb.writeln(); | 196 sb.writeln(); |
| 157 } | 197 } |
| 158 } | 198 } |
| 159 return sb.toString(); | 199 return sb.toString(); |
| 160 } | 200 } |
| 161 | 201 |
| 162 static Map<String, Package> _packagesFromYaml( | 202 static Map<String, Package> _packagesFromYaml( |
| 163 YamlList configPackages, | 203 YamlList configPackages, |
| 164 String configFile, | 204 String configFile, |
| 165 List<DirectoryListItems> allApis) { | 205 List<RestDescription> allApis) { |
| 166 var packages = {}; | 206 var packages = {}; |
| 167 configPackages.forEach((package) { | 207 configPackages.forEach((package) { |
| 168 package.forEach((name, values) { | 208 package.forEach((name, values) { |
| 169 packages[name] = _packageFromYaml(name, values, configFile, allApis); | 209 packages[name] = _packageFromYaml(name, values, configFile, allApis); |
| 170 }); | 210 }); |
| 171 }); | 211 }); |
| 172 | 212 |
| 173 return packages; | 213 return packages; |
| 174 } | 214 } |
| 175 | 215 |
| 176 static Package _packageFromYaml(String name, | 216 static Package _packageFromYaml(String name, |
| 177 YamlMap values, | 217 YamlMap values, |
| 178 String configFile, | 218 String configFile, |
| 179 List<DirectoryListItems> allApis) { | 219 List<RestDescription> allApis) { |
| 180 var apis = _listFromYaml(values['apis']); | 220 var apis = _listFromYaml(values['apis']); |
| 181 var version = | 221 var version = |
| 182 values['version'] != null ? values['version'] : '0.1.0-dev'; | 222 values['version'] != null ? values['version'] : '0.1.0-dev'; |
| 183 var author = values['author']; | 223 var author = values['author']; |
| 184 var homepage = values['homepage']; | 224 var homepage = values['homepage']; |
| 185 | 225 |
| 186 var configUri = new Uri.file(configFile); | 226 var configUri = new Uri.file(configFile); |
| 187 | 227 |
| 228 allApis.sort((RestDescription a, RestDescription b) { |
| 229 int result = a.name.compareTo(b.name); |
| 230 if (result != 0) return result; |
| 231 return a.version.compareTo(b.version); |
| 232 }); |
| 233 |
| 188 var readmeFile; | 234 var readmeFile; |
| 189 if (values['readme'] != null) { | 235 if (values['readme'] != null) { |
| 190 readmeFile = configUri.resolve(values['readme']).path; | 236 readmeFile = configUri.resolve(values['readme']).path; |
| 191 } | 237 } |
| 192 var licenseFile; | 238 var licenseFile; |
| 193 if (values['license'] != null) { | 239 if (values['license'] != null) { |
| 194 licenseFile = configUri.resolve(values['license']).path; | 240 licenseFile = configUri.resolve(values['license']).path; |
| 195 } | 241 } |
| 196 var changelogFile; | 242 var changelogFile; |
| 197 if (values['changelog'] != null) { | 243 if (values['changelog'] != null) { |
| 198 changelogFile = configUri.resolve(values['changelog']).path; | 244 changelogFile = configUri.resolve(values['changelog']).path; |
| 199 } | 245 } |
| 200 | 246 |
| 201 // Generate package description. | 247 // Generate package description. |
| 202 var apiDescriptions = []; | 248 var apiDescriptions = []; |
| 203 var sb = new StringBuffer() | 249 var sb = new StringBuffer() |
| 204 ..write('"Auto-generated client libraries for accessing ' | 250 ..write('"Auto-generated client libraries for accessing ' |
| 205 'the following APIs:'); | 251 'the following APIs:'); |
| 206 bool first = true; | 252 bool first = true; |
| 207 allApis.forEach((DirectoryListItems apiDescription) { | 253 allApis.forEach((RestDescription apiDescription) { |
| 208 if (apis.contains(apiDescription.id)) { | 254 if (apis.contains(apiDescription.id)) { |
| 209 if (!first) sb.write(', '); | 255 if (!first) sb.write(', '); |
| 210 sb.write(apiDescription.id); | 256 sb.write(apiDescription.id); |
| 211 apiDescriptions.add(apiDescription); | 257 apiDescriptions.add(apiDescription); |
| 212 first = false; | 258 first = false; |
| 213 } | 259 } |
| 214 }); | 260 }); |
| 215 sb.write('"'); | 261 sb.write('"'); |
| 216 | 262 |
| 217 // Generate the README.md file content. | 263 // Generate the README.md file content. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 235 YamlList skippedApis) { | 281 YamlList skippedApis) { |
| 236 var knownApis = new Set(); | 282 var knownApis = new Set(); |
| 237 knownApis.addAll(skippedApis); | 283 knownApis.addAll(skippedApis); |
| 238 packages.forEach((_, package) => knownApis.addAll(package.apis)); | 284 packages.forEach((_, package) => knownApis.addAll(package.apis)); |
| 239 return knownApis; | 285 return knownApis; |
| 240 } | 286 } |
| 241 | 287 |
| 242 /// The missing APIs are the APIs returned from the Discovery Service | 288 /// The missing APIs are the APIs returned from the Discovery Service |
| 243 /// but not mentioned in the configuration. | 289 /// but not mentioned in the configuration. |
| 244 static Iterable<String> _calculateMissingApis( | 290 static Iterable<String> _calculateMissingApis( |
| 245 Iterable<String> knownApis, List<DirectoryListItems> allApis) { | 291 Iterable<String> knownApis, List<RestDescription> allApis) { |
| 246 return allApis | 292 return allApis |
| 247 .where((item) => !knownApis.contains(item.id)) | 293 .where((item) => !knownApis.contains(item.id)) |
| 248 .map((item) => item.id); | 294 .map((item) => item.id); |
| 249 } | 295 } |
| 250 | 296 |
| 251 /// The excess APIs are the APIs mentioned in the configuration but not | 297 /// The excess APIs are the APIs mentioned in the configuration but not |
| 252 /// returned from the Discovery Service. | 298 /// returned from the Discovery Service. |
| 253 static Iterable<String> _calculateExcessApis( | 299 static Iterable<String> _calculateExcessApis( |
| 254 Iterable<String> knownApis, List<DirectoryListItems> allApis) { | 300 Iterable<String> knownApis, List<RestDescription> allApis) { |
| 255 var excessApis = new Set.from(knownApis); | 301 var excessApis = new Set.from(knownApis); |
| 256 allApis.forEach((item) => excessApis.remove(item.id)); | 302 allApis.forEach((item) => excessApis.remove(item.id)); |
| 257 return excessApis; | 303 return excessApis; |
| 258 } | 304 } |
| 259 } | 305 } |
| 260 | 306 |
| OLD | NEW |