How to add gradle dependency when buildFeature.compose = true? - gradle

Each time when a module needs enabled compose I have to do the following steps:
android.buildFeatures.compose = true
add a set of dependencies androidx.compose.xxx
I have a common build script and now I want to simplify usage of compose in my modules.
I would like to simplify that process by automatically add all compose dependencies if child module enables compose by android.buildFeatures.compose = true
How can I do it?

Something like this is done in the Now in android example app. They are using gradle plugins to do that, you can see common logic for all jetpack compose modules here: AndroidCompose.kt. There is a readme that explains it pretty well.

Related

How do you set the --frames option for a Javadoc task in Gradle?

We recently updated to JDK 11 and the javadoc team has seen fit to remove frame generation from the javadocs in favor of a search box. Our community is comprised heavily of students who don't know what keywords to search for, but who can browse a sidebar and find what they need. For them a search box is useless. They require discovery through browsing. For that reason, we would like to turn frames back on by adding the --frames option to the javadoc task, and then we'll just never move off of JDK 11.
We are using Gradle 7.4.2 and there doesn't appear to be a method exposing the --frames option in the StandardJavadocDocletOptions class.
If the options section of my Javadoc task looks like this:
options.memberLevel = JavadocMemberLevel.PROTECTED
options.links "https://developer.android.com/references"
options.encoding = 'UTF-8'
Then I see those options in gradle's generated options file.
Adding...
options.setStringOption('-frames')
...does not result in any new option appearing in the generated options file. To be honest I have no idea what setStringOption() without the second string parameter actually does.
Adding...
options.setStringOption('-frames', '')
... results in --frames '' appearing on the generated options file, but that confuses javadoc.
I don't see anything in the Gradle documentation that indicates how one might add simply '--frames' to the command line of the javadoc executable. Or any other option that javadoc might expose, but the gradle version one is sitting on does not expose for that matter.
To set flags use addBooleanOption()
// build.gradle.kts
tasks.javadoc {
options {
require(this is StandardJavadocDocletOptions) // workaround https://github.com/gradle/gradle/issues/7038
addBooleanOption("frames", true)
}
}
Note that the Kotlin DSL requires a workaround https://github.com/gradle/gradle/issues/7038#issuecomment-448294937

Create paketo builder based on another

Spring boot maven plugin is using paketo builder to build images.
gcr.io/paketo-buildpacks/builder:base-platform-api-0.3
What I would like to do is to add another step to what is being done by this builder.
I've created my own buildpack and tried to create builder with base buildpacks included.
builder.toml
...
...
[[buildpacks]]
image = "my-own-buildpack"
[[buildpacks]]
image = "gcr.io/paketo-buildpacks/builder:base-platform-api-0.3"
...
First problem that I'm having is this error when trying to create a builder out of builder.toml:
ERROR: failed to add buildpacks to builder: extracting buildpacks from gcr.io/paketo-buildpacks/builder:base-platform-api-0.3: could not find label io.buildpacks.buildpackage.metadata
Another problem is that even if that worked I guess I would still have to specify all order.group from paketo:base.
Is there actually a way to create a builder out of paketo-buildpacks/builder without going into details of what is happening inside?
At the moment, I do not believe there's a way to "extend" a builder. There is a Github issue open against the buildpacks spec though to add a feature like this. See here.
One option is to fully copy the builder.toml for the builder that you wish to extend. Then edit/modify it and create a new builder. This can be tricky as the builder.toml's are not, at the time I write this, published anywhere that's easy to find and copy them.
One alternative, which is probably closer to what you want anyway, is to make use of meta CNBs (a meta CNB is a collection of buildpacks). If you reference a meta CNB in the buildpacks section of your builder.toml, it will pull in all referenced buildpacks. You can then define your own custom order.
Ex:
[[buildpacks]]
id = "paketo-buildpacks/node-engine"
image = "gcr.io/paketo-buildpacks/node-engine:0.1.1"
[[buildpacks]]
id = "paketo-buildpacks/java"
image = "gcr.io/paketo-buildpacks/java:3.1.0"
[[order]]
[[order.group]]
id = "paketo-buildpacks/node-engine"
version = "0.1.1"
[[order.group]]
id = "paketo-buildpacks/java"
version = "3.1.0"
[stack]
id = "io.buildpacks.stacks.bionic"
build-image = "gcr.io/paketo-buildpacks/build:base-cnb"
run-image = "gcr.io/paketo-buildpacks/run:base-cnb"
This example would add the node-engine CNB and make it run before the Java meta CNB. You could alternatively make it run after the Java meta CNB, or even define a custom order as you can reference the buildpack id/version of buildpacks included by your version of the meta CNB in the order groups.

