text: """
  Common CLI options shared by various commands
  """
  
  import os
  import logging
  from functools import partial
  
  import click
  from click.types import FuncParamType
  from samcli.cli.types import CfnParameterOverridesType, CfnMetadataType, CfnTags
  from samcli.commands._utils.custom_options.option_nargs import OptionNargs
  
  
  _TEMPLATE_OPTION_DEFAULT_VALUE = "template.[yaml|yml]"
  DEFAULT_STACK_NAME = "sam-app"
  
  
  LOG = logging.getLogger(__name__)
  
  
  def get_or_default_template_file_name(ctx, param, provided_value, include_build):
      """
      Default value for the template file name option is more complex than what Click can handle.
      This method either returns user provided file name or one of the two default options (template.yaml/template.yml)
      depending on the file that exists
  
      :param ctx: Click Context
      :param param: Param name
      :param provided_value: Value provided by Click. It could either be the default value or provided by user.
      :return: Actual value to be used in the CLI
      """
  
      original_template_path = os.path.abspath(provided_value)
  
      search_paths = ["template.yaml", "template.yml"]
  
      if include_build:
          search_paths.insert(0, os.path.join(".aws-sam", "build", "template.yaml"))
  
      if provided_value == _TEMPLATE_OPTION_DEFAULT_VALUE:
          # Default value was used. Value can either be template.yaml or template.yml. Decide based on which file exists
          # .yml is the default, even if it does not exist.
          provided_value = "template.yml"
  
          for option in search_paths:
              if os.path.exists(option):
                  provided_value = option
                  break
      result = os.path.abspath(provided_value)
  
      if ctx:
          # sam configuration file should always be relative to the supplied original template and should not to be set
          # to be .aws-sam/build/
          setattr(ctx, "samconfig_dir", os.path.dirname(original_template_path))
      LOG.debug("Using SAM Template at %s", result)
      return result
  
  
  def guided_deploy_stack_name(ctx, param, provided_value):
      """
      Provide a default value for stack name if invoked with a guided deploy.
      :param ctx: Click Context
      :param param: Param name
      :param provided_value: Value provided by Click, it would be the value provided by the user.
      :return: Actual value to be used in the CLI
      """
  
      guided = ctx.params.get("guided", False) or ctx.params.get("g", False)
  
      if not guided and not provided_value:
          raise click.BadOptionUsage(
              option_name=param.name,
              ctx=ctx,
              message="Missing option '--stack-name', 'sam deploy --guided' can "
              "be used to provide and save needed parameters for future deploys.",
          )
  
      return provided_value if provided_value else DEFAULT_STACK_NAME
  
  
  def template_common_option(f):
      """
      Common ClI option for template
  
      :param f: Callback passed by Click
      :return: Callback
      """
      return template_click_option()(f)
  
  
  def template_option_without_build(f):
      """
      Common ClI option for template
  
      :param f: Callback passed by Click
      :return: Callback
      """
      return template_click_option(include_build=False)(f)
  
  
  def template_click_option(include_build=True):
      """
      Click Option for template option
      """
      return click.option(
          "--template-file",
          "--template",
          "-t",
          default=_TEMPLATE_OPTION_DEFAULT_VALUE,
          type=click.Path(),
          envvar="SAM_TEMPLATE_FILE",
          callback=partial(get_or_default_template_file_name, include_build=include_build),
          show_default=True,
          is_eager=True,
          help="AWS SAM template file",
      )
  
  
  def docker_common_options(f):
      for option in reversed(docker_click_options()):
          option(f)
  
      return f
  
  
  def docker_click_options():
  
      return [
          click.option(
              "--skip-pull-image",
              is_flag=True,
              help="Specify whether CLI should skip pulling down the latest Docker image for Lambda runtime.",
              envvar="SAM_SKIP_PULL_IMAGE",
              default=False,
          ),
          click.option(
              "--docker-network",
              envvar="SAM_DOCKER_NETWORK",
              help="Specifies the name or id of an existing docker network to lambda docker "
              "containers should connect to, along with the default bridge network. If not specified, "
              "the Lambda containers will only connect to the default bridge docker network.",
          ),
      ]
  
  
  def parameter_override_click_option():
      return click.option(
          "--parameter-overrides",
          cls=OptionNargs,
          type=CfnParameterOverridesType(),
          default={},
          help="Optional. A string that contains AWS CloudFormation parameter overrides encoded as key=value pairs."
          "For example, 'ParameterKey=KeyPairName,ParameterValue=MyKey ParameterKey=InstanceType,"
          "ParameterValue=t1.micro' or KeyPairName=MyKey InstanceType=t1.micro",
      )
  
  
  def parameter_override_option(f):
      return parameter_override_click_option()(f)
  
  
  def metadata_click_option():
      return click.option(
          "--metadata",
          type=CfnMetadataType(),
          help="Optional. A map of metadata to attach to ALL the artifacts that are referenced in your template.",
      )
  
  
  def metadata_override_option(f):
      return metadata_click_option()(f)
  
  
  def capabilities_click_option():
      return click.option(
          "--capabilities",
          cls=OptionNargs,
          required=False,
          type=FuncParamType(func=_space_separated_list_func_type),
          help="A list of  capabilities  that  you  must  specify"
          "before  AWS  Cloudformation  can create certain stacks. Some stack tem-"
          "plates might include resources that can affect permissions in your  AWS"
          "account,  for  example, by creating new AWS Identity and Access Manage-"
          "ment (IAM) users. For those stacks,  you  must  explicitly  acknowledge"
          "their  capabilities by specifying this parameter. The only valid values"
          "are CAPABILITY_IAM and CAPABILITY_NAMED_IAM. If you have IAM resources,"
          "you  can specify either capability. If you have IAM resources with cus-"
          "tom names, you must specify CAPABILITY_NAMED_IAM. If you don't  specify"
          "this  parameter, this action returns an InsufficientCapabilities error.",
      )
  
  
  def capabilities_override_option(f):
      return capabilities_click_option()(f)
  
  
  def tags_click_option():
      return click.option(
          "--tags",
          cls=OptionNargs,
          type=CfnTags(),
          required=False,
          help="A list of tags to associate with the stack that is created or updated."
          "AWS CloudFormation also propagates these tags to resources "
          "in the stack if the resource supports it.",
      )
  
  
  def tags_override_option(f):
      return tags_click_option()(f)
  
  
  def notification_arns_click_option():
      return click.option(
          "--notification-arns",
          cls=OptionNargs,
          type=FuncParamType(func=_space_separated_list_func_type),
          required=False,
          help="Amazon  Simple  Notification  Service  topic"
          "Amazon  Resource  Names  (ARNs) that AWS CloudFormation associates with"
          "the stack.",
      )
  
  
  def notification_arns_override_option(f):
      return notification_arns_click_option()(f)
  
  
  def _space_separated_list_func_type(value):
      return value.split(" ") if not isinstance(value, tuple) else value
  
  
  _space_separated_list_func_type.__name__ = "LIST"
  