What is the purpose of gradle's buildSrc folder? - configuration

In gradle, what is the purpose of using a buildSrc file as a top level, as opposed to just a typical java project layout (src/main/java)?
If I have a layout of
src
main
java
or
buildSrc
src
main
java
What would be the difference (or the reason for doing this)? Is it more useful in multi module projects? Even for a multi module project, couldn't I do something like
proj1
src
proj2
src
And then just have a top level build.gradle (at the same level as proj1 and proj2) that defines common settings across the projects?

buildSrc is a separate build whose purpose is to build any tasks, plugins, or other classes which are intended to be used in build scripts of the main build, but don't have to be shared across builds.(*) It wouldn't be possible to build such classes as part of the main build, because they have to exist before the main build's build scripts can even be compiled/evaluated, and Gradle compiles/evaluates all build scripts before it does any work (configuration vs. execution phase).
Compared to putting all build code into build scripts, buildSrc gives you a way to develop build code more like regular code, as classes that you can test, import into your IDE, etc. It is one way to keep build scripts simple and DRY even for more complicated builds.
buildSrc is more often seen in multi-project builds simply because larger builds are more likely to implement their own custom tasks and plugins.
Over time, buildSrc will grow into a more general capability of executing multiple dependent builds in a single Gradle invocation.
(*) Sharing classes across builds is possible but more involved. In particular, you'll need to publish the classes to a repository, and consuming builds have to explicitly import them from there, similar to when sharing production libraries between builds.

In gradle, what is the purpose of using a buildSrc file as a top
level, as opposed to just a typical java project layout
(src/main/java)?
You can definitely do this. It is known as a composite build in gradle, but you have to tell Gradle to include any builds from that folder. A unique property of a top-level buildSrc folder is that gradle automatically treats it as an included build.
Note that even though buildSrc is treated as a composite build, it is not visible in the list of included builds when you run gradle.getIncludedBuilds(). I believe the reason is because the list is reserved for builds which you manually included in your settings.gradle.
For you to also include src/main/java as a composite build, you have to run your gradle script using the --include-build flag, followed by the path to src/main/java. This is an unusual place for an included build, but gradle won't complain.
And then just have a top level build.gradle (at the same level as
proj1 and proj2) that defines common settings across the projects?
You CAN have a top-level build.gradle at the same level as your proj1, and proj2 sub-projects. This is typically how most multi-project projects are structured.
As another answer already highlighted, the purpose of the buildSrc project is to create custom plugins or tasks which is meant to be shared locally among the different projects in your build. This is not to imply that you cannot create those custom tasks and plugins in your top-level build.gradle. You can do it this way, but the problem is that you will not be able to use it in any of your sub-projects.
Remember that being able to import something in java/groovy requires that thing to exist in a proper java/groovy file (or module for java 9+). Seeing as your build.gradle is simply a script, it is not arbitrary to simply import a plugin or task from it.
As I have already pointed out and this is from the Gradle docs, one of the reasons for having a buildSrc directory is:
Upon discovery of the directory, Gradle automatically compiles and
tests this code and puts it in the classpath of your build script.
As you can see, the buildSrc acts as an extension of your build process in that it can add additional functionality to all your project's build scripts.
A few more points:
Any dependencies declared in your buildSrc/build.gradle is visible to the rest of the build scripts in your project.
The buildscript block in your buildSrc/build.gradle is only visible to buildSrc/build.gradle and nothing else.
Any plugin class defined in buildSrc can be used in any build script in your project, and does not need to be declared in a META-INF/gradle-plugins.
Any dependencies defined in your main build.gradle or any of your subprojects is not visible in buildSrc. If you remember that this folder is treated as an included build (i.e. external), it should make sense why it cannot see the classpath of the project that includes it.

Related

Bundle assets with libGDX dependency

