Skip to content

Commit 8ee0d43

Browse files
dwighthubbardDwight Hubbard
andauthored
Use packages for style validation (#99)
* Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Update setup.py * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. * Make validate_style actually use the directories for the packages from the package metadata. Co-authored-by: Dwight Hubbard <dhubbard@verizonmedia.com>
1 parent 56e5907 commit 8ee0d43

11 files changed

Lines changed: 126 additions & 80 deletions

File tree

changelog.d/94.feature.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
True otherwise

screwdriver.yaml

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,20 @@ version: 4
55
shared:
66
environment:
77
CHANGELOG_FILENAME: docs/changelog.md
8-
DOCUMENTATION_DEBUG: False
8+
DOCUMENTATION_DEBUG: True
99
DOCUMENTATION_FORMATS: mkdocs
10-
PACKAGE_DIR: src
11-
PACKAGE_DIRECTORY: src
10+
# PACKAGE_DIR: src
11+
# PACKAGE_DIRECTORY: src
1212
steps:
13-
- presetup_deploy_keys: $BASE_PYTHON -m pip install -U .[documentation]
1413
- tag_release: $BASE_PYTHON -m screwdrivercd.repo.release
1514

1615
jobs:
1716
validate_codestyle:
1817
template: python/validate_codestyle
18+
environment:
19+
CODESTYLE_ARGS: -v
20+
steps:
21+
- postinstall_dependencies: $BASE_PYTHON -m pip install -U .
1922
requires: [~commit, ~pr]
2023

2124
validate_dependencies:
@@ -45,12 +48,6 @@ jobs:
4548
# template: python/validate_type
4649
# requires: [~commit, ~pr]
4750

48-
validate_documentation:
49-
template: python/documentation
50-
environment:
51-
DOCUMENTATION_PUBLISH: False
52-
requires: [~pr]
53-
5451
version:
5552
template: python/generate_version
5653
requires: [
@@ -79,4 +76,8 @@ jobs:
7976

8077
publish_documentation:
8178
template: python/documentation
82-
requires: [publish_pypi]
79+
steps:
80+
- postinstall_dependencies: |
81+
$BASE_PYTHON -m pip install -U .
82+
printenv | grep SD | sort
83+
requires: [~pr, ~publish_pypi]

setup.cfg

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,36 +86,29 @@ screwdrivercd.documentation.plugin =
8686

8787
[options.extras_require]
8888
documentation =
89-
dhubbard-sphinx-markdown-tables
89+
# dhubbard-sphinx-markdown-tables
9090
# markdown<3.2 # This is only needed for the mkdocs-material package to install
9191
# pymdown-extensions<6.3 # This is needed to allow markdown < 3.2 to install
9292
markdown
9393
pymdown-extensions
94-
guzzle_sphinx_theme
9594
markdown-include
9695
mkdocs-bootstrap4
9796
mkdocs-cinder
9897
mkdocs-material
99-
nbsphinx
10098
pygments
101-
10299
recommonmark
103-
sphinx_rtd_theme
104-
doc_build =
105-
dhubbard-sphinx-markdown-tables
100+
doc_build =
101+
# dhubbard-sphinx-markdown-tables
106102
# markdown<3.2 # This is only needed for the mkdocs-material package to install
107103
# pymdown-extensions<6.3 # This is needed to allow markdown < 3.2 to install
108104
markdown
109105
pymdown-extensions
110-
guzzle_sphinx_theme
111106
markdown-include
112107
mkdocs-bootstrap4
113108
mkdocs-material
114-
nbsphinx
115109
pygments
116110
recommonmark
117-
sphinx_rtd_theme
118-
test =
111+
test =
119112
pytest
120113
pytest-cov
121114
pypirun

setup.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,5 @@
55
Package setup file for python module screwdrivercd
66
"""
77
import setuptools
8-
import sys
9-
10-
11-
def setuptools_version_supported():
12-
major, minor, patch = setuptools.__version__.split('.')
13-
if int(major) > 38:
14-
return True
15-
return False
168

17-
18-
if __name__ == '__main__':
19-
# Check for a working version of setuptools here because earlier versions did not
20-
# support python_requires.
21-
if not setuptools_version_supported():
22-
print('Setuptools version 38.0.0 or higher is needed to install this package')
23-
sys.exit(1)
24-
25-
# We're being run from the command line so call setup with our arguments
26-
setuptools.setup()
9+
setuptools.setup()

src/screwdrivercd/documentation/cli.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
logging_basicConfig(check_prefix='DOCUMENTATION')
1010
import logging
1111
import os
12-
import sys
12+
13+
from termcolor import colored
1314

1415
from .exceptions import DocBuildError, DocPublishError
1516
from .plugin import build_documentation, publish_documentation
16-
from ..utility import env_bool
17+
from ..utility.environment import env_bool, is_pull_request
1718

1819

1920
logger_name = __name__
@@ -36,15 +37,24 @@ def main(): # pragma: no cover
3637
if documentation_formats:
3738
documentation_formats = [_.strip() for _ in documentation_formats.split(',')]
3839

39-
if env_bool('DOCUMENTATION_PUBLISH', True): # pragma: no cover
40+
documentation_publish_default = False if is_pull_request() else True
41+
42+
rc = 0
43+
if env_bool('DOCUMENTATION_PUBLISH', documentation_publish_default): # pragma: no cover
44+
operation = 'Published'
4045
try:
4146
publish_documentation(documentation_formats=documentation_formats)
4247
except DocPublishError:
43-
return 1
48+
rc = 1
49+
if is_pull_request():
50+
print(colored('Warning: Published documentation from a pull request', 'yellow'))
4451
else:
52+
operation = 'Generated'
4553
try:
4654
build_documentation(documentation_formats=documentation_formats)
4755
except DocBuildError:
48-
return 1
49-
update_job_status(status='SUCCESS', message=f'Generated {", ".join(documentation_formats)} documentation')
50-
return 0
56+
rc = 1
57+
if is_pull_request():
58+
status = 'SUCCESS' if rc == 0 else 'FAILURE'
59+
update_job_status(status=status, message=f'{operation} {", ".join(documentation_formats)} documentation')
60+
return rc

src/screwdrivercd/screwdriver/environment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import logging
88
import os
99
import shutil
10-
from ..utility import env_bool
10+
from ..utility.environment import env_bool, is_pull_request
1111
from .metadata import Metadata
1212

1313

src/screwdrivercd/utility/environment.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def flush_terminals():
7777
sys.stderr.flush()
7878

7979

80-
def interpreter_bin_command(command: str = 'python', fallback_path: bool=True) -> str:
80+
def interpreter_bin_command(command: str='', fallback_path: bool=True) -> str:
8181
"""
8282
Return the full path to a command in the current interpreter's bin directory.
8383
@@ -94,6 +94,8 @@ def interpreter_bin_command(command: str = 'python', fallback_path: bool=True) -
9494
Full path to the command. If the command is not present returns command if fallback_path is True or an empty
9595
string otherwise.
9696
"""
97+
if not command:
98+
command = os.path.basename(sys.executable)
9799
bin_dir = os.path.dirname(sys.executable)
98100
new_command = os.path.join(bin_dir, command)
99101
if os.path.exists(new_command):
@@ -145,14 +147,32 @@ def ins_filename(filename: str) -> str:
145147
Return the filename of an actual file or directory that case insensitively resolves to the filename given. If no
146148
matching files or directories exists, returns an empty string.
147149
"""
148-
dir = os.path.dirname(filename)
149-
contain_dir = dir
150+
contain_dir = os.path.dirname(filename)
150151
base_name = os.path.basename(filename).lower()
151152
if not contain_dir:
152153
contain_dir = '.'
153154
if not os.path.exists(contain_dir):
154155
return ''
155156
for f in os.listdir(contain_dir):
156157
if base_name == f.lower():
157-
return os.path.join(dir, f)
158+
if os.path.dirname(filename):
159+
return os.path.join(os.path.dirname(filename), f)
160+
else:
161+
return f
158162
return ''
163+
164+
165+
def is_pull_request() -> bool:
166+
"""
167+
Return True if the SD_PULL_REQUEST environment variable has a PULL Request value, False otherwise
168+
"""
169+
pr_num_str = os.environ.get('SD_PULL_REQUEST', '')
170+
if not pr_num_str:
171+
return False
172+
173+
try:
174+
pr_num = int(pr_num_str)
175+
except ValueError:
176+
return False
177+
178+
return True

src/screwdrivercd/utility/package.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,36 @@ def get_package_data(self, path=None):
174174
self.options[option_item] = True
175175
else: # pragma: no cover
176176
self.options[option_item] = False
177+
178+
179+
def package_srcdir() -> str:
180+
# Package directory is being specifically set using env variables
181+
env_package_dir = os.environ.get('PACKAGE_DIR', '')
182+
if not env_package_dir:
183+
env_package_dir = os.environ.get('PACKAGE_DIRECTORY', '')
184+
185+
if env_package_dir:
186+
return env_package_dir
187+
188+
package_metadata = PackageMetadata()
189+
package_dir = package_metadata.options.get('package_dir', '').strip().lstrip('=')
190+
191+
# Package directory specified in the package
192+
if package_dir:
193+
return package_dir
194+
195+
package_name = package_metadata.metadata['name']
196+
197+
# Fallback to looking for the package in a directory matching the package name
198+
if os.path.exists(package_name):
199+
return package_name
200+
201+
for entry in os.listdir('.'):
202+
if entry.lower() == package_name.lower():
203+
return entry
204+
205+
for entry in os.listdir('.'):
206+
if entry.lower().replace('-', '_') == package_name.lower().replace('-', '_'):
207+
return entry
208+
209+
return ''

src/screwdrivercd/validation/validate_style.py

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from ..utility import create_artifact_directory
2222
from ..utility.environment import ins_filename
2323
from ..utility.output import print_error
24-
from ..utility.package import PackageMetadata
24+
from ..utility.package import PackageMetadata, package_srcdir
2525

2626

2727
logger_name = 'validate_style' if __name__ == '__main__' else __name__
@@ -33,11 +33,7 @@ def validate_with_codestyle(report_dir):
3333

3434
package_metadata = PackageMetadata()
3535
package_name = package_metadata.metadata['name']
36-
package_dir = package_metadata.options.get('package_dir', '').strip().lstrip('=')
37-
38-
src_dir = os.environ.get('PACKAGE_DIR', package_dir)
39-
if not src_dir:
40-
src_dir = os.environ.get('PACKAGE_DIRECTORY', '')
36+
src_dir = package_srcdir()
4137

4238
parent_interpreter = interpreter_parent(sys.executable)
4339
interpreter = os.environ.get('BASE_PYTHON', parent_interpreter)
@@ -50,6 +46,8 @@ def validate_with_codestyle(report_dir):
5046
if not os.path.exists(pycodestyle_command):
5147
bin_dir = os.path.dirname(parent_interpreter)
5248
pycodestyle_command = os.path.join(bin_dir, 'pycodestyle')
49+
if not os.path.exists(pycodestyle_command):
50+
pycodestyle_command = 'pycodestyle'
5351

5452
# Generate the command line from the environment settings
5553
command = [pycodestyle_command]
@@ -59,25 +57,30 @@ def validate_with_codestyle(report_dir):
5957
if extra_args:
6058
command += extra_args.split()
6159

62-
# Add targets
63-
target = ''
64-
for package in package_metadata.packages:
65-
package_path = os.path.join(src_dir, package)
66-
if os.path.exists(package_path):
67-
target = package_path
68-
break
69-
70-
if not target:
71-
if src_dir not in ['', '.'] and src_dir != package_name:
72-
target = os.path.join(src_dir, package_name.replace('.', '/'))
73-
else:
74-
target = package_name.replace('.', '/')
75-
76-
print(f'target: {target}')
77-
target = ins_filename(target)
78-
if not target:
79-
print_error(f'ERROR: Unable to find package directory for package {package_name!r}, target directory {target!r} does not exist')
80-
return 1
60+
if src_dir and src_dir not in ['.']:
61+
target = src_dir
62+
else:
63+
# Add targets
64+
target = ''
65+
src_dir = '.'
66+
if hasattr(package_metadata, 'packages'):
67+
for package in package_metadata.packages:
68+
package_path = os.path.join(src_dir, package)
69+
if os.path.exists(package_path):
70+
target = package_path
71+
break
72+
73+
if not target:
74+
if src_dir not in ['', '.'] and src_dir != package_name:
75+
target = os.path.join(src_dir, package_name.replace('.', '/'))
76+
else:
77+
target = package_name.replace('.', '/')
78+
79+
print(f'target: {target}')
80+
target = ins_filename(target)
81+
if not target:
82+
print_error(f'ERROR: Unable to find package directory for package {package_name!r}, target directory {target!r} does not exist')
83+
return 1
8184
command.append(target)
8285

8386
print('-' * 90 + '\nRunning:', ' '.join(command) + '\n' + '-' * 90, flush=True)

src/screwdrivercd/validation/validate_type.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121

2222
from termcolor import colored
2323
from ..utility import create_artifact_directory, env_bool
24-
from ..utility.package import PackageMetadata
24+
from ..utility.package import PackageMetadata, package_srcdir
25+
2526

2627

2728
logger_name = 'validate_type' if __name__ == '__main__' else __name__

0 commit comments

Comments
 (0)