buildtools icon indicating copy to clipboard operation
buildtools copied to clipboard

Add ability to mark Starlark macro arguments as deprecated

Open cvrebert opened this issue 6 years ago • 3 comments

Description of the problem / feature request:

I have a Starlark macro. For usability reasons, to avoid duplication, some of the arguments to that macro have been extracted into a separate macro/rule that bundles them together for reuse. This has resulted in those original arguments to the original macro becoming deprecated. Simplified example for concreteness:

# OLD
def foo_lib(name, a, b, c, d):
    # ...

foo_lib(
    name = "x",
    a = "aaa",
    b = "bbb",
    # ...
)
foo_lib(
    name = "y",
    a = "aaa",
    b = "bbb",
    # ...
)

# NEW
def bar_lib(name, a, b):
    # ...

def foo_lib(name, a, b, c, d, bar_dep):
    """
    Args:
        a: DEPRECATED. Use bar_dep instead. <...description...>
        b: DEPRECATED. Use bar_dep instead. <...description...>
        bar_dep: The bar_lib() to use.
        ...
    """
    # ...

# After migration is done:
bar_lib(
    name = "q",
    a = "aaa",
    b = "bbb",
)
foo_lib(
    name = "x",
    bar_dep = ":q",
    # ...
)
foo_lib(
    name = "y",
    bar_dep = ":q",
    # ...
)

I've added prose to my macro's docstring to note that these argument are deprecated, but there's no way to express this deprecation programmatically (vs. e.g. the deprecation attribute that can mark a target as deprecated). This means tools integrated with Bazel cannot automatically warn/discourage the user from using the deprecated arguments in new code, so usages grow at a higher rate, increasing the costs of the eventual migration away from the deprecated arguments by the team that owns the macro.

Feature requests: what underlying problem are you trying to solve with this feature?

To discourage users of a macro from adding new usages of deprecated parameters in new BUILD code or Starlark code that calls the macro. If such deprecations could be expressed syntactically, then automated tools would be able to act upon it. For example:

  • Bazel itself could output deprecation messages when building targets that set such arguments.
  • Code repository browsers and IDEs could highlight/annotate usages of such arguments when viewing BUILD files.
  • Bazel-integrated statistical or dashboarding tools could include such arguments in their general "calls to deprecated code" risk analyses of projects.

Have you found anything relevant by searching the web?

No. My searches didn't locate any previous discussions of similar issues.

Any other information, logs, or outputs that you want to share?

My specific macros which would benefit from this feature are Google-internal.

cvrebert avatar Jul 26 '19 19:07 cvrebert

Inside a monorepo, the usual recommendation is to do a depot cleanup (do it yourself if possible, it's sometimes automatable; or you can file bugs against other teams), and then remove the deprecated function.

To mark a function as deprecated:

def foo():
  """An example function.

  Deprecated:
    <reason and alternative>
  """

However, we lack tooling around this.

laurentlb avatar Jul 29 '19 10:07 laurentlb

the usual recommendation is to do a depot cleanup

Of course, but there can be significant time lag between marking something deprecated and actually executing the cleanup (prioritization is hard; *insert two roads meme here*). Discouraging new uses during that period would be nice.

To mark a function as deprecated:

Erm, I'm only deprecating individual parameters to the function, not the entire function.

cvrebert avatar Jul 29 '19 18:07 cvrebert

I think that's a feature request for Buildifier, so I've transferred the issue.

At the moment, we can only mark functions as deprecated: https://github.com/bazelbuild/buildtools/blob/master/WARNINGS.md#deprecated-function

laurentlb avatar Jul 30 '20 12:07 laurentlb