#!/usr/bin/env python
import logging
import yaml
from dulwich.repo import Repo
from dulwich.client import LocalGitClient
from dulwich.errors import NotGitRepository
from configparser import ConfigParser
from pathlib import Path
from matador import git

logger = logging.getLogger(__name__)


def get_environments(project_folder):
    """Fetch environment details from their config file."""
    file_path = Path(
        project_folder, 'config', 'environments.yml')
    try:
        file = file_path.open('r')
        environments = yaml.load(file)
        if environments:
            return environments
        else:
            raise ValueError()
    except FileNotFoundError:
        logger.error('Cannot find environments.yml file')
    except ValueError:
        logger.error('environments.yml exists but is empty')


def get_credentials(project_folder):
    """Fetch credential details from their config file."""
    file_path = Path(
        project_folder, 'config', 'credentials.yml')
    try:
        file = file_path.open('r')
        credentials = yaml.load(file)
        if credentials:
            return credentials
        else:
            raise ValueError()
    except FileNotFoundError:
        logger.error('Cannot find credentials.yml file')
    except ValueError:
        logger.error('credentials.yml exists but is empty')


def initialise_repository(proj_folder, repo_folder):
    """Create a git repository for matador to use."""
    config_file = Path(repo_folder, '.git', 'config')
    config = ConfigParser()

    repo = Repo.init(str(repo_folder))
    config.read(str(config_file))

    config['core']['sparsecheckout'] = 'true'
    config['remote "origin"'] = {
        'url': proj_folder,
        'fetch': '+refs/heads/*:refs/remotes/origin/*'
    }

    with config_file.open('w') as f:
        config.write(f)
        f.close()

    sparse_checkout_file = Path(
        repo_folder, '.git', 'info', 'sparse-checkout')
    with sparse_checkout_file.open('a') as f:
        f.write('/src\n')
        f.write('/deploy\n')
        f.close()

    return repo


class Session(object):

    """A class to hold variables for a matador session."""

    project_repo = None
    matador_repo = None
    environment = None

    @classmethod
    def initialise(self):
        if self.project_repo is None:
            self.project_repo = Repo.discover()
            self.project_folder = Path(self.project_repo.path)

            self.project = self.project_folder.name

            self.matador_project_folder = Path(
                Path.home(), '.matador', self.project)

            self.matador_repository_folder = Path(
                self.matador_project_folder, 'repository')

            self.environments = get_environments(self.project_folder)
        else:
            return

    @classmethod
    def _initialise_matador_repository(self):
        """Initialise a git repository for matador to use."""
        Path.mkdir(
            self.matador_project_folder, parents=True, exist_ok=True)
        Path.mkdir(
            self.matador_repository_folder, parents=True, exist_ok=True)

        try:
            repo = Repo(str(self.matador_repository_folder))
        except NotGitRepository:
            repo = initialise_repository(
                self.project_folder, self.matador_repository_folder)

        self.matador_repo = repo

    @classmethod
    def set_environment(self, environment):
        """Set a specific environment for those commands which require it."""

        if self.project_folder is None:
            self.initialise()

        if self.environment is None:
            self._initialise_matador_repository()
            self.environment = self.environments[environment]
            credentials = get_credentials(self.project_folder)
            self.credentials = credentials[environment]

            self.matador_environment_folder = Path(
                self.matador_project_folder, environment)
            self.matador_tickets_folder = Path(
                self.matador_environment_folder, 'tickets')
            self.matador_packages_folder = Path(
                self.matador_environment_folder, 'packages')

            Path.mkdir(
                self.matador_environment_folder, parents=True, exist_ok=True)
            Path.mkdir(
                self.matador_tickets_folder, parents=True, exist_ok=True)
            Path.mkdir(
                self.matador_packages_folder, parents=True, exist_ok=True)
        else:
            return

    @classmethod
    def update_repository(self):
        """Fetch all from the project repo to the matador repo."""

        if self.project_repo is None:
            self.initialise()

        if self.matador_repo is None:
            self._initialise_matador_repository()

        refs = LocalGitClient().fetch(str(self.project_folder), self.matador_repo)

        for key, value in refs.items():
            key = key.replace(b'heads', b'remotes/origin')
            self.matador_repo.refs[key] = value

    @classmethod
    def clear(self):
        self.project_repo = None
        self.matador_repo = None
        self.environment = None

@@ -76,50 +76,8 @@
 epo%0A
-from dulwich.client import LocalGitClient%0A
 from
@@ -4755,41 +4755,21 @@
     
-refs = LocalGitClient()
+git
 .fetch
-(str
+_all
 (sel
@@ -4782,183 +4782,32 @@
 ect_
-folder), self.matador_repo)%0A%0A        for key, value in refs.items():%0A            key = key.replace(b'heads', b'remotes/origin')%0A            self.matador_repo.refs%5Bkey%5D = value
+repo, self.matador_repo)
 %0A%0A  

Use git.fetch_all in update_repository