Repository: bazelbuild/bazel
Issue: bash completion requires perl
Labels: untriaged
team-Bazel

### Description of the problem / feature request:

The bash completion uses a very small perl invocation in two places:

```
perl -ne 'print uc'
```

https://github.com/bazelbuild/bazel/blob/master/scripts/bazel-complete-template.bash#L151-L170

As far as I understand this uppercases letters. It also introduces a hard dependency on perl to do bash completion. 

### Feature requests: what underlying problem are you trying to solve with this feature?
 
I’d like to get rid of the perl dependency, since it’s only used to uppercase letters.

There is multiple ways to uppercase letters, according to this stackoverflow question:
https://unix.stackexchange.com/questions/51983/how-to-uppercase-the-command-line-argument

You can use `awk`s `toupper`, which handles unicode correctly. `awk` is already used in the `zsh` completions and it has a considerably lower footprint than perl (2MB vs 50MB).
In this case it looks like it’s only used on bazel option names; if we can assume options will only use `[a-z]`, there is a `coreutils` solution: `tr a-z A-Z`.

An additional datapoint: this is the only place `perl` is used in the `scripts/` folder.

Update: A peer noted quite correctly, that Darwin `awk` might not have support for `toupper`, that would have to be investigated.

Issue comments:
We love contributions @Profpatsch :-)
> We love contributions @Profpatsch :-)

I will open a pull request, do you have any preference on what the `perl` interpreter should replaced with? I think we can assume command line arguments will only use ASCII characters, is that correct?
I don't but @aehlig might
> perl -ne 'print uc'
> 
> [...] As far as I understand this uppercases letters. It also introduces a hard dependency on perl to do bash completion. 

Oh, wow. We're using perl, just to convert a string to upper case letters; and not even
any string, as far as I can see this string is just used for commands and options---and those
are, for sure, 7-bit clean prinable ASCII.

In the spirit of not introducing additional dependencies, I vote for the `tr a-z A-Z`
solution, as the script currently depends on `tr(1)` anyway.

-- 
Klaus Aehlig
Google Germany GmbH, Erika-Mann-Str. 33, 80636 Muenchen
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Geschaeftsfuehrer: Paul Terence Manicle, Halimah DeLaine Prado


Pull request review comments:

Patch that resolved the issue:
diff --git a/scripts/bazel-complete-template.bash b/scripts/bazel-complete-template.bash
index d3f89bb6f86544..531e3296d85e6c 100644
--- a/scripts/bazel-complete-template.bash
+++ b/scripts/bazel-complete-template.bash
@@ -154,7 +154,8 @@ _bazel__package_path() {
 _bazel__options_for() {
   local options
   if [[ "${BAZEL_COMMAND_LIST}" =~ ^(.* )?$1( .*)?$ ]]; then
-      local option_name=$(echo $1 | perl -ne 'print uc' | tr "-" "_")
+      # assumes option names only use ASCII characters
+      local option_name=$(echo $1 | tr a-z A-Z | tr "-" "_")
       eval "echo \${BAZEL_COMMAND_${option_name}_FLAGS}" | tr " " "\n"
   fi
 }
@@ -164,7 +165,8 @@ _bazel__options_for() {
 _bazel__expansion_for() {
   local options
   if [[ "${BAZEL_COMMAND_LIST}" =~ ^(.* )?$1( .*)?$ ]]; then
-      local option_name=$(echo $1 | perl -ne 'print uc' | tr "-" "_")
+      # assumes option names only use ASCII characters
+      local option_name=$(echo $1 | tr a-z A-Z | tr "-" "_")
       eval "echo \${BAZEL_COMMAND_${option_name}_ARGUMENT}"
   fi
 }


Test patch: