17
17
import os
18
18
from pathlib import Path
19
19
import sys
20
+ from typing import Callable , Dict , List , Optional
20
21
21
22
import nox
22
23
27
28
# WARNING - WARNING - WARNING - WARNING - WARNING
28
29
# WARNING - WARNING - WARNING - WARNING - WARNING
29
30
30
- # Copy `noxfile_config.py` to your directory and modify it instead.
31
+ BLACK_VERSION = "black==19.10b0"
31
32
33
+ # Copy `noxfile_config.py` to your directory and modify it instead.
32
34
33
35
# `TEST_CONFIG` dict is a configuration hook that allows users to
34
36
# modify the test configurations. The values here should be in sync
37
39
38
40
TEST_CONFIG = {
39
41
# You can opt out from the test for specific Python versions.
40
- "ignored_versions" : ["2.7" ],
42
+ 'ignored_versions' : ["2.7" ],
43
+
44
+ # Old samples are opted out of enforcing Python type hints
45
+ # All new samples should feature them
46
+ 'enforce_type_hints' : False ,
47
+
41
48
# An envvar key for determining the project id to use. Change it
42
49
# to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a
43
50
# build specific Cloud project. You can also use your own string
44
51
# to use your own Cloud project.
45
- " gcloud_project_env" : " GOOGLE_CLOUD_PROJECT" ,
52
+ ' gcloud_project_env' : ' GOOGLE_CLOUD_PROJECT' ,
46
53
# 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT',
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 ,
47
58
# A dictionary you want to inject into your test. Don't put any
48
59
# secrets here. These values will override predefined values.
49
- " envs" : {},
60
+ ' envs' : {},
50
61
}
51
62
52
63
53
64
try :
54
65
# Ensure we can import noxfile_config in the project's directory.
55
- sys .path .append ("." )
66
+ sys .path .append ('.' )
56
67
from noxfile_config import TEST_CONFIG_OVERRIDE
57
68
except ImportError as e :
58
69
print ("No user noxfile_config found: detail: {}" .format (e ))
62
73
TEST_CONFIG .update (TEST_CONFIG_OVERRIDE )
63
74
64
75
65
- def get_pytest_env_vars ():
76
+ def get_pytest_env_vars () -> Dict [ str , str ] :
66
77
"""Returns a dict for pytest invocation."""
67
78
ret = {}
68
79
69
80
# Override the GCLOUD_PROJECT and the alias.
70
- env_key = TEST_CONFIG [" gcloud_project_env" ]
81
+ env_key = TEST_CONFIG [' gcloud_project_env' ]
71
82
# This should error out if not set.
72
- ret [" GOOGLE_CLOUD_PROJECT" ] = os .environ [env_key ]
83
+ ret [' GOOGLE_CLOUD_PROJECT' ] = os .environ [env_key ]
73
84
74
85
# Apply user supplied envs.
75
- ret .update (TEST_CONFIG [" envs" ])
86
+ ret .update (TEST_CONFIG [' envs' ])
76
87
return ret
77
88
78
89
79
90
# DO NOT EDIT - automatically generated.
80
91
# All versions used to tested samples.
81
- ALL_VERSIONS = ["2.7" , "3.6" , "3.7" , "3.8" ]
92
+ ALL_VERSIONS = ["2.7" , "3.6" , "3.7" , "3.8" , "3.9" ]
82
93
83
94
# Any default versions that should be ignored.
84
- IGNORED_VERSIONS = TEST_CONFIG [" ignored_versions" ]
95
+ IGNORED_VERSIONS = TEST_CONFIG [' ignored_versions' ]
85
96
86
97
TESTED_VERSIONS = sorted ([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS ])
87
98
88
- 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" )
89
100
#
90
101
# Style Checks
91
102
#
92
103
93
104
94
- def _determine_local_import_names (start_dir ) :
105
+ def _determine_local_import_names (start_dir : str ) -> List [ str ] :
95
106
"""Determines all import names that should be considered "local".
96
107
97
108
This is used when running the linter to insure that import order is
@@ -129,17 +140,30 @@ def _determine_local_import_names(start_dir):
129
140
130
141
131
142
@nox .session
132
- def lint (session ):
133
- 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" )
134
148
135
149
local_names = _determine_local_import_names ("." )
136
150
args = FLAKE8_COMMON_ARGS + [
137
151
"--application-import-names" ,
138
152
"," .join (local_names ),
139
- "." ,
153
+ "."
140
154
]
141
155
session .run ("flake8" , * args )
156
+ #
157
+ # Black
158
+ #
159
+
142
160
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 )
143
167
144
168
#
145
169
# Sample Tests
@@ -149,13 +173,22 @@ def lint(session):
149
173
PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml" ]
150
174
151
175
152
- 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 } " )
153
180
"""Runs py.test for a particular project."""
154
181
if os .path .exists ("requirements.txt" ):
155
- 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" )
156
186
157
187
if os .path .exists ("requirements-test.txt" ):
158
- 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" )
159
192
160
193
if INSTALL_LIBRARY_FROM_SOURCE :
161
194
session .install ("-e" , _get_repo_root ())
@@ -175,22 +208,22 @@ def _session_tests(session, post_install=None):
175
208
176
209
177
210
@nox .session (python = ALL_VERSIONS )
178
- def py (session ) :
211
+ def py (session : nox . sessions . Session ) -> None :
179
212
"""Runs py.test for a sample using the specified version of Python."""
180
213
if session .python in TESTED_VERSIONS :
181
214
_session_tests (session )
182
215
else :
183
- session .skip (
184
- "SKIPPED: {} tests are disabled for this sample." . format ( session .python )
185
- )
216
+ session .skip ("SKIPPED: {} tests are disabled for this sample." . format (
217
+ session .python
218
+ ))
186
219
187
220
188
221
#
189
222
# Readmegen
190
223
#
191
224
192
225
193
- def _get_repo_root ():
226
+ def _get_repo_root () -> Optional [ str ] :
194
227
""" Returns the root folder of the project. """
195
228
# Get root of this repository. Assume we don't have directories nested deeper than 10 items.
196
229
p = Path (os .getcwd ())
@@ -199,6 +232,11 @@ def _get_repo_root():
199
232
break
200
233
if Path (p / ".git" ).exists ():
201
234
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 )
202
240
p = p .parent
203
241
raise Exception ("Unable to detect repository root." )
204
242
@@ -208,7 +246,7 @@ def _get_repo_root():
208
246
209
247
@nox .session
210
248
@nox .parametrize ("path" , GENERATED_READMES )
211
- def readmegen (session , path ) :
249
+ def readmegen (session : nox . sessions . Session , path : str ) -> None :
212
250
"""(Re-)generates the readme for a sample."""
213
251
session .install ("jinja2" , "pyyaml" )
214
252
dir_ = os .path .dirname (path )
0 commit comments