text: import contextlib
  import json
  import os
  import subprocess
  import sys
  import stat
  import tempfile
  
  from pathlib import Path
  
  import pytest
  
  from click.testing import CliRunner
  
  from shiv.cli import main, find_entry_point, _interpreter_path
  from shiv.constants import DISALLOWED_PIP_ARGS, NO_PIP_ARGS_OR_SITE_PACKAGES, NO_OUTFILE, DISALLOWED_ARGS
  from shiv.info import main as info_main
  from shiv.pip import install
  
  UGOX = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
  
  
  @contextlib.contextmanager
  def mocked_sys_prefix():
      attribute_to_mock = "real_prefix" if hasattr(sys, "real_prefix") else "base_prefix"
      original = getattr(sys, attribute_to_mock)
      setattr(sys, attribute_to_mock, "/fake/dir")
      yield
      setattr(sys, attribute_to_mock, original)
  
  
  class TestCLI:
  
      @pytest.fixture
      def shiv_root(self, monkeypatch, tmpdir):
  
          with tempfile.TemporaryDirectory(dir=tmpdir) as tmpdir:
              os.environ['SHIV_ROOT'] = tmpdir
              yield tmpdir
  
          os.environ.pop("SHIV_ROOT")
  
      @pytest.fixture
      def runner(self):
          """Returns a click test runner."""
  
          return lambda args: CliRunner().invoke(main, args)
  
      @pytest.fixture
      def info_runner(self):
          """Returns a click test runner (for shiv-info)."""
  
          return lambda args: CliRunner().invoke(info_main, args)
  
      def test_find_entry_point(self, tmpdir, package_location):
          """Test that we can find console_script metadata."""
          install(['-t', str(tmpdir), str(package_location)])
          assert find_entry_point(Path(tmpdir), "hello") == "hello:main"
  
      def test_no_args(self, runner):
          """This should fail with a warning about supplying pip arguments"""
  
          result = runner([])
  
          assert result.exit_code == 1
          assert NO_PIP_ARGS_OR_SITE_PACKAGES in result.output
  
      def test_no_outfile(self, runner):
          """This should fail with a warning about not providing an outfile"""
  
          result = runner(['-e', 'test', 'flask'])
  
          assert result.exit_code == 1
          assert NO_OUTFILE in result.output
  
      def test_find_interpreter(self):
  
          interpreter = _interpreter_path()
  
          assert Path(interpreter).exists()
          assert Path(interpreter).is_file()
  
      def test_find_interpreter_false(self):
  
          with mocked_sys_prefix():
              interpreter = _interpreter_path()
  
          # should fall back on the current sys.executable
          assert interpreter == sys.executable
  
      @pytest.mark.parametrize("arg", [arg for tup in DISALLOWED_ARGS.keys() for arg in tup])
      def test_disallowed_args(self, runner, arg):
          """This method tests that all the potential disallowed arguments match their error messages."""
  
          # run shiv with a disallowed argument
          result = runner(['-o', 'tmp', arg])
  
          # get the 'reason' message:
          for disallowed in DISALLOWED_ARGS:
              if arg in disallowed:
                  reason = DISALLOWED_ARGS[disallowed]
  
          assert result.exit_code == 1
  
          # assert we got the correct reason
          assert DISALLOWED_PIP_ARGS.format(arg=arg, reason=reason) in result.output
  
      @pytest.mark.parametrize('compile_option', ["--compile-pyc", "--no-compile-pyc"])
      @pytest.mark.parametrize('force', ["yes", "no"])
      def test_hello_world(self, runner, info_runner, shiv_root, package_location, compile_option, force):
          output_file = Path(shiv_root, 'test.pyz')
  
          result = runner(['-e', 'hello:main', '-o', str(output_file), str(package_location), compile_option])
  
          # check that the command successfully completed
          assert result.exit_code == 0
  
          # ensure the created file actually exists
          assert output_file.exists()
  
          # build env
          env = {**os.environ, "SHIV_FORCE_EXTRACT": force}
  
          # now run the produced zipapp
          proc = subprocess.run([str(output_file)], stdout=subprocess.PIPE, shell=True, env=env)
  
          assert proc.stdout.decode() == "hello world" + os.linesep
  
          # now run shiv-info on the produced zipapp
          result = info_runner([str(output_file)])
  
          # check the rc and output
          assert result.exit_code == 0
          assert f"pyz file: {str(output_file)}" in result.output
  
          # ensure that executable permissions were retained (skip test on windows)
          if os.name != "nt":
              build_id = json.loads(info_runner([str(output_file), '--json']).output)['build_id']
              assert Path(shiv_root, f"{output_file.stem}_{build_id}", "site-packages", "hello", "script.sh").stat().st_mode & UGOX == UGOX
  
      @pytest.mark.parametrize("extend_path", ["--extend-pythonpath", "--no-extend-pythonpath", "-E"])
      def test_extend_pythonpath(self, shiv_root, runner, extend_path):
  
          output_file = Path(shiv_root, 'test_pythonpath.pyz')
          package_dir = Path(shiv_root, 'package')
          main_script = Path(package_dir, 'env.py')
  
          MAIN_PROG = '\n'.join([
              "import os",
              "def main():",
              "    print(os.environ.get('PYTHONPATH', ''))"
          ])
  
          package_dir.mkdir()
          main_script.write_text(MAIN_PROG)
  
          result = runner([
              '-e', 'env:main',
              '-o', str(output_file),
              '--site-packages', str(package_dir),
              extend_path,
          ])
  
          # check that the command successfully completed
          assert result.exit_code == 0
  
          # ensure the created file actually exists
          assert output_file.exists()
  
          # now run the produced zipapp and confirm shiv_root is in PYTHONPATH
          proc = subprocess.run([str(output_file)], stdout=subprocess.PIPE, shell=True, env=os.environ)
  
          pythonpath_has_root = str(shiv_root) in proc.stdout.decode()
          assert extend_path.startswith('--no') != pythonpath_has_root
  
      def test_no_entrypoint(self, shiv_root, runner, package_location, monkeypatch):
  
          output_file = Path(shiv_root, 'test.pyz')
  
          result = runner(['-o', str(output_file), str(package_location)])
  
          # check that the command successfully completed
          assert result.exit_code == 0
  
          # ensure the created file actually exists
          assert output_file.exists()
  
          # now run the produced zipapp
          proc = subprocess.run(
              [str(output_file)],
              input=b"import hello;print(hello)",
              stdout=subprocess.PIPE,
              stderr=subprocess.PIPE,
              shell=True,
              env=os.environ,
          )
  
          assert proc.returncode == 0
          assert "hello" in proc.stdout.decode()
  