Skip to content
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

Support Gradle multi-project builds #583

Merged
merged 11 commits into from
Jan 5, 2023
Merged

Conversation

LouisBoudreau
Copy link
Contributor

@LouisBoudreau LouisBoudreau commented Dec 2, 2022

Description

The goal of this PR is to add support for Gradle multi project builds. To do so I implemented the suggestion provided in this issue that recommended the use of an init script.

The approach used is different from the other opened PR to fix this issue.

I also upgraded to the latest version of the gradle plugin.

Tests

I have split the gradle fixtures, one single project and one multi project. I also added some tests for the multi-project implementation.

Copy link
Contributor

@jonabc jonabc left a comment

Choose a reason for hiding this comment

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

Thanks for opening this! I'm excited to see the gradle source getting updated.

😓 apologies if any of my questions are simplistic, I don't use gradle at all in my day-to-day development work and am pretty unfamiliar with how it works.

Along with the comments left on the change, a few higher level comments:

  • can you move .gitignore back to test/fixtures/gradle? It looks like both single and multi project fixtures use the same gitignore, and it would be preferable to keep the file closer to root
  • based on ☝️ , can you remove test/fixtures/gradle/.gradle from this change? I don't believe that folder is meant to be checked in based on the .gitignore file, but it wasn't ignored because .gitignore was moved to the different fixture folders
  • can you update the gradle documentation with anything that users need to know for how to use the new multi-project support, including the new gradle.project config value?

lib/licensed/sources/gradle.rb Outdated Show resolved Hide resolved
Dependency.new(
name: name,
version: package["version"],
path: config.pwd,
executable: gradle_executable,
configurations: configurations,
project: project,
Copy link
Contributor

Choose a reason for hiding this comment

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

is it possible for different projects in a multi-project build to have different versions of the same dependency?

If yes, this value should be part of the name: argument rather than being added as a new property value.

lib/licensed/sources/gradle.rb Outdated Show resolved Hide resolved
lib/licensed/sources/gradle.rb Outdated Show resolved Hide resolved
Copy link
Contributor

@jonabc jonabc left a comment

Choose a reason for hiding this comment

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

Just to call out - I appreciate that moving code around so that the logic to run gradle is encapsulated in the new runner class, but all the code moving around makes this change a little hard for me to review and figure out what changes are functional vs what is refactoring.

An easy review in this repo is pretty important to me as I tend to be the only maintainer for the project. The contribution model in this repo has historically looked like

  1. someone adds or updates some piece of logic, or fixing a bug
  2. once everything is working, they don't drop back in until there's something else broken or could be otherwise improved

I'm ok with that model and I REALLY appreciate the community support, but it means that I really need to know the code that ships with licensed so I can support it if I get a bug report that noone else is available to fix.

I think I've gotten to the bottom of this change and better understand what it's doing, but in the future I'd appreciate if you could try to limit the scope of changes and prefer multiple smaller, targeted changes vs a single big change that adds or changes functionality as well as refactoring code for readability.

I've left a few comments, I think the only comments that I'd like to see resolved before merging this are the ones related to finding the license URLs and passing the url into the dependencies in enumerate_dependencies

lib/licensed/sources/gradle.rb Outdated Show resolved Hide resolved
def self.add_gradle_license_report_plugins_block(gradle_build_file)
# Prefixes the gradle command with the project name for multi-build projects.
def format_command(command)
if config.source_path != config.pwd
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this will ever be true now that you're relying on specifying multiple apps via configuration rather than using a special configuration key. Does this function still make sense to use or can it be removed?

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 function is still relevant, here is an example of when:

Let's say my project has the following structure:

project
│   settings.gradle
│   build.gradle
│   licensed.yml   
│
└──/app
  │   build.gradle

And the licensed.yml file content is:

sources:
  gradle: true
apps:
  - source_path: ./app

Then since the config file is at the root of the project and I specified the apps source path, the conditionconfig.source_path != config.pwd is true.

The gradle command will be run in the subproject context like so app:<command>

Does this makes sense to you ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Does this makes sense to you ?

Let me resay what I think you're explaining and let me know if I got it right?

When a command for the app subproject is run from the project directory, the gradle command needs to be prefixed with the project name. Is that correct? So to run a command on the app subproject while in the project directory, you'd need to run app:<command> instead of just command?

If so, I think I get the purpose but the usage might not be correct based on how licensed works elsewhere in the app code. Licensed changes the current directory to an app's source_path when evaluating that app. Also, config.pwd is a shim around Pathname.pwd and doesn't return the directory containing the licensed configuration file. Unless you're manually changing the current directory, config.source_path == config.pwd for the duration of enumerating and evaluating dependencies for an app.

It looks like Gradle::Runner#run changes the directory to it's @root_path value, which is set at the creation of gradle_runner to config.pwd. The value of config.pwd at that point should be equivalent to config.source_path though, so it's probably not actually changing the directory.

I could definitely have missed something here or misunderstood the intentions of prefixing the command with the project name though 🤷 .

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right, I applied the necessary changes

Thanks for taking the time to explain!

lib/licensed/sources/gradle.rb Outdated Show resolved Hide resolved
lib/licensed/sources/gradle.rb Show resolved Hide resolved
lib/licensed/sources/gradle.rb Outdated Show resolved Hide resolved
lib/licensed/sources/gradle.rb Outdated Show resolved Hide resolved
lib/licensed/sources/gradle.rb Outdated Show resolved Hide resolved
script/source-setup/gradle Outdated Show resolved Hide resolved
@LouisBoudreau
Copy link
Contributor Author

You are absolutely right!

While applying the changes for the init script I saw an opportunity to refactor a section of code and did so without thinking about the impact it would have on the review. I apologize, in the future I will make sure to scope the changes so they are smaller and more enjoyable to review!

On another note, I wanted to point out my admiration for the work you do for Licensed. This is a really a beautiful project with excellent quality. Licensed is a project all the more relevant now that open source is more and more widespread in our codebases.

Let me know if I can help 😄

Copy link
Contributor

@jonabc jonabc left a comment

Choose a reason for hiding this comment

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

a few more comments, this is getting closer 🚀

lib/licensed/sources/gradle.rb Outdated Show resolved Hide resolved
lib/licensed/sources/gradle.rb Show resolved Hide resolved
Copy link
Contributor

@jonabc jonabc left a comment

Choose a reason for hiding this comment

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

This looks like it's just stuck up now by how to find the right project name. Also I won't be able to run CI checks until you resolve the merge conflicts on the test file.

Sorry to cause the conflicts, I went through the test.yml workflow file to replace manual usage of actions/cache with setup actions' built-in caching wherever possible.

Copy link
Contributor

@jonabc jonabc left a comment

Choose a reason for hiding this comment

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

🚀 thanks so much for working through all of the feedback on this 🙇 :shipit: !

@jonabc jonabc merged commit 45eabf1 into github:master Jan 5, 2023
jonabc added a commit that referenced this pull request Jan 5, 2023
### Added
- Licensed supports Cocoapods as a dependency source (:tada: @LouisBoudreau #584)
- Licensed supports Gradle multi-project builds (:tada: @LouisBoudreau #583)
### Fixed
- Licensed no longer crashes when run with Bundler >= 2.4.0 (:tada: @JoshReedSchramm #597)
### Changed
- BREAKING: Licensed no longer ships executables with releases (#586)
- BREAKING: Licensed no longer includes support for Go <= 1.11
@jonabc jonabc mentioned this pull request Jan 5, 2023
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