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: add support for metadata comments in samples #230

Merged
merged 3 commits into from
Apr 24, 2019
Merged
Show file tree
Hide file tree
Changes from 2 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
32 changes: 30 additions & 2 deletions synthtool/gcp/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,37 @@ def _load_samples(self, metadata: Dict):
# 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}
sample_metadata = {"title": decamelize(file[:-3]), "file": file}
sample_metadata.update(
self._read_sample_metadata_comment(samples_dir, file)
)
metadata["samples"].append(sample_metadata)

def _read_sample_metadata_comment(self, samples_dir: Path, file: str) -> Dict:
"""
Additional meta-information can be provided through embedded comments:

// sample-metadata:
// title: ACL (Access Control)
// description: Demonstrates setting access control rules.
// usage: node iam.js --help
"""
sample_metadata = {} # type: Dict[str, str]
with open(samples_dir / file) as f:
contents = f.read()
match = re.search(
r"(?P<metadata>// *sample-metadata:([^\n]+|\n//)+)", contents, re.DOTALL
)
if match:
# the metadata yaml is stored in a comments, remove the
# prefix so that we can parse the yaml contained.
sample_metadata_string = re.sub(
r"((#|//) ?)", "", match.group("metadata")
)
sample_metadata = yaml.load(
sample_metadata_string, Loader=yaml.SafeLoader
)["sample-metadata"]
return sample_metadata

def _read_quickstart(self, samples_dir: Path) -> str:
"""
Expand Down
2 changes: 1 addition & 1 deletion synthtool/gcp/templates/node_library/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ has instructions for running the samples.

| Sample | Source Code | Try it |
| --------------------------- | --------------------------------- | ------ |
{% 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) |
{% for sample in metadata['samples'] %}| {{ sample.title }} | [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'] %}
Expand Down
12 changes: 9 additions & 3 deletions synthtool/gcp/templates/node_library/samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

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

## Before you begin

Expand All @@ -27,7 +27,13 @@ Before running the samples, make sure you've followed the steps outlined in
{% if metadata['samples']|length %}
{% for sample in metadata['samples'] %}

### {{sample.name}}
### {{sample.title}}

{%- if 'description' in sample %}

{{ sample.description }}

{%- endif %}

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

Expand All @@ -36,7 +42,7 @@ View the [source code](https://github.com/{{ metadata['repo']['repo'] }}/blob/m
__Usage:__


`node {{ sample.file }}`
{% if 'usage' in sample %}`{{ sample.usage }}`{% else %}`node {{ sample.file }}`{% endif %}

{% if not loop.last %}
-----
Expand Down
4 changes: 3 additions & 1 deletion synthtool/sources/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from pathlib import Path

import jinja2
import re

from synthtool import log
from synthtool import tmp
Expand Down Expand Up @@ -122,7 +123,8 @@ def language_pretty(input: str) -> str:

def slugify(input: str) -> str:
"""Converts Foo Bar into foo-bar, for use wih anchor links."""
return input.lower().replace(" ", "-")
input = re.sub(r"([() ]+)", "-", input.lower())
return re.sub(r"-$", "", input)


def syntax_highlighter(input: str) -> str:
Expand Down
28 changes: 28 additions & 0 deletions tests/fixtures/samples/meta1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Copyright 2017, Google, Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

//
// sample-metadata:
// title: Metadata Example 1
// description: this is a description.
// usage: node hello-world.js
//
'use strict';

async function viewBucketIamMembers(bucketName) {
// [START storage_view_bucket_iam_members]
// Imports the Google Cloud client library
// [END storage_view_bucket_iam_members]
}
29 changes: 29 additions & 0 deletions tests/fixtures/samples/meta2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright 2017, Google, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Can we use the 2019 version of the license?

* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// sample-metadata:
// title: Metadata Example 2
// description: this is a description.
// usage: node goodnight-moon.js


// title: this is not part of metadata block.
'use strict';

async function viewBucketIamMembers(bucketName) {
// [START storage_view_bucket_iam_members]
// Imports the Google Cloud client library
// [END storage_view_bucket_iam_members]
}
16 changes: 13 additions & 3 deletions tests/test_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,17 @@ def test_load_samples():
metadata = {}
common_templates._load_samples(metadata)
# should have loaded samples.
assert metadata["samples"][1]["name"] == "Requester Pays"
assert metadata["samples"][1]["file"] == "requesterPays.js"
assert len(metadata["samples"]) == 2
assert metadata["samples"][3]["title"] == "Requester Pays"
assert metadata["samples"][3]["file"] == "requesterPays.js"
assert len(metadata["samples"]) == 4
# 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"]
# should have included additional meta-information provided.
assert metadata["samples"][0]["title"] == "Metadata Example 1"
assert metadata["samples"][0]["usage"] == "node hello-world.js"
assert metadata["samples"][1]["title"] == "Metadata Example 2"
assert metadata["samples"][1]["usage"] == "node goodnight-moon.js"

os.chdir(cwd)

Expand Down Expand Up @@ -138,3 +143,8 @@ def test_ruby_authentication():
assert "Google::Cloud::Bigquery::DataTransfer.new" in result
assert "Google::Cloud::Bigquery::DataTransfer::V1::Credentials" in result
assert "DATA_TRANSFER_CREDENTIALS" in result


def test_slugify():
assert templates.slugify("Foo Bar") == "foo-bar"
assert templates.slugify("ACL (Access Control)") == "acl-access-control"