How to include a Gradle distribution in the project to be used for the wrapper - gradle

I want to include a specific version of Gradle in the project folder so that when I use the Gradle wrapper it doesn't download it from the remote repository.
I downloaded the version of Gradle I need (gradle-4.0-bin.zip) and I put that zip fine inside of gradle/wrapper/ folder of the project (created with the gradle wrapper command).
Then I edited the gradle-wrapper.properties file in this way:
distributionUrl=file:///Users/pathj/to/the/project/gradle/wrapper/gradle-4.0-bin.zip
But when I run the first command, such as gradle task it returns:
What went wrong: A problem occurred configuring root project '03-gradle-wrapper-local'.
java.io.FileNotFoundException: /Users/myself/.gradle/wrapper/dists/gradle-4.0-bin/3p92xsbhik5vmig8i90n16yxc/gradle-4.0/lib/plugins/gradle-diagnostics-4.0.jar
(No such file or directory)
How do I tell Gradle to get the zip file from the current project folder, with a relative path, instead of downloading it, and to use that zip file to create a wrapper to be used in my builds?

Apart from storing gradle wrapper locally make sense or not it is possible. I assume that gradle-4.0-rc-3-bin distro is used.
Here is the project structure:
.
├── gradle
│   └── wrapper
│   ├── gradle-4.0-rc-3-bin.zip
│   ├── gradle-wrapper.jar
│   └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat
And here the content of gradle-wrapper.properties:
distributionBase=PROJECT
distributionPath=gradle
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=gradle-4.0-rc-3-bin.zip
Since wrapper files will be downloaded to the project dir adding gradle/gradle-4.0-rc-3-bin to SCM ignore file is recommended.
Demo can be found here.

Related

How to tell Gradle and Intellij that the project's folder structure is different?

I'm using Gradle with the wrapper, and the folder structure by default is like so:
.
├── settings.gradle
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat
However, I would like to change it to so:
.
├── gradle
| ├── build.gradle
│ ├── settings.gradle
│ ├── gradle.properties
│ └── wrapper
│ ├── gradlew
│ ├── gradlew.bat
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
└── src
├── main
└── test
Other than the fact that I don't know how to tell IntelliJ about the folder structure, I don't know how to change it for Gradle since the Environment Options related with changing the folder structure are deprecated:
-b, --build-file (deprecated)
Specifies the build file. For example: gradle --build-file=foo.gradle. The default is build.gradle, then build.gradle.kts.
-c, --settings-file (deprecated)
Specifies the settings file. For example: gradle --settings-file=somewhere/else/settings.gradle
You can't tell Gradle and Intellij IDEA that you use a non-standard Gradle build layout. And in all honesty, you shouldn't even consider that unless you have strong reasons to do so. There are mainly two reasons for that:
Developers familiar with one Gradle project feel immediately at home when starting with your Gradle project.
A non-standard build file and directory layout requires additional logic in IDE's (which is not present) and requires to provide extra parameters when building on the command line.
To put things into context, please have look at Gradle issue #16402.
Deprecate command-line options that describe the build layout
The -b and -c command-line options are effectively used to describe a non-standard build layout to Gradle. This is problematic because it means that a specific combination of options must be used whenever Gradle is used on that build, for example whenever invoked from the IDE, CI, command-line or some other tool. These command-line options also have some potentially surprising behaviours, such as running a settings script present in the target directory.
We don't think there are any use cases that are strong enough to justify keeping these options, and we should remove them (via deprecation). If we discover there are some use cases, we might consider replacing the options with more self-describing contracts, for example conventions for build script names.

Make gradle point to subdirectory and treat it as a rootProject

I encountered a problem with gradle project structure. I have a task that needs to be realized and some tests are meant to be executed to check whether my project structure is correct and the tasks in gradle execute correctly. However I think I misunderstood instruction a bit and I'm wondering whether I can do something with my current folders structure or If I will have to rewrite the whole project. My current project structure looks like this:
main-repo-folder/
├── docker-related-file
├── rootProject
│ ├── sub-project-1
│ ├── build(output from tasks is created here)
│ ├── build.gradle
│ ├── sub-project-2
│ ├── gradle
│ ├── gradlew
│ ├── gradlew.bat
│ ├── settings.gradle
│ └── src
As you can see, the root project is a directory inside a repo. In order for my tests to execute I think the repo itself must be a root folder (or act as one) because the tests seem to be trying executing there. And here is my question, is it possible to add f.e settings.gradle file in main-repo-folder (at the same level as rootProject folder) to "point" gradle to build from rootProject and treat that folder as the root?(I mean f.e if I call gradle clean build task_name in main-repo-folder I want to make gradle execute it as I would be in rootProject folder)
I've tried to find some information but I'm at the path of learning gradle and I don't know if it is even possible :/ .
Rename main-repo-folder/rootProject to main-repo-folder.

How to find gradle subproject tasks from different working directory

I'm running into the problem that my gradle wrapper will only find subprojects if I execute it whilst being in the same working directory. For example:
Let's say the project structure is as follows:
.
├── app
│   ├── build.gradle
│   ├── ...
├── build.gradle
├── gradlew
├── settings.gradle
└── ...
It makes a difference whether I run gradlew from it's directory or from a different directory. If I run:
$ ./gradlew projects
> Task :projects
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'com.name'
+--- Project ':app'
it has no problem finding :app. However, if I navigate and execute gradlew from a folder up, it cannot find it:
$ cd ..
$ ./android/gradlew projects
> Task :projects
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'com'
No sub-projects
It can't find the projects. This is problematic for me since I need to run a task in :app from a pipeline from a different working directory, e.g. ./xx/yy/gradlew app:publishTask. However doing it this way, gradle can't find the task because it can't find the project. Is there a way to run these commands from any location?
Yes, it is. You have to:
store your current location in an temporary variable
change location to project directory
run ./gradlew
restore directory from variable
ex:
TMP_DIR=`pwd`
cd /path/to/project
./gradlew projects
cd $TMP_DIR

Bash: automatically add a file to a Xcode project?

I am creating a script.sh file that creates a Test.swift file and adds it into a Xcode project. However, I would like to know if there is a way to add this file to Xcode (in the project.pbxproj file) from this script? Instead of doing it manually in Xcode (Add files to Project...).
Thank you
3/05 Update
I tried #Johnykutty answer, here is my current Xcode project before executing the ruby script:
I have already generated a A folder with a Sample.swift file located in test, but these files are not linked to my Xcode project yet:
Now here is the script that I'm executing:
require 'xcodeproj'
project_path = '../TestCodeProjTest.xcodeproj'
project = Xcodeproj::Project.open(project_path)
file_group = project["TestCodeProjTest"]["test"]
file_group.new_file("#{project.project_dir}/TestCodeProjTest/test/A")
project.save()
This almost works fine, except that it creates a folder reference instead of a group, and it doesn't link it to my target:
Hence the content of Sample.swift is unreachable.
Its hard to achieve by bash. But really easy if you use Ruby and xcodeproj gem from Cocoapods
Consider you have file structure like
├── GeneratedFiles
│   └── Sample1.swift
├── MyProject
│   ├── AppDelegate.swift
│   ├── ... all other files
│   ├── SceneDelegate.swift
│   └── ViewController.swift
├── MyProject.xcodeproj
│   ├── project.pbxproj
│   ├── .....
└── add_file.rb
Then you can add files like
require 'xcodeproj'
project_path = 'MyProject.xcodeproj'
project = Xcodeproj::Project.open(project_path)
file_group = project["MyProject"]
file_group.new_file("../GeneratedFiles/Sample1.swift")
project.save()
UPDATE:
project["MyProject"] returns a file group which is a group named MyProject in the root of the project, you can select another group inside MyProject by file_group = project["MyProject"]["MyGroup"]
Then the generated file path should be either related to that group like file_group.new_file("../../GeneratedFiles/Sample1.swift") or full path like file_group.new_file("#{project.project_dir}/GeneratedFiles/Sample1.swift")
More details about Xcodeproj here

How to make a fully independent module in a Gradle multi-project

I want to develop a piece of software in java with some GUIs on top (in particular, an android app). I would like the core functionality to be a self-contained module that is fully independent from any GUI or other software layer that could be built on top.
The core module is a Gradle project itself:
core
├── src
├── build.gradle
└── settings.gradle
For the app, it is included as a git submodule in a root repository:
project
├── app
│   ├── src
│   └── build.gradle
├── core
│   ├── src
│   ├── build.gradle
│   └── settings.gradle
├── build.gradle
└── settings.gradle
Since the core module is independent and has its own repo, I have to be able to treat it as a Gradle root project; hence it has its own settings.gradle. But when I work in the root project, I want it to behave as a subproject of the latter (so that running gradle in the core directory recognises it as the :core subproject using the settings.gradle in the parent directory). And without changing the contents of core (which will be a git submodule).
I don't want to make a separate branch in core's git repo in which there is no settings.gradle, because in that branch the repo wouldn't make sense on its own, and, again, core shouldn't "need to know anything" about the root project.
The ideal solution would be an alternative version of git submodules in which custom changes to the submodule could be committed to the parent repo alone without affecting the submodule's original repo. (With the ability of merging upstream changes in the submodule with the local commits.) Then I would add one such "local" commit that removes the core/settings.gradle file.
Is there a way to achieve this?
One solution here is to develop all modules as completely separate projects with independent Git repos. Then use Maven to import the core library into project. You should even consider publishing core to a private Maven repository that you can add to your build.gradle file in project.

Resources