class_docstr: EnvironmentController inherits from BaseController and manages business logic related to the
  environment.
  
  Methods
  -------
  create(dictionary)
      Create an environment within the project
  build(id)
      Build the environment for use within the project
  list()
      List all environments within the project
  delete(id)
      Delete the specified environment from the project
class_docstr_tok: ["EnvironmentController","inherits","from","BaseController","and","manages","business","logic","related","to","the","environment",".","Methods","--","--","--","-","create","(","dictionary",")","Create","an","environment","within","the","project","build","(","id",")","Build","the","environment","for","use","within","the","project","list","(",")","List","all","environments","within","the","project","delete","(","id",")","Delete","the","specified","environment","from","the","project"]
docstr: Return the environment hash from contents in project environment directory.
  If environment_directory not present then will assume it is empty
  
  Parameters
  ----------
  save_hardware_file : bool
      include the hardware info file within the hash
  
  Returns
  -------
  str
      unique hash of the project environment directory
docstr_tok: ["Return","the","environment","hash","from","contents","in","project","environment","directory",".","If","environment_directory","not","present","then","will","assume","it","is","empty","Parameters","--","--","--","--","--","save_hardware_file",":","bool","include","the","hardware","info","file","within","the","hash","Returns","--","--","--","-","str","unique","hash","of","the","project","environment","directory"]
code: def _calculate_project_environment_hash(
      self, save_hardware_file=True
  ):
      """Return the environment hash from contents in project environment directory.
      If environment_directory not present then will assume it is empty
  
      Parameters
      ----------
      save_hardware_file : bool
          include the hardware info file within the hash
  
      Returns
      -------
      str
          unique hash of the project environment directory
      """
      # Populate paths from the project environment directory
      paths = []
      if os.path.isdir(
          self.environment_driver.environment_directory_path
      ):
          paths.extend(
              [
                  os.path.join(
                      self.environment_driver.environment_directory_path,
                      filepath,
                  )
                  for filepath in list_all_filepaths(
                      self.environment_driver.environment_directory_path
                  )
              ]
          )
  
      # Create a temp dir to save any additional files necessary
      _temp_dir = get_datmo_temp_path(self.home)
  
      # Setup compatible environment and create add paths
      paths = self._setup_compatible_environment(
          {
              "definition_filename": self.environment_driver.get_default_definition_filename()
          },
          paths,
          _temp_dir,
          save_hardware_file=save_hardware_file,
      )
  
      # Create new temp directory
      _temp_dir_2 = get_datmo_temp_path(self.home)
  
      # Hash the paths of the environment with a different temp dir
      dirhash = self.file_driver.calculate_hash_paths(
          paths, _temp_dir_2
      )
  
      # Remove both temporary directories
      shutil.rmtree(_temp_dir)
      shutil.rmtree(_temp_dir_2)
  
      return dirhash
  
imports: import os
  import shutil
  from datmo.core.controller.base import BaseController
  from datmo.core.controller.file.file_collection import FileCollectionController
  from datmo.core.entity.environment import Environment
  from datmo.core.util.i18n import get
  from datmo.core.util.validation import validate
  from datmo.core.util.spinner import Spinner
  from datmo.core.util.json_store import JSONStore
  from datmo.core.util.misc_functions import get_datmo_temp_path, list_all_filepaths
  from datmo.core.util.exceptions import PathDoesNotExist, RequiredArgumentMissing, TooManyArgumentsFound, EnvironmentNotInitialized, UnstagedChanges, ArgumentError, EnvironmentDoesNotExist, ProjectNotInitialized
label_desc: Use image node_id 19 for calling the EnvironmentController obj's underlying member method code with example usage: obj._calculate_project_environment_hash(save_hardware_file) and returns: dirhash