Skip to content

Commit

Permalink
fix Pyinstaller yamllint test (#344)
Browse files Browse the repository at this point in the history
* change yml_lint test to use runpy

* remove print used in testing

* add yamllint and cfnlint as hidden dependencies

found that cfnlint was also failing for the Pyinstaller build so fixed it as well

* update changelog
  • Loading branch information
ITProKyle authored May 27, 2020
1 parent 8a744f3 commit 7c3fd03
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 64 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- a@e check_auth will now try to refresh tokens 5 minutes before expiration instead of waiting for it to expire
- `runway test` will now return a non-zero exit code if any non-required tests failed
- `static-react` sample uses npm instead of yarn
- `yamllint` is now invoked using `runpy` instead of using `runway run-python`

### Fixed
- issue where `yamllint` and `cfnlint` could not be imported/executed from the Pyinstaller executables

## [1.8.0] - 2020-05-16
### Fixed
Expand Down
9 changes: 7 additions & 2 deletions runway.file.spec
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,13 @@ data_files = [
]
data_files.append(('{}/yamllint/conf'.format(get_distribution('yamllint').location),
'yamllint/conf/'))
data_files.append(('{}/cfnlint/data'.format(get_distribution('cfn-lint').location),
'cfnlint/data/'))
data_files.append(('{}/cfnlint/rules'.format(get_distribution('cfn-lint').location),
'cfnlint/rules/'))
data_files.append(('{}/botocore/data'.format(get_distribution('botocore').location),
'botocore/data/'))
data_files.append(('{}/awscli/data'.format(get_distribution('awscli').location),
'awscli/data/'))
data_files.extend(collect_data_files('cfnlint'))
data_files.extend(collect_data_files('distutils'))
data_files.extend(collect_data_files('pip'))
data_files.extend(collect_data_files('wheel'))
Expand All @@ -90,6 +91,8 @@ import awscli # noqa
import botocore # noqa
import pip # noqa
import wheel # noqa
import yamllint # noqa
import cfnlint # noqa
hiddenimports.extend(get_submodules(runway))
hiddenimports.extend(get_submodules(troposphere))
hiddenimports.extend(get_submodules(awacs))
Expand All @@ -98,6 +101,8 @@ hiddenimports.extend(get_submodules(botocore))
hiddenimports.extend(get_submodules(pip))
hiddenimports.extend(get_submodules(wheel))
hiddenimports.extend(get_submodules(distutils))
hiddenimports.extend(get_submodules(yamllint))
hiddenimports.extend(get_submodules(cfnlint))
# needed due to pkg_resources dropping python2 support
# can be removed on the next pyinstaller release
# https://github.com/pypa/setuptools/issues/1963#issuecomment-582084099
Expand Down
16 changes: 10 additions & 6 deletions runway.folder.spec
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,19 @@ def Entrypoint(dist, group, name, **kwargs): # noqa
# files that are not explicitly imported but consumed at runtime
# need to be included as data_files.
data_files = [
(os.path.join(CLI_PATH, 'templates'), './runway/templates/'),
(os.path.join(CLI_PATH, 'blueprints'), './runway/blueprints/'),
(os.path.join(CLI_PATH, 'hooks'), './runway/hooks/')
(os.path.join(CLI_PATH, 'templates'), './runway/templates'),
(os.path.join(CLI_PATH, 'blueprints'), './runway/blueprints'),
(os.path.join(CLI_PATH, 'hooks'), './runway/hooks')
]

data_files.append(('{}/yamllint/conf'.format(get_distribution('yamllint').location),
'yamllint/conf/'))
data_files.append(('{}/cfnlint/data'.format(get_distribution('cfn-lint').location),
'cfnlint/data/'))
data_files.append(('{}/cfnlint/rules'.format(get_distribution('cfn-lint').location),
'cfnlint/rules/'))
data_files.append(('{}/botocore/data'.format(get_distribution('botocore').location),
'botocore/data/'))
data_files.append(('{}/awscli/data'.format(get_distribution('awscli').location),
'awscli/data/'))
data_files.extend(collect_data_files('cfnlint'))
data_files.extend(collect_data_files('distutils'))
data_files.extend(collect_data_files('pip'))
data_files.extend(collect_data_files('wheel'))
Expand All @@ -91,6 +91,8 @@ import awscli # noqa
import botocore # noqa
import pip # noqa
import wheel # noqa
import yamllint # noqa
import cfnlint # noqa
hiddenimports.extend(get_submodules(runway))
hiddenimports.extend(get_submodules(troposphere))
hiddenimports.extend(get_submodules(awacs))
Expand All @@ -99,6 +101,8 @@ hiddenimports.extend(get_submodules(botocore))
hiddenimports.extend(get_submodules(pip))
hiddenimports.extend(get_submodules(wheel))
hiddenimports.extend(get_submodules(distutils))
hiddenimports.extend(get_submodules(yamllint))
hiddenimports.extend(get_submodules(cfnlint))
# needed due to pkg_resources dropping python2 support
# can be removed on the next pyinstaller release
# https://github.com/pypa/setuptools/issues/1963#issuecomment-582084099
Expand Down
66 changes: 10 additions & 56 deletions runway/tests/handlers/yaml_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
import glob
import logging
import os
import sys
import tempfile
from typing import Dict, Any, List # pylint: disable=unused-import
import runpy
from typing import Any, Dict, List # pylint: disable=unused-import

from runway.tests.handlers.base import TestHandler
from runway.tests.handlers.script import ScriptHandler
from runway.util import change_dir
from runway.util import argv

TYPE_NAME = 'yamllint'
LOGGER = logging.getLogger('runway')
Expand All @@ -31,23 +29,13 @@ def get_yaml_files_at_path(provided_path):
return yaml_files + yml_files

@classmethod
def get_yamllint_options(cls, path, quote_paths=True):
# type: (str, bool) -> List[str]
def get_yamllint_options(cls, path):
# type: (str) -> List[str]
"""Return yamllint option list."""
dirs_to_scan = cls.get_dirs(path)
files_at_base = cls.get_yaml_files_at_path(path)
yamllint_options = []

if dirs_to_scan:
yamllint_options.extend(
["\"%s\"" % x if quote_paths else x for x in dirs_to_scan]
)
if files_at_base:
yamllint_options.extend(
["\"%s\"" % x if quote_paths else x for x in files_at_base]
)

return yamllint_options
return yamllint_options + cls.get_dirs(path) + \
cls.get_yaml_files_at_path(path)

@classmethod
def handle(cls, name, args):
Expand All @@ -69,41 +57,7 @@ def handle(cls, name, args):
)

