Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: also generate samples/README.md #214

Merged
merged 10 commits into from
Apr 2, 2019
78 changes: 42 additions & 36 deletions synthtool/gcp/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import re
import yaml
from pathlib import Path
from typing import List
from typing import List, Dict

from synthtool.languages import node
from synthtool.sources import templates
Expand All @@ -40,6 +40,10 @@ def _generic_library(self, directory: str, **kwargs) -> Path:
# load common repo meta information (metadata that's not language specific).
if "metadata" in kwargs:
self._load_generic_metadata(kwargs["metadata"])
# if no samples were found, don't attempt to render a
# samples/README.md.
if not kwargs["metadata"]["samples"]:
self.excludes.append("samples/README.md")

t = templates.TemplateGroup(_TEMPLATES_DIR / directory, self.excludes)
result = t.render(**kwargs)
Expand All @@ -57,6 +61,8 @@ def node_library(self, **kwargs) -> Path:
# .repo-metadata.json, or excluding README.md, we can remove this.
if not os.path.exists("./.repo-metadata.json"):
self.excludes.append("README.md")
if "samples/README.md" not in self.excludes:
self.excludes.append("samples/README.md")

kwargs["metadata"] = node.read_metadata()
kwargs["publish_token"] = node.get_publish_token(kwargs["metadata"]["name"])
Expand All @@ -68,10 +74,10 @@ def php_library(self, **kwargs) -> Path:
def render(self, template_name: str, **kwargs) -> Path:
return self._templates.render(template_name, **kwargs)

#
# loads additional meta information from .repo-metadata.json.
#
def _load_generic_metadata(self, metadata):
def _load_generic_metadata(self, metadata: Dict):
"""
loads additional meta information from .repo-metadata.json.
"""
self._load_samples(metadata)
self._load_partials(metadata)

Expand All @@ -80,15 +86,15 @@ def _load_generic_metadata(self, metadata):
with open("./.repo-metadata.json") as f:
metadata["repo"] = json.load(f)

#
# walks samples directory and builds up samples data-structure:
#
# {
# "name": "Requester Pays",
# "file": "requesterPays.js"
# }
#
def _load_samples(self, metadata):
def _load_samples(self, metadata: Dict):
"""
walks samples directory and builds up samples data-structure:

{
"name": "Requester Pays",
"file": "requesterPays.js"
}
"""
metadata["samples"] = []
samples_dir = Path(os.getcwd()) / "samples"
if os.path.exists(samples_dir):
Expand All @@ -98,16 +104,18 @@ def _load_samples(self, metadata):
if re.match(r"\w+\.js$", file):
if file == "quickstart.js":
metadata["quickstart"] = self._read_quickstart(samples_dir)
else:
metadata["samples"].append(
{"name": decamelize(file[:-3]), "file": file}
)

#
# quickstart is a special case, it should be read from disk and displayed
# in README.md rather than pushed into samples array.
#
def _read_quickstart(self, samples_dir):
# only add quickstart file to samples list if code sample is found.
if file == "quickstart.js" and not metadata.get("quickstart", None):
continue
metadata["samples"].append(
{"name": decamelize(file[:-3]), "file": file}
)

def _read_quickstart(self, samples_dir: Path) -> str:
"""
quickstart is a special case, it should be read from disk and displayed
in README.md rather than pushed into samples array.
"""
reading = False
quickstart = ""

Expand All @@ -123,14 +131,14 @@ def _read_quickstart(self, samples_dir):

return quickstart

#
# hand-crafted artisinal markdown can be provided in a .readme-partials.yml.
# The following fields are currently supported:
#
# introduction: a more thorough introduction than metadata["description"].
# quickstart_footer: add additional context to footer of quickstart.
#
def _load_partials(self, metadata):
def _load_partials(self, metadata: Dict):
"""
hand-crafted artisinal markdown can be provided in a .readme-partials.yml.
The following fields are currently supported:

introduction: a more thorough introduction than metadata["description"].
body: custom body to include in the usage section of the document.
"""
cwd_path = Path(os.getcwd())
partials_file = None
for file in [".readme-partials.yml", ".readme-partials.yaml"]:
Expand All @@ -143,10 +151,8 @@ def _load_partials(self, metadata):
metadata["partials"] = yaml.load(f, Loader=yaml.SafeLoader)


#
# parser to convert fooBar.js to Foo Bar.
#
def decamelize(str):
def decamelize(str: str):
""" parser to convert fooBar.js to Foo Bar. """
str2 = str[0].upper()
for chr in str[1:]:
if re.match(r"[A-Z]", chr):
Expand Down
33 changes: 16 additions & 17 deletions synthtool/gcp/templates/node_library/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
{{ metadata['description'] }}
{% endif %}

