1717import os
1818from pathlib import Path
1919import sys
20+ from typing import Callable , Dict , List , Optional
2021
2122import nox
2223
2728# WARNING - WARNING - WARNING - WARNING - WARNING
2829# WARNING - WARNING - WARNING - WARNING - WARNING
2930
30- # Copy `noxfile_config.py` to your directory and modify it instead.
31+ BLACK_VERSION = "black==19.10b0"
3132
33+ # Copy `noxfile_config.py` to your directory and modify it instead.
3234
3335# `TEST_CONFIG` dict is a configuration hook that allows users to
3436# modify the test configurations. The values here should be in sync
3739
3840TEST_CONFIG = {
3941 # You can opt out from the test for specific Python versions.
40- 'ignored_versions' : ["2.7" ],
42+ 'ignored_versions' : [],
43+
44+ # Old samples are opted out of enforcing Python type hints
45+ # All new samples should feature them
46+ 'enforce_type_hints' : False ,
4147
4248 # An envvar key for determining the project id to use. Change it
4349 # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a
4450 # build specific Cloud project. You can also use your own string
4551 # to use your own Cloud project.
4652 'gcloud_project_env' : 'GOOGLE_CLOUD_PROJECT' ,
4753 # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT',
48-
54+ # If you need to use a specific version of pip,
55+ # change pip_version_override to the string representation
56+ # of the version number, for example, "20.2.4"
57+ "pip_version_override" : None ,
4958 # A dictionary you want to inject into your test. Don't put any
5059 # secrets here. These values will override predefined values.
5160 'envs' : {},
6473TEST_CONFIG .update (TEST_CONFIG_OVERRIDE )
6574
6675
67- def get_pytest_env_vars ():
76+ def get_pytest_env_vars () -> Dict [ str , str ] :
6877 """Returns a dict for pytest invocation."""
6978 ret = {}
7079
@@ -79,21 +88,21 @@ def get_pytest_env_vars():
7988
8089
8190# DO NOT EDIT - automatically generated.
82- # All versions used to tested samples.
83- ALL_VERSIONS = ["2.7 " , "3.6 " , "3.7 " , "3.8 " ]
91+ # All versions used to test samples.
92+ ALL_VERSIONS = ["3.6 " , "3.7 " , "3.8 " , "3.9 " ]
8493
8594# Any default versions that should be ignored.
8695IGNORED_VERSIONS = TEST_CONFIG ['ignored_versions' ]
8796
8897TESTED_VERSIONS = sorted ([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS ])
8998
90- INSTALL_LIBRARY_FROM_SOURCE = bool ( os .environ .get ("INSTALL_LIBRARY_FROM_SOURCE" , False ))
99+ INSTALL_LIBRARY_FROM_SOURCE = os .environ .get ("INSTALL_LIBRARY_FROM_SOURCE" , False ) in ( "True" , "true" )
91100#
92101# Style Checks
93102#
94103
95104
96- def _determine_local_import_names (start_dir ) :
105+ def _determine_local_import_names (start_dir : str ) -> List [ str ] :
97106 """Determines all import names that should be considered "local".
98107
99108 This is used when running the linter to insure that import order is
@@ -131,8 +140,11 @@ def _determine_local_import_names(start_dir):
131140
132141
133142@nox .session
134- def lint (session ):
135- session .install ("flake8" , "flake8-import-order" )
143+ def lint (session : nox .sessions .Session ) -> None :
144+ if not TEST_CONFIG ['enforce_type_hints' ]:
145+ session .install ("flake8" , "flake8-import-order" )
146+ else :
147+ session .install ("flake8" , "flake8-import-order" , "flake8-annotations" )
136148
137149 local_names = _determine_local_import_names ("." )
138150 args = FLAKE8_COMMON_ARGS + [
@@ -141,7 +153,17 @@ def lint(session):
141153 "."
142154 ]
143155 session .run ("flake8" , * args )
156+ #
157+ # Black
158+ #
159+
144160
161+ @nox .session
162+ def blacken (session : nox .sessions .Session ) -> None :
163+ session .install (BLACK_VERSION )
164+ python_files = [path for path in os .listdir ("." ) if path .endswith (".py" )]
165+
166+ session .run ("black" , * python_files )
145167
146168#
147169# Sample Tests
@@ -151,13 +173,22 @@ def lint(session):
151173PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml" ]
152174
153175
154- def _session_tests (session , post_install = None ):
176+ def _session_tests (session : nox .sessions .Session , post_install : Callable = None ) -> None :
177+ if TEST_CONFIG ["pip_version_override" ]:
178+ pip_version = TEST_CONFIG ["pip_version_override" ]
179+ session .install (f"pip=={ pip_version } " )
155180 """Runs py.test for a particular project."""
156181 if os .path .exists ("requirements.txt" ):
157- session .install ("-r" , "requirements.txt" )
182+ if os .path .exists ("constraints.txt" ):
183+ session .install ("-r" , "requirements.txt" , "-c" , "constraints.txt" )
184+ else :
185+ session .install ("-r" , "requirements.txt" )
158186
159187 if os .path .exists ("requirements-test.txt" ):
160- session .install ("-r" , "requirements-test.txt" )
188+ if os .path .exists ("constraints-test.txt" ):
189+ session .install ("-r" , "requirements-test.txt" , "-c" , "constraints-test.txt" )
190+ else :
191+ session .install ("-r" , "requirements-test.txt" )
161192
162193 if INSTALL_LIBRARY_FROM_SOURCE :
163194 session .install ("-e" , _get_repo_root ())
@@ -177,7 +208,7 @@ def _session_tests(session, post_install=None):
177208
178209
179210@nox .session (python = ALL_VERSIONS )
180- def py (session ) :
211+ def py (session : nox . sessions . Session ) -> None :
181212 """Runs py.test for a sample using the specified version of Python."""
182213 if session .python in TESTED_VERSIONS :
183214 _session_tests (session )
@@ -192,7 +223,7 @@ def py(session):
192223#
193224
194225
195- def _get_repo_root ():
226+ def _get_repo_root () -> Optional [ str ] :
196227 """ Returns the root folder of the project. """
197228 # Get root of this repository. Assume we don't have directories nested deeper than 10 items.
198229 p = Path (os .getcwd ())
@@ -201,6 +232,11 @@ def _get_repo_root():
201232 break
202233 if Path (p / ".git" ).exists ():
203234 return str (p )
235+ # .git is not available in repos cloned via Cloud Build
236+ # setup.py is always in the library's root, so use that instead
237+ # https://github.com/googleapis/synthtool/issues/792
238+ if Path (p / "setup.py" ).exists ():
239+ return str (p )
204240 p = p .parent
205241 raise Exception ("Unable to detect repository root." )
206242
@@ -210,7 +246,7 @@ def _get_repo_root():
210246
211247@nox .session
212248@nox .parametrize ("path" , GENERATED_READMES )
213- def readmegen (session , path ) :
249+ def readmegen (session : nox . sessions . Session , path : str ) -> None :
214250 """(Re-)generates the readme for a sample."""
215251 session .install ("jinja2" , "pyyaml" )
216252 dir_ = os .path .dirname (path )
0 commit comments