blob: 21a18d98b2289e682f7cd6d9312e8803585107fd [file] [log] [blame] [edit]
# Copyright 2020 Google LLC
#
# 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
#
# https://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.
import glob
import re
import os
import yaml
from typing import List, Dict
from synthtool.log import logger
def _read_sample_metadata_comment(sample_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(sample_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"))
try:
sample_metadata = yaml.load(
sample_metadata_string, Loader=yaml.SafeLoader
)["sample-metadata"]
except yaml.scanner.ScannerError:
# warn and continue on bad metadata
logger.warning(f"bad metadata detected in {sample_file}")
return sample_metadata
def _sample_metadata(file: str) -> Dict[str, str]:
metadata = {
"title": _decamelize(os.path.splitext(os.path.basename(file))[0]),
"file": file,
}
return {**metadata, **_read_sample_metadata_comment(file)}
def all_samples(sample_globs: List[str]) -> List[Dict[str, str]]:
"""Walks samples directory and builds up samples data-structure
Args:
sample_globs: (List[str]): List of path globs to search for samples
Returns:
A list of sample metadata in the format:
{
"title": "Requester Pays",
"file": "samples/requesterPays.js"
}
The file path is the relative path from the repository root.
"""
files = []
for sample_glob in sample_globs:
for file in glob.glob(sample_glob, recursive=True):
files.append(file)
return [_sample_metadata(file) for file in sorted(files)]
def _decamelize(value: str):
"""Parser to convert fooBar.js to Foo Bar."""
if not value:
return ""
str_decamelize = re.sub("^.", value[0].upper(), value) # apple -> Apple.
str_decamelize = re.sub(
"([A-Z]+)([A-Z])([a-z0-9])", r"\1 \2\3", str_decamelize
) # ACLBatman -> ACL Batman.
return re.sub("([a-z0-9])([A-Z])", r"\1 \2", str_decamelize) # FooBar -> Foo Bar.