text: from django.core.management.base import BaseCommand
  from argparse import RawTextHelpFormatter
  import os
  import shutil
  import pathlib
  from datetime import datetime
  from distutils.sysconfig import get_python_lib
  
  
  class Command(BaseCommand):
      help = """
      usage: ./manage.py docrootcms [option]
      --------------------------------------
      example: ./manage.py docrootcms install
      example: ./manage.py docrootcms test update
      example: ./manage.py docrootcms update
      example: ./manage.py docrootcms develop
  
      options
      --------
      install - attempts to install the starter files and directories to a new docroot application
      update - attempts to update user files with any configuration changes in settings and urls
      test - creates new version of files that would be changed instead of changing them
      develop - copies the docroot-cms module in the virtual environment to local project for development
      """
      testing = False
  
      def create_parser(self, *args, **kwargs):
          parser = super(Command, self).create_parser(*args, **kwargs)
          parser.formatter_class = RawTextHelpFormatter
          return parser
  
      def add_arguments(self, parser):
          parser.add_argument('option', nargs='+', type=str)
  
      def update(self):
          # look for the lines indicating this is our block and replace them with the current contents
          # otherwise throw an exception and print it as an error
          success_instructions = """
          Successfully updated cms.
  
          """
          # check that docroot app exists
          # NOTE: we will assume if there is a docroot dir then we already installed
          if not os.path.exists('docroot'):
              return 'docroot directory does not exist; can not update.  Did you mean to install it?'
          else:
              self.stdout.write(f'attempting to update docroot app and test files')
              # get the directory from docrootcms/docroot
              module_path = self.get_module_path()
              # we have a module path so now lets try and copy the docroot_settings_append and docroot_urls_append
              # settings.py changes
              local_path = pathlib.Path()
              print(f'local path: {local_path}')
              settings_path = local_path / "docroot" / "settings.py"
              settings_append_path = module_path / "resources" / "docroot_settings_append.py"
              self.append_or_replace_content(settings_path, settings_append_path)
              # urls.py changes
              urls_path = local_path / "docroot" / "urls.py"
              urls_append_path = module_path / "resources" / "docroot_urls_append.py"
              self.append_or_replace_content(urls_path, urls_append_path)
              # create the resources folder if it doesn't exist and bring all the templates and append files over
              module_resources_path = module_path / 'resources'
              resources_path = local_path / 'docroot' / 'resources'
              if os.path.exists(resources_path):
                  shutil.rmtree(resources_path)
                  self.stdout.write(self.style.SUCCESS(f"Removed {resources_path}"))
              # copy the module resources to our resources (should contain various files like append index.dt and data.py
              shutil.copytree(module_resources_path, resources_path)
              self.stdout.write(self.style.SUCCESS(f"Copied {module_resources_path} to {resources_path}"))
              module_template_path = module_path / 'templates'
              shutil.copytree(module_template_path, resources_path / 'templates')
              self.stdout.write(self.style.SUCCESS(f"Copied {module_template_path} to {resources_path / 'templates'}"))
              module_test_path = module_path / 'install' / 'files' / 'test'
              try:
                  shutil.copytree(module_test_path, resources_path, dirs_exist_ok=True)
                  self.stdout.write(self.style.SUCCESS(f"Copied {module_test_path} to {resources_path}"))
              except TypeError:
                  # < 3.8 throws type error because the dirs_exist_ok doesn't exist
                  # NOTE: trying to delete this every time so hopefully we don't need it anymore; if doesn't work go
                  #   back to printing the warning until later
                  shutil.copytree(module_test_path, resources_path)
                  # print('WARNING: python < 3.8 required version; skipping the replacing of any test files...')
  
              return success_instructions
  
      def append_or_replace_content(self, old_path, new_path):
          if os.path.exists(new_path):
              # with open(new_path, 'r') as input_file:
              #     content_block = input_file.read()
              content_block = new_path.read_text()
              content_block = content_block.strip()
              # print(content_block)
              heading_substring = ""
              # look for a pattern match using the first line (heading)
              pos_end = content_block.find("\n")
              if pos_end != -1:
                  heading_substring = content_block[0:pos_end]
              print(f'heading_substring: {heading_substring}')
              print("")
              print("")
              if heading_substring:
                  print('we have substrings so searching new document.')
                  # make sure we have a settings file to add it to (assumes docroot/settings.py)
                  if os.path.exists(old_path):
                      current_content = old_path.read_text()
                      # with open(old_path, 'r') as output_file:
                      #     current_content = output_file.read()
                      start_pos = current_content.find(heading_substring)
                      end_pos = -1
                      new_content = None
                      if start_pos > -1:
                          end_pos = current_content.find(heading_substring, start_pos + len(heading_substring))
                          if end_pos > -1:
                              print('we found start and end positions so we are going to replace')
                              new_content = current_content[0:start_pos]
                              new_content += content_block
                              new_content += current_content[end_pos + len(heading_substring):]
                      # if we did not find a start or end pos so lets append
                      if start_pos <= -1 or end_pos <= -1:
                          print('we did not find start and or end so lets append')
                          new_content = current_content + "\n"
                          new_content += content_block + "\n"
  
                      # print("NEW CONTENT")
                      # print(new_content)
  
                      if new_content:
                          # backup the old file before we mess with it
                          datetime_ext = datetime.now().strftime("%Y%m%d-%H%M")
                          new_file_name = old_path.name + "." + datetime_ext
                          shutil.copy(old_path, old_path.parent / new_file_name)
                          # write the new_content to the current file
                          if self.testing:
                              test_file_name = old_path.stem + "_new.py"
                              test_file = old_path.parent / test_file_name
                              test_file.write_text(new_content)
                              self.stdout.write(self.style.SUCCESS(f'Successfully updated {new_path} to {test_file}'))
                          else:
                              old_path.write_text(new_content)
                              self.stdout.write(self.style.SUCCESS(f'Successfully updated {new_path} to {old_path}'))
                  else:
                      self.stderr.write(self.style.ERROR(f'Settings file [{old_path}] was not found!'))
          else:
              self.stderr.write(self.style.ERROR(f'Settings append file [{new_path}] was not found!'))
  
      @staticmethod
      def get_module_path():
          # first try and get it from distutils (since pyenv symlinks to root version and site doesnt work for virtualenv)
          module_path = pathlib.Path(get_python_lib()) / 'docrootcms'
          print(f'module path from DISTUTILS.SYSCONFIG: {module_path}')
          if not os.path.exists(module_path):
              module_path = pathlib.Path(os.__file__).parent / 'site-packages' / 'docrootcms'
              print(f'module path from runtime: {module_path}')
          if not os.path.exists(module_path):
              # for debugging lets next try to find the app locally to copy from
              module_path = pathlib.Path('docrootcms')
              print(f'module path from project: {module_path}')
          if not os.path.exists(module_path):
              raise ModuleNotFoundError(
                  'Module docrootcms was not installed.  Install using pip install django-docrootcms and try again.')
          return module_path
  
      def install(self):
          success_instructions = """
          Successfully Installed cms.
  
          """
          # check that docroot app exists
          # NOTE: we will assume if there is a docroot dir then we already installed
          if not os.path.exists('docroot'):
              self.stderr.write(self.style.ERROR('docroot application directory not found!'))
              return 'Install docroot application according to instructions: ' \
                     'https://github.com/sstacha/django-docroot-cms'
          else:
              self.stdout.write(f'installing docroot files...')
              # get the directory from docrootcms/docroot/files
              module_path = self.get_module_path()
              module_docroot_files_path = module_path / 'install' / 'files'
              local_path = pathlib.Path()
              local_docroot_files_path = local_path / 'docroot' / 'files'
              print(f'local path: {local_path}')
              shutil.copytree(module_docroot_files_path, local_docroot_files_path)
              self.stdout.write(
                  self.style.SUCCESS(f'Successfully copied {module_docroot_files_path} to {local_docroot_files_path}'))
              # check that required directories exist
              if not os.path.exists(local_path / 'images'):
                  os.makedirs(local_path / 'images')
                  self.stdout.write(self.style.SUCCESS(f"Created {local_path / 'images'}"))
              if not os.path.exists(local_path / 'cache'):
                  os.makedirs(local_path / 'cache')
                  self.stdout.write(self.style.SUCCESS(f"Created {local_path / 'cache'}"))
              if not os.path.exists(local_path / 'data'):
                  os.makedirs(local_path / 'data')
                  self.stdout.write(self.style.SUCCESS(f"Created {local_path / 'data'}"))
              if not os.path.exists(local_path / 'docroot' / 'templates'):
                  os.makedirs(local_path / 'docroot' / 'templates')
                  self.stdout.write(self.style.SUCCESS(f"Created {local_path / 'docroot' / 'templates'}"))
              if not os.path.exists(local_path / 'docroot' / 'dt.inc'):
                  os.makedirs(local_path / 'docroot' / 'dt.inc')
                  self.stdout.write(self.style.SUCCESS(f"Created {local_path / 'docroot' / 'dt.inc'}"))
              return success_instructions
  
      def develop(self):
          success_instructions = """
          Successfully Installed cms application for development.
  
          """
          # check that docroot-cms app doesn't already exist locally
          if os.path.exists('docrootcms'):
              self.stderr.write(self.style.ERROR('docrootcms application already exists locally for development!'))
              return 'Remove the existing directory to reload a newer version.'
          else:
              self.stdout.write(f'installing docrootcms from virtual environment...')
              module_path = self.get_module_path()
              local_path = pathlib.Path() / 'docrootcms'
              print(f'local path: {local_path}')
              shutil.copytree(module_path, local_path, dirs_exist_ok=True)
              self.stdout.write(
                  self.style.SUCCESS(f'Successfully copied {module_path} to {local_path}'))
              return success_instructions
  
      def handle(self, *args, **options):
          if "update" in options['option']:
              try:
                  if "test" in options['option']:
                      self.testing = True
                  self.stdout.write(self.style.WARNING(f'{self.update()}'))
              except ModuleNotFoundError as nfe:
                  self.stderr.write(self.style.ERROR(f'Block not found.  This should not happen. {nfe}'))
          elif "install" in options['option']:
              try:
                  if "test" in options['option']:
                      self.testing = True
                  self.stdout.write(self.style.WARNING(f'{self.install()}'))
              except ModuleNotFoundError as nfe:
                  self.stderr.write(self.style.ERROR(f'{nfe}'))
          elif "develop" in options['option']:
              self.stdout.write(self.style.WARNING(f'{self.develop()}'))
          else:
              self.stdout.write(self.style.SUCCESS(self.help))
  