yamllint_options = ["--config-file=%s" % yamllint_config]
yamllint_options.extend(cls.get_yamllint_options(base_dir,
not getattr(sys, 'frozen', False)))

if getattr(sys, 'frozen', False):
# running in pyinstaller single-exe, so sys.executable will
# be the all-in-one Runway binary
yamllint_options.extend(cls.get_yamllint_options(base_dir))

# This would be a little more natural if yamllint was imported
# directly, but that has unclear license implications so instead
# we'll generate the setuptools invocation script here and shell
# out to it
yamllint_invocation_script = (
"import sys;"
"from yamllint.cli import run;"
"sys.argv = [%s];"
"sys.exit(run());" % ','.join(
"'%s'" % i for i in ['yamllint'] + yamllint_options
)
)

temp_fd, temp_path = tempfile.mkstemp(prefix='yamllint')
os.close(temp_fd)
with open(temp_path, 'w') as fileobj:
fileobj.write(yamllint_invocation_script)

yl_cmd = sys.executable + ' run-python ' + temp_path
else:
# traditional python execution
yl_cmd = "yamllint " + ' '.join(yamllint_options)
with change_dir(base_dir):
try:
ScriptHandler().handle(
'yamllint',
{'commands': [yl_cmd]}
)
finally:
if getattr(sys, 'frozen', False):
os.remove(temp_path)
with argv(*['yamllint'] + yamllint_options):
runpy.run_module('yamllint', run_name='__main__')

0 comments on commit 7c3fd03

Please sign in to comment.