docs: def transfer_command(
      batch,
      sync_level,
      recursive,
      destination,
      source,
      label,
      preserve_mtime,
      verify_checksum,
      encrypt,
      submission_id,
      dry_run,
      delete,
      deadline,
      skip_activation_check,
      notify,
      perf_cc,
      perf_p,
      perf_pp,
      perf_udt,
  ):
      """
      Executor for `globus transfer`
      """
      source_endpoint, cmd_source_path = source
      dest_endpoint, cmd_dest_path = destination
  
      if recursive and batch:
          raise click.UsageError(
              (
                  "You cannot use --recursive in addition to --batch. "
                  "Instead, use --recursive on lines of --batch input "
                  "which need it"
              )
          )
  
      if (cmd_source_path is None or cmd_dest_path is None) and (not batch):
          raise click.UsageError(
              ("transfer requires either SOURCE_PATH and DEST_PATH or " "--batch")
          )
  
      # because python can't handle multiple **kwargs expansions in a single
      # call, we need to get a little bit clever
      # both the performance options (of which there are a few), and the
      # notification options (also there are a few) have elements which should be
      # omitted in some cases
      # notify comes to us clean, perf opts need more care
      # put them together into a dict before passing to TransferData
      kwargs = {}
      perf_opts = dict(
          (k, v)
          for (k, v) in dict(
              perf_cc=perf_cc, perf_p=perf_p, perf_pp=perf_pp, perf_udt=perf_udt
          ).items()
          if v is not None
      )
      kwargs.update(perf_opts)
      kwargs.update(notify)
  
      client = get_client()
      transfer_data = TransferData(
          client,
          source_endpoint,
          dest_endpoint,
          label=label,
          sync_level=sync_level,
          verify_checksum=verify_checksum,
          preserve_timestamp=preserve_mtime,
          encrypt_data=encrypt,
          submission_id=submission_id,
          delete_destination_extra=delete,
          deadline=deadline,
          skip_activation_check=skip_activation_check,
          **kwargs
      )
  
      if batch:
  
          @click.command()
          @click.option("--recursive", "-r", is_flag=True)
          @click.argument("source_path", type=TaskPath(base_dir=cmd_source_path))
          @click.argument("dest_path", type=TaskPath(base_dir=cmd_dest_path))
          def process_batch_line(dest_path, source_path, recursive):
              """
              Parse a line of batch input and turn it into a transfer submission
              item.
              """
              transfer_data.add_item(
                  str(source_path), str(dest_path), recursive=recursive
              )
  
          shlex_process_stdin(
              process_batch_line,
              (
                  "Enter transfers, line by line, as\n\n"
                  "    [--recursive] SOURCE_PATH DEST_PATH\n"
              ),
          )
      else:
          transfer_data.add_item(cmd_source_path, cmd_dest_path, recursive=recursive)
  
      if dry_run:
          formatted_print(
              transfer_data,
              response_key="DATA",
              fields=(
                  ("Source Path", "source_path"),
                  ("Dest Path", "destination_path"),
                  ("Recursive", "recursive"),
              ),
          )
          # exit safely
          return
  
      # autoactivate after parsing all args and putting things together
      # skip this if skip-activation-check is given
      if not skip_activation_check:
          autoactivate(client, source_endpoint, if_expires_in=60)
          autoactivate(client, dest_endpoint, if_expires_in=60)
  
      res = client.submit_transfer(transfer_data)
      formatted_print(
          res,
          text_format=FORMAT_TEXT_RECORD,
          fields=(("Message", "message"), ("Task ID", "task_id")),
      )