Gradle template processing - gradle

I have a gradle build and want to make some text files a bit more dynamic, in the sense that they would always contain the current build's version number. This should be easy peasy once the files are treated as templates and the version number comes as a variable from gradle.
I have tried using Aaron Nies' template plugin like so:
plugins {
id 'application'
id "dev.anies.gradle.template" version "0.0.2"
}
...
tasks.register("template", TemplateTask) {
data += [key: "value"]
from('src/templates')
into('build/templates')
}
But Gradle always complains
Could not get unknown property 'TemplateTask' for project ':app' of type org.gradle.api.Project.
I thought to have stuck to the documentation. What may be wrong here?
BTW, I do not have to use Freemarker Templates at this point. If someone shows how to use the builtin template engine that can replace variables I would accept that as answer as well.

Ok, so I got off the ground using Ant's ReplaceTokenFilter. After all I found the relevant line in the documentation:
https://docs.gradle.org/current/userguide/working_with_files.html#sec:copying_files
Example 36 (Filtering files as they are copied) uses the ReplaceTokenFilter. But unlike so many examples I found on the web it also contains the line
import org.apache.tools.ant.filters.ReplaceTokens
which ultimately made it work for me.
As for the FreeMarkerTemplates I still do not know, but my case is solved.

Related

Validating YAML file in PhpStorm

I'm working on a project where YAMLs are used (among other use cases) for storing synonym lists. A file may look a little like this:
- "streifen,gestreift"
- "fleeceoverall,fleeceanzug"- "federball,badminton"
- "hochgarage,parkgarage"
In this case - "federball,badminton" is on the same row as - "fleeceoverall,fleeceanzug" which causes the build of the application to fail with an error stating
Unexpected characters near "- "federball,badminton".
I tried to configure a code style profile for code inspections as mentioned here in the PhpStorm documentation:
https://www.jetbrains.com/help/phpstorm/customizing-profiles.html?keymap=secondary_default_for_macos
But I don't know what to adjust here. I using the IDE-Standard which looks like this for wrapping and braces (which I guess is what I'm looking for ;) :
I also took a look at validating my YAML against a JSON file as mentioned here: https://www.jetbrains.com/help/phpstorm/yaml.html# but ultimately I don't understand how this works :/
So I guess I'm a little lost on how to avoid the errors at build time beforehand and would love some advice!

conditional include in asciidoc

I am using Spring RestDoc together with AsciiDoc to describe my rest api. RestDoc generates different files depending if there are request parameters described / response fields etc. I would like to have one template conditionally including whatever file exists.
something like this:
Request:
include::{reqresPath}/http-request.adoc[]
Response:
include::{reqresPath}/http-response.adoc[]
Parameters:
ifeval::[{{reqresPath}/request-parameters.adoc}.exists]
include::{reqresPath}/request-parameters.adoc[]
endif::[]
ifeval::[{{reqresPath}/request-parameters.adoc}.exists]
include::{reqresPath}/request-parameters.adoc[]
endif::[]
or at least exclude warnings in case of a missing file. But I could not figure out how to suppress these.
As of today, where is no operator for ifeval available, which can be used to check the existence of a file.
The way I would go is to write an extension for Asciidoctor, which can also be done by using Java. If your projects is big enough, I would suggest to go for this solution.
The most extreme way is to make a custom TemplatedSnippet which is generating an empty snippet to be included...
I hope there is a better way to do this.
Edit:
Take a look of http://asciidoctor.org/docs/user-manual/#by-tagged-regions

How to expand variable into nested directory in maven-archetype

Suppose I have set groupId to com.example, and artifactId to fancy.project, and now I want to create a archetype, such that when created, expands into the following structure:
|--src
|--main
|--com
|--example
|-fancy
|-project
|-App.java
That is, I wonder how to expand a variable into a nested directory.
I understand that the dual-underscore-wrapped variables will be substituted in file/directory names, but I can only get the following with __groupId__.
|--src
|--main
|--com.example
|-fancy.project
|-App.java
As input to the archetype you can specify the package option (which would then follow your input, the groupId and artifactId concatenation if you want, even though it is not always the case and hence provide even more flexibility).
Then, in your archetype you can use the packageInPathFormat option (available since archetype 2.2) which would replace any dot . into slash \ and as such transforming it to a path into the generated project.
However, the option is not officially documented (pity) even though supported and works fine for such a scenario.
Looking at the code, the DefaultFilesetArchetypeGenerator and its getPackageInPathFormat provide the concerned transformation from the package option to a path, while the org.apache.maven.archetype.common.Constants.PACKAGE_IN_PATH_FORMAT is the official entry point for this option.
Some externals pointers on the usage of this option:
http://geekofficedog.blogspot.be/2013/08/creating-maven-archetypes-tutorial.html
http://www.theotherian.com/2012/05/maven-archetypes-part-2-how-do-i-create.html
To further explain:
You can have the __packageInPathFormat__ folder under your src/main/java, for example
The __packageInPathFormat would then be replaced by the package option transforming dots into slashes
The package option has a default value to groupId, so if you don't specify it, for a groupId with value com.sample, the path would be com/sample
You can hence specify at invocation time the package desired via -Dpackage=your.package repeating the values for -DgroupId and -DartifactId (a bit verbose and error prone though), the final result will actually be what you expected (transformed to correct path).
You can specify new default values via a archetype-metada.xml file, as specified in the official documentation, via the requiredProperties section, you could have something like:
<requiredProperties>
<requiredProperty key="package">
<defaultValue>__groupId__.__artifactId__</defaultValue>
</requiredProperty>
</requiredProperties>
However, the generated path would then be com.sample/artifactid rather than com/sample/artifactid. Hence it would not work as expected due to the processing workflow which would replace the placeholders after transforming it to a path (pity!).
(Note: it would transform the dot we provided as configured value, but would then not transform dots into the replaced placeholders).
As of a quick code analysis, seems like the DefaultFilesetArchetypeGenerator class in its generateArchetype method is preparing the context too early (in its prepareVelocityContext method, where the packageInPathFormat is transformed and added to the context), then the context is passed to processArchetypeTemplate* methods which would eventually invoke the Velocity engine (which is going to replace placeholders then). I am not a Velocity expert though, hence I may miss some glue, but the observed behavior and the code workflow seem to lead to this conclusion.
Instead of using the variables __groupId__ and __artifactId__ you can use ${groupId} and ${artifactId} respectively instead (I don't know if these were around when this question was posted), so it would look something like this:
<requiredProperties>
<requiredProperty key="package">
<defaultValue>${groupId}.${artifactId}</defaultValue>
</requiredProperty>
</requiredProperties>
When generating a project using these, in interactive mode it will actually request to enter the package, and in batch mode it will automatically generate CLOSE to what OP wanted.
Ex. groupId being me.zenisbestwolf and artifactId being fancy-app will generate the path of me/zenisbestwolf/fancy-app. Unfortunately automating the artifact ID to go from fancy.app to fancy/app like OP wanted to isn't possible without manually defining the package, AFAIK.

How to simply get custom content into Maven-generated index.html?

In a Maven project with subprojects, each subproject gets an index.html with some content that comes from its POM's description element.
In one of these subprojects, I need that content to contain additional information, including links. There is a section of the doc that suggests I should not do it by trying to put HTML markup in CDATA in the description element (in fact, that doesn't work anyway; the HTML markup just comes out literal). Instead, it suggests there is some better way to get my own content included in the file.
While this element can be specified as CDATA to enable the use of HTML tags
within the description, it is discouraged to allow plain text representation.
If you need to modify the index page of the generated web site, you are able
to specify your own instead of adjusting this text.
Can anyone describe how to do that? I have tried several methods unsuccessfully (I can supply Markdown files with other names and they generate HTML, but a subproject's index.md has no effect on the generated index.html). I have also read about the custom element in site.xml but it seems to require writing a custom Velocity template for the site; I hope the passage "you are able to specify your own" must mean there is some method more straightforward than that.
Of course I would also appreciate a pointer into the docs if there is already an answer I have simply failed to find. (Just pointing me to docs I've already read isn't in itself helpful, though pointing out the answer I missed would be helpful, if it's there.)
In response to inquiries
Directory structure under src/site:
src/site
src/site/resources
src/site/resources/images
src/site/markdown
src/site/markdown/use
src/site/markdown/install
src/site/markdown/examples
src/site/markdown/build
maven-site-plugin version: 3.4
What I mean by 'adding a link':
The part of the index.html that comes from the POM description element
is the central content of the page (not the navigation bar, not the sidebar menus, but the actual content).
I would like that actual-content portion of the page to be able to have a paragraph or two explaining that this is a generated page for developers, and providing links (HTML <a href=...>) for people who arrived at the page from a web search but are really looking for the user-oriented pages.
I can't put that in the description element (even using CDATA), because HTML elements just come out literal. A comment below gives a link to a page on writing a whole custom Velocity template for the site, but is there honestly no simpler way to accomplish this?
I have the same issue. The only thing the generated index.html gives you of value is the list of modules. You can add your own index.md page to src/site/markdown, putting in whatever content you want. To reproduce the list of modules, include something like this:
###Project Modules
This project has declared the following modules:
| Name | Description |
|-|-|
|[Module1 name](module1/index.html)| Module 1 description|
|-|-|
|[Module2 name](module2/index.html)| Module 2 description|
Of course the text is not lifted from the POM. You also have to manually change this file if you have a new module. Not a perfect solution, but the best I could come up with.
Where I wrote:
I can supply Markdown files with other names and they generate HTML,
but a subproject's index.md has no effect on the generated index.html
it turns out the truth is more complex. In a project with subprojects,
there are two places such an index.md might go: in src/site/markdown/subproject-name of the parent project (where all of the other human-written docs for the whole project happen to be), or in a new src/site/markdown directory created within the subproject. A file with any other non-special name can be added in either place, and end up where you expect it in the target. But not for index.md, in that case only the second location can work, and even then, only after a clean.
I had tried both places without success, but trying the second again with a full clean install site site:stage makes it work. Out of the four combinations (parent/clean, parent/noclean, sub/clean, sub/noclean), that was the one I missed trying before posting the question, so of course that's the one that works. :)
If there had been an answer or comment like "hmm, are you sure an index.md in the subproject doesn't work, it works for me?" it probably would have put me quickly back on track. Sometimes after trying several avenues all without success, all that's needed is to know which of them is the one that's supposed to work (if indeed one of them is) and therefore worth spending more time on.

Expressions in a build rule "Output Files"?

Can you include expressions in the "Output Files" section of a build rule in Xcode? Eg:
$(DERIVED_FILE_DIR)$(echo "/dynamic/dir")/$(INPUT_FILE_BASE).m
Specifically, when translating Java files with j2objc, the resulting files are saved in subfolders, based on the java packages (eg. $(DERIVED_FILE_DIR)/com/google/Class.[hm]). This is without using --no-package-directories, which I can't use because of duplicate file names in different packages.
The issue is in Output Files, because Xcode doesn't know how to search for the output file at the correct location. The default location is $(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).m, but I need to perform a string substitution to insert the correct path. However any expression added as $(expression) gets ignored, as it was never there.
I also tried to export a variable from the custom script and use it in Output Files, but that doesn't work either because the Output Files are transformed into SCRIPT_OUTPUT_FILE_X before the custom script is ran.
Unfortunately, Xcode's build support is pretty primitive (compared to say, make, which is third-odd years older :-). One option to try is splitting the Java source, so that the two classes with the same names are in different sub-projects. If you then use different prefixes for each sub-project, the names will be disambiguated.
A more fragile, but maybe simpler approach is to define a separate rule for the one of the two classes, so that it can have a unique prefix assigned. Then add an early build phase to translate it before any other Java classes, so the rules don't overlap.
For me, the second alternative does work (Xcode 7.3.x) - to a point.
My rule is not for Java, but rather for Google Protobuf, and I tried to maintain the same hierarchy (like your Java package hierarchy) in the generated code as in the source .proto files. Indeed files (.pb.cc and .pb.h) were created as expected, with their hierarchies, inside the Build/Intermediates/myProject.build/Debug/DerivedSources directory.
However, Xcode usually knows to continue and compile the generated output into the current target - but that breaks as it only looks for files in the actual ${DERIVED_FILE} - not within sub-directories underneath.
Could you please explain better "Output Files are transformed into SCRIPT_OUTPUT_FILE_X" ? I do not understand.

Resources