Skip to content

Gradle builder for Java #69

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 23 commits into from
Feb 14, 2019
Merged

Gradle builder for Java #69

merged 23 commits into from
Feb 14, 2019

Conversation

dagnir
Copy link
Contributor

@dagnir dagnir commented Jan 9, 2019

Issue #, if available:

Description of changes:
This adds the design document to enable sam build for Gradle based Java projects.

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

compiled classes, resouces, and dependencies into a ZIP.
### Source directory, and artifact directory semantics

To enable the multi build projects where a Gradle project can contain multiple

Choose a reason for hiding this comment

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

I know we did not want to discuss this in relation to sam, but I feel we need to in this case to understand what the UX is for users of sam build.

@jfuss Will this be exposed through sam build that users will need to understand and set? Or will sam build hide this?

Copy link
Contributor

Choose a reason for hiding this comment

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

This will be hidden. Using SAM CLI as an example:

A customer needing this could:
sam build -m ./build.gradle

SAM CLI will then conform to the details here. So we will provide the correct source_dir and artifact_dir. For the use-container, we will need to mount all of ProjectB (only way this will work, I think).

SAM CLI will only do this operation if -m is provided and the runtime is Java. Otherwise, SAM CLI will assume the Project A is what is desired (aka building the individual functions only).

If this map is present, then `source_dir` is treated as the root directory of
the parent project. Additionally, `artifact_dir` will not be the path under
which the artifact will be copied to, but just the parent of the final
directory. `artifact_mapping` will be a mapping from a source subdirectory under

Choose a reason for hiding this comment

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

If the artifact_mapping is provided, should we optimize the build by doing

for each mapping in artifact_mapping:
    cmd =+ " $mapping.folderName:build"

$GRADLE_EXECUTABLE --init-script /$SCRATCH_DIR/lambda-build-init.gradle $cmd

This does lead to issues where people make the sub-project name not match the folder (why people would I do not know...)
In that case we may have to make init script manipulare the task graph based on the project root of each sub-project. It's possible, just question around "should we"

Copy link
Contributor

Choose a reason for hiding this comment

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

We can always optimize later if this is really needed.

jfuss
jfuss previously requested changes Jan 29, 2019
 - Use resolvers for finding Gradle executable
 - Extract copy artifacts into separate action
 - Add tests for mapping
Gradle can be configured to explicitly run with a specific JVM which may
not be the one found on the PATH. Getting the JVM version from Gradle
(i.e. the JVM version that Gradle is running in) helps us be more
accurate with the warning.
- Use archives artifacts to find project class files
- Add extra tests for projects with resources and test dependencies
- Builder only needs to be concerned with building `source_dir` so
remove `artifact_mapping` semantics
- Ensure buildDir is on scratch_dir
- Ensure project-cache-dir in scratch_dir
@sriram-mv
Copy link
Contributor

There is a PR out for searching additional paths when looking for executables that are to be used by the workflow. this will help for locating gradlew at different paths. #77 . #69 needs to integrate that.

@dagnir
Copy link
Contributor Author

dagnir commented Feb 11, 2019

@thesriram Looks like it's #78? Is it mostly ready to go? Or should I wait for it to be merged?

Copy link
Contributor

@sanathkr sanathkr left a comment

Choose a reason for hiding this comment

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

This is a really cool work! Thanks for the detailed design document. Makes it really easy to understand the code. Most of my comments are general cleanup, stylistic and questions. Feel free to push back if it doesn't make sense.

from aws_lambda_builders.exceptions import WorkflowFailedError


class TestJavaGradle(TestCase):
Copy link
Contributor

Choose a reason for hiding this comment

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

Love the extensive coverage of integration tests! Thanks a lot for taking the time. Really helps pushing the boundary for code quality

Copy link
Contributor

@sanathkr sanathkr left a comment

Choose a reason for hiding this comment

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

The general logic makes sense, but I want to find a way to achieve same result without the dummy values and exception message parsing. If needed, we can change PathResolver design to make this implementaiton simper

 - Fix gradlew path resolution to not rely on PathResolver
 - Write class files and libraries directly to artifact_dir root instead of creating a ZIP
 - Raise exceptin if manifest file not found
Copy link
Contributor

@sanathkr sanathkr left a comment

Choose a reason for hiding this comment

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

Appreciate cleaning this up. There is one thing that won't work in Py2. Can you fix it?

@@ -72,7 +76,13 @@ def execute(self):
def _copy_artifacts(self):
lambda_build_output = os.path.join(self.build_dir, 'build', 'distributions', 'lambda-build')
try:
for f in self.os_utils.listdir(lambda_build_output):
self.os_utils.copy(os.path.join(lambda_build_output, f), self.artifacts_dir)
self.os_utils.makedirs(self.artifacts_dir)
Copy link
Contributor

Choose a reason for hiding this comment

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

os.scandir is not available in Python 2.7. Can you use this osutils helper instead?

https://github.com/awslabs/aws-lambda-builders/blob/develop/aws_lambda_builders/workflows/python_pip/utils.py#L56-L66

Copy/paste it in your code for now.

@sanathkr sanathkr changed the title Add design for Gradle builder for Java Gradle builder for Java Feb 14, 2019
Copy link
Contributor

@sanathkr sanathkr left a comment

Choose a reason for hiding this comment

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

You made it! 💥Thanks a lot for diving deep to get the design right and all the revisions to improve implementation.

Copy link
Contributor

@sriram-mv sriram-mv left a comment

Choose a reason for hiding this comment

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

💃

self.assert_artifact_contains_files(expected_files)
self.assert_artifact_not_contains_file(p('lib', 's3-2.1.0.jar'))

def test_build_single_build_with_deps_gradlew(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice! executable search paths :)

@sanathkr sanathkr dismissed jfuss’s stale review February 14, 2019 20:16

2 approvals from sriram & sanath

@sanathkr sanathkr merged commit 8415ccd into aws:develop Feb 14, 2019
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.

5 participants