gradle project dependency on a distributed layout - layout

We have some old projects with Ant builds that are grouped in different directories. We're trying to convert them to gradle builds.
The repo has a structure like the following where let say that all the WebComponent projects depend on DbComponent projects so they are not in hierarchical layout neither in flat layout. I realize that in the longer run we probably want to publish DBComponent projects as artifacts but for the moment I was wondering if we it is possible to create a multi-project build where subprojects are not flat nor hierarchical. include and includeFlat with compile project do not seem to do the trick in this case.
Is this something that can work at all?
|-WebComponents
|
|
|--project1
|
|--project2
|
|--project3
|
|
|-DbComponents
|
|--dbproj1
|
|--dbproj2
Thank you for any suggestion

Gradle can work with any layout; a custom layout just takes a bit more configuration than a hierarchical or flat layout. Anyway, what you have looks very much like a hierarchical layout, just two levels deep. In this case, the easiest solution is to use includes such as include "WebComponents:project1" and project dependencies such as dependencies { compile project(":WebComponents:project1") }.

Related

What is the use of com.diffplug.spotless plugin in Android Studio?

I am working with Jetpack Compose and I came across "com.diffplug.spotless" plugin in the app's build.gradle file of many examples, but I am not sure if I need it in my project. Can anyone explain the purpose of using it in the Jetpack compose projects?
''' apply plugin: "com.diffplug.spotless" '''
Spotless: Keep your code spotless with Gradle
While working, Many a times you will get formatting issues at the stage of every commit like removing empty lines, cutting white spaces correct, indentation and other minor formatting mistakes.
Using tool/plugin called “Spotless” will reduce time in addressing code review comments.
Spotless provides support for a variety of languages.
Spotless consists of a list of format and each format has:-
1.a target (the files to format), which you set with target.
2.a list of FormatterStep, which are just String -> String functions, such as replace, replaceRegex, trimTrailingWhitespace, custom, prettier, eclipseWtp, licenseHeader etc.
To start integration with Gradle:-
1.Add the following dependency to your build.gradle file
classpath(“com.diffplug.spotless:spotless-plugin-gradle:$spotlessVersion”)
2.Apply the following plugin
apply plugin: ‘com.diffplug.gradle.spotless’
3.Applying spotless to your gradle file in Android Java source
spotless {
java {
// ...
target '**/*.java'
// ...
}
}
Note:- Be sure to add target '**/*.java' otherwise spotless will not detect Java code
inside Android modules.
For more detail you can refer this link : 1

Multiple dex files define Lcom/android/volley/toolbox/Volley;

I am getting an error
"Multiple dex files define Lcom/android/volley/toolbox/Volley;
Is it possible to use two volley libraries i.e compile com.android.volley:volley:1.0.0 and dev.dworks.libs:volleyplus:+ in a single project?
If these two volley libraries have different package names, it is fine to have both as dependency.
But, what is the added value for using two (same? or similar?) libraries? Why not refactor your project to slim down your dependencies?
The solution to multiple dex definition for a particular package and class is adding a proper packaging option. e.g.
packagingOptions {
pickFirst "anyFileWillDo"
exclude "/secret-data/**"
}
In my opinion, having a duplicate library dependency is really not a good practice, it may yield some uncertainties on the final binary. Because the pickFirst option is not deterministic on choosing the class from the right version of library, it will only pick up the one it sees first.
Please see here: https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html

How to customize destination path of each dependency

