How to disable gradle task name abbreviation?

Is there a way to disable task name abbreviation?

I find it very confusing when it happens with some build scripts that have similar task names. I get confused a lot when I mistype the task name and Gradle still runs a task (possibly a wrong one!). I’d rather have gradle fail than trying to correct me.

Sort of. I’m not sure if this catches every case, but it seems to work.

I think this does break any other rule we add (e.g., for build* and clean*).

tasks.addRule("Note: This build does not allow task abbreviations.") { requestedName ->
    if (!tasks*.name.find { it == requestedName }) {
        throw new GradleException("Could not find a task defined with name $requestedName")
    }
}

You might be able to do something fancier and look for only abbreviated tasks that could be confused with other tasks.

How about an option to disable that feature in the source directly? I see the TaskSelector and the TaskNameResolver? Are there a couple of points of control for command line abbreviations and case insensitivity, or is it in many places?

I think all the magic is done by NameMatcher, which is only used to find abbreviated project and task names.

I know we’ve talked about the ergonomics of some of the native task names (abbreviations are useful there just because they’re so long). I don’t know if there’s been any talk about disabling abbreviations altogether.

I think I’d like to see better CLI support for autocomplete, but I’m not sure if there are any strong opinions about making this configurable somehow (e.g., something like org.gradle.daemon).

The best I could offer right now is before adding that rule to disable abbreviations, see if you can come up with some better/more memorable lifecycle task names and just alias those, e.g.,

task betterName(dependsOn: "hardToTypeOutLongName", group: "Easy Names")

Then you can use ‘betterName’ over ‘hardToTypeOutLongName’.

If you come across any really badly named tasks that we’re creating, feel free to suggest better alternatives (gradle-dev might be better for that).

Selecting good names matters, but the reality is that first and foremost, syntactically correct names, good, bad or ugly, should work at all times, unambiguously. I will do weird things as I learn any language, such as using poor variable names, intentionally or not: it’s part of the learning, it’s part of bending my mind to think like the compiler of that language.

Now for a personal opinion: Aliases and abbreviations are sugar: I ignore them as long as they don’t cause confusion, they don’t prevent valid syntax from working, and they don’t hide potential problems. But I have found a scenario where task abbreviation lets a type of problem slip through silently, so I think there should really be a way to disable it.

Here is an example of an error prone scenario involving task abbreviation. Consider this build file:

apply plugin: 'distribution'
  task binaryFiles1(type: Tar) {
  from('.') {
    include 'file.bin'
  }
  destinationDir(libsDir)
}
  artifacts {
  archives binaryFiles1
}
  distributions {
  binaryFiles {
    contents {
      from(libsDir) {
        include binaryFiles1.archiveName
      }
    }
  }
}

Now we type: ‘’‘gradle binaryFiles’’’

:binaryFiles1 UP-TO-DATE
  BUILD SUCCESSFUL
  Total time: 0.959 secs

Gradle ran ‘’‘binaryFiles1’’’, but it happens that it is a user error, the user really wanted ‘’‘binaryFilesDistTar’’’. But it goes unnoticed as Gradle does not throw an error.

This error is even harder to find when Gradle is called from inside another script and the task name is a variable:

#!/bin/bash
...
gradle $theTask
...

I think that having the ability to disable task abbreviation helps find bugs faster in this kind of scenario and that this scenario is not uncommon.

Ah, that’s a bug. We shouldn’t allow abbreviations to work when it’s ambiguous like that.

We have a similar situation with the ‘java’ plugin. We have ‘compileJava’ and ‘compileTestJava’ and you can’t just use ‘compile’ since it’s ambiguous. That seems to be working, but your example definitely doesn’t. If I change your task name to ‘binaryFilesA’ instead of ‘binaryFiles1’, I get the ambiguous error.

Thanks for finding this.

You are welcome.

If I wanted to disable task abbreviation, is this the right place:

public class NameMatcher {
                                                                                                                    ....
    public String find(String pattern, Collection<String> items) {
                                                                                this.pattern = pattern;
                                                                                                                   matches.clear();
                                                                                                                          candidates.clear();
                                                                                                                                                                                                                                                                   if (items.contains(pattern)) {
                                                                                                                matches.add(pattern);
                                                                                                                     return pattern;
                                                                                                                       }
          // Can I return here if there is no match and the command line has --no-task-abbrev?
        // Or will this bypass computed task name look ups?
        // In other words, is the Collection the complete list of all possible tasks?

I still have to find how to lookup how the presence of a command line arg is detected.

What are the chances that this feature request be accepted?

I raised GRADLE-3258 for the issue you found.

I think you should send a note to gradle-dev and see what everyone else thinks. I think they’d be against a command-line switch to turn it off just because it’s such a low-level thing.