I'm making a card game engine on top of libGDX for many similar games I plan to make. Here's how I plan to structure this: each game is a separate project and the engine is a dependency added to the core module. The engine itself will have a lot of assets like card sprites and other UI elements, and they need to be included too.
How can I make that structure work? Is there any way to make a dependency include its assets? The alternative is to duplicate all assets for each game which I don't think is very efficient. Also the assets are in the android module by default, which the engine dependency doesn't have (the engine is a single module). Where do I put the assets in the engine module?
We have a setup that seems similar to what you've outlined above with a "many to one" relationship of projects to assets. Here's a potential way to go about it.
The basic idea is:
Have a single, authoritative assets folder
Have individual projects copy this folder to their build output at build time
Accomplish this by having a project's compile task dependsOn or be finalizedBy a copy task.
Ensure that the Android and other projects are happy by copying the assets to the place that libgdx's internal File APIs look for that particular type of project. (For example, android projects automatically get an assets/ prepended to the URI provided to Gdx.files.internal(). This step is more dependent on your personal file structure, so it may take a little tweaking to get the pathing right for all projects, but don't get discouraged!
Side-note: Gradle should automatically track whether or not the assets dir actually changed. If nothing's been updated, then the copy tasks will effectively become no-ops, which speeds up the build quite a bit for non-first runs. Obviously if you do a cleanAssets like I mention below, then this won't apply.
The advantage of this approach (to me anyway) is that it no longer relies on cross-project links or funky classpath manipulation. It's just real files in real directories. The downside is that it increases the disk space used because there can be multiple physical copies of the assets in the various projects.
The following is not a complete example, but should hopefully give you enough to go by.
Example of a copy task in action. This particular one takes an assets dir from a "core" project and copies it into an android project.
android/build.gradle
task copyAssets(type: Copy) {
from "../core/assets"
into "./assets"
}
Example of how to make the android project's build depend on this task:
android/build.gradle
afterEvaluate { project ->
project.tasks.preDebugBuild {
dependsOn copyAssets
}
project.tasks.preReleaseBuild {
dependsOn cleanAssets
finalizedBy copyAssets
}
}
You'll notice in the preReleaseBuild I added a cleanAssets task as well. It's always a good idea to clean up any junk and do a fresh copy during a production build. cleanAssets is just a basic Delete task.
Example of a copy task dependency for a non-android project:
build {
finalizedBy copyAssets
}
If you're still stuck, let me know where and I'll try to help.
Do it like libgdx does itself. There are assets included in the classpath, like arial-15.fnt which is located in the core project at gdx/src/com/badlogic/gdx/utils/. Take a look at BitmapFont's no-param constructor how it is referenced.

Grav's asset manager can fully replace a need for gulpjs?

GravCMS has it's own asset manager: https://learn.getgrav.org/themes/asset-manager
It can minify, concatenate js/scss files.
Is it better to do such tasks via gulp (gulp-sass, gulp-concat, gulp-uglify), rather than using built-in asset manager in Grav?
Well I don't have any experience with the grav asset manager. But since you want to do grav-related tasks, I'd recommend to use the built in manager, as long as it can cover all your needs.
I don't see any benefit of using and adding an extra dependency in gulp/grunt or any other build tool.
The only time I'd consider using gulp is, if you already have an existing project with a gulp configuration and you can re-use it and have complex logic.
However probably you just want to minify/concatenate files. So the built in asset manager is the way to go

How to allow web-component-tester to run tests stored with my components

I am experimenting with the framework to build an SPA using polymer. This will include a large number of custom elements at various levels in the overall application hierarchy. I would like to use web-component-tester to run the module tests on them.
web-component-tester seems to be opinionated about where the tests will be stored - in a separate test directory, where it will run all files found.
I am of an opposite opinion. I would like to store tests in the same directory as the element definition. I would like to differentiate tests by naming them xxx.test.html (or possibly xxx.test.js). I also want to run different "sets" of tests controlled by gulp some of which will be watching for changes and then running the tests (for the app side of my project) and some of which will be elements that use core-ajax to unit test my server side scripts. These will more than likely be in a totally different directory hierarchy (my dist directory) and will be served by a proper web server.
I "think" the "suite" config option wct-conf.js file in my project root might be how I can define this, or alternatively a wct command with some file globs. Unfortunately web-component-tester's README is somewhat confusing on any detail and when you have your own web server it says "You'll need to save WCT's browser.js in order to go this route." What does that mean?
Can someone enlighten me on how can get WCT to run each of the elements/**/*.test.html files as its own "suite" ( I actually intend to use describe, it format - but I assume I still need to use the term suite).
Can someone also explain what I need to do the browser.js when I have my own web server.
I ran some experiments and did a bit of debugging with node-inspector. Firstly, the command line overwrites the suites parameter in the config file
wct app/elements**/*.test.html
does find all my module tests if I have them stored with the elements and ignores the contents of the wct.conf.js file's suites parameter.
also putting the same value (ie app/elements/**/*.test.html) in the wct-conf.js file for the suite parameter does the same job. In fact in this mode, gulp test:local
Also works correctly
So to run different tests for module and distribution, I just need to set up for wct.conf.js for my module tests, and set up gulp to run a command line with the correct location of my test file
I still haven't understood the instructions for running with your own web server.

RazorGenerator.MsBuild - Achieving harmony from Developer machine to Buildserver

We are currently using the RazorGenerator library to generate pre-compiled views for a project. Up until now we have been using the Visual Studio Extension to handle the generation, with these generated files also being committed to our repository.
This is causing bit of a pain point as we constantly have to resolve merge defects in a generated file. With that in mind I've set about to try and integrate the RazorGenerator.MsBuild target library into our build process so we can get away from storing the code-genned files in our repository.
So far I've disabled the VS Extension, and got the build target working as required however I've now lost intellisense and resharper support for the generated files as they are no longer part of the Solution.
I'm wondering if anyone else has come down this path before, Ideally what I'm trying to achieve is using the Build target to generate the cs files, removing the need to include these cs files in the repository, and still having Intellisense/Resharper coverage for the generated files.
Any thoughts?
I've resolved this problem by creating a an empty partial class for each of the cshtml templates which implements our own base class, which in-turn implements RazorGenerator.Templating.RazorTemplateBase.
By doing it this way we have access to all the publicly accessible properties and methods exposed on those classes which makes intellisense/resharper happy and at build time the templates .cs files are generated which do the heavy lifting for outputting the layout etc.

What should NOT be under source control?

It would be nice to have a more or less complete list over what files and/or directories that shouldn't (in most cases) be under source control. What do you think should be excluded?
Suggestion so far:
In general
Config files with sensitive information (passwords, private keys etc.)
Thumbs.db, .DS_Store and desktop.ini
Editor backups: *~ (emacs)
Generated files (for instance DoxyGen output)
C#
bin\*
obj\*
*.exe
Visual Studio
*.suo
*.ncb
*.user
*.aps
*.cachefile
*.backup
_UpgradeReport_Files
Java
*.class
Eclipse
I don't know, and this is what I'm looking for right now :-)
Python
*.pyc
Temporary files
- .*.sw?
- *~
Anything that is generated. Binary, bytecode, code/documents generated from XML.
From my commenters, exclude:
Anything generated by the build, including code documentations (doxygen, javadoc, pydoc, etc.)
But include:
3rd party libraries that you don't have the source for OR don't build.
FWIW, at my work for a very large project, we have the following under ClearCase:
All original code
Qt source AND built debug/release
(Terribly outdated) specs
We do not have built modules for our software. A complete binary is distributed every couple weeks with the latest updates.
OS specific files, generated by their file browsers such as
Thumbs.db and .DS_Store
Some other Visual Studio typical files/folders are
*.cachefile
*.backup
_UpgradeReport_Files
My tortoise global ignore pattern for example looks like this
bin obj *.suo *.user *.cachefile *.backup _UpgradeReport_Files
files that get built should not be checked in
I would approach the problem a different way; what things should be included in source control? You should only source control those files that:
( need revision history OR are created outside of your build but are part of the build, install, or media ) AND
can't be generated by the build process you control AND
are common to all users that build the product (no user config)
The list includes things like:
source files
make, project, and solution files
other build tool configuration files (not user related)
3rd party libraries
pre-built files that go on the media like PDFs & documents
documentation
images, videos, sounds
description files like WSDL, XSL
Sometimes a build output can be a build input. For example, an obfuscation rename file may be an output and an input to keep the same renaming scheme. In this case, use the checked-in file as the build input and put the output in a different file. After the build, check out the input file and copy the output file into it and check it in.
The problem with using an exclusion list is that you will never know all the right exclusions and might end up source controlling something that shouldn't be source controlled.
Like Corey D has said anything that is generated, specifically anything that is generated by the build process and development environment are good candidates. For instance:
Binaries and installers
Bytecode and archives
Documents generated from XML and code
Code generated by templates and code generators
IDE settings files
Backup files generated by your IDE or editor
Some exceptions to the above could be:
Images and video
Third party libraries
Team specific IDE settings files
Take third party libraries, if you need to ship or your build depends on a third party library it wouldn't be unreasonable to put it under source control, especially if you don't have the source. Also consider some source control systems aren't very efficient at storing binary blobs and you probably will not be able to take advantage of the systems diff tools for those files.
Paul also makes a great comment about generated files and you should check out his answer:
Basically, if you can't reasonably
expect a developer to have the exact
version of the exact tool they need,
there is a case for putting the
generated files in version control.
With all that being said ultimately you'll need to consider what you put under source control on a case by case basis. Defining a hard list of what and what not to put under it will only work for some and only probably for so long. And of course the more files you add to source control the longer it will take to update your working copy.
Anything that can be generated by the IDE, build process or binary executable process.
An exception:
4 or 5 different answers have said that generated files should not go under source control. Thats not quite true.
Files generated by specialist tools may belong in source control, especially if particular versions of those tools are necessary.
Examples:
parsers generated by bison/yacc/antlr,
autotools files such as configure or Makefile.in, created by autoconf, automake, libtool etc,
translation or localization files,
files may be generated by expensive tools, and it might be cheaper to only install them on a few machines.
Basically, if you can't reasonably expect a developer to have the exact version of the exact tool they need, there is a case for putting the generated files in version control.
This exception is discussed by the svn guys in their best practices talk.
Temp files from editors.
.*.sw?
*~
etc.
desktop.ini is another windows file I've seen sneak in.
Config files that contain passwords or any other sensitive information.
Actual config files such a web.config in asp.net because people can have different settings. Usually the way I handle this is by having a web.config.template that is on SVN. People get it, make the changes they want and rename it as web.config.
Aside from this and what you said, be careful of sensitive files containing passwords (for instance).
Avoid all the annoying files generated by Windows (thumb) or Mac OS (.ds_store)
*.bak produced by WinMerge.
additionally:
Visual Studio
*.ncb
The best way I've found to think about it is as follows:
Pretend you've got a brand-new, store-bought computer. You install the OS and updates; you install all your development tools including the source control client; you create an empty directory to be the root of your local sources; you do a "get latest" or whatever your source control system calls it to fetch out clean copies of the release you want to build; you then run the build (fetched from source control), and everything builds.
This thought process tells you why certain files have to be in source control: all of those necessary for the build to work on a clean system. This includes .designer.cs files, the outputs of T4 templates, and any other artifact that the build will not create.
Temp files, config for anything other than global development and sensitive information
Things that don't go into source control come in 3 classes
Things totally unrelated to the project (obviously)
Things that can be found on installation media, and are never changed (eg: 3rd-party APIs).
Things that can be mechanically generated, via your build process, from things that are in source control (or from things in class 2).
Whatever the language :
cache files
generally, imported files should not either (like images uploaded by users, on a web application)
temporary files ; even the ones generated by your OS (like thumbs.db under windows) or IDE
config files with passwords ? Depends on who has access to the repository
And for those who don't know about it : svn:ignore is great!
If you have a runtime environment for your code (e.g. dependency libraries, specific compiler versions etc.) do not put the packages into the source control. My approach is brutal, but effective. I commit a makefile, whose role is to downloads (via wget) the stuff, unpack it, and build my runtime environment.
I have a particular .c file that does not go in source control.
The rule is nothing in source control that is generated during the build process.
The only known exception is if a tool requires an older version of itself to build (bootstrap problem). In that case you will need a known good bootstrap copy in source control so you can build from blank.
Going out on a limb here, but I believe that if you use task lists in Visual Studio, they are kept in the .suo file. This may not be a reason to keep them in source control, but it is a reason to keep a backup somewhere, just in case...
A lot of time has passed since this question was asked, and I think a lot of the answers, while relevant, don't have hard details on .gitignore on a per language or IDE level.
Github came out with a very useful, community collaborated list of .gitignore files for all sorts of projects and IDEs that is worth taking a look.
Here's a link to that git repo: https://github.com/github/gitignore
To answer the question, here are the related examples for:
C# -> see Visual Studio
Visual Studio
Java
Eclipse
Python
There are also OS-specific .gitignore files. Following:
Windows
OS X
Linux
So, assuming you're running Windows and using Eclipse, you can just concatenate Eclipse.gitignore and Windows.gitignore to a .gitignore file in the top level directory of your project. Very nifty stuff.
Don't forget to add the .gitignore to your repo and commit it!
Chances are, your IDE already handles this for you. Visual Studio does anyway.
And for the .gitignore files, If you see any files or patterns missing in a particular .gitignore, you can open a PR on that file with the proposed change. Take a look at the commit and pull request trackers for ideas.
I am always using www.gitignore.io to generate a proper one .ignore file.
Opinion: everything can be in source control, if you need to, unless it brings significant repository overhead such as frequently changing or large blobs.
3rd party binaries, hard-to-generate (in terms of time) generated files to speed up your deployment process, all are ok.
The main purpose of source control is to match one coherent system state to a revision number. If it would be possible, I'd freeze the entire universe with the code - build tools and the target operating system.