Display gradle property in readme.md file

I have a gradle project with a gradle.properties file. One of the properties displays the current version of my project and I would like to include this proprerty in the project's README.md on github. How can I do this?
The Gradle Copy task is capable of such functionality. Simply use its expand method to specify the values to insert. Of course you'll need to define a template somewhere in your project:
task copy(type: Copy) {
from 'src/templates'
into "$buildDir"
include 'projectinfo.html.template'
rename { file -> 'projectinfo.html' }
expand(project: project, title: 'ProjectInfo', generated: new Date())
}
I took this example from a post of Mr. Hakis Blog.
This functionality is based on the Groovy SimpleTemplateEngine. Of course you can simply use this class or any other templating engine to implement the required functionality in your build script on your own.
#KrispyK,
I believe this would be possible. You could write a simple serverless script using webtask (or similar service) that reads your gradle properties file and creates a custom status badge using a badge service like shields.io. Finally, you would only need to add this badge to your markdown file.
Please refer to this webtask script that I created. This calls an external API and uses the data returned by that API to create a custom Shields badge.
I've then used this badge in my readme file.
Hope this helps.

Getting settings object from the buildscript

I am trying to access the settings object from the root project's build script.
The reason is I want to define a list in the settings.gradle file which will be a list of subprojects, kind of:
settings.gradle
projectNames = ['prjA', 'prjB']
Would like to do something like:
build.gradle (root project)
projectNames = settings.projectNames
// Use projectName in tasks
And then access it in build.gradle for various tasks, such as resolving those names into URLs to git-clone them. However I can't seem to find a way to declare some arbitrary groovy object which is visible between these two scripts. Note I may potentially like that list to be related but not equal to the project names. I guess the question sums up to sharing POGOs between those two files and accessing the settings object.
I'm pretty new to Gradle.
There isn't a way to get to the settings object from a build script. However, both scripts share a gradle object, which you could use to set an extra property in the settings script (e.g. gradle.ext.foo = "bar"), and read it in the build script (e.g. println gradle.foo).
If you need access to the Settings instance from your build.gradle file after the
settings have been loaded and evaluated, you can register a lifecycle closure or listener.
A great place to start is the method Gradle#settingsEvaluated(Closure)
that provides the Settings object as a closure parameter.

Building a plugin system for a nodejs based MVC platform

I would like to be able to build functionality for my application in a plugin style system for a couple reasons:
New projects can choose which plugins are necessary and not have code for functionality that's not needed
Other developers can build plugins for the system without needing too much knowledge of the core workings.
I'm not really sure how to go about implementing this. I would like to have a plugins folder to host these separately but I guess my questions are:
How do plugins interact with the core system?
How does the folder structure work? Would each hold the standard MVC structure: controllers, services, models, views, etc?
I guess if anyone has a tutorial or some documentation relating to this technique that would be helpful. I've done a bit of searching but it's all a little too closely related to the actual code they're working with instead of the concept and I hadn't found anything specifically related to nodejs.
I suggest an approach similar to what I've done on the uptime project (https://github.com/fzaninotto/uptime/blob/master/app.js#L46):
trigger application events in critical parts of your application
add a 'plugins' section in the applicaition configuration
each plugin name must be a package name. The plugin packages should return either a callback, or an object with an init() function.
either way, inject to the plugins the objects they will need to run (configuration, connections, etc) when calling init(), or executing the callback.
plugin modules register listeners to the application events and modify it
Benefits:
lightweight
rely on npm for dependencies
don't reivent the wheel
Create a plugin prototype for the base
functionality, and let the user define its plugin in a module. In the
module the user would inherit an object from the prototype, extend its
functionality, and then export a constructor which returns the plugin
object.
The main system loads all plugins by require("pluginname") and for
each calls the constructor.

Resources