What's the timeframe for this? Personally I strongly prefer a solution that does not expose the version string, but maybe your proposal is the best we can do. In any case, I'm a little nervous as a rules author (OBazl) and I'd like a little more time to study this. (I confess I have not actually used either repo_mapping or bzlmod yet). FWIW OCaml has a similar problem, a flat namespace and ensuing name clashes. The solution was to allow (OCaml) module aliasing and leave it to the build tools to make it all work.
Aside from the pros and cons of your proposal the documentation could use some work. I suspect this is one of those areas where the documentation is harder to write than the code. Some observations and suggestions:
* "Dependency" and its cognates are overloaded and confusing (to me). Suggest "module dep" (mdep?) and "target dep" (tdep) where appropriate.
* "Repository name". We have repo names, module names, name and
repo_name attributes, module aliases (mappings), version strings,
"the directory name the repository lives in", etc. It's all very
confusing.
* Repository mapping v. (bzlmod) indexing
"Repository mapping" is a legacy featurebug. It is expressed via
attribute "repo_mapping", which is defined for native repo rules
"local_repository" and "new_local_repository", and is implicitly
defined for user-defined repo rules.
Semantically, a repo mapping is an unconstrained alias. It allows the
user to map a repo name (not label) to any other valid repo name. Really should be renamed "module_alias" but I suppose that's a non-starter.
Bzlmod introduces a "bazel_dep" rule, which indirectly serves a
similar purpose. It (implicitly) declares a "canonical repository name" from the
bazel_dep attributes. But the documentation is not clear. It gives a
template "module_name.version"; but where does the module_name come
from? "bazel_dep" has a "name" attribute, but it also has a
"repo_name" attribute - which one is used? Or does this refer to the
"name" and "version" attributes of the "module" rule? What happens if the module is aliased? Either way, why
call this "canonical repository name" instead of "canonical module
name"?
More generally: if we're switching from WORKSPACE.bazel and repos to
MODULE.bazel and modules, then the documentation should be consistent:
modules not repositories.
From
https://bazel.build/docs/bzlmod#repository-names:
"Canonical repository name: The globally unique repository name for
each repository. This will be the directory name the repository lives
in." I don't know what this means. Maybe it's just a mistake; don't
repository (module?) names come from attributes?
"Local repository name: The repository [module?] name to be used in the BUILD
and .bzl files within a repo. The same dependency could have different
local names for different repos." Don't know what that last sentence
means. Does it mean "different repos can use different names for the
same dependency"?
"For Bazel module repos: module_name by default, or the name specified
by the repo_name attribute in bazel_dep." Which is it? And
again, where does module_name come from? What if it's aliased?
An attempt to articulate the problem(s) a little more clearly:
* Modules not repositories. At the very least we need clear, simple,
unambiguous etc. definitions of both terms.
* "Name" should mean name, not name plus version. @foo.1.2.3 should be called an "indexed module name", not a module name (see below).
* "Module" can be thought of as a "family of modules indexed by
version string". A member of that family (version of the module) is
identified by an "Indexed Module Name" or IMN, which is
name plus version string. So @foo names a "module" (= family of modules) whose
members are @foo.1, @foo.2, etc. To be clear: @foo.1 and @foo.1 are separate modules (in the @foo family).
* Indexing a family of modules is expressed via the "bazel_dep" rule with name and version attributes.
* In general this indexing is an implementation detail that need not (and
should not IMO) be exposed to starlark code.
* Module aliases are supported via the 'repo_mapping' rule; such
aliases are scoped to the module in which they are declared.
* The "bazel_dep" rule also supports aliasing via the "repo_name" attribute. (?)
* Indexing and aliasing are mutually orthogonal.
* Aliasing is scoped; it follows that module names are scoped. A Fully
Qualified Module Name would include the context module name.
Possible syntax: "@ctx@mod//pkg:tgt". (This is a label containing an FQMN)
* An "Indexed FQMN" would include the version string but as noted
above this should never be needed in user code.
* Scopes (contexts) nest so we could have e.g. @a@b@c//pkg:tgt
* In principle the FQMN should be sufficient to unambiguously identify
a unique indexed FQMN. So generated BUILD files could use FQMNs.
Your question from another msg: "Say you have a dependency on @foo, and @foo has a dependency on @bar. (You have no visibility into @bar.) You do `bazel query deps(@foo//:target)`.
Your preference is that it emit: