Skip to content
This repository has been archived by the owner on Jun 28, 2022. It is now read-only.

NodeJS: generate readme. #1240

Merged
merged 3 commits into from
May 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ public String getOutputFileName() {
return getNotImplementedString("PackageMetadataNamer.getOutputFileName");
}

// TODO: (landrito) this is copied from SurfaceNamer. Figure out a way to consolidate the methods.
public String getReleaseAnnotation(ReleaseLevel releaseLevel) {
switch (releaseLevel) {
case UNSET_RELEASE_LEVEL:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,53 +16,178 @@

import com.google.api.codegen.InterfaceView;
import com.google.api.codegen.TargetLanguage;
import com.google.api.codegen.config.FlatteningConfig;
import com.google.api.codegen.config.GapicProductConfig;
import com.google.api.codegen.config.PackageMetadataConfig;
import com.google.api.codegen.nodejs.NodeJSUtils;
import com.google.api.codegen.transformer.DynamicLangApiMethodTransformer;
import com.google.api.codegen.transformer.FileHeaderTransformer;
import com.google.api.codegen.transformer.GapicInterfaceContext;
import com.google.api.codegen.transformer.GapicMethodContext;
import com.google.api.codegen.transformer.InitCodeTransformer;
import com.google.api.codegen.transformer.ModelToViewTransformer;
import com.google.api.codegen.transformer.ModelTypeTable;
import com.google.api.codegen.transformer.PackageMetadataTransformer;
import com.google.api.codegen.transformer.TestCaseTransformer;
import com.google.api.codegen.util.js.JSTypeTable;
import com.google.api.codegen.util.testing.StandardValueProducer;
import com.google.api.codegen.util.testing.ValueProducer;
import com.google.api.codegen.viewmodel.ApiMethodView;
import com.google.api.codegen.viewmodel.ImportSectionView;
import com.google.api.codegen.viewmodel.InitCodeView;
import com.google.api.codegen.viewmodel.OptionalArrayMethodView;
import com.google.api.codegen.viewmodel.ViewModel;
import com.google.api.tools.framework.model.Interface;
import com.google.api.tools.framework.model.Method;
import com.google.api.tools.framework.model.Model;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/** Responsible for producing package metadata related views for NodeJS */
public class NodeJSPackageMetadataTransformer implements ModelToViewTransformer {
private static final String PACKAGE_FILE = "nodejs/package.snip";
private static final String README_FILE = "nodejs/README.md.snip";
private static final String README_OUTPUT_FILE = "README.md";
private static final List<String> TOP_LEVEL_FILES = ImmutableList.of("nodejs/package.json.snip");

PackageMetadataConfig packageConfig;
PackageMetadataTransformer metadataTransformer = new PackageMetadataTransformer();
private static final String GITHUB_DOC_HOST =
"https://googlecloudplatform.github.io/google-cloud-node";
private static final String GITHUB_REPO_HOST =
"https://github.com/GoogleCloudPlatform/google-cloud-node";
private static final String AUTH_DOC_PATH = "/#/docs/google-cloud/master/guides/authentication";
private static final String LIB_DOC_PATH = "/#/docs/%s";
private static final String MAIN_README_PATH = "/blob/master/README.md";
private static final String VERSIONING_DOC_PATH = "#versioning";

private static String NODE_PREFIX = "nodejs/";

private final FileHeaderTransformer fileHeaderTransformer =
new FileHeaderTransformer(new NodeJSImportSectionTransformer());
private final PackageMetadataConfig packageConfig;
private final PackageMetadataTransformer metadataTransformer = new PackageMetadataTransformer();
private final ValueProducer valueProducer = new StandardValueProducer();
private final TestCaseTransformer testCaseTransformer = new TestCaseTransformer(valueProducer);

public NodeJSPackageMetadataTransformer(PackageMetadataConfig packageConfig) {
this.packageConfig = packageConfig;
}

@Override
public List<String> getTemplateFileNames() {
return Arrays.asList(PACKAGE_FILE);
return ImmutableList.<String>builder().addAll(TOP_LEVEL_FILES).add(README_FILE).build();
}

@Override
public List<ViewModel> transform(Model model, GapicProductConfig productConfig) {
Iterable<Interface> services = new InterfaceView().getElementIterable(model);
boolean hasMultipleServices = Iterables.size(services) > 1;
List<ViewModel> models = new ArrayList<ViewModel>();
NodeJSPackageMetadataNamer namer =
new NodeJSPackageMetadataNamer(
productConfig.getPackageName(), productConfig.getDomainLayerLocation());
models.add(generateMetadataView(model, namer, hasMultipleServices));
models.addAll(generateMetadataViews(model, namer));
models.add(generateReadmeView(model, productConfig, namer));
return models;
}

private ViewModel generateMetadataView(
Model model, NodeJSPackageMetadataNamer namer, boolean hasMultipleServices) {
private ViewModel generateReadmeView(
Model model, GapicProductConfig productConfig, NodeJSPackageMetadataNamer namer) {
List<ApiMethodView> exampleMethods = generateExampleMethods(model, productConfig);
Iterable<Interface> services = new InterfaceView().getElementIterable(model);
boolean hasMultipleServices = Iterables.size(services) > 1;
return metadataTransformer
.generateMetadataView(
packageConfig, model, PACKAGE_FILE, "package.json", TargetLanguage.NODEJS)
packageConfig, model, README_FILE, README_OUTPUT_FILE, TargetLanguage.NODEJS)
.identifier(namer.getMetadataIdentifier())
.fileHeader(
fileHeaderTransformer.generateFileHeader(
productConfig,
ImportSectionView.newBuilder().build(),
new NodeJSSurfaceNamer(
productConfig.getPackageName(), NodeJSUtils.isGcloud(productConfig))))
.developmentStatusTitle(
namer.getReleaseAnnotation(packageConfig.releaseLevel(TargetLanguage.NODEJS)))
.exampleMethods(exampleMethods)
.hasMultipleServices(hasMultipleServices)
.targetLanguage("NodeJS")
.mainReadmeLink(GITHUB_REPO_HOST + MAIN_README_PATH)
.libraryDocumentationLink(
GITHUB_DOC_HOST + String.format(LIB_DOC_PATH, packageConfig.shortName()))
.authDocumentationLink(GITHUB_DOC_HOST + AUTH_DOC_PATH)
.versioningDocumentationLink(GITHUB_REPO_HOST + VERSIONING_DOC_PATH)
.build();
}

// Generates methods used as examples for the README.md file.
// Note: This is based on sample gen method calls. In the future, the example
// methods may be configured separately.
private List<ApiMethodView> generateExampleMethods(
Model model, GapicProductConfig productConfig) {
ImmutableList.Builder<ApiMethodView> exampleMethods = ImmutableList.builder();
for (Interface apiInterface : new InterfaceView().getElementIterable(model)) {
GapicInterfaceContext context = createContext(apiInterface, productConfig);
if (context.getInterfaceConfig().getSmokeTestConfig() != null) {
Method method = context.getInterfaceConfig().getSmokeTestConfig().getMethod();
FlatteningConfig flatteningGroup =
testCaseTransformer.getSmokeTestFlatteningGroup(
context.getMethodConfig(method), context.getInterfaceConfig().getSmokeTestConfig());
GapicMethodContext flattenedMethodContext =
context.asFlattenedMethodContext(method, flatteningGroup);
exampleMethods.add(createExampleApiMethodView(flattenedMethodContext));
}
}
return exampleMethods.build();
}

private OptionalArrayMethodView createExampleApiMethodView(GapicMethodContext context) {
OptionalArrayMethodView initialApiMethodView =
new DynamicLangApiMethodTransformer(new NodeJSApiMethodParamTransformer())
.generateMethod(context);

OptionalArrayMethodView.Builder apiMethodView = initialApiMethodView.toBuilder();

InitCodeTransformer initCodeTransformer = new InitCodeTransformer();
InitCodeView initCodeView =
initCodeTransformer.generateInitCode(
context, testCaseTransformer.createSmokeTestInitContext(context));
apiMethodView.initCode(initCodeView);

return apiMethodView.build();
}

private List<ViewModel> generateMetadataViews(Model model, NodeJSPackageMetadataNamer namer) {
ImmutableList.Builder<ViewModel> views = ImmutableList.builder();
for (String template : TOP_LEVEL_FILES) {
views.add(generateMetadataView(model, template, namer));
}
return views.build();
}

private ViewModel generateMetadataView(
Model model, String template, NodeJSPackageMetadataNamer namer) {
String noLeadingNodeDir =
template.startsWith(NODE_PREFIX) ? template.substring(NODE_PREFIX.length()) : template;
int extensionIndex = noLeadingNodeDir.lastIndexOf(".");
String outputPath = noLeadingNodeDir.substring(0, extensionIndex);

Iterable<Interface> services = new InterfaceView().getElementIterable(model);
boolean hasMultipleServices = Iterables.size(services) > 1;

return metadataTransformer
.generateMetadataView(packageConfig, model, template, outputPath, TargetLanguage.NODEJS)
.identifier(namer.getMetadataIdentifier())
.hasMultipleServices(hasMultipleServices)
.build();
}

private GapicInterfaceContext createContext(
Interface apiInterface, GapicProductConfig productConfig) {
return GapicInterfaceContext.create(
apiInterface,
productConfig,
new ModelTypeTable(
new JSTypeTable(productConfig.getPackageName()),
new NodeJSModelTypeNameConverter(productConfig.getPackageName())),
new NodeJSSurfaceNamer(productConfig.getPackageName(), NodeJSUtils.isGcloud(productConfig)),
new NodeJSFeatureConfig());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@
import com.google.api.codegen.config.GrpcStreamingConfig.GrpcStreamingType;
import com.google.api.codegen.config.SingleResourceNameConfig;
import com.google.api.codegen.config.VisibilityConfig;
import com.google.api.codegen.metacode.InitFieldConfig;
import com.google.api.codegen.transformer.FeatureConfig;
import com.google.api.codegen.transformer.GapicInterfaceContext;
import com.google.api.codegen.transformer.ModelTypeFormatterImpl;
import com.google.api.codegen.transformer.ModelTypeTable;
import com.google.api.codegen.transformer.SurfaceNamer;
import com.google.api.codegen.transformer.Synchronicity;
import com.google.api.codegen.util.CommonRenderingUtil;
import com.google.api.codegen.util.Name;
import com.google.api.codegen.util.NamePath;
import com.google.api.codegen.util.js.JSCommentReformatter;
Expand All @@ -40,9 +42,11 @@
import com.google.api.tools.framework.model.Method;
import com.google.api.tools.framework.model.ProtoFile;
import com.google.api.tools.framework.model.TypeRef;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

Expand Down Expand Up @@ -465,4 +469,25 @@ public String getStreamTypeName(GrpcStreamingType type) {
"SurfaceNamer.getStreamTypeName(GrpcStreamingType." + type.toString() + ")");
}
}

@Override
public String injectRandomStringGeneratorCode(String randomString) {
String delimiter = ",";
String[] split =
CommonRenderingUtil.stripQuotes(randomString)
.replace(
InitFieldConfig.RANDOM_TOKEN, delimiter + InitFieldConfig.RANDOM_TOKEN + delimiter)
.split(delimiter);
ArrayList<String> stringParts = new ArrayList<>();
for (String token : split) {
if (token.length() > 0) {
if (token.equals(InitFieldConfig.RANDOM_TOKEN)) {
stringParts.add("Date.now().toString()");
} else {
stringParts.add("\"" + token + "\"");
}
}
}
return Joiner.on(" + ").join(stringParts);
}
}
23 changes: 23 additions & 0 deletions src/main/resources/com/google/api/codegen/nodejs/README.md.snip
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@extends "nodejs/method_sample.snip"
@extends "readme.snip"

@snippet generate(metadata)
{@readme(metadata, exampleMethods(metadata.exampleMethods, metadata), installationLines(metadata))}
@end

@private exampleMethods(methods, metadata)
@join method : methods on BREAK
@#### {@method.apiClassName}
```js
var {@method.apiModuleName} = require('{@metadata.identifier}').{@metadata.majorVersion}({
// optional auth parameters.
});

{@decorateSampleCode(method, sampleCode(method))}
```
@end
@end

@private installationLines(metadata)
$ npm install {@metadata.identifier}
@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
============== file: README.md ==============
# NodeJS Client for Google Example Library API ([Alpha](https://github.com/GoogleCloudPlatform/google-cloud-node#versioning))

Idiomatic NodeJS client for [Google Example Library API][Product Documentation]
- [Client Library Documentation][]
- [Product Documentation][]

## Quick Start
In order to use this library, you first need to go through the following steps:

1. [Select or create a Cloud Platform project.](https://console.cloud.google.com/project)
2. [Enable the library api.](https://console.cloud.google.com/apis/api/library)
3. [Setup Authentication.](https://googlecloudplatform.github.io/google-cloud-node/#/docs/google-cloud/master/guides/authentication)

### Installation
```
$ npm install @google-cloud/library
```

### Preview
#### LibraryServiceClient
```js
var libraryV1 = require('@google-cloud/library').v1({
// optional auth parameters.
});

var client = libraryV1.libraryServiceClient();
var formattedName = client.bookPath("testShelf-" + Date.now().toString(), projectId);
var rating = libraryV1.Book.Rating.GOOD;
var book = {
rating : rating
};
var request = {
name: formattedName,
book: book
};
client.updateBook(request).then(function(responses) {
var response = responses[0];
// doThingsWith(response)
}).catch(function(err) {
console.error(err);
});
```

### Next Steps
- Read the [Client Library Documentation][] for Google Example Library API to see other available methods on the client.
- Read the [Google Example Library API Product documentation][Product Documentation] to learn more about the product and see How-to Guides.
- View this [repository's main README](https://github.com/GoogleCloudPlatform/google-cloud-node/blob/master/README.md) to see the full list of Cloud APIs that we cover.

[Client Library Documentation]: https://googlecloudplatform.github.io/google-cloud-node/#/docs/library
[Product Documentation]: https://cloud.google.com/library
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
============== file: README.md ==============
# NodeJS Client for Google Fake API ([Alpha](https://github.com/GoogleCloudPlatform/google-cloud-node#versioning))

Idiomatic NodeJS client for [Google Fake API][Product Documentation]
- [Client Library Documentation][]
- [Product Documentation][]

## Quick Start
In order to use this library, you first need to go through the following steps:

1. [Select or create a Cloud Platform project.](https://console.cloud.google.com/project)
2. [Enable the library api.](https://console.cloud.google.com/apis/api/library)
3. [Setup Authentication.](https://googlecloudplatform.github.io/google-cloud-node/#/docs/google-cloud/master/guides/authentication)

### Installation
```
$ npm install example
```

### Next Steps
- Read the [Client Library Documentation][] for Google Fake API to see other available methods on the client.
- Read the [Google Fake API Product documentation][Product Documentation] to learn more about the product and see How-to Guides.
- View this [repository's main README](https://github.com/GoogleCloudPlatform/google-cloud-node/blob/master/README.md) to see the full list of Cloud APIs that we cover.

[Client Library Documentation]: https://googlecloudplatform.github.io/google-cloud-node/#/docs/library
[Product Documentation]: https://cloud.google.com/library
Loading