# Path: mdk/config.py
# class Conf(Config):
#     """MDK config class"""
# 
#     userFile = None
#     _instance = None
# 
#     def __new__(cls, *args, **kwargs):
#         if not cls._instance:
#             cls._instance = super(Conf, cls).__new__(cls, *args, **kwargs)
#         return cls._instance
# 
#     def __init__(self, userfile=None):
#         if userfile == None:
#             userfile = os.path.expanduser('~/.moodle-sdk/config.json')
#         self.userFile = userfile
#         files = [
#             os.path.join(os.path.dirname(__file__), 'config-dist.json'),
#             os.path.join(os.path.dirname(__file__), 'config.json'),
#             '/etc/moodle-sdk/config.json',
#             self.userFile,
#         ]
#         Config.__init__(self, files)
#         self.load(allowMissing=True)
# 
#     def add(self, name, value):
#         """Set a new setting"""
#         super(Conf, self).add(name, value)
#         self.save()
# 
#     def remove(self, name):
#         """Remove a setting"""
#         # We need to remove from the object we use as a reference in save().
#         self.objects[self.userFile].remove(name)
#         super(Conf, self).remove(name)
#         self.save()
# 
#     def save(self, to=None, confObj=None):
#         """Save only the difference to the user config file"""
# 
#         # The base file to use is the user file
#         to = self.userFile
#         diffData = self.objects[self.userFile]
# 
#         files = list(self.files)
#         files.reverse()
# 
#         # Each of the know settings will be checked
#         data = self.data.getFlat()
#         for k in sorted(data.keys()):
#             v = data[k]
#             different = False
#             found = False
# 
#             # Respect the files order when reading the settings
#             for f in files:
#                 o = self.objects[f]
#                 ov = o.get(k)
#                 present = k in o
# 
#                 # The value hasn't been found and is different
#                 if not found and present and ov is not v:
#                     different = True
#                     break
#                 # The value is set
#                 elif present and ov is v:
#                     found = True
# 
#             # The value differs, or none of the file define it
#             if different or not found:
#                 diffData.set(k, v)
# 
#         confObj = diffData
#         super(Conf, self).save(to, confObj)
# 
#     def set(self, name, value):
#         """Set a new setting"""
#         super(Conf, self).set(name, value)
#         self.save()
# 
# Path: mdk/tools.py
# def mkdir(path, perms=0o755):
#     """Creates a directory ignoring the OS umask"""
#     oldumask = os.umask(0000)
#     os.mkdir(path, perms)
#     os.umask(oldumask)
# 
# def process(cmd, cwd=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE):
#     if type(cmd) != list:
#         cmd = shlex.split(str(cmd))
#     logging.debug(' '.join(cmd))
#     try:
#         proc = subprocess.Popen(cmd, cwd=cwd, stdout=stdout, stderr=stderr, encoding='utf-8')
#         (out, err) = proc.communicate()
#     except KeyboardInterrupt as e:
#         proc.kill()
#         raise e
#     return (proc.returncode, out.decode('utf-8') if type(out) == bytes else out, err)


import logging
import os
from .config import Conf
from .tools import mkdir, process
        if testcase:
            cmd.append(testcase)
        elif unittest:
            cmd.append(unittest)
        elif filter:
            cmd.append('--filter="%s"' % filter)
        elif testsuite:
            cmd.append('--testsuite')
            cmd.append(testsuite)

        return cmd

    def getCoverageDir(self):
        """Get the Coverage directory, and create it if required"""
        return self.Wp.getExtraDir(self.M.get('identifier'), 'coverage')

    def getCoverageUrl(self):
        """Return the code coverage URL"""
        return self.Wp.getUrl(self.M.get('identifier'), extra='coverage')

    def init(self, force=False, prefix=None):
        """Initialise the PHPUnit environment"""

        if self.M.branch_compare(23, '<'):
            raise Exception('PHPUnit is only available from Moodle 2.3')

        # Set PHPUnit data root
        phpunit_dataroot = self.M.get('dataroot') + '_phpu'
        self.M.updateConfig('phpunit_dataroot', phpunit_dataroot)
        if not os.path.isdir(phpunit_dataroot):

# Path: mdk/config.py
# class Conf(Config):
#     """MDK config class"""
# 
#     userFile = None
#     _instance = None
# 
#     def __new__(cls, *args, **kwargs):
#         if not cls._instance:
#             cls._instance = super(Conf, cls).__new__(cls, *args, **kwargs)
#         return cls._instance
# 
#     def __init__(self, userfile=None):
#         if userfile == None:
#             userfile = os.path.expanduser('~/.moodle-sdk/config.json')
#         self.userFile = userfile
#         files = [
#             os.path.join(os.path.dirname(__file__), 'config-dist.json'),
#             os.path.join(os.path.dirname(__file__), 'config.json'),
#             '/etc/moodle-sdk/config.json',
#             self.userFile,
#         ]
#         Config.__init__(self, files)
#         self.load(allowMissing=True)
# 
#     def add(self, name, value):
#         """Set a new setting"""
#         super(Conf, self).add(name, value)
#         self.save()
# 
#     def remove(self, name):
#         """Remove a setting"""
#         # We need to remove from the object we use as a reference in save().
#         self.objects[self.userFile].remove(name)
#         super(Conf, self).remove(name)
#         self.save()
# 
#     def save(self, to=None, confObj=None):
#         """Save only the difference to the user config file"""
# 
#         # The base file to use is the user file
#         to = self.userFile
#         diffData = self.objects[self.userFile]
# 
#         files = list(self.files)
#         files.reverse()
# 
#         # Each of the know settings will be checked
#         data = self.data.getFlat()
#         for k in sorted(data.keys()):
#             v = data[k]
#             different = False
#             found = False
# 
#             # Respect the files order when reading the settings
#             for f in files:
#                 o = self.objects[f]
#                 ov = o.get(k)
#                 present = k in o
# 
#                 # The value hasn't been found and is different
#                 if not found and present and ov is not v:
#                     different = True
#                     break
#                 # The value is set
#                 elif present and ov is v:
#                     found = True
# 
#             # The value differs, or none of the file define it
#             if different or not found:
#                 diffData.set(k, v)
# 
#         confObj = diffData
#         super(Conf, self).save(to, confObj)
# 
#     def set(self, name, value):
#         """Set a new setting"""
#         super(Conf, self).set(name, value)
#         self.save()
# 
# Path: mdk/tools.py
# def mkdir(path, perms=0o755):
#     """Creates a directory ignoring the OS umask"""
#     oldumask = os.umask(0000)
#     os.mkdir(path, perms)
#     os.umask(oldumask)
# 
# def process(cmd, cwd=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE):
#     if type(cmd) != list:
#         cmd = shlex.split(str(cmd))
#     logging.debug(' '.join(cmd))
#     try:
#         proc = subprocess.Popen(cmd, cwd=cwd, stdout=stdout, stderr=stderr, encoding='utf-8')
#         (out, err) = proc.communicate()
#     except KeyboardInterrupt as e:
#         proc.kill()
#         raise e
#     return (proc.returncode, out.decode('utf-8') if type(out) == bytes else out, err)


# Path: mdk/phpunit.py
import logging
import os
from .config import Conf
from .tools import mkdir, process

        if testcase:
            cmd.append(testcase)
        elif unittest:
            cmd.append(unittest)
        elif filter:
            cmd.append('--filter="%s"' % filter)
        elif testsuite:
            cmd.append('--testsuite')
            cmd.append(testsuite)

        return cmd

    def getCoverageDir(self):
        """Get the Coverage directory, and create it if required"""
        return self.Wp.getExtraDir(self.M.get('identifier'), 'coverage')

    def getCoverageUrl(self):
        """Return the code coverage URL"""
        return self.Wp.getUrl(self.M.get('identifier'), extra='coverage')

    def init(self, force=False, prefix=None):
        """Initialise the PHPUnit environment"""

        if self.M.branch_compare(23, '<'):
            raise Exception('PHPUnit is only available from Moodle 2.3')

        # Set PHPUnit data root
        phpunit_dataroot = self.M.get('dataroot') + '_phpu'
        self.M.updateConfig('phpunit_dataroot', phpunit_dataroot)
        if not os.path.isdir(phpunit_dataroot):

            mkdir(phpunit_dataroot, 0o777)