| 743 | |
| 744 | |
| 745 | class RunCommand(DockerComposeCommand): |
| 746 | def __init__(self) -> None: |
| 747 | super().__init__( |
| 748 | "run", |
| 749 | "run a one-off command", |
| 750 | runs_containers=True, |
| 751 | help_epilog="""As an mzcompose extension, run also supports running a workflow, as in: |
| 752 | |
| 753 | $ ./mzcompose run WORKFLOW [workflow-options...] |
| 754 | |
| 755 | In this form, run does not accept any of the arguments listed above. |
| 756 | |
| 757 | To see the available workflows, run: |
| 758 | |
| 759 | $ ./mzcompose list |
| 760 | """, |
| 761 | ) |
| 762 | |
| 763 | def configure(self, parser: argparse.ArgumentParser) -> None: |
| 764 | pass |
| 765 | |
| 766 | def run(self, args: argparse.Namespace) -> Any: |
| 767 | # This is a bit gross, but to determine the first position argument to |
| 768 | # `run` we have no choice but to hardcode the list of `run` options that |
| 769 | # take a value. E.g., in `run --entrypoint bash service`, we need to |
| 770 | # return `service`, not `bash`. We also distinguish between `run --help |
| 771 | # workflow` and `run workflow --help`: the former asks for help on the |
| 772 | # `run` command while the latter asks for help on the named `workflow`. |
| 773 | |
| 774 | KNOWN_OPTIONS_WITH_ARGUMENT = [ |
| 775 | "-d", |
| 776 | "--detach", |
| 777 | "--name", |
| 778 | "--entrypoint", |
| 779 | "-e", |
| 780 | "-l", |
| 781 | "--label", |
| 782 | "-p", |
| 783 | "--publish", |
| 784 | "-v", |
| 785 | "--volume", |
| 786 | "-w", |
| 787 | "--workdir", |
| 788 | ] |
| 789 | |
| 790 | setattr(args, "workflow", None) |
| 791 | setattr(args, "help", False) |
| 792 | arg_iter = iter(args.unknown_subargs) |
| 793 | for arg in arg_iter: |
| 794 | if arg in ["-h", "--help"]: |
| 795 | setattr(args, "help", True) |
| 796 | elif arg in KNOWN_OPTIONS_WITH_ARGUMENT: |
| 797 | # This is an option that's known to take a value, so skip the |
| 798 | # next argument too. |
| 799 | next(arg_iter, None) |
| 800 | elif arg.startswith("-"): |
| 801 | # Flag option. Skip it. |
| 802 | pass |