Repository: bazelbuild/bazel
Issue: Documentation/behavior mismatch with alias + config_setting
Labels: type: documentation (cleanup)
P3
team-Configurability

### Description of the problem / feature request:
The [documentation](https://docs.bazel.build/versions/master/be/general.html#alias) claims that:
> Aliasing only works for "regular" targets. In particular, package_group, config_setting and test_suite rules cannot be aliased.

However, this does not seem to be accurate, at least for `config_setting`. You can create an `alias` with `actual` set to a `config_setting`, and then the `alias` may be used as a condition itself.

Is this a documentation bug or is this not supposed to work (or does it not work in some subtle way that I'll discover down the line)?

The context is that I would like to turn "raw" `config_setting`s  into something more akin to feature flags, where several different possible values for a setting map to a single condition that makes more sense for consumers. Aliasing works for this case although it seems a bit hacky; if there's a better way to achieve the same thing I'd be interested to know.

### Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

Full reproducer [here](https://github.com/jfancher/bazel-issues/tree/alias_config_setting). 

### What operating system are you running Bazel on?

macOS 10.13.2

### What's the output of `bazel info release`?

`release 0.18.0`

###  Have you found anything relevant by searching the web?

No


Issue comments:
Confirmed the behavior you're seeing.

From what I can see from the review history, it looks like there was never any design intention to exclude config_setting from aliases. Pinging @lberki for confirmation or rebuttal.

As to your deeper goal, that's an interesting use of the feature. It seems like another variant of [OR chaining](https://docs.bazel.build/versions/master/configurable-attributes.html#or-chaining). Do you see this as bringing novel functionality even beyond that?
Thanks for the reply.

OR chaining would work, but what I'm trying to achieve is to define the OR in only one place, and have other places use the result of it. I guess you could probably define a constant or macro and then reuse it, but that's awkward compared to the below, which allows consumers to consider it as any other `config_setting`.

The concrete example I added was this:
```python
alias(
    name = "modules_enabled",
    actual = select({
        ":java9": ":java9",
        ":java11": ":java11",
        # rhs just needs to be anything that won't match
        # :java11 will not match if we get to here
        "//conditions:default": ":java11",
    }),
)
```

We have Java runtimes/toolchains controlled by a `--define` flag. Sometimes libraries need to add module-related `javacopts`; this allows them to do:
```python
java_library(
    name = "lib",
    javacopts = select({
         "//tools/java:modules_enabled": ["--add-exports=..."],
         "//conditions:default": [],
   }),
)
```
This is the cleanest solution I found for this issue. The `alias` itself is kinda hacky as I mentioned, but it's worth it so that all consumers have a single intuitive flag to switch on for this behavior.

I could be missing a better answer, which I'd be happy to adopt.
Without engaging with the meat of the bug report, whether aliasing works is different for each rule you mentioned above:
 * `config_setting` should just work, I think it's a documentation bug
 * `package_group` may or may not work -- they are regrettably a little different from regular configured targets, so I wouldn't be surprised if there is a bug lurking somewhere that prevents them from working with `alias`, but I see no fundamental reason for them not to. I'd prefer them to be regular rules since they are special mostly for historical reason and then this wouldn't even be a question.
* `test_suite` is special-cased in a few places, so I'd be even less surprised if `alias` did not work for them than for `package_group`. It should, though.
This approach doesn't look bad to me at all, and I think probably fits your use case as good as you're going to get.

Re: the documentation: what wording would you find clearer given the the comment above? Happy to patch or take a patch from you.
Sorry, was that last question for me? I'm not sure I have enough context to answer -- I don't know what constitutes a 'regular' rule.

From a little more experimentation, neither `package_group` nor `test_suite` may be aliased. However:
- `package_group` is listed as a function, not a rule, so I'm not sure why there's the expectation that it would work in the first place.
- `test_suite` doesn't error or anything, it just doesn't run the tests. That seems to be covered by the next part of the doc that says "Tests are not run if their alias is mentioned on the command line."

So maybe the whole line is redundant and could be removed?
Yeah, removing the line sounds easiest. Will do...

Pull request review comments:
Are you sure this works for `package_group` and `test_suite`? Is this functionality tested? `test_suite` rules are (unfortunately) special-cased in a number of ways e.g. in `bazel query` and other places expanding them (unfortunately, we have more than one) and I have no idea whether aliases are taken into account there.
For `package_group` and `test_suite` I'm following the thought process described at https://github.com/bazelbuild/bazel/issues/6449#issuecomment-433712899.
I think you are technically correct, but the fact that `package_group` is not a proper rule is a very obscure piece of information (except for us who have worked on Bazel since forever) and `test_suite` *is* a rule. Why not call this out explicitly?

(btw, `package_group` totally should be a rule. Totally my fault that it's not.)
Call out what explicitly? Like, don't get into the details that `package_group` and `test_suite` are "special" but call them out.. how?

I don't mind adding some simple tests to check that alias works in a standard build use, but I wouldn't be enthused to check all the corner cases with query and who knows where else. :p
Updated to just remove reference to `config_setting`, which is really the point of the bug. There's no evidence the comments on `package_group` and `test_suite` are confusing people, so let's just leave them be.

Patch that resolved the issue:
diff --git a/src/main/java/com/google/devtools/build/lib/rules/Alias.java b/src/main/java/com/google/devtools/build/lib/rules/Alias.java
index ed8d164f02a61d..806a91199e954d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/Alias.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/Alias.java
@@ -94,8 +94,8 @@ public Metadata getMetadata() {
 </p>
 
 <p>
-  Aliasing only works for "regular" targets. In particular, <code>package_group</code>,
-    <code>config_setting</code> and <code>test_suite</code> rules cannot be aliased.
+  Aliasing only works for "regular" targets. In particular, <code>package_group</code>
+  and <code>test_suite</code> cannot be aliased.
 </p>
 
 <p>


Test patch: