docs: def _verify_app_source_dir_impl(src_dir, temp_dir, mode, enforce=True):
      """Performs syntax and lint checks on the app source.
  
      Precondition: the dxapp.json file exists and can be parsed.
      """
      _lint(os.path.join(src_dir, "dxapp.json"), mode)
  
      # Check that the entry point file parses as the type it is going to
      # be interpreted as. The extension is irrelevant.
      manifest = json.load(open(os.path.join(src_dir, "dxapp.json")))
      if "runSpec" in manifest:
          if "interpreter" not in manifest['runSpec']:
              raise dxpy.app_builder.AppBuilderException('runSpec.interpreter field was not present')
  
          if "release" not in manifest['runSpec'] or "distribution" not in manifest['runSpec']:
              warn_message = 'runSpec.distribution or runSpec.release was not present. These fields '
              warn_message += 'will be required in a future version of the API. Recommended value '
              warn_message += 'for distribution is \"Ubuntu\" and release - \"14.04\".'
              logger.warn(warn_message)
  
          if manifest['runSpec']['interpreter'] in ["python2.7", "bash"]:
              if "file" in manifest['runSpec']:
                  entry_point_file = os.path.abspath(os.path.join(src_dir, manifest['runSpec']['file']))
                  try:
                      _check_file_syntax(entry_point_file, temp_dir, override_lang=manifest['runSpec']['interpreter'], enforce=enforce)
                  except IOError as e:
                      raise dxpy.app_builder.AppBuilderException(
                          'Could not open runSpec.file=%r. The problem was: %s' % (entry_point_file, e))
                  except DXSyntaxError:
                      raise dxpy.app_builder.AppBuilderException('Entry point file %s has syntax errors, see above for details. Rerun with --no-check-syntax to proceed anyway.' % (entry_point_file,))
              elif "code" in manifest['runSpec']:
                  try:
                      _check_syntax(manifest['runSpec']['code'], manifest['runSpec']['interpreter'], temp_dir, enforce=enforce)
                  except DXSyntaxError:
                      raise dxpy.app_builder.AppBuilderException('Code in runSpec.code has syntax errors, see above for details. Rerun with --no-check-syntax to proceed anyway.')
  
              cluster_bootstrap_scripts = _get_all_cluster_bootstrap_script_names(manifest)
              for filename in cluster_bootstrap_scripts:
                  abs_filename = os.path.abspath(os.path.join(src_dir, filename))
                  try:
                      _check_file_syntax(abs_filename,
                                         temp_dir,
                                         override_lang=manifest['runSpec']['interpreter'],
                                         enforce=enforce)
                  except IOError as e:
                      raise dxpy.app_builder.AppBuilderException(
                          'Could not open cluster bootstrap script %r. The problem was: %s' % (abs_filename, e))
                  except DXSyntaxError:
                      raise dxpy.app_builder.AppBuilderException('Code in cluster bootstrapScript %r has syntax errors, see above for details. Rerun with --no-check-syntax to proceed anyway.' % filename)
  
          if 'execDepends' in manifest['runSpec']:
              if not isinstance(manifest['runSpec']['execDepends'], list):
                  raise dxpy.app_builder.AppBuilderException('Expected runSpec.execDepends to be an array. Rerun with --no-check-syntax to proceed anyway.')
              if not all(isinstance(dep, dict) for dep in manifest['runSpec']['execDepends']):
                  raise dxpy.app_builder.AppBuilderException('Expected runSpec.execDepends to be an array of hashes. Rerun with --no-check-syntax to proceed anyway.')
              if any(dep.get('package_manager', 'apt') != 'apt' for dep in manifest['runSpec']['execDepends']):
                  if not isinstance(manifest.get('access'), dict) or 'network' not in manifest['access']:
                      msg = '\n'.join(['runSpec.execDepends specifies non-APT dependencies, but no network access spec is given.',
                      'Add {"access": {"network": ["*"]}} to allow dependencies to install.',
                      'See https://wiki.dnanexus.com/Developer-Tutorials/Request-Additional-App-Resources#Network-Access.',
                      'Rerun with --no-check-syntax to proceed anyway.'])
                      raise dxpy.app_builder.AppBuilderException(msg)
  
      if 'authorizedUsers' in manifest:
          if not isinstance(manifest['authorizedUsers'], list) or isinstance(manifest['authorizedUsers'], basestring):
              raise dxpy.app_builder.AppBuilderException('Expected authorizedUsers to be a list of strings')
          for thing in manifest['authorizedUsers']:
              if thing != 'PUBLIC' and (not isinstance(thing, basestring) or not re.match("^(org-|user-)", thing)):
                  raise dxpy.app_builder.AppBuilderException('authorizedUsers field contains an entry which is not either the string "PUBLIC" or a user or org ID')
  
      if "pricingPolicy" in manifest:
          error_message = "\"pricingPolicy\" at the top level is not accepted. It must be specified "
          error_message += "under the \"regionalOptions\" field in all enabled regions of the app"
          raise dxpy.app_builder.AppBuilderException(error_message)
  
      # Check all other files that are going to be in the resources tree.
      # For these we detect the language based on the filename extension.
      # Obviously this check can have false positives, since the app can
      # execute (or not execute!) all these files in whatever way it
      # wishes, e.g. it could use Python != 2.7 or some non-bash shell.
      # Consequently errors here are non-fatal.
      files_with_problems = []
      for dirpath, dirnames, filenames in os.walk(os.path.abspath(os.path.join(src_dir, "resources"))):
          for filename in filenames:
              # On Mac OS, the resource fork for "FILE.EXT" gets tarred up
              # as a file named "._FILE.EXT". To a naive check this
              # appears to be a file of the same extension. Therefore, we
              # exclude these from syntax checking since they are likely
              # to not parse as whatever language they appear to be.
              if not filename.startswith("._"):
                  try:
                      _check_file_syntax(os.path.join(dirpath, filename), temp_dir, enforce=True)
                  except IOError as e:
                      raise dxpy.app_builder.AppBuilderException(
                          'Could not open file in resources directory %r. The problem was: %s' %
                          (os.path.join(dirpath, filename), e)
                      )
                  except DXSyntaxError:
                      # Suppresses errors from _check_file_syntax so we
                      # only print a nice error message
                      files_with_problems.append(os.path.join(dirpath, filename))
  
      if files_with_problems:
          # Make a message of the form:
          #    "/path/to/my/app.py"
          # OR "/path/to/my/app.py and 3 other files"
          files_str = files_with_problems[0] if len(files_with_problems) == 1 else (files_with_problems[0] + " and " + str(len(files_with_problems) - 1) + " other file" + ("s" if len(files_with_problems) > 2 else ""))
          logging.warn('%s contained syntax errors, see above for details' % (files_str,))