GithubHelp home page GithubHelp logo

dropbox / focus Goto Github PK

View Code? Open in Web Editor NEW
375.0 13.0 20.0 189 KB

A Gradle plugin that helps you speed up builds by excluding unnecessary modules.

License: Apache License 2.0

Kotlin 100.00%
gradle gradle-plugin android build build-tool build-performance

focus's Introduction

🧘 Focus

A Gradle plugin that generates module-specific settings.gradle files, allowing you to focus on a specific feature or module without needing to sync the rest of your monorepo.

The Focus plugin evaluates your project setup and creates a unique settings.gradle file for the module you want to focus on, which only includes the dependencies required by that module. It then creates a .focus file that references the currently focused module.

With these files in place only the modules that you need will be configured by Gradle when you sync your project. Deleting the .focus file, which can be done using the clearFocus task, will revert to using the includes file to configure your entire project.

Setup

Apply the plugin in your settings.gradle file.

// settings.gradle(.kts)
pluginManagement {
  repositories {
    mavenCentral()
    gradlePluginPortal()
  }
}

plugins {
  id("com.dropbox.focus") version "0.4.0"
}

Note that the plugin is currently published to Maven Central, so you need to add it to the repositories list in the pluginsManagement block.

Move all non-required include statements into settings-all.gradle. Projects that are always included can remain in your main settings.gradle file.

// settings-all.gradle(.kts)
include ':sample:app2'
include ':sample:lib2c'
include ':sample:lib-shared'

include ':sample:moved'
project(':sample:moved').projectDir = new File("sample/lib-moved")

Optionally configure the plugin if you'd like to use different settings files than the defaults:

// settings.gradle
focus {
  // The name of the settings file
  allSettingsFileName = "settings-all.gradle" // Default
  focusFileName = ".focus"  // Default
}
// settings.gradle.kts
configure<com.dropbox.focus.FocusExtension> {
  // The name of the settings file
  allSettingsFileName.set("settings-all.gradle") // Default
  focusFileName.set(".focus") // Default
}

Whether or not you configure a custom focus file, it should be added to your .gitignore file as it's meant for a specific developer's workflow.

Usage

The Focus plugin adds a few tasks for you to interact with in your Gradle builds. Using these tasks you can create module specific settings files that will be automatically used by Gradle to configure only the modules which are required.

For example, say you're currently working on the app module :sample:app2 and only need to run that module and its dependencies. You can use the following flow to reduce the number of modules that are loaded and synced into your IDE to speed up development.

# When you start work on the app2 module, bring it into focus
./gradlew :sample:app2:focus

# Click the Sync Elephant to have your IDE reload the gradle config, and you'll only have
# :sample:app2 and it's dependencies loaded by the IDE, allowing you to build and run the sample app
# and it's tests without having to sync the rest of the project.

# If you want to spend time in a specific dependency, you can bring that into focus and sync your
# IDE for even more fine grained development
./gradlew :sample:lib2b:focus

# When you want to clear focus and get back to the entire project, simply use the clearFocus task.
./gradlew clearFocus

Tasks

focus

A focus task is added to all subprojects, and allows you to focus on just that module.

createFocusSettings

A createFocusSettings task is created for each subproject, and is responsible for finding a module's dependencies and creating a module-specific settings file. This is a dependency of the focus task and likely not necessary to call on its own.

clearFocus

A clearFocus task is added to the root project, and allows you to remove any previously focused modules.

License

Copyright (c) 2022 Dropbox, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

focus's People

Contributors

chris-mitchell avatar cramsan avatar digitalbuddha avatar ivk1800 avatar joshafeinberg avatar rharter avatar simonmarquis avatar virtualparticle avatar zacsweers avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

focus's Issues

Regenerate focus.settings.gradle when new module asi added

When I'm focused to module A and add (or merge) new module B to settings-all.gradle, gradle doesn't know module B when gradle sync and I have to call focus task again to generate new focus.settings.gradle.

Would it be possible that focus recognize during gradle sync that settings-all.gradle was changed and regenerate focus.settings.gradle automatically so I don't need to call focus task again?

What is the profit from Focus in the android application

image

Tell me how Focus can help me, if I write an android application and every time I launch the app module, does gradle work for a long time? It seems nothing, because my app module in gradle has all the other modules as dependencies. And if I focus on a particular module, make changes to it and try to compile the app module, I get an error like this : Project with path ':chat' could not be found in project ':app'

Not compatible with configuration cache

Running with configuration caching yields the following errors

* What went wrong:
Configuration cache problems found in this build.

10 problems were found storing the configuration cache, 2 of which seem unique.
- Task `:tooling:vulcan:createFocusSettings` of type `com.dropbox.focus.CreateFocusSettingsTask`: invocation of 'Task.project' at execution time is unsupported.
  See https://docs.gradle.org/7.4/userguide/configuration_cache.html#config_cache:requirements:use_project_during_execution
- Task `:tooling:vulcan:focus` of type `com.dropbox.focus.FocusTask`: invocation of 'Task.project' at execution time is unsupported.
  See https://docs.gradle.org/7.4/userguide/configuration_cache.html#config_cache:requirements:use_project_during_execution

See the complete report at file:///Users/zsweers/dev/slack/android3/build/reports/configuration-cache/7g4wvgv20v66oia9a3wlgl3fw/4wl3j2ake574xd7cq4p2iiwz7/configuration-cache-report.html
> Invocation of 'Task.project' by task ':tooling:vulcan:createFocusSettings' at execution time is unsupported.
> Invocation of 'Task.project' by task ':tooling:vulcan:focus' at execution time is unsupported.

Support running a Gradle Task from right click on a subproject in IDE

Our team recently added the Focus gradle plugin, which adds tasks like :subproject:focus.

I'd love support in the IDE to be able to right click and run specific Gradle tasks from the right-click on subproject context menu.

For example, I have a subproject: :util:app-in-foreground-observer. I would like to be able to right click on the subproject from the left side project menu in Android Studio and see a context menu with:

Run Gradle Task `:util:app-in-foreground-observer:focus`

While this is a useful feature for Focus, it makes sense that the IDE as a whole supports executing generating Gradle tasks from the context of a subproject, so I filed https://youtrack.jetbrains.com/issue/IDEA-291803 as well

New version

hello, please tell me when the new version will be released?

[SUPPORT] After running `:project:focus` unrelated projects fail to configure

We're trying to use this plugin in a large repo. However, when the focus is applied, it generates a .focus file and focus.settings.gradle which appears to have all of the expected projects.

Though, when running ./gradlew clean, it attempts to configure projects that are not in the focus file.

I've been debugging this for a few hours and can't produce a minimal reproducible set. Any help would be appreciated in what to track down. If I hazard a guess, there's some Plugin that is pulling in dependencies recursively -- but I am unsure.

Generated focus.settings.gradle doesn't respect includeBuild statements

In our project s_ettings.gradle_ we use includeBuild statement to add in classpath separate project.
Focus plugin generates focus.settings.gradle without that statement, that's why included project is missing and project configuration become broken.

For example:
original settings.gradle

includeBuild("path_to_project")
include ':app'

generated settings.gradle

include ':app'

Need to point out that included project is not directly used in dependencies section of any subproject. It only contains gradle scripts that is applied at each subprojects.

As workaround, I'm using project.tasks.findByName("createFocusSettings").finalizedBy(myTask) to intercept in settings creation process and append in file missing statements. May be you'll provide special configuration property in focus's extension, to allow edit generated settings file?

Support focusing multiple subprojects

We have have multiple subprojects per feature. So let's say we have a "Sign In" feature, and have tagged a number of subprojects to be under that feature.

Would be nice to allow a developer working on the "Sign In" feature to run:

./gradlew signInFocus

That would "focus" all subprojects with that tag

incompatitble with configuration cache on Gradle 8.4

I tried integrating focus into a project using Gradle 8.4 with configuration cache enabled and got a warning regarding incompatibilities.

I've updated the sample project to Gradle 8.4 and enabled configuration cache as a reproducer and this is the warning I got:

3 problems were found storing the configuration cache, 1 of which seems unique.
- Task `:sample:createFocusSettings` of type `com.dropbox.focus.CreateFocusSettingsTask`: invocation of ‘Task.project’ at execution time is unsupported.
  See https://docs.gradle.org/8.4/userguide/configuration_cache.html#config_cache:requirements:use_project_during_execution

PR with reproducer:#41

focus.settings.gradle for Windows

After calling the "focus" task, a file is generated focus.settings.gradle in which the paths on the module are specified using such a slash - , but Windows only accepts such a slash - /. Please let me know if this is a bug and someone is working on a fix.

Included builds are not yet available for this build.

We recently migrated from buildSrc to convention plugins which are being pulled in as an includeBuild in our settings.gradle.

Currently, I only have our app module in settings-all.gradle and the original settings.gradle file has the rest of the existing logic

pluginManagement {
    includeBuild("build-logic")
}

plugins {
...
}

include("...")

This is the error we're getting

> Task :library:repository:createFocusSettings FAILED

1 problem was found storing the configuration cache.
- Task `:library:repository:createFocusSettings` of type `com.dropbox.focus.CreateFocusSettingsTask`: invocation of 'Task.project' at execution time is unsupported.
  See https://docs.gradle.org/8.0/userguide/configuration_cache.html#config_cache:requirements:use_project_during_execution

See the complete report at file:///Users/changd/code/android/build/reports/configuration-cache/c2kiincfd0w2hzkql27qyhlqc/8pf9nvszsnq578qy2l4bu38yi/configuration-cache-report.html

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/changd/code/android/build.gradle' line: 29

* What went wrong:
Error resolving plugin [id: 'org.gradle.android.cache-fix', version: '2.7.1', apply: false]
> Included builds are not yet available for this build.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org

BUILD FAILED in 3s
10 actionable tasks: 1 executed, 9 up-to-date

Generated focus.settings.gradle disappear on clean/rebuild

Plugin works great! But when trigger clean or rebuild (from Android Studio), all build directories will be removed. So generated focus.settings.gradle will be deleted and project will be broken (.focus file exists, but points at nowhere now).
How do you solve that problem in your team?

As workaround I'm replacing path where generated focus.settings.gradle will be saved - select root folder of target project, which placed in focus.

focus.settings.gradle not being generated

I'm trying to integrate the plugin into our large mono-repo, the focus task generates the .focus file but not the focus.settings.gradle file and thus Gradle is unable to find the file.

I have not configured the plugin, I have:

  • settings.gradle file containing gradleEnterprise and repository configurations
  • settings-all.gradle containing a groovy script that dynamically fetches all the projects in our mono-repo

Is there another requirement that must be done?
Thanks

I am getting below error while integrating

  • What went wrong:
    Could not resolve all artifacts for configuration 'classpath'.

Could not resolve com.dropbox.focus:focus:0.4.0.
Required by:
unspecified:unspecified:unspecified > com.dropbox.focus:com.dropbox.focus.gradle.plugin:0.4.0
Unable to find a matching variant of com.dropbox.focus:focus:0.4.0:
- Variant 'apiElements' capability com.dropbox.focus:focus:0.4.0:
- Incompatible attributes:
- Required org.gradle.jvm.version '8' and found incompatible value '11'.
- Required org.gradle.usage 'java-runtime' and found incompatible value 'java-api'.
- Other attributes:
- Found org.gradle.category 'library' but wasn't required.
- Required org.gradle.dependency.bundling 'external' and found compatible value 'external'.
- Found org.gradle.jvm.environment 'standard-jvm' but wasn't required.
- Required org.gradle.libraryelements 'jar' and found compatible value 'jar'.
- Found org.gradle.status 'release' but wasn't required.
- Found org.jetbrains.kotlin.platform.type 'jvm' but wasn't required.
- Variant 'runtimeElements' capability com.dropbox.focus:focus:0.4.0:
- Incompatible attribute:
- Required org.gradle.jvm.version '8' and found incompatible value '11'.
- Other attributes:
- Found org.gradle.category 'library' but wasn't required.
- Required org.gradle.dependency.bundling 'external' and found compatible value 'external'.
- Found org.gradle.jvm.environment 'standard-jvm' but wasn't required.
- Required org.gradle.libraryelements 'jar' and found compatible value 'jar'.
- Found org.gradle.status 'release' but wasn't required.
- Required org.gradle.usage 'java-runtime' and found compatible value 'java-runtime'.
- Found org.jetbrains.kotlin.platform.type 'jvm' but wasn't required.

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

pluginManagement {
    repositories {
        mavenCentral()
        gradlePluginPortal()
    }
}

plugins {
    id("com.dropbox.focus") version "0.4.0"
}

...included projects here 

settings-all.gradle is empty for now

Documentation is unclear

I was trying to use focus for my project, but I was not able to set it up properly for the following reasons:

  • Documentation is unclear: There is a mix between .gradle files and .kts files in the documentation and in the sample. It should either or, but don't mix both at the same time
  • Only the focus task appears in the task list in Android Studio (right pane)
  • Focus can't be found in settings.gradle.kts, see screenshot for reference
  • The focus gradle file is missing in this repo. For a complete sample, this would be great to have

Gradle version: 7.3
AGP version: 7.1.0

image

Maybe someone can help out

Gradle 8.0 - clearFocus - ClearFocusTask error

After updating to Gradle 8.0 we have the following error :

A problem was found with the configuration of task ':clearFocus' (type 'ClearFocusTask').
  - Type 'com.dropbox.focus.ClearFocusTask' property 'focusFile' has @Input annotation used on property of type 'RegularFileProperty'.
    
    Reason: A property of type 'RegularFileProperty' annotated with @Input cannot determine how to interpret the file.
    
    Possible solutions:
      1. Annotate with @InputFile for regular files.
      2. Annotate with @InputFiles for collections of files.
      3. If you want to track the path, return File.absolutePath as a String and keep @Input.
    
    Please refer to https://docs.gradle.org/8.0.2/userguide/validation_problems.html#incorrect_use_of_input_annotation for more details about this problem.

To reproduce you can update this project to Gradle 8.0.2 and run ./gradlew clearFocus: build scan.

AGP 7.4.2
Gradle 8.0.2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.