Skip to content

feat: Path Resolver and Validator #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jan 14, 2019

Conversation

sriram-mv
Copy link
Contributor

@sriram-mv sriram-mv commented Dec 18, 2018

  • BaseWorkflow provides super simple resolver and a validator.
  • Each Workflow can bring its own path resolver and validator.
  • Each Workflow also can list the binaries to be used in the actions.
  • workflow's run method is decorated to check for validaton of the
    language executable path.

The function "which" at was copied from https://github.com/python/cpython/blob/3.7/Lib/shutil.py
SPDX-License-Identifier: Python-2.0
Copyright 2019 by the Python Software Foundation

Issue #, if available:

Description of changes:

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@sriram-mv
Copy link
Contributor Author

Will refactor and add unit tests, and bring in language specific path resolvers and validators in the next few commits.

@sriram-mv
Copy link
Contributor Author

Ruby resolver works 👍

$nosetests -vs test_ruby.py
test_builds_project_with_dependencies (test_ruby.TestRubyWorkflow) ... ok
test_builds_project_without_dependencies (test_ruby.TestRubyWorkflow) ... ok
test_fails_if_bundler_cannot_resolve_dependencies (test_ruby.TestRubyWorkflow) ... ok

----------------------------------------------------------------------
Ran 3 tests in 12.219s

OK

@sriram-mv
Copy link
Contributor Author

Need to add more unit tests and figure out the failing gates, I have it passing on 3.6 locally.

cmd = [
python_exe,
"-c",
"import pip; assert pip.__version__.split('.')[0] == 9"
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be <= 9? Otherwise we try to do from pip._internal import main for any pip version that isn't 9, which I don't think the intention is correct.

9 should be a string here as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a great catch, thanks! yes will update it.

- BaseWorkflow provides super simple resolver and a No-op validator
- Each Workflow can bring its own path resolver and validator.
- workflow's run method is decorated to check for validaton of the
  language executable path.
@sriram-mv sriram-mv force-pushed the path_resolver_validator branch from 01f3564 to a5a2865 Compare December 20, 2018 19:42
Copy link
Contributor

@jfuss jfuss left a comment

Choose a reason for hiding this comment

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

This PR updates Python and Ruby. Are we not updating Node as well?

"""

@functools.wraps(func)
def wrapper(*args, **kwargs):
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we pass in self here and make that an explicit argument instead of getting the first value out of args?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure we can do that.

"""
Non specialized path resolver that just returns the first executable for the runtime on the path.
"""
return PathResolver(runtime=self.runtime).path
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we make the attribute path more explicit? Something like exec_path?

Should we force get_executable into a strong contract by returning an object that has specific required methods or attributes, instead of just a string?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

what are other attributes did you have in mind?

Copy link
Contributor

Choose a reason for hiding this comment

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

I didn't have any directly in mind but everywhere this method is doing some PathResolver().path. Instead, we can make get_executable() return the PathResolver and then when needed, we call the attribute or methods we need. This is what we are doing for the validation.

self.dependency_builder = DependencyBuilder(osutils=OSUtils(), pip_runner=self.pip_runner,
runtime=runtime)

self.package_builder = PythonPipDependencyBuilder(osutils=OSUtils(),
Copy link
Contributor

Choose a reason for hiding this comment

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

OSUtils() is created 3 times here? Do we need new instances in each (self.pip, self.pip_runner, and self.package_builder).

Have you thought about whether SubprocessPip, PipRunner should be passed into the action here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this place is a mess right now and needs clean up. but yes we need the pips to be intialized with the runtime_path, because we want the appropriate pip belonging to the chosen runtime.

:param string runtime: Runtime to check
:return bool: True, if the runtime is supported.
"""
return self.runtime in self.SUPPORTED_RUNTIMES
Copy link
Contributor

Choose a reason for hiding this comment

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



class RubyRuntimeValidator(object):
SUPPORTED_RUNTIMES = [
Copy link
Contributor

Choose a reason for hiding this comment

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

set?

@sriram-mv
Copy link
Contributor Author

Yep node support coming too. trying to sort out some test issues on python_pip workflow.

@sriram-mv sriram-mv force-pushed the path_resolver_validator branch from 52080e9 to 813e3f9 Compare January 3, 2019 00:54
- Every workflow has a list of validators, resolvers and binaries
- Actions can choose to use it or not.
@sriram-mv sriram-mv force-pushed the path_resolver_validator branch from 7a174b8 to a8cac3c Compare January 9, 2019 06:42
@sriram-mv
Copy link
Contributor Author

Weird that appveyor is going through the python versions, and not finding the one that is in the Path.

.pylintrc Outdated
@@ -9,7 +9,7 @@

# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=compat.py
ignore=compat.py, utils.py, path_resolver.py, validator.py
Copy link
Contributor

Choose a reason for hiding this comment

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

curious, why are these added?

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 had to keep utils.py because of the copying of the which command, the other two can go away.

.appveyor.yml Outdated
@@ -16,7 +16,8 @@ install:
# To run Nodejs workflow integ tests
- ps: Install-Product node 8.10

- "set PATH=%PYTHON%\\Scripts;%PYTHON%\\bin;%PATH%"
- "set PATH=%PYTHON%;%PYTHON%\\Scripts;%PYTHON%\\bin;%PATH%"
- "echo %PATH%"
Copy link
Contributor

Choose a reason for hiding this comment

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

When you rebase: I would move this echo down the script so we see everything in the PATH.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sounds good.

Makefile Outdated
@@ -3,8 +3,8 @@ init:

test:
# Run unit tests
# Fail if coverage falls below 94%
LAMBDA_BUILDERS_DEV=1 pytest --cov aws_lambda_builders --cov-report term-missing --cov-fail-under 94 tests/unit tests/functional
# Fail if coverage falls below 93%
Copy link
Contributor

Choose a reason for hiding this comment

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

Lowering the bar!? Any particular reason?

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 was hovering at 93.76% and didnt have test coverage at that point. and I wanted to see the tick haha, this will go back up.

self.resolver = resolver
self.validator = validator
self.binary = binary
setattr(self, binary, binary)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is equivalent to the line above right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No.

In [1]: class A(object):
   ...:     def __init__(self, a):
   ...:         self.a = a
   ...:         setattr(self, a , a)
   ...:

In [2]: A(a="python")
Out[2]: <__main__.A at 0x109ebcd68>

In [3]: obj = A(a="python")

In [4]: obj.a
Out[4]: 'python'

In [5]: obj.python
Out[5]: 'python'

binary_path.binary_path = valid_path
valid_paths.append(valid_path)
break
if not valid_paths:
Copy link
Contributor

Choose a reason for hiding this comment

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

if len(self.binaries()) is 2 but only 1 is a valid path, we will still execute the workflow, which will fail.

"""
specialized path resolver that just returns the list of executable for the runtime on the path.
"""
return [PathResolver(runtime=self.runtime, binary="node")]
Copy link
Contributor

Choose a reason for hiding this comment

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

Thought node needed npm?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

by default, we look for the language in the workflow.. the workflow's language is filled as nodejs, but the executable is called node.


def execute(self):
os_utils = OSUtils()
python_path = [binary.binary_path for binary in self.binaries if getattr(binary, self.LANGUAGE)][0]
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure I understand this line of code. Could you explain this? My brain can't grasp this right now

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes.
if binary_path.python is set, we get the associated binary_path, this is why I do setattr(self, binary, binary) above in the class.

so that binary_path.python is set.

CopySourceAction(source_dir, artifacts_dir, excludes=self.EXCLUDED_FILES),
]

# def get_resolvers(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

can be removed.

def get_validators(self):
return [PythonRuntimeValidator(runtime=self.runtime)]

# def get_binaries(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can be removed.

LOG = logging.getLogger(__name__)


class RubyRuntimeValidator(object):
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the purpose of this Validator? The ruby workflow uses bundler not ruby. Shouldn't we be validating the binaries the workflow uses?

Copy link
Contributor Author

@sriram-mv sriram-mv Jan 9, 2019

Choose a reason for hiding this comment

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

Yeah agreed on this, we need a best attempt bundler validator instead. What I propose is to remove the ruby validator, and add a bundler validator.

The function "which" at <file> was copied from
https://github.com/python/cpython/blob/3.7/Lib/shutil.py
SPDX-License-Identifier: Python-2.0
Copyright 2019 by the Python Software Foundation
@sriram-mv sriram-mv changed the title WIP feat: Path Resolver and Validator feat: Path Resolver and Validator Jan 10, 2019
@sriram-mv sriram-mv mentioned this pull request Jan 10, 2019
@jfuss jfuss merged commit f53dc86 into aws:develop Jan 14, 2019
volkangurel added a commit to volkangurel/aws-lambda-builders that referenced this pull request Jan 18, 2019
Update the go models path resolvers and validators to the latest framework
merged in aws#55
volkangurel added a commit to volkangurel/aws-lambda-builders that referenced this pull request Jan 18, 2019
Update the go models path resolvers and validators to the latest framework
merged in aws#55
volkangurel added a commit to volkangurel/aws-lambda-builders that referenced this pull request Jan 18, 2019
Update the go models path resolvers and validators to the latest framework
merged in aws#55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants