wntrblm / nox

Flexible test automation for Python
https://nox.thea.codes
Apache License 2.0
1.29k stars 146 forks source link

Tag aliases #663

Open avylove opened 1 year ago

avylove commented 1 year ago

How would this feature be useful?

Let's say you have multiple sessions tagged with 'format', 'lint', and 'test'. Before you commit, you want to run all of these tagged sessions. There are currently two ways to do this, run nox -t format lint test, or add a new tag to all of the sessions, for example, 'check' and run nox -t check.

The problem with the first approach is its getting verbose and a developer could miss one, or not get the message when another tag gets added to the list. There are other methods of enforcement, but I feel like that's out of scope.

The problem with the second approach is it increases maintenance and it's not clear that 'check' means 'format', 'lint', and 'test'.

Describe the solution you'd like

I'd like to see tag aliases (Or pseudo tags, meta tags, tag groups ... whatever name is the most intuitive). Tag aliases would correspond to one or more tags so that when the alias was specified, it would be as if referenced tags were specified.

A possible implementation could look like this:

nox.options.tag_aliases = {
    'check': ('format', 'lint', 'test')
}

Then nox -t check becomes equivalent to nox -t format lint test

Describe alternatives you've considered

Currently adding additional tags to sessions. Would really prefer a different approach.

Anything else?

No response

henryiii commented 1 year ago

Haven't thought about it much, but quick design thought, what about a decorator? Like:

@nox.alias("check")
@nox.session(...)
def format(...): ...

@nox.alias("check")
@nox.session(...)
def lint(...): ...

? Or maybe adding them as a keyword argument to session, aliases=["check'].

Things like how they would show up in help, etc. would probably guide the design more. And I could see this being related to #631.

avylove commented 1 year ago

The problem with a decorator is the same as adding a new tag to all the sessions, it increases the maintenance burden and the intent is not explicit. I really don't see this as being related to the individual sessions as much as being related to the calling arguments.

rmorshea commented 1 year ago

I finally got around to creating a tool I'm calling NoxOpt. It's a very early prototype so it could use some suggestions, and probably has lots of bugs, but I think it might implement something similar to what's requested. NoxOpt has this concept of automatic tags where, if I name my sessions in a particular way, it will generate some tags based on those names. The following example would generate these tags, which will run all session with the same prefix:

from noxopt import NoxOpt, Session

nox = NoxOpt(auto_tag=True)

@nox.session
def check_python_tests(session: Session) -> None:
    ...

@nox.session
def check_python_format(session: Session) -> None:
    ...

@nox.session
def check_javascript_tests(session: Session) -> None:
    ...

@nox.session
def check_javascript_format(session: Session) -> None:
    ...

As a bonus it also lets you define options for your sessions using type annotations:

from noxopt import NoxOpt, Option, Session, Annotated

nox = NoxOpt()

@nox.session
def sum_numbers(
    session: Session,
    nums: Annotated[list[int], Option(nargs="*", type=int)],
) -> None:
    session.log(sum(nums))
$ nox -s sum-numbers -- --nums 10 3 26 4
nox > Running session my-session
nox > Creating virtual environment (virtualenv) using python in .nox/my-session
nox > 43
nox > Session my-session was successful.