feat(pip): provide pypi -> whl target mapping in requirements.bzl (#1532)

Currently a BUILD file can load `all_whl_requirements` but then can't
determine which one is associated with a given package installed by the
user.
This makes it impossible to build rules where the user can choose a
given package and then override the wheel used, for example. @mattem and
I are working at a client where we need this ability.

This PR makes a small, non-breaking refactoring to the generated
`requirements.bzl` file so that this information is available in a new
`all_whl_requirements_by_package` symbol.

Users can then do something like this:

```
load("@pip//:requirements.bzl", "all_whl_requirements_by_package")

some_rule(
  wheels = dict(all_whl_requirements_by_package, **{
    "charset-normalizer": "@charset_1_2_3//:file"
  }),
)
```
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 02aca34..185ac37 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -32,6 +32,10 @@
 * (pip_parse) The installation of `pip_parse` repository rule toolchain
   dependencies is now done as part of `py_repositories` call.
 
+* (pip_parse) The generated `requirements.bzl` file now has an additional symbol
+  `all_whl_requirements_by_package` which provides a map from the original package name
+  (as it appears in requirements.txt) to the target that provides the built wheel file.
+
 * (pip_parse) The flag `incompatible_generate_aliases` has been flipped to
   `True` by default on `non-bzlmod` setups allowing users to use the same label
   strings during the transition period. For example, instead of
diff --git a/examples/pip_parse_vendored/requirements.bzl b/examples/pip_parse_vendored/requirements.bzl
index 53208f5..48371ed 100644
--- a/examples/pip_parse_vendored/requirements.bzl
+++ b/examples/pip_parse_vendored/requirements.bzl
@@ -9,7 +9,9 @@
 
 all_requirements = ["@pip//certifi:pkg", "@pip//charset_normalizer:pkg", "@pip//idna:pkg", "@pip//requests:pkg", "@pip//urllib3:pkg"]
 
-all_whl_requirements = ["@pip//certifi:whl", "@pip//charset_normalizer:whl", "@pip//idna:whl", "@pip//requests:whl", "@pip//urllib3:whl"]
+all_whl_requirements_by_package = {"certifi": "@pip//certifi:whl", "charset-normalizer": "@pip//charset_normalizer:whl", "idna": "@pip//idna:whl", "requests": "@pip//requests:whl", "urllib3": "@pip//urllib3:whl"}
+
+all_whl_requirements = all_whl_requirements_by_package.values()
 
 all_data_requirements = ["@pip//certifi:data", "@pip//charset_normalizer:data", "@pip//idna:data", "@pip//requests:data", "@pip//urllib3:data"]
 
diff --git a/python/pip_install/pip_repository.bzl b/python/pip_install/pip_repository.bzl
index f018f65..b841772 100644
--- a/python/pip_install/pip_repository.bzl
+++ b/python/pip_install/pip_repository.bzl
@@ -276,7 +276,7 @@
 
     packages = [(normalize_name(name), requirement) for name, requirement in parsed_requirements_txt.requirements]
 
-    bzl_packages = sorted([name for name, _ in packages])
+    bzl_packages = dict(sorted([[name, normalize_name(name)] for name, _ in parsed_requirements_txt.requirements]))
 
     imports = [
         'load("@rules_python//python/pip_install:pip_repository.bzl", "whl_library")',
@@ -314,7 +314,7 @@
 
     if rctx.attr.incompatible_generate_aliases:
         macro_tmpl = "@%s//{}:{}" % rctx.attr.name
-        aliases = render_pkg_aliases(repo_name = rctx.attr.name, bzl_packages = bzl_packages)
+        aliases = render_pkg_aliases(repo_name = rctx.attr.name, bzl_packages = bzl_packages.values())
         for path, contents in aliases.items():
             rctx.file(path, contents)
     else:
@@ -324,16 +324,16 @@
     rctx.template("requirements.bzl", rctx.attr._template, substitutions = {
         "%%ALL_DATA_REQUIREMENTS%%": _format_repr_list([
             macro_tmpl.format(p, "data")
-            for p in bzl_packages
+            for p in bzl_packages.values()
         ]),
         "%%ALL_REQUIREMENTS%%": _format_repr_list([
             macro_tmpl.format(p, "pkg")
-            for p in bzl_packages
+            for p in bzl_packages.values()
         ]),
-        "%%ALL_WHL_REQUIREMENTS%%": _format_repr_list([
-            macro_tmpl.format(p, "whl")
-            for p in bzl_packages
-        ]),
+        "%%ALL_WHL_REQUIREMENTS_BY_PACKAGE%%": _format_dict(_repr_dict({
+            name: macro_tmpl.format(p, "whl")
+            for name, p in bzl_packages.items()
+        })),
         "%%ANNOTATIONS%%": _format_dict(_repr_dict(annotations)),
         "%%CONFIG%%": _format_dict(_repr_dict(config)),
         "%%EXTRA_PIP_ARGS%%": json.encode(options),
diff --git a/python/pip_install/pip_repository_requirements.bzl.tmpl b/python/pip_install/pip_repository_requirements.bzl.tmpl
index 92ea5be..23c8311 100644
--- a/python/pip_install/pip_repository_requirements.bzl.tmpl
+++ b/python/pip_install/pip_repository_requirements.bzl.tmpl
@@ -8,7 +8,9 @@
 
 all_requirements = %%ALL_REQUIREMENTS%%
 
-all_whl_requirements = %%ALL_WHL_REQUIREMENTS%%
+all_whl_requirements_by_package = %%ALL_WHL_REQUIREMENTS_BY_PACKAGE%%
+
+all_whl_requirements = all_whl_requirements_by_package.values()
 
 all_data_requirements = %%ALL_DATA_REQUIREMENTS%%
 
diff --git a/python/private/bzlmod/pip_repository.bzl b/python/private/bzlmod/pip_repository.bzl
index f5bb46f..e4e59b5 100644
--- a/python/private/bzlmod/pip_repository.bzl
+++ b/python/private/bzlmod/pip_repository.bzl
@@ -51,10 +51,10 @@
             macro_tmpl.format(p, p)
             for p in bzl_packages
         ]),
-        "%%ALL_WHL_REQUIREMENTS%%": render.list([
-            macro_tmpl.format(p, "whl")
+        "%%ALL_WHL_REQUIREMENTS_BY_PACKAGE%%": render.dict({
+            p: macro_tmpl.format(p, "whl")
             for p in bzl_packages
-        ]),
+        }),
         "%%MACRO_TMPL%%": macro_tmpl,
         "%%NAME%%": rctx.attr.name,
     })
diff --git a/python/private/bzlmod/requirements.bzl.tmpl b/python/private/bzlmod/requirements.bzl.tmpl
index c72187c..5ed1e49 100644
--- a/python/private/bzlmod/requirements.bzl.tmpl
+++ b/python/private/bzlmod/requirements.bzl.tmpl
@@ -5,7 +5,9 @@
 
 all_requirements = %%ALL_REQUIREMENTS%%
 
-all_whl_requirements = %%ALL_WHL_REQUIREMENTS%%
+all_whl_requirements_by_package = %%ALL_WHL_REQUIREMENTS_BY_PACKAGE%%
+
+all_whl_requirements = all_whl_requirements_by_package.values()
 
 all_data_requirements = %%ALL_DATA_REQUIREMENTS%%