Skip to content

Commit

Permalink
feat: add support for generating samples/README.md from samples folder (
Browse files Browse the repository at this point in the history
  • Loading branch information
bcoe authored Apr 2, 2019
1 parent 0d263a3 commit 2651a7e
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 71 deletions.
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'] }}
{% 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

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

0 comments on commit 2651a7e

Please sign in to comment.