* [{{ metadata['repo']['name_pretty'] }} {{ metadata['repo']['language']|language_pretty }} Client API Reference][client-docs]
* [{{ metadata['repo']['name_pretty'] }} Documentation][product-docs]
{% if metadata['repo']['client_documentation'] %}* [{{ metadata['repo']['name_pretty'] }} {{ metadata['repo']['language']|language_pretty }} Client API Reference][client-docs]{% endif %}
{% if metadata['repo']['product_documentation'] %}* [{{ metadata['repo']['name_pretty'] }} Documentation][product-docs]{% endif %}
* [github.com/{{ metadata['repo']['repo'] }}](https://github.com/{{ metadata['repo']['repo'] }})

Read more about the client libraries for Cloud APIs, including the older
Expand All @@ -31,26 +31,26 @@ Google APIs Client Libraries, in [Client Libraries Explained][explained].

**Table of contents:**

{% if metadata['quickstart'] %}

* [Quickstart](#quickstart)
* [Before you begin](#before-you-begin)
{% if metadata['repo']['api_id'] %} * [Before you begin](#before-you-begin){% endif %}
* [Installing the client library](#installing-the-client-library)
* [Using the client library](#using-the-client-library){% endif %}{% if metadata['samples']|length %}
* [Samples](#samples){% endif %}
{% if metadata['quickstart'] %} * [Using the client library](#using-the-client-library){% endif %}
{% if metadata['samples']|length %}* [Samples](#samples){% endif %}
* [Versioning](#versioning)
* [Contributing](#contributing)
* [License](#license)

## Quickstart

{% if metadata['repo']['api_id'] %}
### Before you begin

1. [Select or create a Cloud Platform project][projects].{% if metadata['repo']['requires_billing'] %}
1. [Enable billing for your project][billing].{% endif %}
1. [Enable the {{ metadata['repo']['name_pretty'] }} API][enable_api].
1. [Set up authentication with a service account][auth] so you can access the
API from your local workstation.

{% endif %}
### Installing the client library

```bash
Expand All @@ -61,10 +61,9 @@ Google APIs Client Libraries, in [Client Libraries Explained][explained].
### Using the client library

```{{ metadata['repo']['language']|syntax_highlighter }}
{{ metadata['quickstart'] }}{% if metadata['partials'] and metadata['partials']['quickstart_footer'] %}
{{ metadata['partials']['quickstart_footer'] }}
bcoe marked this conversation as resolved.
Show resolved Hide resolved
{% endif %}```
{% endif %}
{{ metadata['quickstart'] }}
```
{% endif %}{% if metadata['partials'] and metadata['partials']['body'] %}{{ metadata['partials']['body'] }}{% endif %}

{% if metadata['samples']|length %}
## Samples
Expand All @@ -77,10 +76,10 @@ has instructions for running the samples.
{% for sample in metadata['samples'] %}| {{ sample.name }} | [source code](https://github.com/{{ metadata['repo']['repo'] }}/blob/master/samples/{{ sample.file }}) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/{{ metadata['repo']['repo'] }}&page=editor&open_in_editor=samples/{{ sample.file }},samples/README.md) |
{% endfor %}
{% endif %}

{% if metadata['repo']['client_documentation'] %}
The [{{ metadata['repo']['name_pretty'] }} {{ metadata['repo']['language']|language_pretty }} Client API Reference][client-docs] documentation
also contains samples.

{% endif %}
## Versioning

This library follows [Semantic Versioning](http://semver.org/).
Expand Down Expand Up @@ -123,10 +122,10 @@ Apache Version 2.0

See [LICENSE](https://github.com/{{ metadata['repo']['repo'] }}/blob/master/LICENSE)

[client-docs]: {{ metadata['repo']['client_documentation'] }}
[product-docs]: {{ metadata['repo']['product_documentation'] }}
{% if metadata['repo']['client_documentation'] %}[client-docs]: {{ metadata['repo']['client_documentation'] }}{% endif %}
{% if metadata['repo']['product_documentation'] %}[product-docs]: {{ metadata['repo']['product_documentation'] }}{% endif %}
[shell_img]: https://gstatic.com/cloudssh/images/open-btn.png
[projects]: https://console.cloud.google.com/project
[billing]: https://support.google.com/cloud/answer/6293499#enable-billing
[enable_api]: https://console.cloud.google.com/flows/enableapi?apiid={{ metadata['repo']['api_id'] }}
{% if metadata['repo']['api_id'] %}[enable_api]: https://console.cloud.google.com/flows/enableapi?apiid={{ metadata['repo']['api_id'] }}{% endif %}
[auth]: https://cloud.google.com/docs/authentication/getting-started
47 changes: 47 additions & 0 deletions synthtool/gcp/templates/node_library/samples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[//]: # "This README.md file is auto-generated, all changes to this file will be lost."
[//]: # "To regenerate it, use `python -m synthtool`."
<img src="https://avatars2.githubusercontent.com/u/2810941?v=3&s=96" alt="Google Cloud Platform logo" title="Google Cloud Platform" align="right" height="96" width="96"/>

# [{{ metadata['repo']['name_pretty'] }}: {{ metadata['repo']['language']|language_pretty }} Samples](https://github.com/{{ metadata['repo']['repo'] }})

[![Open in Cloud Shell][shell_img]][shell_link]

{{ metadata['partials'] and metadata['partials']['introduction'] }}

## Table of Contents

* [Before you begin](#before-you-begin)
* [Samples](#samples){% if metadata['samples']|length %}{% for sample in metadata['samples'] %}
* [{{ sample.name }}](#{{ sample.name|slugify }}){% endfor %}{% endif %}

## Before you begin

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this README has been simplified, the need for executing samples to generate yargs output, this matches the direction we're moving in for samples any ways.

Before running the samples, make sure you've followed the steps in the
[Using the client library](https://github.com/{{ metadata['repo']['repo'] }}#using-the-client-library) of the client
library's README.

## Samples
{% if metadata['samples']|length %}
{% for sample in metadata['samples'] %}

### {{sample.name}}

View the [source code](https://github.com/{{ metadata['repo']['repo'] }}/blob/master/samples/{{ sample.file }}).

[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/{{ metadata['repo']['repo'] }}&page=editor&open_in_editor=samples/{{ sample.file }},samples/README.md)

__Usage:__


`node {{ sample.file }}`

{% if not loop.last %}
-----
{% endif %}

{% endfor %}
{% endif %}

[shell_img]: https://gstatic.com/cloudssh/images/open-btn.png
[shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/{{ metadata['repo']['repo'] }}&page=editor&open_in_editor=samples/README.md
[product-docs]: {{ metadata['repo']['product_documentation'] }}
28 changes: 14 additions & 14 deletions synthtool/sources/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def _make_env(location):
)
env.filters["release_quality_badge"] = release_quality_badge
env.filters["language_pretty"] = language_pretty
env.filters["slugify"] = slugify
env.filters["syntax_highlighter"] = syntax_highlighter
return env

Expand Down Expand Up @@ -85,13 +86,11 @@ def render(self, **kwargs) -> Path:
return self.dir


#
# Generates a markdown badge for displaying a "Release Quality'.
#
def release_quality_badge(input):
def release_quality_badge(input: str) -> str:
"""Generates a markdown badge for displaying a "Release Quality'."""
if not input:
log.error(f"ensure you pass a string 'quality' to release_quality_badge")
return
return ""

release_quality = input.upper()
badge = ""
Expand All @@ -110,23 +109,24 @@ def release_quality_badge(input):
log.error(
"Expected 'release_quality' to be one of: (ga, beta, alpha, eap, deprecated)"
)
return
return ""
return f"[![release level](https://img.shields.io/badge/release%20level-{badge}.svg?style=flat)](https://cloud.google.com/terms/launch-stages)"


#
# .repo-metadata.json language field to pretty language.
#
def language_pretty(input):
def language_pretty(input: str) -> str:
""".repo-metadata.json language field to pretty language."""
if input == "nodejs":
return "Node.js"
return input


#
# .repo-metadata.json language field to syntax highlighter name.
#
def syntax_highlighter(input):
def slugify(input: str) -> str:
"""Converts Foo Bar into foo-bar, for use wih anchor links."""
return input.lower().replace(" ", "-")


def syntax_highlighter(input: str) -> str:
""".repo-metadata.json language field to syntax highlighter name."""
if input == "nodejs":
return "javascript"
return input
8 changes: 4 additions & 4 deletions tests/test_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ def test_load_samples():
metadata = {}
common_templates._load_samples(metadata)
# should have loaded samples.
assert metadata["samples"][0]["name"] == "Requester Pays"
assert metadata["samples"][0]["file"] == "requesterPays.js"
assert len(metadata["samples"]) == 1
assert metadata["samples"][1]["name"] == "Requester Pays"
assert metadata["samples"][1]["file"] == "requesterPays.js"
assert len(metadata["samples"]) == 2
# should have loaded the special quickstart sample (ignoring header).
assert "ID of the Cloud Bigtable instance" in metadata["quickstart"]
assert "limitations under the License" not in metadata["quickstart"]
Expand All @@ -96,7 +96,7 @@ def test_hide_billing():
t = templates.Templates(NODE_TEMPLATES)

result = t.render(
"README.md", metadata={"repo": {"requires_billing": True}}
"README.md", metadata={"repo": {"requires_billing": True, "api_id": "fooapi"}}
).read_text()
assert "Enable billing for your project" in result

Expand Down