# Path: ice/environment_checker.py
# class EnvironmentChecker(object):
# 
#   def __init__(self, filesystem):
#     self.filesystem = filesystem
# 
#   def __enter__(self):
#     self.requirement_errors = []
#     return self
# 
#   def __exit__(self, type, value, tb):
#     self.resolve_unment_requirements()
# 
#   def require_directory_exists(self, path):
#     """
#     Validate that a directory exists.
# 
#     An attempt will be made to create a directory if it is missing
# 
#     Validation will fail if a directory cant be created at that path
#     or if a file already exists there
#     """
#     if not self.filesystem.is_directory(path):
#       self.requirement_errors.append(PathExistanceError(self.filesystem, path))
# 
#   def require_writable_path(self, path):
#     """
#     Validate that a path is writable.
# 
#     Returns an error if the path doesn't exist or it isn't writable
#     None otherwise
#     """
#     if not self.filesystem.is_writable(path):
#       self.requirement_errors.append(WritablePathError(path))
# 
#   def require_program_not_running(self, program_name):
#     """
#     Validate that a program with the name `program_name` is not currently
#     running on the users system.
#     """
#     for pid in psutil.pids():
#       try:
#         p = psutil.Process(pid)
#         if p.name().lower().startswith(program_name.lower()):
#           return self.requirement_errors.append(
#               ProcessRunningError(p.name()))
#       except Exception:
#         continue
# 
#   def resolve_unment_requirements(self):
#     """
#     Attempts to resolve any added requirements that were unmet
#     """
#     for err in self.requirement_errors:
#       err.resolve()
# 
# Path: ice/filesystem.py
# class RealFilesystem(object):
# 
#   def create_directories(self, path):
#     return os.makedirs(path)
# 
#   def path_exists(self, path):
#     return os.path.exists(path)
# 
#   def is_directory(self, path):
#     return os.path.isdir(path)
# 
#   def is_file(self, path):
#     return os.path.isfile(path)
# 
#   def is_writable(self, path):
#     return os.access(path, os.W_OK)
# 
#   def _paths_in_directory(self, directory, incl_subdirs=False):
#     assert self.is_directory(directory)
#     # Use glob instead of `os.listdir` to find files because glob will ignore
#     # hidden files. Or at least some hidden files. It ignores any file whose
#     # name starts with ".", which is basically equivalent to 'hidden files' on
#     # OSX/Linux, but means nothing on Windows. Still, its good enough, and I'd
#     # like to avoid having OS-specific 'ignore hidden files' logic in this file
#     # and let Python handle it instead.
#     pattern = os.path.join(directory, "*")
#     result = glob.glob(pattern)
#     # Unfortunately Python glob doesn't support `**` for matching 0 or 1
#     # subdirectories (like I was hoping it would), so instead we run a second
#     # glob if we need subdirectories
#     subdir_pattern = os.path.join(directory, "*", "*")
#     subdir_result = glob.glob(subdir_pattern) if incl_subdirs else []
#     return result + subdir_result
# 
#   def files_in_directory(self, directory, include_subdirectories=False):
#     assert self.is_directory(directory), "Must specify a directory"
#     return filter(
#       os.path.isfile,
#       self._paths_in_directory(directory, incl_subdirs=include_subdirectories),
#     )
# 
#   def subdirectories_of_directory(self, directory, recursive=False):
#     assert self.is_directory(directory), "Must specify a directory"
#     return filter(
#       os.path.isdir,
#       self._paths_in_directory(directory, incl_subdirs=recursive),
#     )


import os
import shutil
import stat
import tempfile
import unittest
from ice.environment_checker import EnvironmentChecker
from ice.error.env_checker_error import EnvCheckerError
from ice.filesystem import RealFilesystem


class EnvironmentCheckerTests(unittest.TestCase):

  def setUp(self):
    self.tempdir = tempfile.mkdtemp()

  def tearDown(self):
    shutil.rmtree(self.tempdir)

  def testRequireDirectoryExistsSucceedsWhenDirectoryExists(self):
    try:
      with EnvironmentChecker(RealFilesystem()) as env_checker:
        env_checker.require_directory_exists(self.tempdir)
    except:
      self.fail("Should succeed when given a directory that exists")

  def testRequireDirectoryExistsCreatesMissingDirectory(self):
    path = os.path.join(self.tempdir, "missing")
    self.assertFalse(os.path.exists(path))
    with EnvironmentChecker(RealFilesystem()) as env_checker:
      env_checker.require_directory_exists(path)
    self.assertTrue(os.path.isdir(path))

  def testRequireDirectoryExistsFailsWhenFileExistsAtPath(self):
    path = os.path.join(self.tempdir, "missing")
    self.assertFalse(os.path.exists(path))
    with open(path, "w+") as f:
      f.write("Batman")
    with self.assertRaises(EnvCheckerError):

