Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions nox.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,3 +320,12 @@ def mark_if_necessary(requirement):
for requirement in sorted(requirements, key=lambda s: s.lower()):
if not requirement.startswith('#'):
f.write(requirement)


def session_readmegen(session):
Copy link
Contributor

Choose a reason for hiding this comment

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

...read-memegen 😏

Copy link
Contributor

Choose a reason for hiding this comment

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

lol

session.install('-r', 'testing/requirements-dev.txt')

in_files = list(list_files('.', 'README.rst.in'))
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not a .yaml extension?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

.in indicates that the file is used to generate the file of the same name before it, so README.rst.in -> README.rst, whereas README.yaml.in -> README.yaml.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh - I meant README.rst.yaml to make clear that it's a yaml file (and for syntax highlighting, etc). The fact that it's an input to the resulting rst would be implied.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think .in is clearer that it's used exclusively for generating the README.rst file, but I'm happy to be disagreed with. @waprin, thoughts?


for in_file in in_files:
session.run('python', 'scripts/readme-gen/readme_gen.py', in_file)
65 changes: 65 additions & 0 deletions scripts/readme-gen/readme_gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env python

# Copyright 2016 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.

Copy link
Contributor

Choose a reason for hiding this comment

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

A module-level docstring would be nice

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a simple one for now.

"""Generates READMEs using configuration defined in yaml."""

import argparse
import io
import os
import subprocess

import jinja2
import yaml


jinja_env = jinja2.Environment(
trim_blocks=True,
loader=jinja2.FileSystemLoader(
os.path.abspath(os.path.join(os.path.dirname(__file__), 'templates'))))

README_TMPL = jinja_env.get_template('README.tmpl.rst')
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: we could adopt the rails convention of ordering the file extensions by processing order? ie README.rst.jinja2, where it'd get processed by jinja2 first, then as an rst

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Meh.



def get_help(file):
return subprocess.check_output(['python', file, '--help'])


def main():
parser = argparse.ArgumentParser()
parser.add_argument('source')
parser.add_argument('--destination', default='README.rst')

args = parser.parse_args()

source = os.path.abspath(args.source)
root = os.path.dirname(source)
destination = os.path.join(root, args.destination)

jinja_env.globals['get_help'] = get_help

with io.open(source, 'r') as f:
config = yaml.load(f)

# This allows get_help to execute in the right directory.
os.chdir(root)

output = README_TMPL.render(config)

with io.open(destination, 'w') as f:
f.write(output)

if __name__ == '__main__':
main()
62 changes: 62 additions & 0 deletions scripts/readme-gen/templates/README.tmpl.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{# The following line is a lie. BUT! Once jinja2 is done with it, it will
become truth! #}
.. This file is automatically generated. Do not edit this file directly.
Copy link
Contributor

Choose a reason for hiding this comment

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

Possibly add a jinja2 comment that's like:

{# The following line is a lie. BUT! Once jinja2 is done with it, it will become truth! #}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done (verbatim)


{{product.name}} Python Samples
===============================================================================

This directory contains samples for {{product.name}}. {{product.description}}

.. _{{product.name}}: {{product.url}}

{% if setup %}
Setup
-------------------------------------------------------------------------------

{% for section in setup %}

{% include section + '.tmpl.rst' %}

{% endfor %}
{% endif %}

{% if samples %}
Samples
-------------------------------------------------------------------------------

{% for sample in samples %}
{{sample.name}}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

{{sample.description}}

To run this sample:

.. code-block:: bash

$ python {{sample.file}}
{% if sample.show_help %}

{{get_help(sample.file)|indent}}
{% endif %}


{% endfor %}
{% endif %}

{% if cloud_client_library %}

The client library
-------------------------------------------------------------------------------

This sample uses the `Google Cloud Client Library for Python <ccl-docs>`_.
You can read the documentation for more details on API usage and use GitHub
to `browse the source <ccl-source>`_ and `report issues <ccl-issues>`_.

.. ccl-docs: https://googlecloudplatform.github.io/google-cloud-python/
.. ccl-source: https://github.com/GoogleCloudPlatform/google-cloud-python
.. ccl-issues: https://github.com/GoogleCloudPlatform/google-cloud-python/issues

{% endif %}

.. _Google Cloud SDK: https://cloud.google.com/sdk/
33 changes: 33 additions & 0 deletions scripts/readme-gen/templates/auth.tmpl.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Authentication
++++++++++++++

Authentication is typically done through `Application Default Credentials`_,
which means you do not have to change the code to authenticate as long as
your environment has credentials. You have a few options for setting up
authentication:

{% if not no_sdk_credentials %}
#. When running locally, use the `Google Cloud SDK`_

.. code-block:: bash
gcloud beta auth application-default login
Copy link
Contributor

Choose a reason for hiding this comment

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

Think the command is out of beta

{% endif %}

#. When running on App Engine or Compute Engine, credentials are already
set-up. However, you may need to configure your Compute Engine instance
with `additional scopes <gce-auth>`_.

#. You can create a `Service Account key file`_. This file can be used to
authenticate to Google Cloud Platform services from any environment. To use
the file, set the ``GOOGLE_APPLICATION_CREDENTIALS`` environment variable to
the path to the key file, for example:

.. code-block:: bash
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service_account.json
.. _Application Default Credentials: https://cloud.google.com/docs/authentication#getting_credentials_for_server-centric_flow
.. _gce-auth: https://cloud.google.com/compute/docs/authentication#using
.. _Service Account key file: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatinganaccount
20 changes: 20 additions & 0 deletions scripts/readme-gen/templates/install_deps.tmpl.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Install Dependencies
++++++++++++++++++++

#. Install `pip`_ and `virtualenv`_ if you do not already have them.

#. Create a virtualenv. Samples are compatible with Python 2.7 and 3.4+.

.. code-block:: bash

$ virtualenv env
$ source env/bin/activate

#. Install the dependencies needed to run the samples.

.. code-block:: bash

$ pip install -r requirements.txt

.. _pip: https://pip.pypa.io/
.. _virtualenv: https://virtualenv.pypa.io/
12 changes: 0 additions & 12 deletions storage/api/README.md

This file was deleted.

Loading