jmeter-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Vladimir Sitnikov <sitnikov.vladi...@gmail.com>
Subject Re: Migrating build system to Gradle
Date Sun, 10 Mar 2019 16:29:40 GMT
sebb>What are the inputs and what are the outputs?

There are multiple tasks there. What do you mean by "inputs/outputs"?

In fact, in Gradle you can invoke a task at ANY moment, and it would
automatically build all the prerequisites.

The output of "Tar / Zip" file is a relevant archive file. The output
of Copy tasks are files/directories specified in the relevant "into"
folder.
I guess that does not require clarifications.

sebb>I find it really hard to work out what is happening.
sebb>As a particular example, I think it has insufficient documentation.
sebb>For example, why does depencies include:
sebb>compile(Libs.log4j_slf4j_impl)

Well, I've added the comment there. I agree "the reason why
log4j-slf4j-impl was added for distribution" does not immediately
follow from the source code.

However I guess it was the only part of src/dist/build.gradle.kts that
needed extra comments.
The rest is either commented or it is just obvious from the code.

sebb, could you please clarify exactly what you are failing to follow?
Feel free to post comments at GitHub PR or in this thread.

I'm proficient in Ant (I have written macrodefs, and custom Ant
tasks), however it was really tough for me to follow current
exclude-include logic.
For instance: can you tell me why current JMeter artifacts do not
include bin/threaddump.cmd file?
The file is missing in both binary and source artifacts for some
reason. I learned that when I did a quick comparison of
Gradle-generated archive with the one from the site.

I was not able to understand _pack-binaries and friends.
I just gave up, and what I did was:
1) I've downloaded JMeter artifacts
2) I've reimplemented that in Gradle. In other words, I just added
files a folder by folder.

sebb>I think that depends on knowing how Gradle works.

Of course it requires certain skills (remember, Ant requires knowing
how Ant works, doesn't it?).
However Gradle is way way easier to follow than current Ant logic.

Let us compare the ways to produce binary artifacts?
Here is the target to prepare binary artifacts in Ant:

<target name="_pack-binaries">
  <property name="pack.name" value="${dist.name}_bin"/>
  <mkdir dir="${dist.dir}"/>
  <tar destfile="${dist.dir}/${pack.name}.tar" longfile="gnu">
    <tarfileset dir="." prefix="${dist.name}"
excludes="${dist.executables}" defaultexcludes="yes">
      <patternset refid="dist.binaries.native"/>
    </tarfileset>
    <tarfileset dir="." prefix="${dist.name}"
excludes="${dist.executables}" defaultexcludes="yes">
      <patternset refid="dist.binaries.non.native"/>
    </tarfileset>
    <tarfileset mode="755" includes="${dist.executables}" dir="."
prefix="${dist.name}" defaultexcludes="yes"/>
  </tar>
  <gzip destfile="${dist.dir}/${pack.name}.tgz"
src="${dist.dir}/${pack.name}.tar" />
  <!-- no longer needed -->
  <delete file="${dist.dir}/${pack.name}.tar"/>
  <zip  destfile="${dist.dir}/${pack.name}.zip">
    <zipfileset dir="." prefix="${dist.name}" defaultexcludes="yes">
      <patternset refid="dist.binaries.native"/>
    </zipfileset>
    <zipfileset dir="." prefix="${dist.name}" defaultexcludes="yes">
      <patternset refid="dist.binaries.non.native"/>
    </zipfileset>
  </zip>
</target>

Here's how task definition look in Gradle:

val distZip by tasks.registering(Zip::class) {
    group = distributionGroup
    description = "Creates binary distribution with CRLF line endings
for text files"
    dependsOn(populateLibs)

    archiveBaseName.set("apache-jmeter")
    with(binaryLayout(LineEndings.CRLF))
}

val distTar by tasks.registering(Tar::class) {
    group = distributionGroup
    description = "Creates binary distribution with LF line endings
for text files"
    compression = Compression.GZIP
    dependsOn(populateLibs)

    archiveBaseName.set("apache-jmeter")
    with(binaryLayout(LineEndings.LF))
}

I claim Gradle is way less verbose. It does contain comments (which
happens to be task description), so the tasks look decent in "gw
tasks" output.
In fact, I'm sure this code does not need other comments. It is quite
obvious even for those who see Kotlin for the first time.

Of course you might say that I'm cheating by placing all the funny
logic into binaryLayout function.

Here it follows. "into" specifies a folder in the destination archive
while "from" specifies the path to get files from (which is more or
less obvious, isn't it?)

val baseFolder = "apache-jmeter-${rootProject.version}"

fun binaryLayout(textEol: LineEndings) = copySpec {
    into(baseFolder) {
        with(licenseNotice(textEol))
        with(commonFiles(textEol))
        into("bin") {
            with(binLibs)
        }
        into("lib") {
            with(libs)
            into("ext") {
                with(libsExt)
            }
        }
        with(printableDocumentation(textEol))
        into("docs/api") {
            from(javadocAggregate, textEol) {
                text("**/*") // all except binary
                binary("**/*.zip", "**/*.png")
            }
        }
    }
}

What it does it just specifies which files go into which folders.
It does specify which files are binary and which are text ones.
That's it.

I'm afraid Ant counterpart is a complete mess.

Vladimir

Mime
View raw message