From 3e21b68005e89205ffc1cda9c46fc1fb879ee056 Mon Sep 17 00:00:00 2001 From: John Pedrie Date: Fri, 10 Mar 2017 17:24:36 -0500 Subject: [PATCH] Component split (#360) * Reorganize namespaces and fix tests * # This is a combination of 9 commits. # This is the 1st commit message: Reorganize namespaces and fix tests Update component versions via the CLI # This is the commit message #2: Create tags in components # This is the commit message #3: Send component name and version in user agent # This is the commit message #4: Add README files # This is the commit message #5: Fix CLI # This is the commit message #6: Add split to travis # This is the commit message #7: Test datastore release # This is the commit message #8: Compile splitsh # This is the commit message #9: Reintroduce full split process * # This is a combination of 2 commits. # This is the 1st commit message: Reorganize namespaces and fix tests Update component versions via the CLI Create tags in components Send component name and version in user agent Add README files Fix CLI Add split to travis Test datastore release Compile splitsh Reintroduce full split process Release patches # This is the commit message #2: Run split in each build matrix * Reorganize namespaces and fix tests Update component versions via the CLI Create tags in components Send component name and version in user agent Add README files Fix CLI Add split to travis Test datastore release Compile splitsh Reintroduce full split process Release patches Run split in each build matrix Release datastore patch enable set -e * Work with github API directly * Fix Vision class reference * Create VERSION file for all components * Remove componentName * Fix int64 snippet tests * Update component release target * Parse documentation separately for each component * This works now * Add flag to docs to use JSON_PRETTY_PRINT for debugging * Parse correct links between components * Fix unit tests * Doc links within component should not change version * Cross-component links should go to the correct version docs * Update snippets to remove refs to ServiceBuilder * Remove unnecessary env vars * Don't write VERSION for parent * Release packages * release v0.24.1 * Add autoloaders to each component * Pass libVersion to gax config * Update push docs command * add gcsUri helper * allow gcsUri or storage object * Release 0.24.2 * Update things again * this is the worst * Link to upstream tag * tag * Update table of contents * Reset versions * Update suggests and requires * fix build docs trigger * dont throw exceptions on decode * Fix docs link * Fix various doc issues * fix namespace --- .travis.yml | 35 +-- composer.json | 8 + dev/google-cloud | 2 + dev/sh/build-docs | 8 +- dev/sh/compile-splitsh | 13 + dev/sh/push-docs | 19 +- dev/sh/split | 10 + dev/sh/trigger-split | 9 + dev/src/DocGenerator/Command/Docs.php | 100 +++++++- dev/src/DocGenerator/DocGenerator.php | 56 +++- dev/src/DocGenerator/Parser/CodeParser.php | 90 ++++++- .../DocGenerator/Parser/MarkdownParser.php | 2 +- dev/src/DocGenerator/TableOfContents.php | 44 ++++ dev/src/DocGenerator/TypeGenerator.php | 4 +- dev/src/DocGenerator/Writer.php | 12 +- dev/src/GetComponentsTrait.php | 116 +++++++++ dev/src/Release/Command/Release.php | 131 +++++++--- dev/src/Snippet/Parser/Snippet.php | 11 +- dev/src/Split/Command/Split.php | 172 +++++++++++++ docs/contents/cloud-bigquery.json | 31 +++ docs/contents/cloud-core.json | 30 +++ docs/contents/cloud-datastore.json | 25 ++ docs/contents/cloud-error-reporting.json | 20 ++ docs/contents/cloud-logging.json | 35 +++ docs/contents/cloud-monitoring.json | 17 ++ docs/contents/cloud-natural-language.json | 7 + docs/contents/cloud-pubsub.json | 26 ++ docs/contents/cloud-speech.json | 17 ++ docs/contents/cloud-storage.json | 13 + docs/contents/cloud-translate.json | 4 + docs/contents/cloud-vision.json | 34 +++ docs/contents/google-cloud.json | 4 + docs/home.html | 2 +- docs/manifest.json | 162 +++++++++--- docs/toc.json | 239 +----------------- src/BigQuery/BigQueryClient.php | 21 +- src/BigQuery/Bytes.php | 5 +- .../Connection/ConnectionInterface.php | 2 + src/BigQuery/Connection/Rest.php | 18 +- src/BigQuery/Dataset.php | 2 +- src/BigQuery/Date.php | 5 +- src/BigQuery/Job.php | 2 +- src/BigQuery/LICENSE | 202 +++++++++++++++ src/BigQuery/QueryResults.php | 4 +- src/BigQuery/README.md | 10 + src/BigQuery/Table.php | 17 +- src/BigQuery/Time.php | 4 + src/BigQuery/Timestamp.php | 4 + src/BigQuery/ValueMapper.php | 8 +- src/BigQuery/composer.json | 26 ++ src/{ => Core}/ArrayTrait.php | 2 +- src/{ => Core}/CallTrait.php | 2 +- src/{ => Core}/ClientTrait.php | 7 +- src/{ => Core}/Compute/Metadata.php | 8 +- .../Metadata/Readers/ReaderInterface.php | 2 +- .../Compute/Metadata/Readers/StreamReader.php | 2 +- src/{ => Core}/EmulatorTrait.php | 6 +- .../Exception/BadRequestException.php | 2 +- .../Exception/ConflictException.php | 2 +- src/{ => Core}/Exception/GoogleException.php | 2 +- .../Exception/NotFoundException.php | 2 +- src/{ => Core}/Exception/ServerException.php | 2 +- src/{ => Core}/Exception/ServiceException.php | 2 +- src/{ => Core}/ExponentialBackoff.php | 2 +- src/{ => Core}/GrpcRequestWrapper.php | 12 +- src/{ => Core}/GrpcTrait.php | 11 +- src/{ => Core}/Iam/Iam.php | 14 +- src/{ => Core}/Iam/IamConnectionInterface.php | 2 +- src/{ => Core}/Iam/PolicyBuilder.php | 4 +- src/{ => Core}/Int64.php | 2 +- src/{ => Core}/JsonTrait.php | 2 +- src/Core/LICENSE | 202 +++++++++++++++ .../Logger/AppEngineFlexFormatter.php | 4 +- .../Logger/AppEngineFlexHandler.php | 2 +- src/{ => Core}/PhpArray.php | 2 +- src/Core/README.md | 7 + src/{ => Core}/RequestBuilder.php | 4 +- src/{ => Core}/RequestWrapper.php | 27 +- src/{ => Core}/RequestWrapperTrait.php | 2 +- src/{ => Core}/RestTrait.php | 8 +- src/{ => Core}/Upload/AbstractUploader.php | 6 +- src/{ => Core}/Upload/MultipartUploader.php | 4 +- src/{ => Core}/Upload/ResumableUploader.php | 6 +- src/{ => Core}/Upload/StreamableUploader.php | 2 +- src/{ => Core}/UriTrait.php | 2 +- src/{ => Core}/ValidateTrait.php | 2 +- src/Core/composer.json | 28 ++ src/Datastore/Blob.php | 5 +- src/Datastore/Connection/Rest.php | 14 +- src/Datastore/DatastoreClient.php | 29 +-- src/Datastore/DatastoreSessionHandler.php | 12 +- src/Datastore/Entity.php | 7 +- src/Datastore/EntityMapper.php | 6 +- src/Datastore/GeoPoint.php | 6 +- src/Datastore/Key.php | 7 +- src/Datastore/LICENSE | 202 +++++++++++++++ src/Datastore/Operation.php | 2 +- src/Datastore/Query/GqlQuery.php | 7 +- src/Datastore/Query/Query.php | 5 +- src/Datastore/README.md | 10 + src/Datastore/Transaction.php | 5 +- src/Datastore/composer.json | 22 ++ src/ErrorReporting/README.md | 3 + src/ErrorReporting/composer.json | 24 ++ src/Logging/Connection/Grpc.php | 9 +- src/Logging/Connection/Rest.php | 12 +- src/Logging/Entry.php | 5 +- src/Logging/LICENSE | 202 +++++++++++++++ src/Logging/Logger.php | 9 +- src/Logging/LoggingClient.php | 12 +- src/Logging/Metric.php | 7 +- src/Logging/PsrLogger.php | 5 +- src/Logging/README.md | 10 + src/Logging/Sink.php | 7 +- src/Logging/composer.json | 26 ++ src/Monitoring/LICENSE | 202 +++++++++++++++ src/Monitoring/README.md | 3 + src/Monitoring/composer.json | 24 ++ src/NaturalLanguage/Annotation.php | 7 +- src/NaturalLanguage/Connection/Rest.php | 12 +- src/NaturalLanguage/LICENSE | 202 +++++++++++++++ src/NaturalLanguage/NaturalLanguageClient.php | 67 +++-- src/NaturalLanguage/README.md | 10 + src/NaturalLanguage/composer.json | 25 ++ src/PubSub/Connection/Grpc.php | 11 +- src/PubSub/Connection/IamSubscription.php | 2 +- src/PubSub/Connection/IamTopic.php | 2 +- src/PubSub/Connection/Rest.php | 14 +- src/PubSub/IncomingMessageTrait.php | 2 +- src/PubSub/LICENSE | 202 +++++++++++++++ src/PubSub/Message.php | 5 +- src/PubSub/PubSubClient.php | 20 +- src/PubSub/README.md | 139 +--------- src/PubSub/Subscription.php | 13 +- src/PubSub/Topic.php | 10 +- src/PubSub/composer.json | 26 ++ src/ServiceBuilder.php | 4 +- src/Speech/Connection/Rest.php | 12 +- src/Speech/LICENSE | 202 +++++++++++++++ src/Speech/Operation.php | 7 +- src/Speech/README.md | 10 + src/Speech/SpeechClient.php | 42 +-- src/Speech/composer.json | 27 ++ src/Storage/Acl.php | 5 +- src/Storage/Bucket.php | 12 +- src/Storage/Connection/Rest.php | 20 +- src/Storage/LICENSE | 202 +++++++++++++++ src/Storage/README.md | 10 + src/Storage/StorageClient.php | 13 +- src/Storage/StorageObject.php | 27 +- src/Storage/StreamWrapper.php | 4 +- src/Storage/WriteStream.php | 2 +- src/Storage/composer.json | 22 ++ src/Translate/Connection/Rest.php | 12 +- src/Translate/LICENSE | 202 +++++++++++++++ src/Translate/README.md | 10 + src/Translate/TranslateClient.php | 13 +- src/Translate/composer.json | 22 ++ src/Vision/Annotation.php | 5 +- src/Vision/Annotation/CropHint.php | 7 +- src/Vision/Annotation/Document.php | 7 +- src/Vision/Annotation/Entity.php | 7 +- src/Vision/Annotation/Face.php | 7 +- src/Vision/Annotation/Face/Landmarks.php | 5 +- src/Vision/Annotation/ImageProperties.php | 5 +- src/Vision/Annotation/SafeSearch.php | 7 +- src/Vision/Annotation/Web.php | 5 +- src/Vision/Annotation/Web/WebEntity.php | 7 +- src/Vision/Annotation/Web/WebImage.php | 7 +- src/Vision/Annotation/Web/WebPage.php | 7 +- src/Vision/Connection/Rest.php | 12 +- src/Vision/Image.php | 15 +- src/Vision/LICENSE | 202 +++++++++++++++ src/Vision/README.md | 10 + src/Vision/VisionClient.php | 16 +- src/Vision/composer.json | 25 ++ .../snippets/BigQuery/BigQueryClientTest.php | 10 +- tests/snippets/BigQuery/TableTest.php | 2 +- .../{ => Core}/Compute/MetadataTest.php | 6 +- tests/snippets/{ => Core}/Iam/IamTest.php | 6 +- .../{ => Core}/Iam/PolicyBuilderTest.php | 4 +- tests/snippets/{ => Core}/Int64Test.php | 4 +- .../Datastore/DatastoreClientTest.php | 14 +- tests/snippets/Logging/LoggingClientTest.php | 8 - .../NaturalLanguageClientTest.php | 7 - tests/snippets/PubSub/MessageTest.php | 2 +- tests/snippets/PubSub/PubSubClientTest.php | 12 +- tests/snippets/PubSub/SubscriptionTest.php | 2 +- tests/snippets/PubSub/TopicTest.php | 2 +- tests/snippets/Speech/SpeechClientTest.php | 8 - tests/snippets/Storage/BucketTest.php | 8 +- tests/snippets/Storage/StorageClientTest.php | 7 - tests/snippets/Storage/StorageObjectTest.php | 10 + .../Translate/TranslateClientTest.php | 8 - tests/snippets/Vision/VisionClientTest.php | 8 - tests/snippets/bootstrap.php | 4 +- tests/system/BigQuery/BigQueryTestCase.php | 2 +- .../system/BigQuery/LoadDataAndQueryTest.php | 2 +- tests/system/BigQuery/ManageTablesTest.php | 2 +- tests/system/Datastore/DatastoreTestCase.php | 2 +- tests/system/Datastore/SaveAndModifyTest.php | 2 +- tests/system/Logging/LoggingTestCase.php | 2 +- .../system/Logging/WriteAndListEntryTest.php | 2 +- .../NaturalLanguageTestCase.php | 2 +- tests/system/PubSub/PubSubTestCase.php | 2 +- tests/system/Storage/ManageAclTest.php | 2 +- tests/system/Storage/StorageTestCase.php | 2 +- tests/unit/BigQuery/BigQueryClientTest.php | 2 +- tests/unit/BigQuery/BytesTest.php | 2 +- tests/unit/BigQuery/Connection/RestTest.php | 15 +- tests/unit/BigQuery/DatasetTest.php | 4 +- tests/unit/BigQuery/DateTest.php | 2 +- tests/unit/BigQuery/InsertResponseTest.php | 2 +- tests/unit/BigQuery/JobTest.php | 4 +- tests/unit/BigQuery/QueryResultsTest.php | 4 +- tests/unit/BigQuery/TableTest.php | 26 +- tests/unit/BigQuery/TimeTest.php | 2 +- tests/unit/BigQuery/TimestampTest.php | 2 +- tests/unit/BigQuery/ValueMapperTest.php | 4 +- tests/unit/{ => Core}/ArrayTraitTest.php | 6 +- tests/unit/{ => Core}/CallTraitTest.php | 6 +- tests/unit/{ => Core}/ClientTraitTest.php | 26 +- .../unit/{ => Core}/Compute/MetadataTest.php | 8 +- tests/unit/{ => Core}/EmulatorTraitTest.php | 6 +- .../Exception/ServiceExceptionTest.php | 5 +- .../{ => Core}/ExponentialBackoffTest.php | 6 +- .../{ => Core}/GrpcRequestWrapperTest.php | 21 +- tests/unit/{ => Core}/GrpcTraitTest.php | 15 +- tests/unit/{ => Core}/Iam/IamTest.php | 7 +- .../unit/{ => Core}/Iam/PolicyBuilderTest.php | 5 +- tests/unit/{ => Core}/Int64Test.php | 6 +- tests/unit/{ => Core}/JsonTraitTest.php | 4 +- .../Logger/AppEngineFlexHandlerTest.php | 5 +- tests/unit/{ => Core}/PhpArrayTest.php | 8 +- tests/unit/{ => Core}/RequestBuilderTest.php | 12 +- tests/unit/{ => Core}/RequestWrapperTest.php | 46 ++-- tests/unit/{ => Core}/RestTraitTest.php | 12 +- tests/unit/{ => Core}/ServiceBuilderTest.php | 4 +- .../Upload/MultipartUploaderTest.php | 11 +- .../Upload/ResumableUploaderTest.php | 27 +- .../Upload/StreamableUploaderTest.php | 17 +- tests/unit/{ => Core}/UriTraitTest.php | 6 +- tests/unit/{ => Core}/ValidateTraitTest.php | 6 +- tests/unit/Datastore/BlobTest.php | 2 +- tests/unit/Datastore/Connection/RestTest.php | 7 +- tests/unit/Datastore/DatastoreClientTest.php | 2 +- .../Datastore/DatastoreSessionHandlerTest.php | 2 +- tests/unit/Datastore/DatastoreTraitTest.php | 2 +- tests/unit/Datastore/EntityMapperTest.php | 4 +- tests/unit/Datastore/EntityTest.php | 2 +- tests/unit/Datastore/GeoPointTest.php | 2 +- tests/unit/Datastore/KeyTest.php | 2 +- tests/unit/Datastore/OperationTest.php | 2 +- tests/unit/Datastore/Query/GqlQueryTest.php | 2 +- tests/unit/Datastore/Query/QueryTest.php | 2 +- tests/unit/Datastore/TransactionTest.php | 2 +- tests/unit/JsonFileTest.php | 37 ++- tests/unit/Logging/Connection/GrpcTest.php | 6 +- tests/unit/Logging/Connection/RestTest.php | 7 +- tests/unit/Logging/LoggerTest.php | 2 +- tests/unit/Logging/LoggingClientTest.php | 2 +- tests/unit/Logging/MetricTest.php | 4 +- .../Logging/PsrLoggerCompatabilityTest.php | 2 +- tests/unit/Logging/PsrLoggerTest.php | 2 +- tests/unit/Logging/SinkTest.php | 4 +- tests/unit/NaturalLanguage/AnnotationTest.php | 4 +- .../NaturalLanguage/Connection/RestTest.php | 9 +- .../NaturalLanguageClientTest.php | 20 +- tests/unit/PubSub/Connection/GrpcTest.php | 4 +- .../PubSub/Connection/IamSubscriptionTest.php | 2 +- tests/unit/PubSub/Connection/IamTopicTest.php | 2 +- tests/unit/PubSub/Connection/RestTest.php | 7 +- .../unit/PubSub/IncomingMessageTraitTest.php | 4 +- tests/unit/PubSub/MessageTest.php | 2 +- tests/unit/PubSub/PubSubClientTest.php | 2 +- tests/unit/PubSub/ResourceNameTraitTest.php | 2 +- tests/unit/PubSub/SubscriptionTest.php | 6 +- tests/unit/PubSub/TopicTest.php | 6 +- tests/unit/Speech/Connection/RestTest.php | 7 +- tests/unit/Speech/OperationTest.php | 4 +- tests/unit/Speech/SpeechClientTest.php | 23 +- tests/unit/Storage/AclTest.php | 2 +- tests/unit/Storage/BucketTest.php | 25 +- tests/unit/Storage/Connection/RestTest.php | 23 +- tests/unit/Storage/EncryptionTraitTest.php | 2 +- tests/unit/Storage/StorageClientTest.php | 2 +- tests/unit/Storage/StorageObjectTest.php | 12 +- tests/unit/Storage/StreamWrapperTest.php | 16 +- tests/unit/Storage/WriteStreamTest.php | 2 +- tests/unit/Translate/Connection/RestTest.php | 7 +- tests/unit/Translate/TranslateClientTest.php | 2 +- tests/unit/Vision/Annotation/EntityTest.php | 2 +- .../Vision/Annotation/Face/LandmarksTest.php | 2 +- tests/unit/Vision/Annotation/FaceTest.php | 2 +- .../Vision/Annotation/LikelihoodTraitTest.php | 2 +- .../unit/Vision/Annotation/SafeSearchTest.php | 2 +- tests/unit/Vision/AnnotationTest.php | 2 +- tests/unit/Vision/Connection/RestTest.php | 7 +- tests/unit/Vision/ImageTest.php | 2 +- tests/unit/Vision/VisionClientTest.php | 2 +- 300 files changed, 4638 insertions(+), 1319 deletions(-) create mode 100755 dev/sh/compile-splitsh create mode 100755 dev/sh/split create mode 100755 dev/sh/trigger-split create mode 100644 dev/src/DocGenerator/TableOfContents.php create mode 100644 dev/src/GetComponentsTrait.php create mode 100644 dev/src/Split/Command/Split.php create mode 100644 docs/contents/cloud-bigquery.json create mode 100644 docs/contents/cloud-core.json create mode 100644 docs/contents/cloud-datastore.json create mode 100644 docs/contents/cloud-error-reporting.json create mode 100644 docs/contents/cloud-logging.json create mode 100644 docs/contents/cloud-monitoring.json create mode 100644 docs/contents/cloud-natural-language.json create mode 100644 docs/contents/cloud-pubsub.json create mode 100644 docs/contents/cloud-speech.json create mode 100644 docs/contents/cloud-storage.json create mode 100644 docs/contents/cloud-translate.json create mode 100644 docs/contents/cloud-vision.json create mode 100644 docs/contents/google-cloud.json create mode 100644 src/BigQuery/LICENSE create mode 100644 src/BigQuery/README.md create mode 100644 src/BigQuery/composer.json rename src/{ => Core}/ArrayTrait.php (98%) rename src/{ => Core}/CallTrait.php (97%) rename src/{ => Core}/ClientTrait.php (97%) rename src/{ => Core}/Compute/Metadata.php (93%) rename src/{ => Core}/Compute/Metadata/Readers/ReaderInterface.php (93%) rename src/{ => Core}/Compute/Metadata/Readers/StreamReader.php (96%) rename src/{ => Core}/EmulatorTrait.php (93%) rename src/{ => Core}/Exception/BadRequestException.php (95%) rename src/{ => Core}/Exception/ConflictException.php (95%) rename src/{ => Core}/Exception/GoogleException.php (94%) rename src/{ => Core}/Exception/NotFoundException.php (94%) rename src/{ => Core}/Exception/ServerException.php (95%) rename src/{ => Core}/Exception/ServiceException.php (97%) rename src/{ => Core}/ExponentialBackoff.php (99%) rename src/{ => Core}/GrpcRequestWrapper.php (95%) rename src/{ => Core}/GrpcTrait.php (95%) rename src/{ => Core}/Iam/Iam.php (93%) rename src/{ => Core}/Iam/IamConnectionInterface.php (97%) rename src/{ => Core}/Iam/PolicyBuilder.php (98%) rename src/{ => Core}/Int64.php (98%) rename src/{ => Core}/JsonTrait.php (98%) create mode 100644 src/Core/LICENSE rename src/{ => Core}/Logger/AppEngineFlexFormatter.php (96%) rename src/{ => Core}/Logger/AppEngineFlexHandler.php (98%) rename src/{ => Core}/PhpArray.php (99%) create mode 100644 src/Core/README.md rename src/{ => Core}/RequestBuilder.php (98%) rename src/{ => Core}/RequestWrapper.php (91%) rename src/{ => Core}/RequestWrapperTrait.php (99%) rename src/{ => Core}/RestTrait.php (93%) rename src/{ => Core}/Upload/AbstractUploader.php (96%) rename src/{ => Core}/Upload/MultipartUploader.php (96%) rename src/{ => Core}/Upload/ResumableUploader.php (97%) rename src/{ => Core}/Upload/StreamableUploader.php (98%) rename src/{ => Core}/UriTrait.php (98%) rename src/{ => Core}/ValidateTrait.php (98%) create mode 100644 src/Core/composer.json create mode 100644 src/Datastore/LICENSE create mode 100644 src/Datastore/README.md create mode 100644 src/Datastore/composer.json create mode 100644 src/ErrorReporting/composer.json create mode 100644 src/Logging/LICENSE create mode 100644 src/Logging/README.md create mode 100644 src/Logging/composer.json create mode 100644 src/Monitoring/LICENSE create mode 100644 src/Monitoring/composer.json create mode 100644 src/NaturalLanguage/LICENSE create mode 100644 src/NaturalLanguage/README.md create mode 100644 src/NaturalLanguage/composer.json create mode 100644 src/PubSub/LICENSE create mode 100644 src/PubSub/composer.json create mode 100644 src/Speech/LICENSE create mode 100644 src/Speech/README.md create mode 100644 src/Speech/composer.json create mode 100644 src/Storage/LICENSE create mode 100644 src/Storage/README.md create mode 100644 src/Storage/composer.json create mode 100644 src/Translate/LICENSE create mode 100644 src/Translate/README.md create mode 100644 src/Translate/composer.json create mode 100644 src/Vision/LICENSE create mode 100644 src/Vision/README.md create mode 100644 src/Vision/composer.json rename tests/snippets/{ => Core}/Compute/MetadataTest.php (96%) rename tests/snippets/{ => Core}/Iam/IamTest.php (96%) rename tests/snippets/{ => Core}/Iam/PolicyBuilderTest.php (96%) rename tests/snippets/{ => Core}/Int64Test.php (96%) rename tests/unit/{ => Core}/ArrayTraitTest.php (96%) rename tests/unit/{ => Core}/CallTraitTest.php (93%) rename tests/unit/{ => Core}/ClientTraitTest.php (88%) rename tests/unit/{ => Core}/Compute/MetadataTest.php (92%) rename tests/unit/{ => Core}/EmulatorTraitTest.php (93%) rename tests/unit/{ => Core}/Exception/ServiceExceptionTest.php (90%) rename tests/unit/{ => Core}/ExponentialBackoffTest.php (97%) rename tests/unit/{ => Core}/GrpcRequestWrapperTest.php (89%) rename tests/unit/{ => Core}/GrpcTraitTest.php (96%) rename tests/unit/{ => Core}/Iam/IamTest.php (96%) rename tests/unit/{ => Core}/Iam/PolicyBuilderTest.php (97%) rename tests/unit/{ => Core}/Int64Test.php (92%) rename tests/unit/{ => Core}/JsonTraitTest.php (95%) rename tests/unit/{ => Core}/Logger/AppEngineFlexHandlerTest.php (93%) rename tests/unit/{ => Core}/PhpArrayTest.php (96%) rename tests/unit/{ => Core}/RequestBuilderTest.php (91%) rename tests/unit/{ => Core}/RequestWrapperTest.php (88%) rename tests/unit/{ => Core}/RestTraitTest.php (88%) rename tests/unit/{ => Core}/ServiceBuilderTest.php (97%) rename tests/unit/{ => Core}/Upload/MultipartUploaderTest.php (81%) rename tests/unit/{ => Core}/Upload/ResumableUploaderTest.php (84%) rename tests/unit/{ => Core}/Upload/StreamableUploaderTest.php (89%) rename tests/unit/{ => Core}/UriTraitTest.php (95%) rename tests/unit/{ => Core}/ValidateTraitTest.php (95%) diff --git a/.travis.yml b/.travis.yml index fd8876ac630c..0c37a6d81b32 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,30 +1,31 @@ language: php - sudo: required dist: trusty matrix: - include: - - php: 5.5.38 - - php: 5.6.25 - - php: 7.0 - - php: 7.1 - - php: hhvm - group: edge - fast_finish: true + include: + - php: 5.5.38 + - php: 5.6.25 + - php: 7.0 + - php: 7.1 + - php: hhvm + group: edge + fast_finish: true before_script: - - pecl install grpc || echo 'Failed to install grpc' - - composer install + - pecl install grpc || echo 'Failed to install grpc' + - composer install script: - - ./dev/sh/tests - - vendor/bin/phpcs --standard=./phpcs-ruleset.xml - - ./dev/sh/build-docs + - ./dev/sh/tests + - vendor/bin/phpcs --standard=./phpcs-ruleset.xml + - ./dev/sh/build-docs after_success: - - bash <(curl -s https://codecov.io/bash) - - ./dev/sh/push-docs + - bash <(curl -s https://codecov.io/bash) + - ./dev/sh/push-docs + - ./dev/sh/trigger-split + - cat ./build/snippets-uncovered.json after_failure: - - echo "SNIPPET COVERAGE REPORT" && cat ./build/snippets-uncovered.json + - echo "SNIPPET COVERAGE REPORT" && cat ./build/snippets-uncovered.json diff --git a/composer.json b/composer.json index 4402d1145b28..0ed669718bb4 100644 --- a/composer.json +++ b/composer.json @@ -76,5 +76,13 @@ }, "scripts": { "google-cloud": "dev/google-cloud" + }, + "extra": { + "component": { + "id": "google-cloud", + "target": "git@github.com:jdpedrie-gcp/google-cloud-php.git", + "path": "src", + "entry": "ServiceBuilder.php" + } } } diff --git a/dev/google-cloud b/dev/google-cloud index cd0636602a4f..e004b499d438 100755 --- a/dev/google-cloud +++ b/dev/google-cloud @@ -20,6 +20,7 @@ require __DIR__ . '/../vendor/autoload.php'; use Google\Cloud\Dev\DocGenerator\Command\Docs; use Google\Cloud\Dev\Release\Command\Release; +use Google\Cloud\Dev\Split\Command\Split; use Symfony\Component\Console\Application; if (!class_exists(Application::class)) { @@ -33,4 +34,5 @@ if (!class_exists(Application::class)) { $app = new Application; $app->add(new Release(__DIR__)); $app->add(new Docs(__DIR__)); +$app->add(new Split(__DIR__)); $app->run(); diff --git a/dev/sh/build-docs b/dev/sh/build-docs index cc09be67d534..1079b9de9dd6 100755 --- a/dev/sh/build-docs +++ b/dev/sh/build-docs @@ -5,7 +5,13 @@ set -ev function buildDocs () { echo "doc dir before generation:" find docs - composer google-cloud docs + + if [ -z "$TRAVIS_TAG" ]; then + ./dev/google-cloud docs + else + ./dev/google-cloud docs -r ${TRAVIS_TAG} + fi + echo "doc dir after generation:" find docs } diff --git a/dev/sh/compile-splitsh b/dev/sh/compile-splitsh new file mode 100755 index 000000000000..1cef5094d2b0 --- /dev/null +++ b/dev/sh/compile-splitsh @@ -0,0 +1,13 @@ +#!/bin/bash + +mkdir $ +export GOPATH=$TRAVIS_BUILD_DIR/go + +go get -d github.com/libgit2/git2go +cd $GOPATH/src/github.com/libgit2/git2go +git checkout next +git submodule update --init +make install + +go get github.com/splitsh/lite +go build -o $TRAVIS_BUILD_DIR/splitsh-lite github.com/splitsh/lite diff --git a/dev/sh/push-docs b/dev/sh/push-docs index a0ef3d50e770..0ee349729324 100755 --- a/dev/sh/push-docs +++ b/dev/sh/push-docs @@ -2,20 +2,11 @@ set -ev -function generateDocs () { - echo "doc dir before generation:" - find docs - composer google-cloud docs - echo "doc dir after generation:" - find docs -} - function pushDocs () { - git submodule add -q -f -b gh-pages https://${GH_OAUTH_TOKEN}@github.com/${GH_OWNER}/${GH_PROJECT_NAME} ghpages - mkdir -p ghpages/json/${1} - cp -R docs/json/master/* ghpages/json/${1} - cp docs/overview.html ghpages/json/${1} - cp docs/toc.json ghpages/json/${1} + git submodule add -q -f -b gh-pages https://${GH_OAUTH_TOKEN}@github.com/${TRAVIS_REPO_SLUG} ghpages + + rsync -aP docs/json/* ghpages/json/ + cp docs/home.html ghpages/json cp docs/manifest.json ghpages cd ghpages @@ -25,7 +16,7 @@ function pushDocs () { git config user.email "travis@travis-ci.org" git commit -m "Updating docs for ${1}" git status - git push -q https://${GH_OAUTH_TOKEN}@github.com/${GH_OWNER}/${GH_PROJECT_NAME} HEAD:gh-pages + git push -q https://${GH_OAUTH_TOKEN}@github.com/${TRAVIS_REPO_SLUG} HEAD:gh-pages else echo "Nothing to commit." fi diff --git a/dev/sh/split b/dev/sh/split new file mode 100755 index 000000000000..6ff7c259f9ac --- /dev/null +++ b/dev/sh/split @@ -0,0 +1,10 @@ +#!/bin/bash + +set -e + +branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p') + +SHA=`$TRAVIS_BUILD_DIR/splitsh-lite --prefix=$1` +git push -q \ + "https://${GH_OAUTH_TOKEN}@github.com/$2" \ + $SHA:master --force diff --git a/dev/sh/trigger-split b/dev/sh/trigger-split new file mode 100755 index 000000000000..5685a6fe239e --- /dev/null +++ b/dev/sh/trigger-split @@ -0,0 +1,9 @@ +#!/bin/bash + +if [[ "$TRAVIS_JOB_NUMBER" == *.1 && -n "$TRAVIS_TAG" ]]; then + $(dirname $0)/compile-splitsh + git fetch --unshallow + composer google-cloud split +else + echo "Split occurs only in a tag run, and in the first matrix build" +fi diff --git a/dev/src/DocGenerator/Command/Docs.php b/dev/src/DocGenerator/Command/Docs.php index 33c522682c84..2ade7f174d00 100644 --- a/dev/src/DocGenerator/Command/Docs.php +++ b/dev/src/DocGenerator/Command/Docs.php @@ -19,7 +19,9 @@ use Google\Cloud\Dev\DocGenerator\DocGenerator; use Google\Cloud\Dev\DocGenerator\GuideGenerator; +use Google\Cloud\Dev\DocGenerator\TableOfContents; use Google\Cloud\Dev\DocGenerator\TypeGenerator; +use Google\Cloud\Dev\GetComponentsTrait; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use RecursiveRegexIterator; @@ -27,11 +29,16 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class Docs extends Command { - const DEFAULT_OUTPUT_DIR = 'docs/json/master'; + use GetComponentsTrait; + + const DEFAULT_OUTPUT_DIR = 'docs/json'; + const TOC_SOURCE_DIR = 'docs/contents'; + const TOC_TEMPLATE = 'docs/toc.json'; const DEFAULT_SOURCE_DIR = 'src'; private $cliBasePath; @@ -47,29 +54,94 @@ protected function configure() { $this->setName('docs') ->setDescription('Generate Documentation') - ->addArgument('source', InputArgument::OPTIONAL, 'The source directory to traverse and parse') - ->addArgument('output', InputArgument::OPTIONAL, 'The directory to output files into'); + ->addOption('release', 'r', InputOption::VALUE_REQUIRED, 'If set, docs will be generated into tag folders' . + ' such as v1.0.0 rather than master.', false) + ->addOption('pretty', 'p', InputOption::VALUE_OPTIONAL, 'If set, json files will be written with pretty'. + ' formatting using PHP\'s JSON_PRETTY_PRINT flag', false); } protected function execute(InputInterface $input, OutputInterface $output) { + $release = ($input->getOption('release') === false && $input->getOption('release') !== 'false') + ? null + : $input->getOption('release'); + + $pretty = ($input->getOption('pretty') === false) ? false : true; + $paths = [ - 'source' => ($input->getArgument('source')) - ? $this->cliBasePath .'/../'. $input->getArgument('source') - : $this->cliBasePath .'/../'. self::DEFAULT_SOURCE_DIR, + 'source' => $this->cliBasePath .'/../'. self::DEFAULT_SOURCE_DIR, + 'output' => $this->cliBasePath .'/../'. self::DEFAULT_OUTPUT_DIR, + 'project' => $this->cliBasePath .'/../', + 'manifest' => $this->cliBasePath .'/../docs/manifest.json', + 'toc' => $this->cliBasePath .'/../'. self::TOC_SOURCE_DIR, + 'tocTemplate' => $this->cliBasePath .'/../'. self::TOC_TEMPLATE + ]; - 'output' => ($input->getArgument('output')) - ? $this->cliBasePath .'/../'. $input->getArgument('output') - : $this->cliBasePath .'/../'. self::DEFAULT_OUTPUT_DIR + $components = $this->getComponents($paths['source']); + $tocTemplate = json_decode(file_get_contents($paths['tocTemplate']), true); + + foreach ($components as $component) { + $input = $paths['project'] . $component['path']; + $source = $this->getFilesList($input); + $this->generateComponentDocumentation($output, $source, $component, $paths, $tocTemplate, $release, $pretty); + } + + $source = [$paths['project'] .'src/ServiceBuilder.php']; + $component = [ + 'id' => 'google-cloud', + 'path' => 'src/' ]; + $this->generateComponentDocumentation($output, $source, $component, $paths, $tocTemplate, $release, $pretty); + } + + private function generateComponentDocumentation( + OutputInterface $output, + array $source, + array $component, + array $paths, + $tocTemplate, + $release = false, + $pretty = false + ) { + $output->writeln(sprintf('Writing documentation for %s', $component['id'])); + $output->writeln('--------------'); + + $version = $this->getComponentVersion($paths['manifest'], $component['id']); + + $outputPath = ($release) + ? $paths['output'] .'/'. $component['id'] .'/'. $version + : $paths['output'] .'/'. $component['id'] .'/master'; + + $output->writeln(sprintf('Writing to %s', realpath($outputPath))); + + $types = new TypeGenerator($outputPath); + + $docs = new DocGenerator( + $types, + $source, + $outputPath, + $this->cliBasePath, + $component['id'], + $paths['manifest'], + $release + ); + $docs->generate($component['path'], $pretty); + + $types->write($pretty); - $types = new TypeGenerator($paths['output']); + $output->writeln(sprintf('Writing table of contents to %s', realpath($outputPath))); + $services = json_decode(file_get_contents($paths['toc'] .'/'. $component['id'] .'.json'), true); - $sourceFiles = $this->getFilesList($paths['source']); - $docs = new DocGenerator($types, $sourceFiles, $paths['output'], $this->cliBasePath); - $docs->generate(); + $toc = new TableOfContents( + $tocTemplate, + $services, + $release, + $outputPath + ); + $toc->generate($pretty); - $types->write(); + $output->writeln(' '); + $output->writeln(' '); } private function getFilesList($source) diff --git a/dev/src/DocGenerator/DocGenerator.php b/dev/src/DocGenerator/DocGenerator.php index 7394002af896..239e54eb1dca 100644 --- a/dev/src/DocGenerator/DocGenerator.php +++ b/dev/src/DocGenerator/DocGenerator.php @@ -32,16 +32,29 @@ class DocGenerator private $files; private $outputPath; private $executionPath; + private $componentId; + private $manifestPath; + private $release; /** * @param array $files */ - public function __construct(TypeGenerator $types, array $files, $outputPath, $executionPath) - { + public function __construct( + TypeGenerator $types, + array $files, + $outputPath, + $executionPath, + $componentId, + $manifestPath, + $release + ) { $this->types = $types; $this->files = $files; $this->outputPath = $outputPath; $this->executionPath = $executionPath; + $this->componentId = $componentId; + $this->manifestPath = $manifestPath; + $this->release = $release; } /** @@ -49,31 +62,56 @@ public function __construct(TypeGenerator $types, array $files, $outputPath, $ex * * @return void */ - public function generate() + public function generate($basePath, $pretty) { foreach ($this->files as $file) { - $currentFile = substr(str_replace($this->executionPath, '', $file), 3); + if ($basePath) { + $currentFileArr = explode($basePath, trim($file, '/')); + if (isset($currentFileArr[1])) { + $currentFile = trim($currentFileArr[1], '/'); + } + } + $isPhp = strrpos($file, '.php') == strlen($file) - strlen('.php'); if ($isPhp) { $fileReflector = new FileReflector($file); - $parser = new CodeParser($file, $currentFile, $fileReflector); + $parser = new CodeParser( + $file, + $currentFile, + $fileReflector, + dirname($this->executionPath), + $this->componentId, + $this->manifestPath, + $this->release + ); } else { $content = file_get_contents($file); - $parser = new MarkdownParser($currentFile, $content); + $split = explode('src/', $file); + $parser = new MarkdownParser($split[1], $content); } $document = $parser->parse(); - $writer = new Writer(json_encode($document), $this->outputPath); - $writer->write(substr($currentFile, 4)); + $writer = new Writer($document, $this->outputPath, $pretty); + $writer->write($currentFile); $this->types->addType([ 'id' => $document['id'], 'title' => $document['title'], - 'contents' => $document['id'] . '.json' + 'contents' => $this->prune($document['id'] . '.json') ]); } } + + private function prune($contentsFileName) + { + $explode = explode('/', $contentsFileName); + if (count($explode) > 1) { + array_shift($explode); + } + + return implode('/', $explode); + } } diff --git a/dev/src/DocGenerator/Parser/CodeParser.php b/dev/src/DocGenerator/Parser/CodeParser.php index e478bdd41d42..fd13c43f8885 100644 --- a/dev/src/DocGenerator/Parser/CodeParser.php +++ b/dev/src/DocGenerator/Parser/CodeParser.php @@ -18,6 +18,7 @@ namespace Google\Cloud\Dev\DocGenerator\Parser; use Google\Cloud\Dev\DocBlockStripSpaces; +use Google\Cloud\Dev\GetComponentsTrait; use phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\Tag\SeeTag; @@ -25,21 +26,38 @@ class CodeParser implements ParserInterface { + use GetComponentsTrait; + const SNIPPET_NAME_REGEX = '/\/\/\s?\[snippet\=(\w{0,})\]/'; private $path; private $outputName; private $reflector; private $markdown; + private $projectRoot; private $externalTypes; - - public function __construct($path, $outputName, FileReflector $reflector) - { + private $componentId; + private $manifestPath; + private $release; + + public function __construct( + $path, + $outputName, + FileReflector $reflector, + $projectRoot, + $componentId, + $manifestPath, + $release + ) { $this->path = $path; $this->outputName = $outputName; $this->reflector = $reflector; $this->markdown = \Parsedown::instance(); + $this->projectRoot = $projectRoot; $this->externalTypes = json_decode(file_get_contents(__DIR__ .'/../../../../docs/external-classes.json'), true); + $this->componentId = $componentId; + $this->manifestPath = $manifestPath; + $this->release = $release; } public function parse() @@ -485,15 +503,59 @@ private function buildExternalType($type) private function buildLink($content) { - if ($content[0] === '\\') { - $content = substr($content, 1); + $componentId = null; + if (substr_compare(trim($content, '\\'), 'Google\Cloud', 0, 12) === 0) { + try { + $matches = []; + preg_match('/[Generator\<]?(Google\\\Cloud\\\[\w\\\]{0,})[\>]?[\[\]]?/', $content, $matches); + $ref = new \ReflectionClass($matches[1]); + } catch (\ReflectionException $e) { + throw new \Exception(sprintf( + 'Reflection Exception: %s in %s. Given class was %s', + $e->getMessage(), + realpath($this->path), + $content + )); + } + + $recurse = true; + $file = $ref->getFileName(); + + if (strpos($file, dirname(realpath($this->path))) !== false) { + $recurse = false; + } + + do { + $composer = dirname($file) .'/composer.json'; + if (file_exists($composer) && $component = $this->isComponent($composer)) { + $componentId = $component['id']; + if ($componentId === $this->componentId) { + $componentId = null; + } + $recurse = false; + } elseif (trim($file, '/') === trim($this->projectRoot, '/')) { + $recurse = false; + } else { + $file = dirname($file); + } + } while($recurse); } + $content = trim($content, '\\'); + $displayName = $content; $content = substr($content, 13); $parts = explode('::', $content); $type = strtolower(str_replace('\\', '/', $parts[0])); + if ($componentId) { + $version = ($this->release) + ? $this->getComponentVersion($this->manifestPath, $componentId) + : 'master'; + + $type = $componentId .'/'. $version .'/'. $type; + } + $openTag = ' $examples ]; } + + private static $composerFiles = []; + + private function isComponent($composerPath) + { + if (isset(self::$composerFiles[$composerPath])) { + $contents = self::$composerFiles[$composerPath]; + } else { + $contents = json_decode(file_get_contents($composerPath), true); + self::$composerFiles[$composerPath] = $contents; + } + + if (isset($contents['extra']['component'])) { + return $contents['extra']['component']; + } + + return false; + } } diff --git a/dev/src/DocGenerator/Parser/MarkdownParser.php b/dev/src/DocGenerator/Parser/MarkdownParser.php index 2599f80d4954..058dba85bbfe 100644 --- a/dev/src/DocGenerator/Parser/MarkdownParser.php +++ b/dev/src/DocGenerator/Parser/MarkdownParser.php @@ -49,7 +49,7 @@ public function parse() $body = $doc->getElementsByTagName('body')->item(0); return [ - 'id' => strtolower(substr($pathinfo['dirname'] .'/'. $pathinfo['filename'], 5)), + 'id' => strtolower(trim($pathinfo['dirname'] .'/'. $pathinfo['filename'], '/.')), 'type' => 'guide', 'title' => $heading->textContent, 'name' => $heading->textContent, diff --git a/dev/src/DocGenerator/TableOfContents.php b/dev/src/DocGenerator/TableOfContents.php new file mode 100644 index 000000000000..162a5877c8be --- /dev/null +++ b/dev/src/DocGenerator/TableOfContents.php @@ -0,0 +1,44 @@ +template = $template; + $this->component = $component; + $this->componentVersion = $componentVersion; + $this->outputPath = $outputPath; + } + + public function generate($pretty = false) + { + $toc = $this->template; + $toc['services'] = $this->component; + $toc['tagName'] = $this->componentVersion; + + $writer = new Writer($toc, $this->outputPath, $pretty); + $writer->write('toc.json'); + } +} diff --git a/dev/src/DocGenerator/TypeGenerator.php b/dev/src/DocGenerator/TypeGenerator.php index f05a39a6fcfc..8abfc8d4ac87 100644 --- a/dev/src/DocGenerator/TypeGenerator.php +++ b/dev/src/DocGenerator/TypeGenerator.php @@ -36,9 +36,9 @@ public function addType(array $type) $this->types[] = $type; } - public function write() + public function write($pretty = false) { - $writer = new Writer(json_encode($this->types), $this->outputPath); + $writer = new Writer($this->types, $this->outputPath, $pretty); $writer->write('types.json'); } } diff --git a/dev/src/DocGenerator/Writer.php b/dev/src/DocGenerator/Writer.php index 4cafcb9200e3..f2c22e458b63 100644 --- a/dev/src/DocGenerator/Writer.php +++ b/dev/src/DocGenerator/Writer.php @@ -21,11 +21,13 @@ class Writer { private $content; private $outputPath; + private $pretty; - public function __construct($content, $outputPath) + public function __construct(array $content, $outputPath, $pretty = false) { $this->content = $content; $this->outputPath = $outputPath; + $this->pretty = (bool) $pretty; } public function write($currentFile) @@ -33,10 +35,14 @@ public function write($currentFile) $path = $this->buildOutputPath($currentFile); if (!is_dir(dirname($path))) { - mkdir(dirname($path), 0777, true); + @mkdir(dirname($path), 0777, true); } - file_put_contents($path, $this->content); + $content = ($this->pretty) + ? json_encode($this->content, JSON_PRETTY_PRINT) + : json_encode($this->content); + + file_put_contents($path, $content); } private function buildOutputPath($currentFile) diff --git a/dev/src/GetComponentsTrait.php b/dev/src/GetComponentsTrait.php new file mode 100644 index 000000000000..3efa11290fe5 --- /dev/null +++ b/dev/src/GetComponentsTrait.php @@ -0,0 +1,116 @@ + 1) { + $component['prefix'] = dirname('src' . $path[1]); + } else { + $component['prefix'] = ''; + } + + $components[] = $component; + } + + return $components; + } + + private function getComponentVersion($manifestPath, $componentId) + { + $manifest = $this->getComponentManifest($manifestPath, $componentId); + return $manifest['versions'][0]; + } + + private function getComponentManifest($manifestPath, $componentId) + { + $manifest = $this->getManifest($manifestPath); + $index = $this->getManifestComponentModuleIndex($manifestPath, $manifest, $componentId); + + return $manifest['modules'][$index]; + } + + private function getManifestComponentModuleIndex($manifestPath, array $manifest, $componentId) + { + $modules = array_filter($this->getManifest($manifestPath)['modules'], function ($module) use ($componentId) { + return ($module['id'] === $componentId); + }); + + return array_keys($modules)[0]; + } + + private function getManifest($manifestPath) + { + if (self::$__manifest) { + $manifest = self::$__manifest; + } else { + $manifest = json_decode(file_get_contents($manifestPath), true); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw new RuntimeException('Could not decode manifest json'); + } + + self::$__manifest = $manifest; + } + + return $manifest; + } + + private function getComponentComposer($componentId) + { + $components = $this->getComponents($this->components, $this->defaultComponentComposer); + + $components = array_values(array_filter($components, function ($component) use ($componentId) { + return ($component['id'] === $componentId); + })); + + if (count($components) === 0) { + throw new \InvalidArgumentException(sprintf( + 'Given component id %s is not a valid component.', + $componentId + )); + } + + return $components[0]; + } +} diff --git a/dev/src/Release/Command/Release.php b/dev/src/Release/Command/Release.php index edc3bd1f21c3..37e0b62400c8 100644 --- a/dev/src/Release/Command/Release.php +++ b/dev/src/Release/Command/Release.php @@ -17,20 +17,35 @@ namespace Google\Cloud\Dev\Release\Command; +use Google\Cloud\Dev\GetComponentsTrait; use RuntimeException; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use vierbergenlars\SemVer\version; class Release extends Command { - const PATH_MANIFEST = 'docs/manifest.json'; - const PATH_SERVICE_BUILDER = 'src/ServiceBuilder.php'; + use GetComponentsTrait; + + const COMPONENT_BASE = '%s/../src'; + const DEFAULT_COMPONENT = 'google-cloud'; + const DEFAULT_COMPONENT_COMPOSER = '%s/../composer.json'; + const PATH_MANIFEST = '%s/../docs/manifest.json'; + const PATH_SERVICE_BUILDER = '%s/../src/ServiceBuilder.php'; private $cliBasePath; + private $defaultClient; + + private $manifest; + + private $defaultComponentComposer; + + private $components; + private $allowedReleaseTypes = [ 'major', 'minor', 'patch' ]; @@ -39,6 +54,11 @@ public function __construct($cliBasePath) { $this->cliBasePath = $cliBasePath; + $this->defaultClient = sprintf(self::PATH_SERVICE_BUILDER, $cliBasePath); + $this->manifest = sprintf(self::PATH_MANIFEST, $cliBasePath); + $this->defaultComponentComposer = sprintf(self::DEFAULT_COMPONENT_COMPOSER, $cliBasePath); + $this->components = sprintf(self::COMPONENT_BASE, $cliBasePath); + parent::__construct(); } @@ -46,23 +66,31 @@ protected function configure() { $this->setName('release') ->setDescription('Prepares a new release') - ->addArgument('version', InputArgument::REQUIRED, 'The new version number'); + ->addArgument('version', InputArgument::REQUIRED, 'The new version number.') + ->addOption( + 'component', + 'c', + InputOption::VALUE_REQUIRED, + 'The component for which the version should be updated.', + self::DEFAULT_COMPONENT + ); } protected function execute(InputInterface $input, OutputInterface $output) { + $component = $this->getComponentComposer($input->getOption('component')); + $version = $input->getArgument('version'); + + // If the version is one of "major", "minor" or "patch", determine the + // correct incrementation. if (in_array(strtolower($version), $this->allowedReleaseTypes)) { - $version = $this->getNextVersionName($version); + $version = $this->getNextVersionName($version, $component); } try { $validatedVersion = new version($version); } catch (\Exception $e) { - $validatedVersion = null; - } - - if (is_null($validatedVersion)) { throw new RuntimeException(sprintf( 'Given version %s is not a valid version name', $version @@ -72,18 +100,33 @@ protected function execute(InputInterface $input, OutputInterface $output) $version = (string) $validatedVersion; $output->writeln(sprintf( - 'Adding version %s to Documentation Manifest.', - $version + 'Adding version %s to Documentation Manifest for component %s.', + $version, + $component['id'] )); - $this->addToManifest($version); + $this->addToComponentManifest($version, $component); $output->writeln(sprintf( - 'Setting ServiceBuilder version constant to %s.', + 'Setting component version constant to %s.', $version )); - $this->updateServiceBuilder($version); + $this->updateComponentVersionConstant($version, $component); + $output->writeln(sprintf( + 'File %s VERSION constant updated to %s', + $component['entry'], + $version + )); + + if ($component['id'] !== 'google-cloud') { + $this->updateComponentVersionFile($version, $component); + $output->writeln(sprintf( + 'Component %s VERSION file updated to %s', + $component['id'], + $version + )); + } $output->writeln(sprintf( 'Release %s generated!', @@ -91,64 +134,72 @@ protected function execute(InputInterface $input, OutputInterface $output) )); } - private function getNextVersionName($type) + private function getNextVersionName($type, array $component) { - $manifest = $this->getManifest(); - $lastRelease = new version($manifest['versions'][0]); + $manifest = $this->getComponentManifest($this->manifest, $component['id']); + + if ($manifest['versions'][0] === 'master') { + $lastRelease = new version('0.0.0'); + } else { + $lastRelease = new version($manifest['versions'][0]); + } return $lastRelease->inc($type); } - private function addToManifest($version) + private function addToComponentManifest($version, array $component) { - $manifest = $this->getManifest(); - - if (json_last_error() !== JSON_ERROR_NONE) { - throw new RuntimeException('Could not decode manifest json'); - } + $manifest = $this->getManifest($this->manifest); + $index = $this->getManifestComponentModuleIndex($this->manifest, $manifest, $component['id']); - array_unshift($manifest['versions'], 'v'. $version); + array_unshift($manifest['modules'][$index]['versions'], 'v'. $version); $content = json_encode($manifest, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) ."\n"; - $result = file_put_contents($this->getManifestPath(), $content); + $result = file_put_contents($this->manifest, $content); if (!$result) { throw new RuntimeException('File write failed'); } } - private function updateServiceBuilder($version) + private function updateComponentVersionConstant($version, array $component) { - $path = $this->cliBasePath .'/../'. self::PATH_SERVICE_BUILDER; + if (is_null($component['entry'])) { + return false; + } + + $path = $this->cliBasePath .'/../'. $component['path'] .'/'. $component['entry']; if (!file_exists($path)) { - throw new RuntimeException('ServiceBuilder not found at '. $path); + throw new \RuntimeException(sprintf( + 'Component entry file %s does not exist', + $path + )); } - $sb = file_get_contents($path); + $entry = file_get_contents($path); $replacement = sprintf("const VERSION = '%s';", $version); - $sb = preg_replace("/const VERSION = '[0-9.]{0,}'\;/", $replacement, $sb); + $entry = preg_replace("/const VERSION = [\'\\\"]([0-9.]{0,}|master)[\'\\\"]\;/", $replacement, $entry); - $result = file_put_contents($path, $sb); + $result = file_put_contents($path, $entry); if (!$result) { throw new RuntimeException('File write failed'); } + + return true; } - private function getManifest() + private function updateComponentVersionFile($version, array $component) { - $path = $this->getManifestPath(); - if (!file_exists($path)) { - throw new RuntimeException('Manifest file not found at '. $path); - } + $path = $this->cliBasePath .'/../'. $component['path'] .'/VERSION'; + $result = file_put_contents($path, $version); - return json_decode(file_get_contents($path), true); - } + if (!$result) { + throw new RuntimeException('File write failed'); + } - private function getManifestPath() - { - return $this->cliBasePath .'/../'. self::PATH_MANIFEST; + return true; } } diff --git a/dev/src/Snippet/Parser/Snippet.php b/dev/src/Snippet/Parser/Snippet.php index 74316ecaf25d..d1ace59affdf 100644 --- a/dev/src/Snippet/Parser/Snippet.php +++ b/dev/src/Snippet/Parser/Snippet.php @@ -152,9 +152,14 @@ public function invoke($returnVar = null) $cb = function($return) use ($content) { extract($this->locals); - ob_start(); - $res = eval($content ."\n\n". $return); - $out = ob_get_clean(); + try { + ob_start(); + $res = eval($content ."\n\n". $return); + $out = ob_get_clean(); + } catch (\Exception $e) { + ob_end_clean(); + throw $e; + } return new InvokeResult($res, $out); }; diff --git a/dev/src/Split/Command/Split.php b/dev/src/Split/Command/Split.php new file mode 100644 index 000000000000..6959e6985ac7 --- /dev/null +++ b/dev/src/Split/Command/Split.php @@ -0,0 +1,172 @@ +cliBasePath = $cliBasePath; + $this->splitShell = sprintf(self::SPLIT_SHELL, $cliBasePath); + $this->components = sprintf(self::COMPONENT_BASE, $cliBasePath); + $this->manifest = sprintf(self::PATH_MANIFEST, $cliBasePath); + + $this->http = new Client; + $this->token = getenv(self::TOKEN_ENV); + + parent::__construct(); + } + + protected function configure() + { + $this->setName('split') + ->setDescription('Split subtree and push to various remotes.'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + if (!getenv(self::TAG_ENV)) { + $output->writeln('This command should only be run inside a CI post-release process'); + return; + } + + $components = $this->getComponents($this->components); + + $tag = getenv(self::TAG_ENV); + + $parentTagSource = sprintf(self::PARENT_TAG_NAME, $tag); + + foreach ($components as $component) { + $output->writeln(''); + $output->writeln(sprintf('Starting on component %s', $component['id'])); + $output->writeln('------------'); + shell_exec(sprintf( + '%s %s %s', + $this->splitShell, + $component['prefix'], + $component['target'] + )); + + $target = $component['target']; + $matches = []; + preg_match(self::TARGET_REGEX, $target, $matches); + + $org = $matches[1]; + $repo = $matches[2]; + + $version = $this->getComponentVersion($this->manifest, $component['id']); + try { + new version($version); + } catch (SemVerException $e) { + $output->writeln(sprintf( + 'Component %s version %s is invalid.', + $component['id'], + $version + )); + continue; + } + + if ($this->doesTagExist($version, $org, $repo)) { + $output->writeln(sprintf( + 'Component %s already tagged at version %s', + $component['id'], + $version + )); + continue; + } + + $name = $component['displayName'] .' '. $version; + $notes = sprintf( + 'For release notes, please see the [associated Google Cloud PHP release](%s).', + $parentTagSource + ); + $this->createRelease($version, $org, $repo, $name, $notes); + + $output->writeln(sprintf( + 'Release %s created for component %s', + $version, + $component['id'] + )); + } + } + + private function doesTagExist($tagName, $org, $repo) + { + $res = $this->http->get(sprintf( + self::GITHUB_RELEASES_ENDPOINT, + $org, $repo, $tagName + ), [ + 'http_errors' => false, + 'auth' => [null, $this->token] + ]); + + return ($res->getStatusCode() === 200); + } + + private function createRelease($tagName, $org, $repo, $name, $notes) + { + $requestBody = [ + 'tag_name' => $tagName, + 'name' => $name, + 'body' => $notes + ]; + + $res = $this->http->post(sprintf( + self::GITHUB_RELEASE_CREATE_ENDPOINT, + $org, $repo + ), [ + 'http_errors' => false, + 'json' => $requestBody, + 'auth' => [null, $this->token] + ]); + } +} diff --git a/docs/contents/cloud-bigquery.json b/docs/contents/cloud-bigquery.json new file mode 100644 index 000000000000..1d92ef396619 --- /dev/null +++ b/docs/contents/cloud-bigquery.json @@ -0,0 +1,31 @@ +[{ + "title": "BigQueryClient", + "type": "bigquery/bigqueryclient" +}, { + "title": "Bytes", + "type": "bigquery/bytes" +}, { + "title": "Dataset", + "type": "bigquery/dataset" +}, { + "title": "Date", + "type": "bigquery/date" +}, { + "title": "InsertResponse", + "type": "bigquery/insertresponse" +}, { + "title": "Job", + "type": "bigquery/job" +}, { + "title": "QueryResults", + "type": "bigquery/queryresults" +}, { + "title": "Table", + "type": "bigquery/table" +}, { + "title": "Time", + "type": "bigquery/time" +}, { + "title": "Timestamp", + "type": "bigquery/timestamp" +}] diff --git a/docs/contents/cloud-core.json b/docs/contents/cloud-core.json new file mode 100644 index 000000000000..9779bf4b5c63 --- /dev/null +++ b/docs/contents/cloud-core.json @@ -0,0 +1,30 @@ +[{ + "title": "Overview", + "type": "core/readme" +}, { + "title": "IAM", + "type": "core/iam/iam", + "patterns": [ + "core/iam/\\w{1,}" + ], + "nav": [{ + "title": "PolicyBuilder", + "type": "core/iam/policybuilder" + }] +}, { + "title": "Upload", + "type": "core/upload/abstractuploader", + "nav": [{ + "title": "MultipartUploader", + "type": "core/upload/multipartuploader" + }, { + "title": "ResumableUploader", + "type": "core/upload/resumableuploader" + }, { + "title": "StreamableUploader", + "type": "core/upload/streamableuploader" + }] +}, { + "title": "Int64", + "type": "core/int64" +}] diff --git a/docs/contents/cloud-datastore.json b/docs/contents/cloud-datastore.json new file mode 100644 index 000000000000..aec83962d0d2 --- /dev/null +++ b/docs/contents/cloud-datastore.json @@ -0,0 +1,25 @@ +[{ + "title": "DatastoreClient", + "type": "datastore/datastoreclient" +}, { + "title": "Transaction", + "type": "datastore/transaction" +}, { + "title": "Entity", + "type": "datastore/entity" +}, { + "title": "Key", + "type": "datastore/key" +}, { + "title": "Query", + "type": "datastore/query/query" +}, { + "title": "GQL Query", + "type": "datastore/query/gqlquery" +}, { + "title": "GeoPoint", + "type": "datastore/geopoint" +}, { + "title": "Blob", + "type": "datastore/blob" +}] diff --git a/docs/contents/cloud-error-reporting.json b/docs/contents/cloud-error-reporting.json new file mode 100644 index 000000000000..a6f2d22170da --- /dev/null +++ b/docs/contents/cloud-error-reporting.json @@ -0,0 +1,20 @@ +[{ + "title": "Overview", + "type": "errorreporting/readme" +}, { + "title": "v1beta1", + "type": "errorreporting/v1beta1/readme", + "patterns": [ + "errorreporting/v1beta1/\\w{1,}" + ], + "nav": [{ + "title": "ErrorGroupServiceClient", + "type": "errorreporting/v1beta1/errorgroupserviceclient" + }, { + "title": "ErrorStatsServiceClient", + "type": "errorreporting/v1beta1/errorstatsserviceclient" + }, { + "title": "ReportErrorsServiceClient", + "type": "errorreporting/v1beta1/reporterrorsserviceclient" + }] +}] diff --git a/docs/contents/cloud-logging.json b/docs/contents/cloud-logging.json new file mode 100644 index 000000000000..8b40def8299f --- /dev/null +++ b/docs/contents/cloud-logging.json @@ -0,0 +1,35 @@ +[{ + "title": "LoggingClient", + "type": "logging/loggingclient" +}, { + "title": "Entry", + "type": "logging/entry" +}, { + "title": "Logger", + "type": "logging/logger" +}, { + "title": "Metric", + "type": "logging/metric" +},{ + "title": "PsrLogger", + "type": "logging/psrlogger" +},{ + "title": "Sink", + "type": "logging/sink" +}, { + "title": "v2", + "type": "logging/v2/readme", + "patterns": [ + "logging/v2/\\w{1,}" + ], + "nav": [{ + "title": "ConfigServiceV2Client", + "type": "logging/v2/configservicev2client" + }, { + "title": "LoggingServiceV2Client", + "type": "logging/v2/loggingservicev2client" + }, { + "title": "MetricsServiceV2Client", + "type": "logging/v2/metricsservicev2client" + }] +}] diff --git a/docs/contents/cloud-monitoring.json b/docs/contents/cloud-monitoring.json new file mode 100644 index 000000000000..092ed41613bc --- /dev/null +++ b/docs/contents/cloud-monitoring.json @@ -0,0 +1,17 @@ +[{ + "title": "Overview", + "type": "monitoring/readme" +}, { + "title": "v3", + "type": "monitoring/v3/readme", + "patterns": [ + "monitoring/v3/\\w{1,}" + ], + "nav": [{ + "title": "GroupServiceClient", + "type": "monitoring/v3/groupserviceclient" + }, { + "title": "MetricServiceClient", + "type": "monitoring/v3/metricserviceclient" + }] +}] diff --git a/docs/contents/cloud-natural-language.json b/docs/contents/cloud-natural-language.json new file mode 100644 index 000000000000..c9d82e7b35cd --- /dev/null +++ b/docs/contents/cloud-natural-language.json @@ -0,0 +1,7 @@ +[{ + "title": "NaturalLanguageClient", + "type": "naturallanguage/naturallanguageclient" +}, { + "title": "Annotation", + "type": "naturallanguage/annotation" +}] diff --git a/docs/contents/cloud-pubsub.json b/docs/contents/cloud-pubsub.json new file mode 100644 index 000000000000..ef5acc571971 --- /dev/null +++ b/docs/contents/cloud-pubsub.json @@ -0,0 +1,26 @@ +[{ + "title": "PubSubClient", + "type": "pubsub/pubsubclient" +}, { + "title": "Message", + "type": "pubsub/message" +}, { + "title": "Subscription", + "type": "pubsub/subscription" +}, { + "title": "Topic", + "type": "pubsub/topic" +}, { + "title": "v1", + "type": "pubsub/v1/readme", + "patterns": [ + "pubsub/v1/\\w{1,}" + ], + "nav": [{ + "title": "PublisherClient", + "type": "pubsub/v1/publisherclient" + }, { + "title": "SubscriberClient", + "type": "pubsub/v1/subscriberclient" + }] +}] diff --git a/docs/contents/cloud-speech.json b/docs/contents/cloud-speech.json new file mode 100644 index 000000000000..d433dce34a69 --- /dev/null +++ b/docs/contents/cloud-speech.json @@ -0,0 +1,17 @@ +[{ + "title": "SpeechClient", + "type": "speech/speechclient" +}, { + "title": "Operation", + "type": "speech/operation" +}, { + "title": "v1beta1", + "type": "speech/v1beta1/readme", + "patterns": [ + "speech/v1beta1/\\w{1,}" + ], + "nav": [{ + "title": "SpeechClient", + "type": "speech/v1beta1/speechclient" + }] +}] diff --git a/docs/contents/cloud-storage.json b/docs/contents/cloud-storage.json new file mode 100644 index 000000000000..0b7c36cbfd68 --- /dev/null +++ b/docs/contents/cloud-storage.json @@ -0,0 +1,13 @@ +[{ + "title": "StorageClient", + "type": "storage/storageclient" +}, { + "title": "ACL", + "type": "storage/acl" +}, { + "title": "Bucket", + "type": "storage/bucket" +}, { + "title": "StorageObject", + "type": "storage/storageobject" +}] diff --git a/docs/contents/cloud-translate.json b/docs/contents/cloud-translate.json new file mode 100644 index 000000000000..d829deaa0161 --- /dev/null +++ b/docs/contents/cloud-translate.json @@ -0,0 +1,4 @@ +[{ + "title": "TranslateClient", + "type": "translate/translateclient" +}] diff --git a/docs/contents/cloud-vision.json b/docs/contents/cloud-vision.json new file mode 100644 index 000000000000..1ffef7a6ec5f --- /dev/null +++ b/docs/contents/cloud-vision.json @@ -0,0 +1,34 @@ +[{ + "title": "VisionClient", + "type": "vision/visionclient" +}, { + "title": "Image", + "type": "vision/image" +}, { + "title": "Annotation", + "type": "vision/annotation", + "nav": [ + { + "title": "CropHint", + "type": "vision/annotation/crophint" + }, { + "title": "Document", + "type": "vision/annotation/document" + }, { + "title": "Entity", + "type": "vision/annotation/entity" + }, { + "title": "Face", + "type": "vision/annotation/face" + }, { + "title": "ImageProperties", + "type": "vision/annotation/imageproperties" + }, { + "title": "SafeSearch", + "type": "vision/annotation/safesearch" + }, { + "title": "Web", + "type": "vision/annotation/web" + } + ] +}] diff --git a/docs/contents/google-cloud.json b/docs/contents/google-cloud.json new file mode 100644 index 000000000000..ab88991df84b --- /dev/null +++ b/docs/contents/google-cloud.json @@ -0,0 +1,4 @@ +[{ + "title": "ServiceBuilder", + "type": "servicebuilder" +}] diff --git a/docs/home.html b/docs/home.html index 46eb81f7d874..82f9296f1687 100644 --- a/docs/home.html +++ b/docs/home.html @@ -22,7 +22,7 @@