I'm trying to use Gradle to manage dependencies in non-Java projects. The idea is to have a single, generic plugin that along with a project's gradle.build file will bring into the project any dependencies the project needs, placing each dependency where the project expects the files to reside. Currently, it is working by placing them all in a /libs/ folder in the project, but that is not enough. What I'd like to be able to do is to specify in the gradle.build file where to put the dependency in the project.
Here is a simple example: I have a project that has been used for years as a component in other projects. It is a real pain to update all projects when that core component code has been updated... each project repository has to have the new files committed (using SVN, specifically). The files must reside in a particular directory so the ColdFusion framework (FW/1) correctly interacts with the code.
So what has been done is that core component is now in Artifactory and the gradle.build file pulls it down into the projects. That would be the end of the story if it was the only dependency, but there are others that need to be pulled down and the code expects those to be in a different directory than that one component. Each project will have different dependencies, and potentially different file structures (for example, our older apps are using the Fusebox framework). So the ability to control where a dependency ends up as specified in the gradle.build file is what I'm after.
This is what I was hoping to be able to do:
dependencies {
// exploded is a configuration that is added to this plugin
exploded('com.foo:bar:2.0-SNAPSHOT#zip') {
ext {
moveWhat = ['app']
moveWhere = 'assets'
}
}
exploded('com.foo2:bar2:1.0-SNAPSHOT#zip') {
ext {
moveWhat = ['*']
moveWhere = 'lib'
}
}
...
The hope was that I could pass directories/files into moveWhat that would then get placed into the directory specified by moveWhere, but I'm having trouble figuring out how to associate properties with each dependency. I'm having trouble figuring out if this is even possible.
Can anyone point me in the right direction?
I would suggest you use a separate task to extract what you need from the configuration. Something like this:
task copyFromExploded(type: Copy) {
into new File(project.buildDir, "assets")
from (configurations.exploded)
include "**/app"
}

Pharo dependency hell

I am trying to develop a simple project in Pharo, and I would like to add its dependencies in Metacello. My project depends on Glamour, Roassal and XMLSupport.
A way to cleanly install my project is to install the dependencies by hand first. Following the book Deep into Pharo one can do
Gofer new
smalltalkhubUser: 'Moose' project: 'Glamour';
package: 'ConfigurationOfGlamour';
load.
(Smalltalk at: #ConfigurationOfGlamour) perform: #loadDefault.
Gofer new smalltalkhubUser: 'ObjectProfile'
project: 'Roassal';
package: 'ConfigurationOfRoassal';
load.
(Smalltalk at: #ConfigurationOfRoassal) load.
Gofer new
squeaksource: 'XMLSupport';
package: 'ConfigurationOfXMLSupport';
load.
(Smalltalk at: #ConfigurationOfXMLSupport) perform: #loadDefault.
and then my project will work fine.
I have tried to create a ConfigurationOfMyProject using the Versionner, and I have added Glamour, Roassal and XMLSupport as dependencies, using the version that are currently installed in my image (2.6-snapshot, 1.430 and 1.2.1 respectively).
The problem is that I am not able to load my project using Metacello in a fresh image. The project loads fine, but whenever I try to load my classes I get method missing errors in Glamour. Moreover, it is apparent that something is different, because even the world menu has different entries.
I have tried other combinations of versions, including using the stable Glamour (2.1) but I have obtained more errors, including not even being able to open the project in the Versioner (it complains about a missing Roassal name).
What is the correct way to add these dependencies cleanly?
First of all I want to highlight that if configuration is in class ConfigurationOf<proj-name> you can load it as using #configuration message:
Gofer new
smalltalkhubUser: 'Moose' project: 'Glamour';
configuration;
load.
(Smalltalk at: #ConfigurationOfGlamour) perform: #loadDefault.
A I don't see your project, I can just suggest you to write configuration by hand. There is an easy tutorial called Dead simple intro to Metacello.
According to your description it should be something like:
baseline01: spec
<version: '0.1'>
spec for: #common do: [
spec blessing: #release.
spec repository: 'your repo url'.
spec
package: 'YourPackage' with: [
spec requires: #('Glamour' 'Roassal' 'XMLSupport') ].
"also maybe you have a couple of packages that depend on different projects"
spec project: 'Glamour' with: [
spec
className: 'ConfigurationOf Glamour';
repository: 'http://smalltalkhub.com/mc/Moose/Glamour/main';
version: #'2.6-snapshot' ].
spec project: 'Roassal' with: [
spec
className: 'ConfigurationOfRoassal';
repository: 'http://smalltalkhub.com/mc/ObjectProfile/Roassal/main';
version: #'1.430' ].
"and same for XMLSupport" ].
Also you can try to load #development versions, as I have an impression that projects like Roassal and Glamour have very outdated stable versions. Also please note that Roassal2 is actively developed and will replace original Roassal in Moose platform, maybe you want to consider using it.
I would seriously discourage writing configs by hand - that is the assembly code of Metacello ;) Unless you are working on cross-Smalltalk-platform projects with platform-specific code (e.g. code for Pharo 1.4 vs Squeak 4.5) - an area which hasn't been explored yet, Versionner is the tool for you. I have written dozens of configs with it and have yet to run into a roadblock.
When you say you added them as dependencies, did you just add them as projects in the "Dependent projects" pane?
If so, you also have to specify which of your project's packages depend on them. To do this, you select the relevant package of your project on the "Packages" pane.
Now, click on the edit button with the pencil icon that just became enabled. In the dialog that appears, click the green + button and add the external projects of interest.
It looks like you are trying this in an old version of Pharo?
Roassal has been superseded by Roassal2, and the support for XML is on smalltalkhub, split into ConfigurationOfXMLWriter and ConfigurationOfXMLParser, both in PharoExtras.
If you load the right groups from Glamour you don't need to describe the dependencies on Roassal, as Glamour already depends on Roassal(2). That explains your cyclic dependency.
You have also run into the problem we've recently talk about on the pharo mailing lists
that #stable is not a usable symbolic version name. In the Seaside/Magritte/Grease projects we've changed to using #'release3.1' style symbolic version names. That ensures that there is less of a ripple effect when progressing stable.
Snapshot versions should never be a dependency, they just describe what is loaded at the moment, and are basically not upgradable.
[edit]
Metacello by default tries to be smart about not installing older versions over newer. This works pretty well as long as things are not moved to different packages. So it's a bit of bad luck there that you ended up with a non-working combination.
Metacello support complex workflows, and different smalltalk projects (need to) use different workflows. It often takes some time to reach consensus on the best way to do things.
Roassal does not depend on Glamour, but you can create the cycle in your own configuration :)
Packages were moved from squeaksource to ss3 and smalltalkhub because the server had had stability problems. More recently, those problems seem to have been fixed. The xml support was split as it was noted that a lot of applications actually don't need both writing and reading of xml.
Once you have a working configuration, it might be a good idea to build and test it on the continuous integration server of pharo: http://ci.inria.fr/pharo-contribution
If not your actually application, at least the open source parts as used by you. That way the Pharo, Glamour & Roassal teams can know if a change they make breaks something.

Is there any global flag for Groovy static compilation?

I know that since Groovy 2.0 there are annotations for static compilation.
However it's ease to omit such annotation by accident and still run into troubles.
Is there any way to achieve the opposite compiler behaviour, like compile static all project files by default and compile dynamic only files chosen by purpose with some kind #CompileDynamic annotation for example?
I have found some (I believe recently introduced) feature which allows doing so with Gradle.
In build.gradle file for the project containing groovy sources we need to add following lines:
compileGroovy {
configure(groovyOptions) {
configurationScript = file("$rootDir/config/groovy/compiler-config.groovy")
}
}
or compileTestGroovy { ... for applying the same to test sources. Keep in mind that neither static compilation nor type checking works well with Spock Framework though. Spock by its nature utilizes dynamic 'groovyness' a lot.
Then on a root of the project create folder config/groovy/ and a file named compiler-config.groovy within. The content of the file is as follows:
import groovy.transform.CompileStatic
withConfig(configuration) {
ast(CompileStatic)
}
Obviously path and name of the configurationScript may vary and it's up to you. It shouldn't rather go to the same src/main/groovy though as it would be mixing totally separate concerns.
The same may be done with groovy.transform.TypeChecked or any other annotation, of course.
To reverse applied behaviour on certain classes or methods then #CompileDynamic annotation or #TypeChecked(TypeCheckingMode.SKIP) respectively may be used.
I'm not sure how to achieve the same when no Gradle is in use as build tool. I may update this answer in the future with such info though.
Not at this time, but there is an open Jira issue here you can follow to watch progress for this feature
There was also a discussion about methods for doing this on the Groovy developers list

Resources