# Path: ice/environment_checker.py
# class EnvironmentChecker(object):
# 
#   def __init__(self, filesystem):
#     self.filesystem = filesystem
# 
#   def __enter__(self):
#     self.requirement_errors = []
#     return self
# 
#   def __exit__(self, type, value, tb):
#     self.resolve_unment_requirements()
# 
#   def require_directory_exists(self, path):
#     """
#     Validate that a directory exists.
# 
#     An attempt will be made to create a directory if it is missing
# 
#     Validation will fail if a directory cant be created at that path
#     or if a file already exists there
#     """
#     if not self.filesystem.is_directory(path):
#       self.requirement_errors.append(PathExistanceError(self.filesystem, path))
# 
#   def require_writable_path(self, path):
#     """
#     Validate that a path is writable.
# 
#     Returns an error if the path doesn't exist or it isn't writable
#     None otherwise
#     """
#     if not self.filesystem.is_writable(path):
#       self.requirement_errors.append(WritablePathError(path))
# 
#   def require_program_not_running(self, program_name):
#     """
#     Validate that a program with the name `program_name` is not currently
#     running on the users system.
#     """
#     for pid in psutil.pids():
#       try:
#         p = psutil.Process(pid)
#         if p.name().lower().startswith(program_name.lower()):
#           return self.requirement_errors.append(
#               ProcessRunningError(p.name()))
#       except Exception:
#         continue
# 
#   def resolve_unment_requirements(self):
#     """
#     Attempts to resolve any added requirements that were unmet
#     """
#     for err in self.requirement_errors:
#       err.resolve()
# 
# Path: ice/filesystem.py
# class RealFilesystem(object):
# 
#   def create_directories(self, path):
#     return os.makedirs(path)
# 
#   def path_exists(self, path):
#     return os.path.exists(path)
# 
#   def is_directory(self, path):
#     return os.path.isdir(path)
# 
#   def is_file(self, path):
#     return os.path.isfile(path)
# 
#   def is_writable(self, path):
#     return os.access(path, os.W_OK)
# 
#   def _paths_in_directory(self, directory, incl_subdirs=False):
#     assert self.is_directory(directory)
#     # Use glob instead of `os.listdir` to find files because glob will ignore
#     # hidden files. Or at least some hidden files. It ignores any file whose
#     # name starts with ".", which is basically equivalent to 'hidden files' on
#     # OSX/Linux, but means nothing on Windows. Still, its good enough, and I'd
#     # like to avoid having OS-specific 'ignore hidden files' logic in this file
#     # and let Python handle it instead.
#     pattern = os.path.join(directory, "*")
#     result = glob.glob(pattern)
#     # Unfortunately Python glob doesn't support `**` for matching 0 or 1
#     # subdirectories (like I was hoping it would), so instead we run a second
#     # glob if we need subdirectories
#     subdir_pattern = os.path.join(directory, "*", "*")
#     subdir_result = glob.glob(subdir_pattern) if incl_subdirs else []
#     return result + subdir_result
# 
#   def files_in_directory(self, directory, include_subdirectories=False):
#     assert self.is_directory(directory), "Must specify a directory"
#     return filter(
#       os.path.isfile,
#       self._paths_in_directory(directory, incl_subdirs=include_subdirectories),
#     )
# 
#   def subdirectories_of_directory(self, directory, recursive=False):
#     assert self.is_directory(directory), "Must specify a directory"
#     return filter(
#       os.path.isdir,
#       self._paths_in_directory(directory, incl_subdirs=recursive),
#     )


# Path: tests/environment_checker_tests.py
import os
import shutil
import stat
import tempfile
import unittest
from ice.environment_checker import EnvironmentChecker
from ice.error.env_checker_error import EnvCheckerError
from ice.filesystem import RealFilesystem



class EnvironmentCheckerTests(unittest.TestCase):

  def setUp(self):
    self.tempdir = tempfile.mkdtemp()

  def tearDown(self):
    shutil.rmtree(self.tempdir)

  def testRequireDirectoryExistsSucceedsWhenDirectoryExists(self):
    try:
      with EnvironmentChecker(RealFilesystem()) as env_checker:
        env_checker.require_directory_exists(self.tempdir)
    except:
      self.fail("Should succeed when given a directory that exists")

  def testRequireDirectoryExistsCreatesMissingDirectory(self):
    path = os.path.join(self.tempdir, "missing")
    self.assertFalse(os.path.exists(path))
    with EnvironmentChecker(RealFilesystem()) as env_checker:
      env_checker.require_directory_exists(path)
    self.assertTrue(os.path.isdir(path))

  def testRequireDirectoryExistsFailsWhenFileExistsAtPath(self):
    path = os.path.join(self.tempdir, "missing")
    self.assertFalse(os.path.exists(path))
    with open(path, "w+") as f:
      f.write("Batman")
    with self.assertRaises(EnvCheckerError):

      with EnvironmentChecker(RealFilesystem()) as env_checker: