示例#1
0
    def setUp(self):
        self.file = os.path.join(tempfile.gettempdir(), "ConfParserTestFile")
        with open(self.file, "w", encoding='utf-8') as file:
            file.write(self.example_file)

        self.conf_parser = ConfParser()
        self.write_file_name = os.path.join(tempfile.gettempdir(),
                                            "ConfWriterTestFile")
        self.uut = ConfWriter(self.write_file_name)
示例#2
0
    def __init__(self):
        self.cli_sections = None
        self.default_section = None
        self.conf_sections = None

        self.cli_parser = CliParser()
        self.conf_parser = ConfParser()
        self.conf_writer = None

        self.local_bears = {}
        self.global_bears = {}
示例#3
0
    def load(cls, language: str, docstyle: str, coalang_dir=None):
        """
        Loads a ``DocstyleDefinition`` from the coala docstyle definition files.

        This function considers all settings inside the according coalang-files
        as markers.

        :param language:           The case insensitive programming language of
                                   the documentation comment as a string.
        :param docstyle:           The case insensitive documentation
                                   style/tool used to document code, e.g.
                                   ``"default"`` or ``"doxygen"``.
        :param coalang_dir:        Path to directory with coalang docstyle
                                   definition files. This replaces the default
                                   path if given.
        :raises FileNotFoundError: Raised when the given docstyle was not
                                   found.
        :raises KeyError:          Raised when the given language is not
                                   defined for given docstyle.
        :return:                   The ``DocstyleDefinition`` for given language
                                   and docstyle.
        """

        docstyle = docstyle.lower()

        language_config_parser = ConfParser(remove_empty_iter_elements=False)

        coalang_file = os.path.join(
            coalang_dir or os.path.dirname(__file__), docstyle + ".coalang")

        try:
            docstyle_settings = language_config_parser.parse(coalang_file)
        except FileNotFoundError:
            raise FileNotFoundError("Docstyle definition " + repr(docstyle) +
                                    " not found.")

        language = language.lower()

        try:
            docstyle_settings = docstyle_settings[language]
        except KeyError:
            raise KeyError("Language {!r} is not defined for docstyle {!r}."
                           .format(language, docstyle))

        marker_sets = (tuple(value)
                       for key, value in
                       filter(lambda kv: not kv[0].startswith("comment"),
                              docstyle_settings.contents.items()))

        return cls(language, docstyle, marker_sets)
示例#4
0
    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, '.coafile')
        self.nonexistentfile = os.path.join(self.tempdir, 'e81k7bd98t')
        with open(self.file, 'w') as file:
            file.write(self.example_file)

        self.uut = ConfParser()
        try:
            os.remove(self.nonexistentfile)
        except FileNotFoundError:
            pass

        self.sections = self.uut.parse(self.file)
示例#5
0
    def load(cls, language: str, docstyle: str, coalang_dir=None):
        """
        Loads a ``DocstyleDefinition`` from the coala docstyle definition files.

        This function considers all settings inside the according coalang-files
        as markers.

        :param language:           The case insensitive programming language of
                                   the documentation comment as a string.
        :param docstyle:           The case insensitive documentation
                                   style/tool used to document code, e.g.
                                   ``"default"`` or ``"doxygen"``.
        :param coalang_dir:        Path to directory with coalang docstyle
                                   definition files. This replaces the default
                                   path if given.
        :raises FileNotFoundError: Raised when the given docstyle was not
                                   found.
        :raises KeyError:          Raised when the given language is not
                                   defined for given docstyle.
        :return:                   The ``DocstyleDefinition`` for given language
                                   and docstyle.
        """

        docstyle = docstyle.lower()

        language_config_parser = ConfParser(remove_empty_iter_elements=False)

        coalang_file = os.path.join(coalang_dir or os.path.dirname(__file__),
                                    docstyle + ".coalang")

        try:
            docstyle_settings = language_config_parser.parse(coalang_file)
        except FileNotFoundError:
            raise FileNotFoundError("Docstyle definition " + repr(docstyle) +
                                    " not found.")

        language = language.lower()

        try:
            docstyle_settings = docstyle_settings[language]
        except KeyError:
            raise KeyError(
                "Language {!r} is not defined for docstyle {!r}.".format(
                    language, docstyle))

        marker_sets = (tuple(value) for key, value in filter(
            lambda kv: not kv[0].startswith("comment"),
            docstyle_settings.contents.items()))

        return cls(language, docstyle, marker_sets)
示例#6
0
    def __init__(self):
        self.cli_sections = None
        self.default_sections = None
        self.user_sections = None
        self.coafile_sections = None
        self.sections = None

        self.cli_parser = CliParser()
        self.conf_parser = ConfParser()
        self.conf_writer = None

        self.local_bears = {}
        self.global_bears = {}

        self.targets = []
示例#7
0
def load_config_file(filename, log_printer, silent=False):
    """
    Loads sections from a config file. Prints an appropriate warning if
    it doesn't exist and returns a section dict containing an empty
    default section in that case.

    It assumes that the cli_sections are available.

    :param filename:    The file to load settings from.
    :param log_printer: The log printer to log the warning/error to (in case).
    :param silent:      Whether or not to warn the user/exit if the file
                        doesn't exist.
    :raises SystemExit: Exits when given filename is invalid and is not the
                        default coafile. Only raised when `silent` is `False`.
    """
    filename = os.path.abspath(filename)

    try:
        return ConfParser().parse(filename)
    except FileNotFoundError:
        if not silent:
            if os.path.basename(filename) == Constants.default_coafile:
                log_printer.warn("The default coafile " +
                                 repr(Constants.default_coafile) + " was not "
                                 "found. Ignoring it.")
            else:
                log_printer.err("The requested coafile " + repr(filename) +
                                " does not exist.")
                sys.exit(2)

        return {"default": Section("default")}
示例#8
0
    def get_available_definitions():
        """
        Returns a sequence of pairs with ``(docstyle, language)`` which are
        available when using ``load()``.

        :return: A sequence of pairs with ``(docstyle, language)``.
        """
        language_config_parser = ConfParser(remove_empty_iter_elements=False)
        pattern = os.path.join(os.path.dirname(__file__), '*.coalang')

        for coalang_file in iglob(pattern):
            docstyle = os.path.splitext(os.path.basename(coalang_file))[0]
            # Ignore files that are not lowercase, as coalang files have to be.
            if docstyle.lower() == docstyle:
                for language in language_config_parser.parse(coalang_file):
                    yield docstyle, language.lower()
示例#9
0
    def get_available_definitions():
        """
        Returns a sequence of pairs with ``(docstyle, language)`` which are
        available when using ``load()``.

        :return: A sequence of pairs with ``(docstyle, language)``.
        """
        language_config_parser = ConfParser(remove_empty_iter_elements=False)
        pattern = os.path.join(os.path.dirname(__file__), '*.coalang')

        for coalang_file in iglob(pattern):
            docstyle = os.path.splitext(os.path.basename(coalang_file))[0]
            # Ignore files that are not lowercase, as coalang files have to be.
            if docstyle.lower() == docstyle:
                for language in language_config_parser.parse(coalang_file):
                    yield docstyle, language.lower()
def load_config_file(filename, log_printer=None, silent=False):
    """
    Loads sections from a config file. Prints an appropriate warning if
    it doesn't exist and returns a section dict containing an empty
    default section in that case.

    It assumes that the cli_sections are available.

    :param filename:    The file to load settings from.
    :param log_printer: The log printer to log the warning/error to (in case).
    :param silent:      Whether or not to warn the user/exit if the file
                        doesn't exist.
    :raises SystemExit: Exits when the given filename is invalid and is not the
                        default coafile. Only raised when ``silent`` is
                        ``False``.
    """
    filename = os.path.abspath(filename)

    try:
        return ConfParser().parse(filename)
    except FileNotFoundError:
        if not silent:
            if os.path.basename(filename) == Constants.default_coafile:
                logging.warning(
                    COAFILE_OUTPUT.substitute(type='Default coafile',
                                              file=Constants.default_coafile,
                                              found='not found'))
            else:
                logging.error(
                    COAFILE_OUTPUT.substitute(type='Requested coafile',
                                              file=filename,
                                              found='does not exist'))
                sys.exit(2)

        return {'default': Section('default')}
示例#11
0
def load_config_file(filename, log_printer, silent=False):
    """
    Loads sections from a config file. Prints an appropriate warning if
    it doesn't exist and returns a section dict containing an empty
    default section in that case.

    It assumes that the cli_sections are available.

    :param filename:    The file to load settings from.
    :param log_printer: The log printer to log the warning/error to (in case).
    :param silent:      Whether or not to warn the user/exit if the file
                        doesn't exist.
    :raises SystemExit: Exits when the given filename is invalid and is not the
                        default coafile. Only raised when ``silent`` is
                        ``False``.
    """
    filename = os.path.abspath(filename)

    try:
        return ConfParser().parse(filename)
    except FileNotFoundError:
        if not silent:
            if os.path.basename(filename) == Constants.default_coafile:
                log_printer.warn("The default coafile {0!r} was not found. "
                                 "You can generate a configuration file with "
                                 "your current options by adding the `--save` "
                                 "flag.".format(Constants.default_coafile))
            else:
                log_printer.err(
                    "The requested coafile {0!r} does not exist. "
                    "You can generate it with your current "
                    "options by adding the `--save` flag.".format(filename))
                sys.exit(2)

        return {"default": Section("default")}
示例#12
0
    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, ".coafile")
        self.nonexistentfile = os.path.join(self.tempdir, "e81k7bd98t")
        with open(self.file, "w") as filehandler:
            filehandler.write(self.example_file)

        self.uut = ConfParser()
        if sys.version_info < (3, 3):
            err = OSError
        else:
            err = FileNotFoundError
        try:
            os.remove(self.nonexistentfile)
        except err:
            pass
示例#13
0
    def setUp(self):
        self.file = os.path.join(tempfile.gettempdir(), "ConfParserTestFile")
        with open(self.file, "w", encoding="utf-8") as file:
            file.write(self.example_file)

        self.conf_parser = ConfParser()
        self.write_file_name = os.path.join(tempfile.gettempdir(), "ConfWriterTestFile")
        self.uut = ConfWriter(self.write_file_name)
示例#14
0
class ConfWriterTest(unittest.TestCase):
    example_file = ("to be ignored \n"
                    "    save=true\n"
                    "    a_default, another = val \n"
                    "    TEST = tobeignored  # thats a comment \n"
                    "    test = push \n"
                    "    t = \n"
                    "    [Section] \n"
                    "    [MakeFiles] \n"
                    "     j  , ANother = a \n"
                    "                   multiline \n"
                    "                   value \n"
                    "    ; just a omment \n"
                    "    ; just a omment \n"
                    "    key\\ space = value space\n"
                    "    key\\=equal = value=equal\n"
                    "    key\\\\backslash = value\\\\backslash\n"
                    "    key\\,comma = value,comma\n"
                    "    key\\#hash = value\\#hash\n"
                    "    key\\.dot = value.dot\n")

    def setUp(self):
        self.file = os.path.join(tempfile.gettempdir(), "ConfParserTestFile")
        with open(self.file, "w", encoding='utf-8') as file:
            file.write(self.example_file)

        self.conf_parser = ConfParser()
        self.write_file_name = os.path.join(tempfile.gettempdir(),
                                            "ConfWriterTestFile")
        self.uut = ConfWriter(self.write_file_name)

    def tearDown(self):
        self.uut.close()
        os.remove(self.file)
        os.remove(self.write_file_name)

    def test_exceptions(self):
        self.assertRaises(TypeError, self.uut.write_section, 5)

    def test_write(self):
        result_file = [
            "[Default]\n", "save = true\n", "a_default, another = val\n",
            "# thats a comment\n", "test = push\n", "t = \n", "[Section]\n",
            "[MakeFiles]\n", "j, ANother = a\n", "multiline\n", "value\n",
            "; just a omment\n", "; just a omment\n",
            "key\\ space = value space\n", "key\\=equal = value=equal\n",
            "key\\\\backslash = value\\\\backslash\n",
            "key\\,comma = value,comma\n", "key\\#hash = value\\#hash\n",
            "key\\.dot = value.dot\n"
        ]
        self.uut.write_sections(self.conf_parser.parse(self.file))
        self.uut.close()

        with open(self.write_file_name, "r") as f:
            lines = f.readlines()

        self.assertEqual(result_file, lines)
示例#15
0
 def test_warning_typo(self):
     logger = logging.getLogger()
     with self.assertLogs(logger, 'WARNING') as cm:
         newConf = ConfParser(comment_seperators=('#', ))
         self.assertEquals(
             cm.output[0], 'WARNING:root:The setting '
             '`comment_seperators` is deprecated. '
             'Please use `comment_separators` '
             'instead.')
示例#16
0
    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, '.coafile')
        self.nonexistentfile = os.path.join(self.tempdir, 'e81k7bd98t')
        with open(self.file, 'w') as file:
            file.write(self.example_file)

        self.uut = ConfParser()
        try:
            os.remove(self.nonexistentfile)
        except FileNotFoundError:
            pass

        logger = logging.getLogger()

        isnotdir = mock.Mock(return_value=False)
        with self.assertLogs(logger, 'WARNING') as self.cm:
            with mock.patch('os.path.isdir', isnotdir):
                self.sections = self.uut.parse(self.file)
示例#17
0
    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, ".coafile")
        self.nonexistentfile = os.path.join(self.tempdir, "e81k7bd98t")
        with open(self.file, "w") as filehandler:
            filehandler.write(self.example_file)

        self.uut = ConfParser()
        try:
            os.remove(self.nonexistentfile)
        except FileNotFoundError:
            pass
示例#18
0
class ConfWriterTest(unittest.TestCase):
    example_file = ("to be ignored \n"
                    "    save=true\n"
                    "    a_default, another = val \n"
                    "    TEST = tobeignored  # thats a comment \n"
                    "    test = push \n"
                    "    t = \n"
                    "    [MakeFiles] \n"
                    "     j  , ANother = a \n"
                    "                   multiline \n"
                    "                   value \n"
                    "    ; just a omment \n"
                    "    ; just a omment \n")

    def setUp(self):
        self.file = os.path.join(tempfile.gettempdir(), "ConfParserTestFile")
        with open(self.file, "w", encoding='utf-8') as filehandler:
            filehandler.write(self.example_file)

        self.conf_parser = ConfParser()
        self.write_file_name = os.path.join(tempfile.gettempdir(),
                                            "ConfWriterTestFile")
        self.uut = ConfWriter(self.write_file_name)

    def tearDown(self):
        self.uut.close()
        os.remove(self.file)
        os.remove(self.write_file_name)

    def test_exceptions(self):
        self.assertRaises(TypeError, self.uut.write_section, 5)

    def test_write(self):
        result_file = ["[Default]\n",
                       "save = true\n",
                       "a_default, another = val\n",
                       "# thats a comment\n",
                       "test = push\n",
                       "t = \n",
                       "\n",
                       "[MakeFiles]\n",
                       "j, ANother = a\n",
                       "multiline\n",
                       "value\n",
                       "; just a omment\n",
                       "; just a omment\n"]
        self.uut.write_sections(self.conf_parser.parse(self.file))
        self.uut.close()

        with open(self.write_file_name, "r") as f:
            lines = f.readlines()

        self.assertEqual(result_file, lines)
示例#19
0
class ConfWriterTestCase(unittest.TestCase):
    example_file = "to be ignored \n\
    save=true\n\
    a_default, another = val \n\
    TEST = tobeignored  # do you know that thats a comment \n\
    test = push \n\
    t = \n\
    [MakeFiles] \n\
     j  , ANother = a \n\
                   multiline \n\
                   value \n\
    ; just a omment \n\
    ; just a omment \n"

    def setUp(self):
        self.file = os.path.join(tempfile.gettempdir(), "ConfParserTestFile")
        with open(self.file, "w", encoding='utf-8') as filehandler:
            filehandler.write(self.example_file)

        self.conf_parser = ConfParser()
        self.write_file_name = os.path.join(tempfile.gettempdir(),
                                            "ConfWriterTestFile")
        self.uut = ConfWriter(self.write_file_name)

    def tearDown(self):
        os.remove(self.file)
        os.remove(self.write_file_name)

    def test_exceptions(self):
        self.assertRaises(TypeError, self.uut.write_section, 5)

    def test_write(self):
        result_file = ["[Default]\n",
                       "save = true\n",
                       "a_default, another = val\n",
                       "# do you know that thats a comment\n",
                       "test = push\n",
                       "t = \n",
                       "\n",
                       "[MakeFiles]\n",
                       "j, ANother = a\n",
                       "multiline\n",
                       "value\n",
                       "; just a omment\n",
                       "; just a omment\n"]
        self.uut.write_sections(self.conf_parser.reparse(self.file))
        del self.uut

        with open(self.write_file_name, "r") as f:
            lines = f.readlines()

        self.assertEqual(result_file, lines)
示例#20
0
    def test_run(self):
        defaults = ConfParser().parse(
            os.path.abspath(
                os.path.join(StringConstants.coalib_root, "default_coafile")))

        uut = SectionManager()
        # We need to use a bad filename or this will parse the .coafile we use for coala
        conf_sections = uut.run(
            arg_list=['-S', "test=5", "-c", "some_bad_filename"])[0]

        self.assertEqual(str(conf_sections["default"]),
                         "Default {config : some_bad_filename, test : 5}")
        self.assertEqual(str(conf_sections["default"].defaults),
                         str(defaults["default"]))
示例#21
0
    def __init__(self):
        self.cli_sections = None
        self.default_sections = None
        self.user_sections = None
        self.coafile_sections = None
        self.sections = None

        self.cli_parser = CliParser()
        self.conf_parser = ConfParser()
        self.conf_writer = None

        self.local_bears = {}
        self.global_bears = {}

        self.targets = []
示例#22
0
    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, ".coafile")
        self.nonexistentfile = os.path.join(self.tempdir, "e81k7bd98t")
        with open(self.file, "w") as filehandler:
            filehandler.write(self.example_file)

        self.uut = ConfParser()
        if sys.version_info < (3, 3):
            err = OSError
        else:
            err = FileNotFoundError
        try:
            os.remove(self.nonexistentfile)
        except err:
            pass
示例#23
0
    def __init__(self, language: str, coalang_dir=None):
        """
        Creates a new LanguageDefinition object from file.

        A Language Definition holds constants which may help parsing the
        language. If you want to write a bear you'll probably want to use those
        definitions to keep your bear independent of the semantics of each
        language.

        You can easily get your language definition by just creating it with
        the name of the language desired:

        >>> list(LanguageDefinition("cpp")['extensions'])
        ['.c', '.cpp', '.h', '.hpp']

        For some languages aliases exist, the name is case insensitive:

        >>> list(LanguageDefinition("C++")['extensions'])
        ['.c', '.cpp', '.h', '.hpp']

        If no language exists, you will get a ``FileNotFoundError``:

        >>> LanguageDefinition("BULLSHIT!")  # +ELLIPSIS
        Traceback (most recent call last):
         ...
        FileNotFoundError: ...

        :param language:           The actual language (e.g. C++).
        :param coalang_dir:        Path to directory with coalang language
                                   definition files. This replaces the default
                                   path if given.
        :raises FileNotFoundError: Raised when no definition is available for
                                   the given language.
        """
        SectionCreatable.__init__(self)
        self.language = language.lower()
        if self.language in LANGUAGE_DICT:
            self.language = LANGUAGE_DICT[self.language]

        coalang_file = os.path.join(
            coalang_dir or Constants.language_definitions,
            self.language + ".coalang")

        self.lang_dict = ConfParser().parse(coalang_file)["default"]
示例#24
0
    def __init__(self, language: str):
        """
        Creates a new LanguageDefinition object from file.

        A Language Definition holds constants which may help parsing the
        language. If you want to write a bear you'll probably want to use those
        definitions to keep your bear independent of the semantics of each
        language.

        :param language:           The actual language (e.g. C++).
        :raises FileNotFoundError: Raised when no definition is available for
                                   the given family.
        :raises KeyError:          Raised when no definition is available for
                                   the given language.
        """
        SectionCreatable.__init__(self)
        self.language = language.lower()
        filename = os.path.join(Constants.language_definitions,
                                language.lower() + ".coalang")
        self.lang_dict = ConfParser().parse(filename)["default"]
示例#25
0
    def __init__(self, language: str, coalang_dir=None):
        """
        Creates a new LanguageDefinition object from file.

        A Language Definition holds constants which may help parsing the
        language. If you want to write a bear you'll probably want to use those
        definitions to keep your bear independent of the semantics of each
        language.

        :param language:           The actual language (e.g. C++).
        :param coalang_dir:        Path to directory with coalang language
                                   definition files. This replaces the default
                                   path if given.
        :raises FileNotFoundError: Raised when no definition is available for
                                   the given language.
        """
        SectionCreatable.__init__(self)
        self.language = language.lower()

        coalang_file = os.path.join(
            coalang_dir or Constants.language_definitions,
            self.language + ".coalang")

        self.lang_dict = ConfParser().parse(coalang_file)["default"]
示例#26
0
class ConfParserTest(unittest.TestCase):
    example_file = """to be ignored
    a_default, another = val
    TEST = tobeignored  # do you know that thats a comment
    test = push
    t =
    [MakeFiles]
     j  , another = a
                   multiline
                   value
    # just a omment
    # just a omment
    nokey. = value
    default.test = content
    makefiles.lastone = val

    [EMPTY_ELEM_STRIP]
    A = a, b, c
    B = a, ,, d
    C = ,,,
    """

    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, ".coafile")
        self.nonexistentfile = os.path.join(self.tempdir, "e81k7bd98t")
        with open(self.file, "w") as filehandler:
            filehandler.write(self.example_file)

        self.uut = ConfParser()
        try:
            os.remove(self.nonexistentfile)
        except FileNotFoundError:
            pass

        self.sections = self.uut.parse(self.file)

    def tearDown(self):
        os.remove(self.file)

    def test_parse_nonexisting_file(self):
        self.assertRaises(FileNotFoundError,
                          self.uut.parse,
                          self.nonexistentfile)
        self.assertNotEqual(self.uut.parse(self.file, True), self.sections)

    def test_parse_nonexisting_section(self):
        self.assertRaises(IndexError,
                          self.uut.get_section,
                          "inexistent section")

    def test_parse_default_section(self):
        default_should = OrderedDict([
            ('a_default', 'val'),
            ('another', 'val'),
            ('comment0', '# do you know that thats a comment'),
            ('test', 'content'),
            ('t', '')])

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'default')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, default_should)

    def test_parse_makefiles_section(self):
        makefiles_should = OrderedDict([
            ('j', 'a\nmultiline\nvalue'),
            ('another', 'a\nmultiline\nvalue'),
            ('comment1', '# just a omment'),
            ('comment2', '# just a omment'),
            ('lastone', 'val'),
            ('comment3', ''),
            ('a_default', 'val'),
            ('comment0', '# do you know that thats a comment'),
            ('test', 'content'),
            ('t', '')])

        # Pop off the default section.
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'makefiles')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, makefiles_should)

        self.assertEqual(val["comment1"].key, "comment1")

    def test_parse_empty_elem_strip_section(self):
        empty_elem_strip_should = OrderedDict([
            ('a', 'a, b, c'),
            ('b', 'a, ,, d'),
            ('c', ',,,'),
            ('comment4', ''),
            ('a_default', 'val'),
            ('another', 'val'),
            ('comment0', '# do you know that thats a comment'),
            ('test', 'content'),
            ('t', '')])

        # Pop off the default and makefiles section.
        self.sections.popitem(last=False)
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'empty_elem_strip')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, empty_elem_strip_should)

    def test_remove_empty_iter_elements(self):
        # Test with empty-elem stripping.
        uut = ConfParser(remove_empty_iter_elements=True)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["A"]),
                         ["a", "b", "c"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["B"]),
                         ["a", "d"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["C"]),
                         [])

        # Test without stripping.
        uut = ConfParser(remove_empty_iter_elements=False)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["A"]),
                         ["a", "b", "c"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["B"]),
                         ["a", "", "", "d"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["C"]),
                         ["", "", "", ""])

    def test_config_directory(self):
        self.uut.parse(self.tempdir)
示例#27
0
class SectionManager:
    """
    The SectionManager does the following things:

    - Reading all settings in sections from
        - Default config
        - CLI
        - Configuration file
    - Collecting all the bears
    - Filling up all needed settings
    - Write back the new sections to the configuration file if needed
    - Give all information back to caller

    This is done when the run() method is invoked. Anything else is just helper
    stuff and initialization.
    """
    def __init__(self):
        self.cli_sections = None
        self.default_sections = None
        self.user_sections = None
        self.coafile_sections = None
        self.sections = None

        self.cli_parser = CliParser()
        self.conf_parser = ConfParser()
        self.conf_writer = None

        self.local_bears = {}
        self.global_bears = {}

        self.targets = []

    def run(self, arg_list=sys.argv[1:]):
        self._load_configuration(arg_list)
        self._fill_settings()
        self._save_configuration()
        self._warn_nonexistent_targets()

        return self.sections, self.local_bears, self.global_bears, self.targets

    def _load_configuration(self, arg_list):
        self.cli_sections = self.cli_parser.reparse(arg_list=arg_list)
        # We dont want to store targets argument back to file, thus remove it
        for item in list(
                self.cli_sections["default"].contents.pop("targets", "")):
            self.targets.append(item.lower())

        self.default_sections = self._load_config_file(
            StringConstants.system_coafile)

        self.user_sections = self._load_config_file(
            StringConstants.user_coafile,
            silent=True)

        default_config = str(
            self.default_sections["default"].get("config", ".coafile"))
        user_config = str(
            self.user_sections["default"].get("config", default_config))
        config = os.path.abspath(str(
            self.cli_sections["default"].get("config", user_config)))

        self.coafile_sections = self._load_config_file(config)

        self.sections = self._merge_section_dicts(self.default_sections,
                                                  self.user_sections)

        self.sections = self._merge_section_dicts(self.sections,
                                                  self.coafile_sections)

        self.sections = self._merge_section_dicts(self.sections,
                                                  self.cli_sections)

        for section in self.sections:
            if section != "default":
                self.sections[section].defaults = self.sections["default"]

    def _load_config_file(self, filename, silent=False):
        """
        Loads sections from a config file. Prints an appropriate warning if
        it doesn't exist and returns a section dict containing an empty
        default section in that case.

        It assumes that the cli_sections are available.

        :param filename: The file to load settings from.
        :param silent:   Whether or not to warn the user if the file doesn't
                         exist.
        """
        filename = os.path.abspath(filename)

        try:
            return self.conf_parser.reparse(filename)
        except self.conf_parser.FileNotFoundError:
            if not silent:
                self.cli_sections["default"].retrieve_logging_objects()
                self.cli_sections["default"].log_printer.warn(
                    _("The requested coafile '{filename}' does not exist. "
                      "Thus it will not be used.").format(filename=filename))

            return {"default": Section("default")}

    def _fill_settings(self):
        for section_name in self.sections:
            section = self.sections[section_name]
            section.retrieve_logging_objects()

            bear_dirs = path_list(section.get("bear_dirs", ""))
            bear_dirs.append(os.path.join(StringConstants.coalib_bears_root,
                                          "**"))
            bears = list(section.get("bears", ""))
            local_bears = collect_bears(bear_dirs,
                                        bears,
                                        [BEAR_KIND.LOCAL])
            global_bears = collect_bears(bear_dirs,
                                         bears,
                                         [BEAR_KIND.GLOBAL])
            filler = SectionFiller(section)
            all_bears = copy.deepcopy(local_bears)
            all_bears.extend(global_bears)
            filler.fill_section(all_bears)

            self.local_bears[section_name] = local_bears
            self.global_bears[section_name] = global_bears

    def _save_configuration(self):
        self.conf_writer = None
        default_section = self.sections["default"]
        try:
            if bool(default_section.get("save", "false")):
                self.conf_writer = ConfWriter(str(
                    default_section.get("config", ".coafile")))
        except ValueError:
            self.conf_writer = ConfWriter(str(default_section.get("save",
                                                                  ".coafile")))

        if self.conf_writer is not None:
            self.conf_writer.write_sections(self.sections)

    @staticmethod
    def _merge_section_dicts(lower, higher):
        """
        Merges the section dictionaries. The values of higher will take
        precedence over the ones of lower. Lower will hold the modified dict in
        the end.
        """
        for name in higher:
            if name in lower:
                lower[name].update(higher[name], ignore_defaults=True)
            else:
                # no deep copy needed
                lower[name] = higher[name]

        return lower

    def _warn_nonexistent_targets(self):
        for target in self.targets:
            if target not in self.sections:
                self.sections["default"].log_printer.warn(
                    _("The requested section '{section}' is not existent. "
                      "Thus it cannot be executed.").format(section=target))
示例#28
0
class ConfParserTest(unittest.TestCase):
    example_file = """to be ignored
    a_default, another = val
    TEST = tobeignored  # do you know that thats a comment
    test = push
    t =
    [MakeFiles]
     j  , another = a
                   multiline
                   value
    # just a omment
    # just a omment
    nokey. = value
    default.test = content
    makefiles.lastone = val

    [EMPTY_ELEM_STRIP]
    A = a, b, c
    B = a, ,, d
    C = ,,,
    """

    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, ".coafile")
        self.nonexistentfile = os.path.join(self.tempdir, "e81k7bd98t")
        with open(self.file, "w") as filehandler:
            filehandler.write(self.example_file)

        self.uut = ConfParser()
        try:
            os.remove(self.nonexistentfile)
        except FileNotFoundError:
            pass

        self.sections = self.uut.parse(self.file)

    def tearDown(self):
        os.remove(self.file)

    def test_parse_nonexisting_file(self):
        self.assertRaises(FileNotFoundError, self.uut.parse,
                          self.nonexistentfile)
        self.assertNotEqual(self.uut.parse(self.file, True), self.sections)

    def test_parse_nonexisting_section(self):
        self.assertRaises(IndexError, self.uut.get_section,
                          "inexistent section")

    def test_parse_default_section(self):
        default_should = OrderedDict([('a_default', 'val'), ('another', 'val'),
                                      ('comment0',
                                       '# do you know that thats a comment'),
                                      ('test', 'content'), ('t', '')])

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'default')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, default_should)

    def test_parse_makefiles_section(self):
        makefiles_should = OrderedDict([('j', 'a\nmultiline\nvalue'),
                                        ('another', 'a\nmultiline\nvalue'),
                                        ('comment1', '# just a omment'),
                                        ('comment2', '# just a omment'),
                                        ('lastone', 'val'), ('comment3', ''),
                                        ('a_default', 'val'),
                                        ('comment0',
                                         '# do you know that thats a comment'),
                                        ('test', 'content'), ('t', '')])

        # Pop off the default section.
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'makefiles')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, makefiles_should)

        self.assertEqual(val["comment1"].key, "comment1")

    def test_parse_empty_elem_strip_section(self):
        empty_elem_strip_should = OrderedDict([
            ('a', 'a, b, c'), ('b', 'a, ,, d'), ('c', ',,,'), ('comment4', ''),
            ('a_default', 'val'), ('another', 'val'),
            ('comment0', '# do you know that thats a comment'),
            ('test', 'content'), ('t', '')
        ])

        # Pop off the default and makefiles section.
        self.sections.popitem(last=False)
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'empty_elem_strip')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, empty_elem_strip_should)

    def test_remove_empty_iter_elements(self):
        # Test with empty-elem stripping.
        uut = ConfParser(remove_empty_iter_elements=True)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["A"]),
                         ["a", "b", "c"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["B"]),
                         ["a", "d"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["C"]), [])

        # Test without stripping.
        uut = ConfParser(remove_empty_iter_elements=False)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["A"]),
                         ["a", "b", "c"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["B"]),
                         ["a", "", "", "d"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["C"]),
                         ["", "", "", ""])

    def test_config_directory(self):
        self.uut.parse(self.tempdir)
示例#29
0
class ConfWriterTest(unittest.TestCase):
    example_file = ('to be ignored \n'
                    '    save=true\n'
                    '    a_default, another = val \n'
                    '    TEST = tobeignored  # thats a comment \n'
                    '    test = push \n'
                    '    t = \n'
                    '    [Section] \n'
                    '    [MakeFiles] \n'
                    '     j  , ANother = a \n'
                    '                   multiline \n'
                    '                   value \n'
                    '    ; just a omment \n'
                    '    ; just a omment \n'
                    '    key\\ space = value space\n'
                    '    key\\=equal = value=equal\n'
                    '    key\\\\backslash = value\\\\backslash\n'
                    '    key\\,comma = value,comma\n'
                    '    key\\#hash = value\\#hash\n'
                    '    key\\.dot = value.dot\n')

    def setUp(self):
        self.file = os.path.join(tempfile.gettempdir(), 'ConfParserTestFile')
        with open(self.file, 'w', encoding='utf-8') as file:
            file.write(self.example_file)

        self.conf_parser = ConfParser()
        self.write_file_name = os.path.join(tempfile.gettempdir(),
                                            'ConfWriterTestFile')
        self.uut = ConfWriter(self.write_file_name)

    def tearDown(self):
        self.uut.close()
        os.remove(self.file)
        os.remove(self.write_file_name)

    def test_exceptions(self):
        self.assertRaises(TypeError, self.uut.write_section, 5)

    def test_write(self):
        result_file = ['[Default]\n',
                       'save = true\n',
                       'a_default, another = val\n',
                       '# thats a comment\n',
                       'test = push\n',
                       't = \n',
                       '[Section]\n',
                       '[MakeFiles]\n',
                       'j, ANother = a\n',
                       'multiline\n',
                       'value\n',
                       '; just a omment\n',
                       '; just a omment\n',
                       'key\\ space = value space\n',
                       'key\\=equal = value=equal\n',
                       'key\\\\backslash = value\\\\backslash\n',
                       'key\\,comma = value,comma\n',
                       'key\\#hash = value\\#hash\n',
                       'key\\.dot = value.dot\n']
        self.uut.write_sections(self.conf_parser.parse(self.file))
        self.uut.close()

        with open(self.write_file_name, 'r') as f:
            lines = f.readlines()

        self.assertEqual(result_file, lines)
示例#30
0
    def load(cls, language: str, docstyle: str, coalang_dir=None):
        """
        Loads a ``DocstyleDefinition`` from the coala docstyle definition files.

        This function considers all settings inside the according coalang-files
        as markers, except ``param_start``, ``param_end`` and ``return_sep``
        which are considered as special metadata markers.

        .. note::

            When placing new coala docstyle definition files, these must
            consist of only lowercase letters and end with ``.coalang``!

        :param language:           The case insensitive programming language of
                                   the documentation comment as a string.
        :param docstyle:           The case insensitive documentation
                                   style/tool used to document code, e.g.
                                   ``"default"`` or ``"doxygen"``.
        :param coalang_dir:        Path to directory with coalang docstyle
                                   definition files. This replaces the default
                                   path if given.
        :raises FileNotFoundError: Raised when the given docstyle was not
                                   found.
        :raises KeyError:          Raised when the given language is not
                                   defined for given docstyle.
        :return:                   The ``DocstyleDefinition`` for given language
                                   and docstyle.
        """

        docstyle = docstyle.lower()

        language_config_parser = ConfParser(remove_empty_iter_elements=False)

        coalang_file = os.path.join(
            coalang_dir or os.path.dirname(__file__), docstyle + '.coalang')

        try:
            docstyle_settings = language_config_parser.parse(coalang_file)
        except FileNotFoundError:
            raise FileNotFoundError('Docstyle definition ' + repr(docstyle) +
                                    ' not found.')

        language = language.lower()

        try:
            docstyle_settings = docstyle_settings[language]
        except KeyError:
            raise KeyError('Language {!r} is not defined for docstyle {!r}.'
                           .format(language, docstyle))

        metadata_settings = ('param_start', 'param_end', 'return_sep')

        metadata = cls.Metadata(*(str(docstyle_settings.get(req_setting, ''))
                                  for req_setting in metadata_settings))

        marker_sets = (tuple(value)
                       for key, value in
                       docstyle_settings.contents.items()
                       if key not in metadata_settings and
                       not key.startswith('comment'))

        return cls(language, docstyle, marker_sets, metadata)
示例#31
0
    def test_remove_empty_iter_elements(self):
        # Test with empty-elem stripping.
        uut = ConfParser(remove_empty_iter_elements=True)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["A"]),
                         ["a", "b", "c"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["B"]),
                         ["a", "d"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["C"]), [])

        # Test without stripping.
        uut = ConfParser(remove_empty_iter_elements=False)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["A"]),
                         ["a", "b", "c"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["B"]),
                         ["a", "", "", "d"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["C"]),
                         ["", "", "", ""])
示例#32
0
    def test_remove_empty_iter_elements(self):
        # Test with empty-elem stripping.
        uut = ConfParser(remove_empty_iter_elements=True)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["A"]),
                         ["a", "b", "c"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["B"]),
                         ["a", "d"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["C"]),
                         [])

        # Test without stripping.
        uut = ConfParser(remove_empty_iter_elements=False)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["A"]),
                         ["a", "b", "c"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["B"]),
                         ["a", "", "", "d"])
        self.assertEqual(list(uut.get_section("EMPTY_ELEM_STRIP")["C"]),
                         ["", "", "", ""])
示例#33
0
class ConfParserTest(unittest.TestCase):
    example_file = """setting = without_section
    [foo]
    to be ignored
    a_default, another = val
    TEST = tobeignored  # do you know that thats a comment
    test = push
    t =
    escaped_\\=equal = escaped_\\#hash
    escaped_\\\\backslash = escaped_\\ space
    escaped_\\,comma = escaped_\\.dot
    [MakeFiles]
     j  , another = a
                   multiline
                   value
    # just a comment
    # just a comment
    nokey. = value
    foo.test = content
    makefiles.lastone = val
    append += key

    [EMPTY_ELEM_STRIP]
    A = a, b, c
    B = a, ,, d
    C = ,,,

    [name]
    key1 = value1
    key2 = value1
    key1 = value2
    """

    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, '.coafile')
        self.nonexistentfile = os.path.join(self.tempdir, 'e81k7bd98t')
        with open(self.file, 'w') as file:
            file.write(self.example_file)

        self.uut = ConfParser()
        try:
            os.remove(self.nonexistentfile)
        except FileNotFoundError:
            pass

        logger = logging.getLogger()

        with self.assertLogs(logger, 'WARNING') as self.cm:
            self.sections = self.uut.parse(self.file)

    def tearDown(self):
        os.remove(self.file)

    def test_warning_typo(self):
        logger = logging.getLogger()
        with self.assertLogs(logger, 'WARNING') as cm:
            newConf = ConfParser(comment_seperators=('#',))
            self.assertEquals(cm.output[0], 'WARNING:root:The setting '
                              '`comment_seperators` is deprecated. '
                              'Please use `comment_separators` '
                              'instead.')

    def test_parse_nonexisting_file(self):
        self.assertRaises(FileNotFoundError,
                          self.uut.parse,
                          self.nonexistentfile)
        self.assertNotEqual(self.uut.parse(self.file, True), self.sections)

    def test_parse_nonexisting_section(self):
        self.assertRaises(IndexError,
                          self.uut.get_section,
                          'non-existent section')

    def test_parse_default_section_deprecated(self):
        default_should = OrderedDict([
            ('setting', 'without_section')])

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'default')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, default_should)

        self.assertRegex(self.cm.output[0],
                         'A setting does not have a section.')

        # Check if line number is correctly set when
        # no section is given
        line_num = val.contents['setting'].line_number
        self.assertEqual(line_num, 1)

    def test_parse_foo_section(self):
        foo_should = OrderedDict([
            ('a_default', 'val'),
            ('another', 'val'),
            ('comment0', '# do you know that thats a comment'),
            ('test', 'content'),
            ('t', ''),
            ('escaped_=equal', 'escaped_#hash'),
            ('escaped_\\backslash', 'escaped_ space'),
            ('escaped_,comma', 'escaped_.dot')])

        # Pop off the default section.
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'foo')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, foo_should)

    def test_parse_makefiles_section(self):
        makefiles_should = OrderedDict([
            ('j', 'a\nmultiline\nvalue'),
            ('another', 'a\nmultiline\nvalue'),
            ('comment1', '# just a comment'),
            ('comment2', '# just a comment'),
            ('lastone', 'val'),
            ('append', 'key'),
            ('comment3', '')])

        # Pop off the default and foo section.
        self.sections.popitem(last=False)
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'makefiles')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, makefiles_should)

        self.assertEqual(val['comment1'].key, 'comment1')

        # Check starting line number of
        # settings in makefiles section.
        line_num = val.contents['another'].line_number
        self.assertEqual(line_num, 12)
        line_num = val.contents['append'].line_number
        self.assertEqual(line_num, 20)

    def test_parse_empty_elem_strip_section(self):
        empty_elem_strip_should = OrderedDict([
            ('a', 'a, b, c'),
            ('b', 'a, ,, d'),
            ('c', ',,,'),
            ('comment4', '')])

        # Pop off the default, foo and makefiles section.
        self.sections.popitem(last=False)
        self.sections.popitem(last=False)
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'empty_elem_strip')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, empty_elem_strip_should)

        # Check starting line number of
        # settings in empty_elem_strip section.
        line_num = val.contents['b'].line_number
        self.assertEqual(line_num, 24)

    def test_line_number_name_section(self):
        # Pop off the default, foo, makefiles and empty_elem_strip sections.
        self.sections.popitem(last=False)
        self.sections.popitem(last=False)
        self.sections.popitem(last=False)
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        line_num = val.contents['key1'].line_number
        self.assertEqual(line_num, 30)

    def test_remove_empty_iter_elements(self):
        # Test with empty-elem stripping.
        uut = ConfParser(remove_empty_iter_elements=True)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['A']),
                         ['a', 'b', 'c'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['B']),
                         ['a', 'd'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['C']),
                         [])

        # Test without stripping.
        uut = ConfParser(remove_empty_iter_elements=False)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['A']),
                         ['a', 'b', 'c'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['B']),
                         ['a', '', '', 'd'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['C']),
                         ['', '', '', ''])

    def test_config_directory(self):
        self.uut.parse(self.tempdir)

    def test_settings_override_warning(self):
        self.assertEqual(self.cm.output[1], 'WARNING:root:test setting has '
                                            'already been defined in section '
                                            'foo. The previous setting will '
                                            'be overridden.')
        self.assertEqual(self.cm.output[2], 'WARNING:root:key1 setting has '
                                            'already been defined in section '
                                            'name. The previous setting will '
                                            'be overridden.')
示例#34
0
class ConfParserTestCase(unittest.TestCase):
    example_file = """to be ignored
    a_default, another = val
    TEST = tobeignored  # do you know that thats a comment
    test = push
    t =
    [MakeFiles]
     j  , another = a
                   multiline
                   value
    ; just a omment
    ; just a omment
    nokey. = value
    default.test = content
    makefiles.lastone = val
    """

    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, ".coafile")
        self.nonexistentfile = os.path.join(self.tempdir, "e81k7bd98t")
        with open(self.file, "w") as filehandler:
            filehandler.write(self.example_file)

        self.uut = ConfParser()
        if sys.version_info < (3, 3):
            err = OSError
        else:
            err = FileNotFoundError
        try:
            os.remove(self.nonexistentfile)
        except err:
            pass

    def tearDown(self):
        os.remove(self.file)

    def test_parse(self):
        default_should = OrderedDict([('a_default', 'val'), ('another', 'val'),
                                      ('comment0',
                                       '# do you know that thats a comment'),
                                      ('test', 'content'), ('t', '')])

        makefiles_should = OrderedDict([('j', 'a\nmultiline\nvalue'),
                                        ('another', 'a\nmultiline\nvalue'),
                                        ('comment1', '; just a omment'),
                                        ('comment2', '; just a omment'),
                                        ('lastone', 'val'), ('comment3', ''),
                                        ('a_default', 'val'),
                                        ('comment0',
                                         '# do you know that thats a comment'),
                                        ('test', 'content'), ('t', '')])

        self.assertRaises(self.uut.FileNotFoundError, self.uut.parse,
                          self.nonexistentfile)
        sections = self.uut.parse(self.file)
        self.assertNotEqual(self.uut.reparse(self.file), sections)

        key, val = sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'default')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, default_should)

        key, val = sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'makefiles')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, makefiles_should)

        self.assertEqual(val["comment1"].key, "comment1")

        self.assertRaises(IndexError, self.uut.get_section,
                          "inexistent section")

    def test_config_directory(self):
        self.uut.parse(self.tempdir)
示例#35
0
class SectionManager:
    """
    The SectionManager does the following things:

    - Reading all settings in sections from
        - Default config
        - CLI
        - Configuration file
    - Collecting all the bears
    - Filling up all needed settings
    - Write back the new sections to the configuration file if needed
    - Give all information back to caller

    This is done when the run() method is invoked. Anything else is just helper
    stuff and initialization.
    """
    def __init__(self):
        self.cli_sections = None
        self.default_sections = None
        self.user_sections = None
        self.coafile_sections = None
        self.sections = None

        self.cli_parser = CliParser()
        self.conf_parser = ConfParser()
        self.conf_writer = None

        self.local_bears = {}
        self.global_bears = {}

        self.targets = []

    def run(self, arg_list=sys.argv[1:]):
        self._load_configuration(arg_list)
        self._fill_settings()
        self._save_configuration()
        self._warn_nonexistent_targets()

        return self.sections, self.local_bears, self.global_bears, self.targets

    def _load_configuration(self, arg_list):
        self.cli_sections = self.cli_parser.reparse(arg_list=arg_list)
        # We dont want to store targets argument back to file, thus remove it
        for item in list(self.cli_sections["default"].contents.pop(
                "targets", "")):
            self.targets.append(item.lower())

        self.default_sections = self._load_config_file(
            StringConstants.system_coafile)

        self.user_sections = self._load_config_file(
            StringConstants.user_coafile, silent=True)

        default_config = str(self.default_sections["default"].get(
            "config", ".coafile"))
        user_config = str(self.user_sections["default"].get(
            "config", default_config))
        config = os.path.abspath(
            str(self.cli_sections["default"].get("config", user_config)))

        self.coafile_sections = self._load_config_file(config)

        self.sections = self._merge_section_dicts(self.default_sections,
                                                  self.user_sections)

        self.sections = self._merge_section_dicts(self.sections,
                                                  self.coafile_sections)

        self.sections = self._merge_section_dicts(self.sections,
                                                  self.cli_sections)

        for section in self.sections:
            if section != "default":
                self.sections[section].defaults = self.sections["default"]

    def _load_config_file(self, filename, silent=False):
        """
        Loads sections from a config file. Prints an appropriate warning if
        it doesn't exist and returns a section dict containing an empty
        default section in that case.

        It assumes that the cli_sections are available.

        :param filename: The file to load settings from.
        :param silent:   Whether or not to warn the user if the file doesn't
                         exist.
        """
        filename = os.path.abspath(filename)

        try:
            return self.conf_parser.reparse(filename)
        except self.conf_parser.FileNotFoundError:
            if not silent:
                self.cli_sections["default"].retrieve_logging_objects()
                self.cli_sections["default"].log_printer.warn(
                    _("The requested coafile '{filename}' does not exist. "
                      "Thus it will not be used.").format(filename=filename))

            return {"default": Section("default")}

    def _fill_settings(self):
        for section_name in self.sections:
            section = self.sections[section_name]
            section.retrieve_logging_objects()

            bear_dirs = path_list(section.get("bear_dirs", ""))
            bear_dirs.append(
                os.path.join(StringConstants.coalib_bears_root, "**"))
            bears = list(section.get("bears", ""))
            local_bears = collect_bears(bear_dirs, bears, [BEAR_KIND.LOCAL])
            global_bears = collect_bears(bear_dirs, bears, [BEAR_KIND.GLOBAL])
            filler = SectionFiller(section)
            all_bears = copy.deepcopy(local_bears)
            all_bears.extend(global_bears)
            filler.fill_section(all_bears)

            self.local_bears[section_name] = local_bears
            self.global_bears[section_name] = global_bears

    def _save_configuration(self):
        self.conf_writer = None
        default_section = self.sections["default"]
        try:
            if bool(default_section.get("save", "false")):
                self.conf_writer = ConfWriter(
                    str(default_section.get("config", ".coafile")))
        except ValueError:
            self.conf_writer = ConfWriter(
                str(default_section.get("save", ".coafile")))

        if self.conf_writer is not None:
            self.conf_writer.write_sections(self.sections)

    @staticmethod
    def _merge_section_dicts(lower, higher):
        """
        Merges the section dictionaries. The values of higher will take
        precedence over the ones of lower. Lower will hold the modified dict in
        the end.
        """
        for name in higher:
            if name in lower:
                lower[name].update(higher[name], ignore_defaults=True)
            else:
                # no deep copy needed
                lower[name] = higher[name]

        return lower

    def _warn_nonexistent_targets(self):
        for target in self.targets:
            if target not in self.sections:
                self.sections["default"].log_printer.warn(
                    _("The requested section '{section}' is not existent. "
                      "Thus it cannot be executed.").format(section=target))
示例#36
0
class ConfParserTest(unittest.TestCase):
    example_file = """to be ignored
    a_default, another = val
    TEST = tobeignored  # do you know that thats a comment
    test = push
    t =
    [MakeFiles]
     j  , another = a
                   multiline
                   value
    # just a omment
    # just a omment
    nokey. = value
    default.test = content
    makefiles.lastone = val
    """

    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, ".coafile")
        self.nonexistentfile = os.path.join(self.tempdir, "e81k7bd98t")
        with open(self.file, "w") as filehandler:
            filehandler.write(self.example_file)

        self.uut = ConfParser()
        try:
            os.remove(self.nonexistentfile)
        except FileNotFoundError:
            pass

    def tearDown(self):
        os.remove(self.file)

    def test_parse(self):
        default_should = OrderedDict(
            [
                ("a_default", "val"),
                ("another", "val"),
                ("comment0", "# do you know that thats a comment"),
                ("test", "content"),
                ("t", ""),
            ]
        )

        makefiles_should = OrderedDict(
            [
                ("j", "a\nmultiline\nvalue"),
                ("another", "a\nmultiline\nvalue"),
                ("comment1", "# just a omment"),
                ("comment2", "# just a omment"),
                ("lastone", "val"),
                ("comment3", ""),
                ("a_default", "val"),
                ("comment0", "# do you know that thats a comment"),
                ("test", "content"),
                ("t", ""),
            ]
        )

        self.assertRaises(FileNotFoundError, self.uut.parse, self.nonexistentfile)
        sections = self.uut.parse(self.file)
        self.assertNotEqual(self.uut.parse(self.file, True), sections)

        key, val = sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, "default")

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, default_should)

        key, val = sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, "makefiles")

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, makefiles_should)

        self.assertEqual(val["comment1"].key, "comment1")

        self.assertRaises(IndexError, self.uut.get_section, "inexistent section")

    def test_config_directory(self):
        self.uut.parse(self.tempdir)
示例#37
0
    def load(cls, language: str, docstyle: str, coalang_dir=None):
        """
        Loads a ``DocstyleDefinition`` from the coala docstyle definition files.

        This function considers all settings inside the according coalang-files
        as markers, except ``param_start``, ``param_end`` and ``return_sep``
        which are considered as special metadata markers.

        .. note::

            When placing new coala docstyle definition files, these must
            consist of only lowercase letters and end with ``.coalang``!

        :param language:           The case insensitive programming language of
                                   the documentation comment as a string.
        :param docstyle:           The case insensitive documentation
                                   style/tool used to document code, e.g.
                                   ``"default"`` or ``"doxygen"``.
        :param coalang_dir:        Path to directory with coalang docstyle
                                   definition files. This replaces the default
                                   path if given.
        :raises FileNotFoundError: Raised when the given docstyle was not
                                   found.
        :raises KeyError:          Raised when the given language is not
                                   defined for given docstyle.
        :return:                   The ``DocstyleDefinition`` for given language
                                   and docstyle.
        """

        docstyle = docstyle.lower()

        language_config_parser = ConfParser(remove_empty_iter_elements=False)

        coalang_file = os.path.join(coalang_dir or os.path.dirname(__file__),
                                    docstyle + '.coalang')

        try:
            docstyle_settings = language_config_parser.parse(coalang_file)
        except FileNotFoundError:
            raise FileNotFoundError('Docstyle definition ' + repr(docstyle) +
                                    ' not found.')

        language = language.lower()

        try:
            docstyle_settings = docstyle_settings[language]
        except KeyError:
            raise KeyError(
                'Language {!r} is not defined for docstyle {!r}.'.format(
                    language, docstyle))

        metadata_settings = ('param_start', 'param_end', 'exception_start',
                             'exception_end', 'return_sep')

        metadata = cls.Metadata(*(str(docstyle_settings.get(req_setting, ''))
                                  for req_setting in metadata_settings))

        marker_sets = (
            tuple(value) for key, value in docstyle_settings.contents.items()
            if key not in metadata_settings and not key.startswith('comment'))

        return cls(language, docstyle, marker_sets, metadata)
示例#38
0
    def test_remove_empty_iter_elements(self):
        # Test with empty-elem stripping.
        uut = ConfParser(remove_empty_iter_elements=True)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['A']),
                         ['a', 'b', 'c'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['B']),
                         ['a', 'd'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['C']),
                         [])

        # Test without stripping.
        uut = ConfParser(remove_empty_iter_elements=False)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['A']),
                         ['a', 'b', 'c'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['B']),
                         ['a', '', '', 'd'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['C']),
                         ['', '', '', ''])
示例#39
0
class ConfParserTest(unittest.TestCase):
    example_file = """to be ignored
    a_default, another = val
    TEST = tobeignored  # do you know that thats a comment
    test = push
    t =
    [MakeFiles]
     j  , another = a
                   multiline
                   value
    ; just a omment
    ; just a omment
    nokey. = value
    default.test = content
    makefiles.lastone = val
    """

    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, ".coafile")
        self.nonexistentfile = os.path.join(self.tempdir, "e81k7bd98t")
        with open(self.file, "w") as filehandler:
            filehandler.write(self.example_file)

        self.uut = ConfParser()
        if sys.version_info < (3, 3):
            err = OSError
        else:
            err = FileNotFoundError
        try:
            os.remove(self.nonexistentfile)
        except err:
            pass

    def tearDown(self):
        os.remove(self.file)

    def test_parse(self):
        default_should = OrderedDict([
            ('a_default', 'val'),
            ('another', 'val'),
            ('comment0', '# do you know that thats a comment'),
            ('test', 'content'),
            ('t', '')
        ])

        makefiles_should = OrderedDict([
            ('j', 'a\nmultiline\nvalue'),
            ('another', 'a\nmultiline\nvalue'),
            ('comment1', '; just a omment'),
            ('comment2', '; just a omment'),
            ('lastone', 'val'),
            ('comment3', ''),
            ('a_default', 'val'),
            ('comment0', '# do you know that thats a comment'),
            ('test', 'content'),
            ('t', '')
        ])

        self.assertRaises(self.uut.FileNotFoundError,
                          self.uut.parse,
                          self.nonexistentfile)
        sections = self.uut.parse(self.file)
        self.assertNotEqual(self.uut.parse(self.file, True), sections)

        key, val = sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'default')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, default_should)

        key, val = sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'makefiles')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, makefiles_should)

        self.assertEqual(val["comment1"].key, "comment1")

        self.assertRaises(IndexError,
                          self.uut.get_section,
                          "inexistent section")

    def test_config_directory(self):
        self.uut.parse(self.tempdir)
示例#40
0
class ConfParserTest(unittest.TestCase):
    example_file = """to be ignored
    a_default, another = val
    TEST = tobeignored  # do you know that thats a comment
    test = push
    t =
    escaped_\\=equal = escaped_\\#hash
    escaped_\\\\backslash = escaped_\\ space
    escaped_\\,comma = escaped_\\.dot
    [MakeFiles]
     j  , another = a
                   multiline
                   value
    # just a omment
    # just a omment
    nokey. = value
    default.test = content
    makefiles.lastone = val

    [EMPTY_ELEM_STRIP]
    A = a, b, c
    B = a, ,, d
    C = ,,,
    """

    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, '.coafile')
        self.nonexistentfile = os.path.join(self.tempdir, 'e81k7bd98t')
        with open(self.file, 'w') as file:
            file.write(self.example_file)

        self.uut = ConfParser()
        try:
            os.remove(self.nonexistentfile)
        except FileNotFoundError:
            pass

        self.sections = self.uut.parse(self.file)

    def tearDown(self):
        os.remove(self.file)

    def test_parse_nonexisting_file(self):
        self.assertRaises(FileNotFoundError,
                          self.uut.parse,
                          self.nonexistentfile)
        self.assertNotEqual(self.uut.parse(self.file, True), self.sections)

    def test_parse_nonexisting_section(self):
        self.assertRaises(IndexError,
                          self.uut.get_section,
                          'inexistent section')

    def test_parse_default_section(self):
        default_should = OrderedDict([
            ('a_default', 'val'),
            ('another', 'val'),
            ('comment0', '# do you know that thats a comment'),
            ('test', 'content'),
            ('t', ''),
            ('escaped_=equal', 'escaped_#hash'),
            ('escaped_\\backslash', 'escaped_ space'),
            ('escaped_,comma', 'escaped_.dot')])

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'default')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, default_should)

    def test_parse_makefiles_section(self):
        makefiles_should = OrderedDict([
            ('j', 'a\nmultiline\nvalue'),
            ('another', 'a\nmultiline\nvalue'),
            ('comment1', '# just a omment'),
            ('comment2', '# just a omment'),
            ('lastone', 'val'),
            ('comment3', ''),
            ('a_default', 'val'),
            ('comment0', '# do you know that thats a comment'),
            ('test', 'content'),
            ('t', ''),
            ('escaped_=equal', 'escaped_#hash'),
            ('escaped_\\backslash', 'escaped_ space'),
            ('escaped_,comma', 'escaped_.dot')])

        # Pop off the default section.
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'makefiles')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, makefiles_should)

        self.assertEqual(val['comment1'].key, 'comment1')

    def test_parse_empty_elem_strip_section(self):
        empty_elem_strip_should = OrderedDict([
            ('a', 'a, b, c'),
            ('b', 'a, ,, d'),
            ('c', ',,,'),
            ('comment4', ''),
            ('a_default', 'val'),
            ('another', 'val'),
            ('comment0', '# do you know that thats a comment'),
            ('test', 'content'),
            ('t', ''),
            ('escaped_=equal', 'escaped_#hash'),
            ('escaped_\\backslash', 'escaped_ space'),
            ('escaped_,comma', 'escaped_.dot')])

        # Pop off the default and makefiles section.
        self.sections.popitem(last=False)
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'empty_elem_strip')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, empty_elem_strip_should)

    def test_remove_empty_iter_elements(self):
        # Test with empty-elem stripping.
        uut = ConfParser(remove_empty_iter_elements=True)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['A']),
                         ['a', 'b', 'c'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['B']),
                         ['a', 'd'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['C']),
                         [])

        # Test without stripping.
        uut = ConfParser(remove_empty_iter_elements=False)
        uut.parse(self.file)
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['A']),
                         ['a', 'b', 'c'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['B']),
                         ['a', '', '', 'd'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['C']),
                         ['', '', '', ''])

    def test_config_directory(self):
        self.uut.parse(self.tempdir)
示例#41
0
class ConfParserTest(unittest.TestCase):
    example_file = """setting = without_section
    [foo]
    to be ignored
    a_default, another = val
    TEST = tobeignored  # do you know that thats a comment
    test = push
    t =
    escaped_\\=equal = escaped_\\#hash
    escaped_\\\\backslash = escaped_\\ space
    escaped_\\,comma = escaped_\\.dot
    [MakeFiles]
     j  , another = a
                   multiline
                   value
    # just a omment
    # just a omment
    nokey. = value
    foo.test = content
    makefiles.lastone = val
    append += key

    [EMPTY_ELEM_STRIP]
    A = a, b, c
    B = a, ,, d
    C = ,,,

    [name]
    key1 = value1
    key2 = value1
    key1 = value2
    """

    def setUp(self):
        self.tempdir = tempfile.gettempdir()
        self.file = os.path.join(self.tempdir, '.coafile')
        self.nonexistentfile = os.path.join(self.tempdir, 'e81k7bd98t')
        with open(self.file, 'w') as file:
            file.write(self.example_file)

        self.uut = ConfParser()
        try:
            os.remove(self.nonexistentfile)
        except FileNotFoundError:
            pass

        logger = logging.getLogger()

        isnotdir = mock.Mock(return_value=False)
        with self.assertLogs(logger, 'WARNING') as self.cm:
            with mock.patch('os.path.isdir', isnotdir):
                self.sections = self.uut.parse(self.file)

    def tearDown(self):
        os.remove(self.file)

    def test_parse_nonexisting_file(self):
        isdir = mock.Mock(return_value=True)
        isnotdir = mock.Mock(return_value=False)
        with mock.patch('os.path.isdir', isdir):
            self.assertRaises(FileNotFoundError, self.uut.parse,
                              self.nonexistentfile)

        with mock.patch('os.path.isdir', isnotdir):
            self.assertRaises(FileNotFoundError, self.uut.parse,
                              self.nonexistentfile)

        self.assertNotEqual(self.uut.parse(self.file, True), self.sections)

    def test_parse_nonexisting_section(self):
        self.assertRaises(IndexError, self.uut.get_section,
                          'inexistent section')

    def test_parse_default_section_deprecated(self):
        default_should = OrderedDict([('setting', 'without_section')])

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'default')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, default_should)

        self.assertRegex(self.cm.output[0],
                         'A setting does not have a section.')

    def test_parse_foo_section(self):
        foo_should = OrderedDict([('a_default', 'val'), ('another', 'val'),
                                  ('comment0',
                                   '# do you know that thats a comment'),
                                  ('test', 'content'), ('t', ''),
                                  ('escaped_=equal', 'escaped_#hash'),
                                  ('escaped_\\backslash', 'escaped_ space'),
                                  ('escaped_,comma', 'escaped_.dot')])

        # Pop off the default section.
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'foo')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, foo_should)

    def test_parse_makefiles_section(self):
        makefiles_should = OrderedDict([('j', 'a\nmultiline\nvalue'),
                                        ('another', 'a\nmultiline\nvalue'),
                                        ('comment1', '# just a omment'),
                                        ('comment2', '# just a omment'),
                                        ('lastone', 'val'), ('append', 'key'),
                                        ('comment3', '')])

        # Pop off the default and foo section.
        self.sections.popitem(last=False)
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'makefiles')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, makefiles_should)

        self.assertEqual(val['comment1'].key, 'comment1')

    def test_parse_empty_elem_strip_section(self):
        empty_elem_strip_should = OrderedDict([('a', 'a, b, c'),
                                               ('b', 'a, ,, d'), ('c', ',,,'),
                                               ('comment4', '')])

        # Pop off the default, foo and makefiles section.
        self.sections.popitem(last=False)
        self.sections.popitem(last=False)
        self.sections.popitem(last=False)

        key, val = self.sections.popitem(last=False)
        self.assertTrue(isinstance(val, Section))
        self.assertEqual(key, 'empty_elem_strip')

        is_dict = OrderedDict()
        for k in val:
            is_dict[k] = str(val[k])
        self.assertEqual(is_dict, empty_elem_strip_should)

    def test_remove_empty_iter_elements(self):
        # Test with empty-elem stripping.
        uut = ConfParser(remove_empty_iter_elements=True)
        isnotdir = mock.Mock(return_value=False)
        with mock.patch('os.path.isdir', isnotdir):
            uut.parse(self.file)
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['A']),
                         ['a', 'b', 'c'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['B']),
                         ['a', 'd'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['C']), [])

        # Test without stripping.
        uut = ConfParser(remove_empty_iter_elements=False)
        with mock.patch('os.path.isdir', isnotdir):
            uut.parse(self.file)
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['A']),
                         ['a', 'b', 'c'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['B']),
                         ['a', '', '', 'd'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['C']),
                         ['', '', '', ''])

    def test_config_directory(self):
        self.uut.parse(self.tempdir)

    def test_settings_override_warning(self):
        self.assertEqual(
            self.cm.output[1], 'WARNING:root:test setting has '
            'already been defined in section '
            'foo. The previous setting will '
            'be overridden.')
        self.assertEqual(
            self.cm.output[2], 'WARNING:root:key1 setting has '
            'already been defined in section '
            'name. The previous setting will '
            'be overridden.')
示例#42
0
class SectionManager:
    """
    The SectionManager does the following things:

    - Reading all settings in sections from
        - Default config
        - CLI
        - Configuration file
    - Collecting all the bears
    - Filling up all needed settings
    - Write back the new sections to the configuration file if needed
    - Give all information back to caller

    This is done when the run() method is invoked. Anything else is just helper stuff and initialization.
    """
    def __init__(self):
        self.cli_sections = None
        self.default_section = None
        self.conf_sections = None

        self.cli_parser = CliParser()
        self.conf_parser = ConfParser()
        self.conf_writer = None

        self.local_bears = {}
        self.global_bears = {}

    def run(self, arg_list=sys.argv[1:]):
        self._load_configuration(arg_list)
        self._fill_settings()
        self._save_configuration()

        return self.conf_sections, self.local_bears, self.global_bears

    def _load_configuration(self, arg_list):
        self.cli_sections = self.cli_parser.reparse(arg_list=arg_list)

        try:
            self.default_section = self.conf_parser.reparse(
                os.path.abspath(
                    os.path.join(StringConstants.coalib_root,
                                 "default_coafile")))["default"]
        except self.conf_parser.FileNotFoundError:
            self.cli_sections["default"].retrieve_logging_objects()
            self.cli_sections["default"].log_printer.err(
                _("The global default coafile for the settings was not found. "
                  "It seems your installation is broken.") + " " +
                StringConstants.THIS_IS_A_BUG)
            raise SystemExit

        for section in self.cli_sections:
            self.cli_sections[section].defaults = self.default_section

        try:
            config = os.path.abspath(
                str(self.cli_sections["default"].get("config", "./coafile")))
            self.conf_sections = self.conf_parser.reparse(config)

            # We'll get the default section as default section for every section in this dict with this
            # Furthermore we will have the CLI Values take precedence over the conf values.
            self._merge_section_dicts()
        except self.conf_parser.FileNotFoundError:
            self.conf_sections = self.cli_sections

    def _fill_settings(self):
        for section_name in self.conf_sections:
            section = self.conf_sections[section_name]
            section.retrieve_logging_objects()
            local_bears = BearCollector.from_section([BEAR_KIND.LOCAL],
                                                     section).collect()
            global_bears = BearCollector.from_section([BEAR_KIND.GLOBAL],
                                                      section).collect()
            filler = SectionFiller(section)
            all_bears = copy.deepcopy(local_bears)
            all_bears.extend(global_bears)
            filler.fill_section(all_bears)

            self.local_bears[section_name] = local_bears
            self.global_bears[section_name] = global_bears

    def _save_configuration(self):
        self.conf_writer = None
        try:
            if bool(self.conf_sections["default"]["save"]):
                self.conf_writer = ConfWriter(
                    str(self.conf_sections["default"]["config"]))
        except ValueError:
            self.conf_writer = ConfWriter(
                str(self.conf_sections["default"]["save"]))

        if self.conf_writer is not None:
            self.conf_writer.write_sections(self.conf_sections)

    def _merge_section_dicts(self):
        for section_name in self.cli_sections:
            if section_name in self.conf_sections:
                self.conf_sections[section_name].update(
                    self.cli_sections[section_name])
            else:
                self.conf_sections[section_name] = self.cli_sections[
                    section_name]  # no deep copy needed
示例#43
0
    def test_remove_empty_iter_elements(self):
        # Test with empty-elem stripping.
        uut = ConfParser(remove_empty_iter_elements=True)
        isnotdir = mock.Mock(return_value=False)
        with mock.patch('os.path.isdir', isnotdir):
            uut.parse(self.file)
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['A']),
                         ['a', 'b', 'c'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['B']),
                         ['a', 'd'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['C']), [])

        # Test without stripping.
        uut = ConfParser(remove_empty_iter_elements=False)
        with mock.patch('os.path.isdir', isnotdir):
            uut.parse(self.file)
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['A']),
                         ['a', 'b', 'c'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['B']),
                         ['a', '', '', 'd'])
        self.assertEqual(list(uut.get_section('EMPTY_ELEM_STRIP')['C']),
                         ['', '', '', ''])