Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: new manifest.bzl #94

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

jjmaestro
Copy link
Contributor

Note

Stacked on top of #93

refactor: move all manifest parsing and validation to manifest.bzl

Cleanup resolve.bzl and package_index.bzl by moving all of the manifest functionality to a separate manifest.bzl file where we now do all of the work to generate the lock: manifest parsing, validation and the package index and resolution. IMHO this is how it should be because the lock is the "frozen state" of the manifest.

  • _parse parses the YAML

  • _from_dict validates the manifest dict and does the rest of the changes that we need to produce a manifest struct

  • add extra validation for e.g. duplicated architectures

  • _lock is the only method that's exposed to the outside and it encapsulates all of the other parts, calling _from_dict and all of the package index and resolution, to produce the lock file.

  • move get_dupes to util.bzl

  • refactor the "source" struct into the new manifest where we can now centralize a lot of the structure and logic spread across multiple parts of the code.

  • remove the yq_toolchain_prefix attribute since it's always "yq" and, looking at GH code search, this seems to be a copy-paste leftover from rules_js (or the other way around)... the code is always the same and it never receives a string different from "yq").

See bazelbuild/bazel#20369

While working on refactoring, I kept hitting rebase conflicts due to
issues with the MODULE lock. I guess it's because the Bazel version in
e2e tests is much lower than the current one with the fix (7.2) but
still, I don't think it adds much to have the lock in e2e testing.
PR GoogleContainerTools#73 added the `_resolve` and this breaks the buildozer fix / autofix
It seemed like 75afff9 in GoogleContainerTools#47 added the new locks but as new files, that
is, the old ones were left behind.
Add support for MODULE.bazel to the lock script and avoid printing an
unnecessary (and annoying 😅) error when building in a "modern repo".
Add a `nolock` attribute to avoid getting annoying DEBUG messages for
repos that we explicitly want to run without a lock.
* make apt/tests more readable by factoring out the parameters

* add a "test suite macro" in each test file that group all of the unit
  tests in the file and prepends a "test suite prefix". IMHO this is
  better than using `unittest.suite` because we provide better naming
  than the automated `_test<NUMBER>` plus these better names are actual
  targets that can be executed one-by-one by name.
Add other nolock tests to exercise the package repos (the templates,
etc).
* separate the script into a template file so it's easier to shellcheck
  and syntax highlight in editors.

* shellcheck the script and remove all SC2086 warnings
  ("Double quote to prevent globbing and word splitting")

* improve the buildozer help messages in the copy.sh script:
  * reduce duplication of buildozer command
  * add a more clear autofix bazel run command that can be easily
    copy-pasted

* change some of the variable names in the copy.sh template for longer,
  easier to understand names (repo_name >> name, lock_label >> label)

* move repo_name and workspace_relative_path into variables to reduce
  line length and improve readability
While working with some flaky mirrors and trying to figure out why they
were failing I found the _fetch_package_index code a bit hard to follow
so here's my attempt at streamlining it a bit:

* Change the general flow of the for-loop so that we can directly set
  the reasons for failure in failed_attempts

* Remove both integrity as an argument and as a return value since
  neither is ever used.

* return the content of the Packages index instead of the path, since we
  already have the repository_context. This way we don't need rctx
  anywhere else.

* Reword failure messages adding more context and debug information

* Shorter lines and templated strings, trying to make the code easier to
  read and follow.
* remove the `state` "intermediary `struct`" in `package_resolution.bzl`
  since it wasn't used / needed.

* refactor and move _set_dict from `util.bzl` to a `_package_set` method

* use `dict .get()` with default values instead of the "nested `if`s"

* renamed `package()` to `package_get` and make it return all package
  versions when the version is not specified so we can remove
  `_package_versions`

* reordeder `(name, version, arch)` args to match the order of the index
  keys `(arch, name, version)`
Add testing for package_index mocking the external / side effects
(downloads, decompression, etc).
The package resolution debugging that e.g. checks the package
dependencies should all be within package_resolution.bzl _resolve_all()
and not "leak out" returning the information that's only needed for
debugging / logging.

Also:

* reduce the verbosity of the optional dependencies warning by just
  printing one message per root package instead of one per package.

* break up the long lines to build the error messages and remove the
  "# buildifier: disable=print".
* move version constraint parsing from package_resolution to its own
  _parse_version_and_constraint method in version.bzl

* refactor _version_relop into a compare method in version.bzl plus a
  VERSION_OPERATORS dict so that (1) we use the operator strings
  everywhere and (2) we can use the keys to validate the operators.
Previously we had:
```starlark
    pkgindex = package_index.new(rctx, sources = sources, archs = manifest["archs"])
    pkgresolution = package_resolution.new(index = pkgindex)
```
And none of the code of package_resolution was used anywhere but in
resolve.bzl and after initializing the `pkgindex`.

Also, it makes sense since we are building the index from the manifest
and once we have the index we use it to resolve the packages and
populate the lock.
Cleanup resolve.bzl and package_index.bzl by moving all of the manifest
functionality to a separate manifest.bzl file where we now do all of the
work to generate the lock: manifest parsing, validation and the package
index and resolution. IMHO this is how it should be because the lock is
the "frozen state" of the manifest.

* _parse() parses the YAML

* _from_dict validates the manifest dict and does the rest of the
  changes that we need to produce a manifest struct

* add extra validation for e.g. duplicated architectures

* _lock is the only method that's exposed to the outside and it
  encapsulates all of the other parts, calling _from_dict and all of the
  package index and resolution, to produce the lock file.

* move get_dupes to util.bzl

* refactor the "source" struct into the new manifest where we can now
  centralize a lot of the structure and logic spread across multiple
  parts of the code.

* remove yq_toolchain_prefix since it's always "yq" and, looking at GH
  code search, this seems to be a copy-paste leftover from rules_js (or
  the other way around)... the code is always the same and it never
  receives a string different from "yq".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant