-
Notifications
You must be signed in to change notification settings - Fork 140
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
Add Include resource functionality to npm and npm/esbuild #431
Conversation
Thanks for opening this pull request! We will look at your feature request and see if your changes can be accepted! |
I'll take a look and see what is causing unit tests to fail in Windows |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking the time to raise this PR! I've left a few comments but overall it looks good. I do wonder if this should be applied to other runtimes since it seems it's applicable to more than just Node.js (maybe compiled languages).
Would you also be able to raise the corresponding SAM-CLI PR for sending this parameter down?
aws_lambda_builders/utils.py
Outdated
known_paths = [] | ||
for item in items: | ||
if Path(item).is_absolute(): | ||
raise ValueError('"{item}" is not a relative path'.format(item=item)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use custom exceptions instead of raising ValueError
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any specific one you want me to use, or should I roll one? Would something like this work?
class FileOperationError(LambdaBuilderError):
"""
Raised when a file operation fails
"""
MESSAGE = "{operation_name} - {reason}"
aws_lambda_builders/utils.py
Outdated
def get_option_from_args(args: Union[None, Dict[str, any]], option_name: str) -> any: | ||
if args is not None: | ||
if "options" in args: | ||
if args["options"] is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do
if args.get("options") is not None:
instead so that if options isn't there, it doesn't raise a key error. And the same thing for wherever else we do dictionary accesses like this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Roger that. Is this the correct way - should I be doing something more "pythonic"?
def get_option_from_args(args: Union[None, Dict[str, any]], option_name: str) -> any:
if args is not None:
options = args.get("options", None)
if options is not None:
return options.get(option_name, None)
return None
Assuming we can get this shepherded through, sure! |
I've updated the following:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing to consider, and I'll take ownership of this, is that this will require a documentation update to publicize this new option.
aws_lambda_builders/exceptions.py
Outdated
Raised when a file operation fails | ||
""" | ||
|
||
MESSAGE = "{operation_name} - {reason}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to run make black
to reformat according to our style guide.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, missed that
aws_lambda_builders/utils.py
Outdated
@@ -222,3 +225,53 @@ def extract_tarfile(tarfile_path: Union[str, os.PathLike], unpack_dir: Union[str | |||
raise tarfile.ExtractError("Attempted Path Traversal in Tar File") | |||
|
|||
tar.extractall(unpack_dir) | |||
|
|||
|
|||
def glob_copy(source: Union[str, list], destination: str) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add type hints and docstrings to all functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure thing
aws_lambda_builders/utils.py
Outdated
dest_path = Path(destination) | ||
known_paths = [] | ||
for item in items: | ||
if os.path.isabs(item.replace('\\', '/')): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the item.replace()
? I think os.path.isabs()
should already handle this, I could be wrong though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to have the replace in there to get the "absolute" detection to work properly under Windows. "\foo" is considered a relative path, but "/foo" is absolute (go figure). The purposes of this call is to make sure that the requested asset 's path is relative to the project, so either "\foo" or "/foo" should be treated as non-relative.
if isinstance(include, (list, str)): | ||
self.actions.append(CopyResourceAction(source_dir, include, artifacts_dir)) | ||
elif include is not None: | ||
raise ValueError("Resource include items must be strings or lists of strings") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use a custom exception here too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes sir
aws_lambda_builders/utils.py
Outdated
shutil.copyfile(file, save_to) | ||
|
||
|
||
def robust_rmtree(path, timeout=1): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is only used in tests, we should move it there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to test/functional/test_utils.py
If I take a stab at working on this stuff over the weekend, can you enable me to have Build & Test checks run. I promise not to submit 100 times. |
Already enabled 👍 |
Hi, latest changes committed - With regard to documentation, happy to submit it if you tell me where it should go and in what format. Here's some Markdown I've put together as a first pass.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a general comment on this PR, I feel that this action is not related to a specific Runtime, and instead it can be part of sam build
command or may be sam package
but not part of aws-lambda-builders
library. I will raise this PR with the team to discuss what is the better approach to implement this feature.
I will make this PR as draft till we discuss it, and will update it later.
I don't disagree that, ideally, this would be a Runtime-independent feature. However, even within NodeJS, there are differences in when you implement it, based upon whether esbuild is being used or not. You could go the route of creating some kind of event-driven mechanism so that the individual Runtime workflows can take actions (before build, after build, copy resources after build, etc.), but that isn't there today. Anyways, it's months later and I had to end up going a different route (orchestrating esbuild external to SAM). If you want to nuke this PR, that's fine, we have a workaround, although it would have been nicer to use the integrated esbuild workflow. |
Closing until we figure out the correct path forward. Consolidating include/exclude functionality design and discussion into a single issue #516. |
Issue #: 430
Description of changes:
Include
property that can be set to a file mask, or list of file masks, of files in the source directory, and copy those to the artifact (output) directory after build/packagingCopyResourceAction
and utilitiesglob_copy
andget_option_from_args
have been added to support the functionalityNote: esbuild will work with the SAM CLI as-is, but for npm (without esbuild), SAM CLI will need to be updated to support sending include (currently, it will only send use_npm_ci and no other Metadata options).
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.