Пример #1
0
    def test_source_options(self):
        data = dedent("""
          options:
            sources:
              conan:
                extra_args: foo
              goat:
                sound: baah
          packages:
            foo:
              source: apt
            bar:
              source: conan
              remote: bar/1.2.3
        """)
        files = {'mopack.yml': data}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        opts.add('sources', 'conan')
        opts.sources['conan'].extra_args.append('foo')
        self.assertEqual(cfg.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = ConanPackage('bar',
                            remote='bar/1.2.3',
                            _options=opts,
                            config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg1),
                                                      ('bar', pkg2)])
Пример #2
0
    def test_builder_options(self):
        data = dedent("""
          options:
            builders:
              bfg9000:
                toolchain: toolchain.bfg
              goat:
                sound: baah
          packages:
            foo:
              source: apt
            bar:
              source: directory
              path: /path/to/src
              build: bfg9000
        """)
        files = {'mopack.yml': data}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        opts.add('builders', 'bfg9000')
        opts.builders['bfg9000'].toolchain = os.path.abspath('toolchain.bfg')
        self.assertEqual(cfg.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = DirectoryPackage('bar',
                                path=normpath('/path/to/src'),
                                build='bfg9000',
                                _options=opts,
                                config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg1),
                                                      ('bar', pkg2)])
Пример #3
0
    def test_multiple_common_options(self):
        data1 = dedent("""
          options:
            target_platform: linux
            env:
              FOO: foo
          packages:
            foo:
              source: apt
        """)
        data2 = dedent("""
          options:
            target_platform: windows
            env:
              FOO: bad
          packages:
            bar:
              source: apt
        """)

        files = {'mopack.yml': data1, 'mopack2.yml': data2}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack2.yml', 'mopack.yml'])
        cfg.finalize()

        opts = Options()
        opts.common.target_platform = 'linux'
        opts.common.env = {'FOO': 'foo'}
        opts.common.finalize()
        self.assertEqual(cfg.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = AptPackage('bar', _options=opts, config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg1),
                                                      ('bar', pkg2)])
Пример #4
0
    def test_empty_file(self):
        with mock.patch('builtins.open', mock_open_files({'mopack.yml': ''})):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        self.assertEqual(cfg.options, opts)
        self.assertEqual(list(cfg.packages.items()), [])
Пример #5
0
    def test_multiple_source_options(self):
        data1 = dedent("""
          options:
            sources:
              conan:
                extra_args: -B
        """)
        data2 = dedent("""
          options:
            sources:
              conan:
                extra_args: -C
                final: true
          packages:
            foo:
              source: apt
        """)
        data3 = dedent("""
          options:
            sources:
              conan:
                extra_args: -D
          packages:
            bar:
              source: conan
              remote: bar/1.2.3
        """)

        files = {
            'mopack.yml': data1,
            'mopack2.yml': data2,
            'mopack3.yml': data3
        }
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack3.yml', 'mopack2.yml', 'mopack.yml'],
                         {'sources': {
                             'conan': {
                                 'extra_args': '-A'
                             }
                         }})
        cfg.finalize()

        opts = Options.default()
        opts.add('sources', 'conan')
        opts.sources['conan'].extra_args.extend(['-A', '-B', '-C'])
        self.assertEqual(cfg.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = ConanPackage('bar',
                            remote='bar/1.2.3',
                            _options=opts,
                            config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg1),
                                                      ('bar', pkg2)])
Пример #6
0
    def test_empty_file(self):
        files = {'mopack.yml': '', 'mopack-child.yml': ''}
        with mock.patch('builtins.open', mock_open_files(files)):
            parent = Config(['mopack.yml'])

        with mock.patch('builtins.open', mock_open_files(files)):
            child = ChildConfig(['mopack-child.yml'], parent=parent)
        self.assertEqual(list(child.packages.items()), [])

        parent.finalize()

        opts = Options.default()
        self.assertEqual(parent.options, opts)
        self.assertEqual(list(parent.packages.items()), [])
Пример #7
0
    def test_packages(self):
        data = dedent("""
          packages:
            foo:
              source: apt
        """)
        files = {'mopack.yml': data}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        self.assertEqual(cfg.options, opts)

        pkg = AptPackage('foo', _options=opts, config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg)])
Пример #8
0
    def make_options(self, common_options=None, deploy_paths=None):
        options = Options(deploy_paths)
        if common_options:
            options.common.accumulate(common_options)
        with mock.patch.object(os, 'environ', return_value={}):
            options.common.finalize()

        for i in pkg_resources.iter_entry_points('mopack.sources'):
            opts_type = i.load().Options
            if opts_type:
                options.sources[opts_type.source] = opts_type()

        for i in pkg_resources.iter_entry_points('mopack.builders'):
            opts_type = i.load().Options
            if opts_type:
                options.builders[opts_type.type] = opts_type()

        return options
Пример #9
0
    def test_source_options(self):
        data1 = dedent("""
          options:
            sources:
              conan:
                extra_args: foo
        """)
        data2 = dedent("""
          options:
            sources:
              conan:
                extra_args: bar
              goat:
                sound: baah
          packages:
            foo:
              source: apt
            bar:
              source: conan
              remote: bar/1.2.3
        """)

        files = {'mopack.yml': data1, 'mopack-child.yml': data2}

        with mock.patch('builtins.open', mock_open_files(files)):
            parent = Config(['mopack.yml'])
        with mock.patch('builtins.open', mock_open_files(files)):
            child = ChildConfig(['mopack-child.yml'], parent=parent)

        parent.add_children([child])
        parent.finalize()

        opts = Options.default()
        opts.add('sources', 'conan')
        opts.sources['conan'].extra_args.extend(['foo', 'bar'])
        self.assertEqual(parent.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = ConanPackage('bar',
                            remote='bar/1.2.3',
                            _options=opts,
                            config_file='mopack.yml')
        self.assertEqual(list(parent.packages.items()), [('foo', pkg1),
                                                         ('bar', pkg2)])
Пример #10
0
    def test_builder_options(self):
        data = dedent("""
          options:
            builders:
              bfg9000:
                toolchain: toolchain.bfg
              goat:
                sound: baah
          packages:
            foo:
              source: apt
            bar:
              source: directory
              path: /path/to/src
              build: bfg9000
        """)
        files = {'mopack.yml': '', 'mopack-child.yml': data}

        with mock.patch('builtins.open', mock_open_files(files)):
            parent = Config(['mopack.yml'])
        with mock.patch('builtins.open', mock_open_files(files)):
            child = ChildConfig(['mopack-child.yml'], parent=parent)

        parent.add_children([child])
        parent.finalize()

        opts = Options.default()
        opts.add('builders', 'bfg9000')
        self.assertEqual(parent.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = DirectoryPackage('bar',
                                path=normpath('/path/to/src'),
                                build='bfg9000',
                                _options=opts,
                                config_file='mopack.yml')
        self.assertEqual(list(parent.packages.items()), [('foo', pkg1),
                                                         ('bar', pkg2)])
Пример #11
0
    def test_conditional_packages(self):
        data = dedent("""
          packages:
            foo:
              - if: false
                source: apt
              - source: conan
                remote: foo/1.2.3
        """)
        files = {'mopack.yml': data}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        opts.add('sources', 'conan')
        self.assertEqual(cfg.options, opts)

        pkg = ConanPackage('foo',
                           remote='foo/1.2.3',
                           _options=opts,
                           config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg)])
Пример #12
0
class TestPath(UsageTest):
    usage_type = PathUsage
    type = 'path'
    symbols = Options.default().expr_symbols

    def check_usage(self,
                    usage,
                    *,
                    auto_link=False,
                    include_path=[],
                    library_path=[],
                    headers=[],
                    libraries=[{
                        'type': 'guess',
                        'name': 'foo'
                    }],
                    compile_flags=[],
                    link_flags=[]):
        self.assertEqual(usage.auto_link, auto_link)
        self.assertEqual(usage.include_path, include_path)
        self.assertEqual(usage.library_path, library_path)
        self.assertEqual(usage.headers, headers)
        self.assertEqual(usage.libraries, libraries)
        self.assertEqual(usage.compile_flags, ShellArguments(compile_flags))
        self.assertEqual(usage.link_flags, ShellArguments(link_flags))

    def test_basic(self):
        usage = self.make_usage('foo')
        self.check_usage(usage)
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_auto_link(self):
        usage = self.make_usage('foo', auto_link=True)
        self.check_usage(usage, auto_link=True)
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': True,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_include_path_relative(self):
        usage = self.make_usage('foo', include_path='include')
        self.check_usage(usage, include_path=[srcpathobj('include')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [abspath('/srcdir/include')],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo', include_path=['include'])
        self.check_usage(usage, include_path=[srcpathobj('include')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [abspath('/srcdir/include')],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_include_path_srcdir(self):
        usage = self.make_usage('foo', include_path='$srcdir/include')
        self.check_usage(usage, include_path=[srcpathobj('include')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [abspath('/srcdir/include')],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo', include_path=['$srcdir/include'])
        self.check_usage(usage, include_path=[srcpathobj('include')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [abspath('/srcdir/include')],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_include_path_builddir(self):
        usage = self.make_usage('foo', include_path='$builddir/include')
        self.check_usage(usage, include_path=[buildpathobj('include')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [abspath('/builddir/include')],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo', include_path=['$builddir/include'])
        self.check_usage(usage, include_path=[buildpathobj('include')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [abspath('/builddir/include')],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_include_path_absolute(self):
        usage = self.make_usage('foo', include_path='/path/to/include')
        self.check_usage(usage, include_path=[abspathobj('/path/to/include')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [abspath('/path/to/include')],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo', include_path='/path/to/include')
        self.check_usage(usage, include_path=[abspathobj('/path/to/include')])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [abspath('/path/to/include')],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_invalid_include_path(self):
        with self.assertRaises(FieldError):
            self.make_usage('foo', include_path='../include')

    def test_library_path_relative(self):
        usage = self.make_usage('foo', library_path='lib')
        self.check_usage(usage, library_path=[buildpathobj('lib')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [abspath('/builddir/lib')],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo', library_path=['lib'])
        self.check_usage(usage, library_path=[buildpathobj('lib')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [abspath('/builddir/lib')],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_library_path_srcdir(self):
        usage = self.make_usage('foo', library_path='$srcdir/lib')
        self.check_usage(usage, library_path=[srcpathobj('lib')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [abspath('/srcdir/lib')],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo', library_path=['$srcdir/lib'])
        self.check_usage(usage, library_path=[srcpathobj('lib')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [abspath('/srcdir/lib')],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_library_path(self):
        usage = self.make_usage('foo', library_path='$builddir/lib')
        self.check_usage(usage, library_path=[buildpathobj('lib')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [abspath('/builddir/lib')],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo', library_path=['$builddir/lib'])
        self.check_usage(usage, library_path=[buildpathobj('lib')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [abspath('/builddir/lib')],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_library_path_absolute(self):
        usage = self.make_usage('foo', library_path='/path/to/lib')
        self.check_usage(usage, library_path=[abspathobj('/path/to/lib')])
        self.assertEqual(
            usage.get_usage(None, '/srcdir', '/builddir'), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [abspath('/path/to/lib')],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo', library_path='/path/to/lib')
        self.check_usage(usage, library_path=[abspathobj('/path/to/lib')])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [abspath('/path/to/lib')],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_invalid_library_path(self):
        with self.assertRaises(FieldError):
            self.make_usage('foo', library_path='../lib')

    def test_headers(self):
        usage = self.make_usage('foo', headers='foo.hpp')
        self.check_usage(usage, headers=['foo.hpp'])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': ['foo.hpp'],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo', headers=['foo.hpp'])
        self.check_usage(usage, headers=['foo.hpp'])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': ['foo.hpp'],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_libraries(self):
        usage = self.make_usage('foo', libraries='bar')
        self.check_usage(usage, libraries=['bar'])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['bar'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo', libraries=['bar'])
        self.check_usage(usage, libraries=['bar'])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['bar'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo', libraries=None)
        self.check_usage(usage, libraries=[])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': [],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo',
                                libraries=[
                                    {
                                        'type': 'library',
                                        'name': 'bar'
                                    },
                                ])
        self.check_usage(usage, libraries=['bar'])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['bar'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo',
                                libraries=[
                                    {
                                        'type': 'guess',
                                        'name': 'bar'
                                    },
                                ])
        self.check_usage(usage, libraries=[{'type': 'guess', 'name': 'bar'}])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['bar'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo',
                                libraries=[
                                    {
                                        'type': 'framework',
                                        'name': 'bar'
                                    },
                                ])
        self.check_usage(usage,
                         libraries=[{
                             'type': 'framework',
                             'name': 'bar'
                         }])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': [{
                    'type': 'framework',
                    'name': 'bar'
                }],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_compile_flags(self):
        usage = self.make_usage('foo', compile_flags='-pthread -fPIC')
        self.check_usage(usage, compile_flags=['-pthread', '-fPIC'])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': ['-pthread', '-fPIC'],
                'link_flags': [],
            })

        usage = self.make_usage('foo', compile_flags=['-pthread', '-fPIC'])
        self.check_usage(usage, compile_flags=['-pthread', '-fPIC'])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': ['-pthread', '-fPIC'],
                'link_flags': [],
            })

    def test_link_flags(self):
        usage = self.make_usage('foo', link_flags='-pthread -fPIC')
        self.check_usage(usage, link_flags=['-pthread', '-fPIC'])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': ['-pthread', '-fPIC'],
            })

        usage = self.make_usage('foo', link_flags=['-pthread', '-fPIC'])
        self.check_usage(usage, link_flags=['-pthread', '-fPIC'])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['foo'],
                'compile_flags': [],
                'link_flags': ['-pthread', '-fPIC'],
            })

    def test_submodules(self):
        submodules_required = {'names': '*', 'required': True}
        submodules_optional = {'names': '*', 'required': False}

        usage = self.make_usage('foo', submodules=submodules_required)
        self.check_usage(usage, libraries=[])
        self.assertEqual(
            usage.get_usage(['sub'], None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['foo_sub'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo',
                                libraries=['bar'],
                                submodules=submodules_required)
        self.check_usage(usage, libraries=['bar'])
        self.assertEqual(
            usage.get_usage(['sub'], None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['bar', 'foo_sub'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo', submodules=submodules_optional)
        self.check_usage(usage, libraries=[{'type': 'guess', 'name': 'foo'}])
        self.assertEqual(
            usage.get_usage(['sub'], None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['foo', 'foo_sub'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo',
                                libraries=['bar'],
                                submodules=submodules_optional)
        self.check_usage(usage, libraries=['bar'])
        self.assertEqual(
            usage.get_usage(['sub'], None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['bar', 'foo_sub'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_submodule_map(self):
        submodules_required = {'names': '*', 'required': True}

        usage = self.make_usage('foo',
                                submodule_map='$submodule',
                                submodules=submodules_required)
        self.check_usage(usage, libraries=[])
        self.assertEqual(
            usage.get_usage(['sub'], None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['sub'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo',
                                submodule_map={
                                    '*': {
                                        'libraries': '$submodule'
                                    },
                                },
                                submodules=submodules_required)
        self.check_usage(usage, libraries=[])
        self.assertEqual(
            usage.get_usage(['sub'], None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['sub'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo',
                                submodule_map={
                                    'sub': {
                                        'include_path': '/sub/incdir',
                                        'library_path': '/sub/libdir',
                                        'headers': 'sub.hpp',
                                        'libraries': 'sublib',
                                        'compile_flags': '-Dsub',
                                        'link_flags': '-Wl,-sub',
                                    },
                                    '*': {
                                        'libraries': '$submodule'
                                    }
                                },
                                submodules=submodules_required)
        self.check_usage(usage, libraries=[])
        self.assertEqual(
            usage.get_usage(['sub'], None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [abspath('/sub/incdir')],
                'library_path': [abspath('/sub/libdir')],
                'headers': ['sub.hpp'],
                'libraries': ['sublib'],
                'compile_flags': ['-Dsub'],
                'link_flags': ['-Wl,-sub'],
            })
        self.assertEqual(
            usage.get_usage(['sub2'], None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['sub2'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo',
                                submodule_map={
                                    'sub': {
                                        'include_path': '/incdir/$submodule',
                                        'library_path': '/libdir/$submodule',
                                        'headers': '$submodule/file.hpp',
                                        'libraries': '$submodule',
                                        'compile_flags': '-D$submodule',
                                        'link_flags': '-Wl,-$submodule',
                                    },
                                    '*': {
                                        'include_path':
                                        '/incdir/star/$submodule',
                                        'library_path':
                                        '/libdir/star/$submodule',
                                        'headers': 'star/$submodule/file.hpp',
                                        'libraries': 'star$submodule',
                                        'compile_flags': '-Dstar$submodule',
                                        'link_flags': '-Wl,-star$submodule',
                                    },
                                },
                                submodules=submodules_required)
        self.check_usage(usage, libraries=[])
        self.assertEqual(
            usage.get_usage(['sub'], None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [abspath('/incdir/sub')],
                'library_path': [abspath('/libdir/sub')],
                'headers': ['sub/file.hpp'],
                'libraries': ['sub'],
                'compile_flags': ['-Dsub'],
                'link_flags': ['-Wl,-sub'],
            })
        self.assertEqual(
            usage.get_usage(['sub2'], None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [abspath('/incdir/star/sub2')],
                'library_path': [abspath('/libdir/star/sub2')],
                'headers': ['star/sub2/file.hpp'],
                'libraries': ['starsub2'],
                'compile_flags': ['-Dstarsub2'],
                'link_flags': ['-Wl,-starsub2'],
            })

    def test_boost(self):
        submodules = {'names': '*', 'required': False}
        for plat in ['linux', 'darwin', 'windows']:
            opts = {'target_platform': plat}
            usage = self.make_usage('boost',
                                    submodules=submodules,
                                    common_options=opts)
            self.check_usage(usage,
                             auto_link=(plat == 'windows'),
                             headers=['boost/version.hpp'],
                             libraries=[],
                             include_path=[],
                             library_path=[])
            self.assertEqual(
                usage.get_usage(None, None, None), {
                    'type': 'path',
                    'auto_link': plat == 'windows',
                    'headers': ['boost/version.hpp'],
                    'libraries': [],
                    'compile_flags': [],
                    'link_flags': [],
                    'include_path': [],
                    'library_path': [],
                })
            self.assertEqual(
                usage.get_usage(['thread'], None, None), {
                    'type': 'path',
                    'auto_link': plat == 'windows',
                    'headers': ['boost/version.hpp'],
                    'libraries': ['boost_thread'] if plat != 'windows' else [],
                    'compile_flags': ['-pthread'] if plat != 'windows' else [],
                    'link_flags': ['-pthread'] if plat == 'linux' else [],
                    'include_path': [],
                    'library_path': [],
                })

            usage = self.make_usage('boost',
                                    libraries=['boost'],
                                    submodules=submodules,
                                    common_options=opts)
            self.check_usage(usage,
                             auto_link=(plat == 'windows'),
                             headers=['boost/version.hpp'],
                             libraries=['boost'],
                             include_path=[],
                             library_path=[])
            self.assertEqual(
                usage.get_usage(None, None, None), {
                    'type': 'path',
                    'auto_link': plat == 'windows',
                    'headers': ['boost/version.hpp'],
                    'libraries': ['boost'],
                    'compile_flags': [],
                    'link_flags': [],
                    'include_path': [],
                    'library_path': [],
                })
            extra_libs = ['boost_regex'] if plat != 'windows' else []
            self.assertEqual(
                usage.get_usage(['regex'], None, None), {
                    'type': 'path',
                    'auto_link': plat == 'windows',
                    'headers': ['boost/version.hpp'],
                    'libraries': ['boost'] + extra_libs,
                    'compile_flags': [],
                    'link_flags': [],
                    'include_path': [],
                    'library_path': [],
                })

    def test_boost_env_vars(self):
        submodules = {'names': '*', 'required': False}
        boost_root = os.path.abspath('/boost')
        boost_inc = os.path.abspath('/boost/inc')
        opts = {
            'target_platform': 'linux',
            'env': {
                'BOOST_ROOT': boost_root,
                'BOOST_INCLUDEDIR': boost_inc,
            }
        }
        paths = {
            'include_path': [boost_inc],
            'library_path': [os.path.join(boost_root, 'lib')]
        }
        pathobjs = {k: [abspathobj(i) for i in v] for k, v in paths.items()}

        usage = self.make_usage('boost',
                                submodules=submodules,
                                common_options=opts)
        self.check_usage(usage,
                         auto_link=False,
                         headers=['boost/version.hpp'],
                         libraries=[],
                         **pathobjs)
        self.assertEqual(
            usage.get_usage(None, None, None),
            merge_dicts(
                {
                    'type': 'path',
                    'auto_link': False,
                    'headers': ['boost/version.hpp'],
                    'libraries': [],
                    'compile_flags': [],
                    'link_flags': [],
                }, paths))
        self.assertEqual(
            usage.get_usage(['thread'], None, None),
            merge_dicts(
                {
                    'type': 'path',
                    'auto_link': False,
                    'headers': ['boost/version.hpp'],
                    'libraries': ['boost_thread'],
                    'compile_flags': ['-pthread'],
                    'link_flags': ['-pthread'],
                }, paths))

        usage = self.make_usage('boost',
                                libraries=['boost'],
                                submodules=submodules,
                                common_options=opts)
        self.check_usage(usage,
                         auto_link=False,
                         headers=['boost/version.hpp'],
                         libraries=['boost'],
                         **pathobjs)
        self.assertEqual(
            usage.get_usage(None, None, None),
            merge_dicts(
                {
                    'type': 'path',
                    'auto_link': False,
                    'headers': ['boost/version.hpp'],
                    'libraries': ['boost'],
                    'compile_flags': [],
                    'link_flags': [],
                }, paths))
        self.assertEqual(
            usage.get_usage(['regex'], None, None),
            merge_dicts(
                {
                    'type': 'path',
                    'auto_link': False,
                    'headers': ['boost/version.hpp'],
                    'libraries': ['boost', 'boost_regex'],
                    'compile_flags': [],
                    'link_flags': [],
                }, paths))

    def test_target_platform(self):
        usage = self.make_usage('gl',
                                common_options={
                                    'target_platform': 'linux',
                                })
        self.check_usage(usage, libraries=[{'type': 'guess', 'name': 'gl'}])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['GL'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('gl',
                                common_options={
                                    'target_platform': 'darwin',
                                })
        self.check_usage(usage, libraries=[{'type': 'guess', 'name': 'gl'}])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': [{
                    'type': 'framework',
                    'name': 'OpenGL'
                }],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('gl',
                                libraries=['gl'],
                                common_options={
                                    'target_platform': 'linux',
                                })
        self.check_usage(usage, libraries=['gl'])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['gl'],
                'compile_flags': [],
                'link_flags': [],
            })

        usage = self.make_usage('foo',
                                libraries=[{
                                    'type': 'guess',
                                    'name': 'gl'
                                }],
                                common_options={'target_platform': 'linux'})
        self.check_usage(usage, libraries=[{'type': 'guess', 'name': 'gl'}])
        self.assertEqual(
            usage.get_usage(None, None, None), {
                'type': 'path',
                'auto_link': False,
                'include_path': [],
                'library_path': [],
                'headers': [],
                'libraries': ['GL'],
                'compile_flags': [],
                'link_flags': [],
            })

    def test_rehydrate(self):
        opts = self.make_options()
        path_bases = ('srcdir', 'builddir')
        usage = self.usage_type('foo',
                                submodules=None,
                                _options=opts,
                                _path_bases=path_bases)
        data = usage.dehydrate()
        self.assertEqual(usage, Usage.rehydrate(data, _options=opts))

        usage = self.usage_type('foo',
                                submodules=None,
                                compile_flags=['compile'],
                                link_flags=['link'],
                                _options=opts,
                                _path_bases=path_bases)
        data = through_json(usage.dehydrate())
        self.assertEqual(usage, Usage.rehydrate(data, _options=opts))

        submodules = {'names': '*', 'required': False}
        usage = self.usage_type('foo',
                                submodules=submodules,
                                submodule_map={
                                    'foosub': {
                                        'include_path': 'include',
                                        'library_path': 'lib',
                                    },
                                    'barsub': {
                                        'compile_flags': 'compile',
                                        'link_flags': 'link',
                                    },
                                },
                                _options=opts,
                                _path_bases=path_bases)
        data = through_json(usage.dehydrate())
        self.assertEqual(usage, Usage.rehydrate(data, _options=opts))

    def test_upgrade(self):
        opts = self.make_options()
        data = {
            'type': self.type,
            '_version': 0,
            'include_path': [],
            'library_path': [],
            'compile_flags': [],
            'link_flags': []
        }
        with mock.patch.object(self.usage_type,
                               'upgrade',
                               side_effect=self.usage_type.upgrade) as m:
            pkg = Usage.rehydrate(data, _options=opts)
            self.assertIsInstance(pkg, self.usage_type)
            m.assert_called_once()

    def test_invalid_usage(self):
        with self.assertRaises(FieldError):
            self.make_usage('foo',
                            include_path='$builddir/include',
                            _path_bases=('srcdir', ))

        with self.assertRaises(FieldError):
            self.make_usage('foo',
                            library_path='$srcdir/lib',
                            _path_bases=('builddir', ))

        with self.assertRaises(FieldError):
            self.make_usage('foo', include_path='include', _path_bases=())
Пример #13
0
class TestChildConfig(TestCase):
    default_opts = Options.default()

    def test_empty_file(self):
        files = {'mopack.yml': '', 'mopack-child.yml': ''}
        with mock.patch('builtins.open', mock_open_files(files)):
            parent = Config(['mopack.yml'])

        with mock.patch('builtins.open', mock_open_files(files)):
            child = ChildConfig(['mopack-child.yml'], parent=parent)
        self.assertEqual(list(child.packages.items()), [])

        parent.finalize()

        opts = Options.default()
        self.assertEqual(parent.options, opts)
        self.assertEqual(list(parent.packages.items()), [])

    def test_export_config(self):
        cfg = dedent("""
        export:
          build: bfg9000
          usage: pkg_config
        """) + bar_cfg
        files = {'mopack.yml': '', 'mopack-child.yml': cfg}
        with mock.patch('builtins.open', mock_open_files(files)):
            parent = Config(['mopack.yml'])

        with mock.patch('builtins.open', mock_open_files(files)):
            child = ChildConfig(['mopack-child.yml'], parent=parent)
        self.assertEqual(child.export.build, 'bfg9000')
        self.assertEqual(child.export.usage, 'pkg_config')

    def test_child_in_parent(self):
        files = {'mopack.yml': foobar_cfg, 'mopack-child.yml': foo_cfg}
        with mock.patch('builtins.open', mock_open_files(files)):
            parent = Config(['mopack.yml'])
        with mock.patch('builtins.open', mock_open_files(files)):
            child = ChildConfig(['mopack-child.yml'], parent=parent)
        self.assertEqual(list(child.packages.items()),
                         [('foo', PlaceholderPackage)])

        parent.add_children([child])
        self.assertEqual(list(parent.packages.items()), [
            ('foo',
             AptPackage(
                 'foo', _options=self.default_opts, config_file='mopack.yml')),
            ('bar',
             AptPackage(
                 'bar', _options=self.default_opts, config_file='mopack.yml')),
        ])

    def test_child_not_in_parent(self):
        files = {'mopack.yml': foo_cfg, 'mopack-child.yml': bar_cfg}
        with mock.patch('builtins.open', mock_open_files(files)):
            parent = Config(['mopack.yml'])
        with mock.patch('builtins.open', mock_open_files(files)):
            child = ChildConfig(['mopack-child.yml'], parent=parent)
        self.assertEqual(list(child.packages.items()), [
            ('bar',
             AptPackage('bar',
                        remote='libbar1-dev',
                        _options=self.default_opts,
                        config_file='mopack-child.yml')),
        ])

        parent.add_children([child])
        self.assertEqual(list(parent.packages.items()), [
            ('bar',
             AptPackage('bar',
                        remote='libbar1-dev',
                        _options=self.default_opts,
                        config_file='mopack-child.yml')),
            ('foo',
             AptPackage('foo',
                        remote='libfoo1-dev',
                        _options=self.default_opts,
                        config_file='mopack.yml')),
        ])

    def test_child_mixed_in_parent(self):
        files = {'mopack.yml': foo_cfg, 'mopack-child.yml': foobar_cfg}
        with mock.patch('builtins.open', mock_open_files(files)):
            parent = Config(['mopack.yml'])
        with mock.patch('builtins.open', mock_open_files(files)):
            child = ChildConfig(['mopack-child.yml'], parent=parent)
        self.assertEqual(list(child.packages.items()), [
            ('foo', PlaceholderPackage),
            ('bar',
             AptPackage('bar',
                        _options=self.default_opts,
                        config_file='mopack-child.yml')),
        ])

        parent.add_children([child])
        self.assertEqual(list(parent.packages.items()), [
            ('foo',
             AptPackage('foo',
                        remote='libfoo1-dev',
                        _options=self.default_opts,
                        config_file='mopack.yml')),
            ('bar',
             AptPackage('bar',
                        _options=self.default_opts,
                        config_file='mopack-child.yml')),
        ])

    def test_child_duplicate(self):
        files = {'mopack-child1.yml': foo_cfg, 'mopack-child2.yml': foo_cfg}
        parent = Config([])
        with mock.patch('builtins.open', mock_open_files(files)):
            child1 = ChildConfig(['mopack-child1.yml'], parent=parent)
        with mock.patch('builtins.open', mock_open_files(files)):
            child2 = ChildConfig(['mopack-child2.yml'], parent=parent)

        parent.add_children([child1, child2])
        self.assertEqual(list(parent.packages.items()), [
            ('foo',
             AptPackage('foo',
                        remote='libfoo1-dev',
                        _options=self.default_opts,
                        config_file='mopack.yml')),
        ])

    def test_child_conflicts(self):
        files = {'mopack-child1.yml': foobar_cfg, 'mopack-child2.yml': foo_cfg}
        parent = Config([])
        with mock.patch('builtins.open', mock_open_files(files)):
            child1 = ChildConfig(['mopack-child1.yml'], parent=parent)
        with mock.patch('builtins.open', mock_open_files(files)):
            child2 = ChildConfig(['mopack-child2.yml'], parent=parent)

        with self.assertRaises(ValueError):
            parent.add_children([child1, child2])

    def test_builder_options(self):
        data = dedent("""
          options:
            builders:
              bfg9000:
                toolchain: toolchain.bfg
              goat:
                sound: baah
          packages:
            foo:
              source: apt
            bar:
              source: directory
              path: /path/to/src
              build: bfg9000
        """)
        files = {'mopack.yml': '', 'mopack-child.yml': data}

        with mock.patch('builtins.open', mock_open_files(files)):
            parent = Config(['mopack.yml'])
        with mock.patch('builtins.open', mock_open_files(files)):
            child = ChildConfig(['mopack-child.yml'], parent=parent)

        parent.add_children([child])
        parent.finalize()

        opts = Options.default()
        opts.add('builders', 'bfg9000')
        self.assertEqual(parent.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = DirectoryPackage('bar',
                                path=normpath('/path/to/src'),
                                build='bfg9000',
                                _options=opts,
                                config_file='mopack.yml')
        self.assertEqual(list(parent.packages.items()), [('foo', pkg1),
                                                         ('bar', pkg2)])

    def test_source_options(self):
        data1 = dedent("""
          options:
            sources:
              conan:
                extra_args: foo
        """)
        data2 = dedent("""
          options:
            sources:
              conan:
                extra_args: bar
              goat:
                sound: baah
          packages:
            foo:
              source: apt
            bar:
              source: conan
              remote: bar/1.2.3
        """)

        files = {'mopack.yml': data1, 'mopack-child.yml': data2}

        with mock.patch('builtins.open', mock_open_files(files)):
            parent = Config(['mopack.yml'])
        with mock.patch('builtins.open', mock_open_files(files)):
            child = ChildConfig(['mopack-child.yml'], parent=parent)

        parent.add_children([child])
        parent.finalize()

        opts = Options.default()
        opts.add('sources', 'conan')
        opts.sources['conan'].extra_args.extend(['foo', 'bar'])
        self.assertEqual(parent.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = ConanPackage('bar',
                            remote='bar/1.2.3',
                            _options=opts,
                            config_file='mopack.yml')
        self.assertEqual(list(parent.packages.items()), [('foo', pkg1),
                                                         ('bar', pkg2)])
Пример #14
0
class TestConfig(TestCase):
    default_opts = Options.default()

    def test_empty_file(self):
        with mock.patch('builtins.open', mock_open_files({'mopack.yml': ''})):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        self.assertEqual(cfg.options, opts)
        self.assertEqual(list(cfg.packages.items()), [])

    def test_single_file(self):
        files = {'mopack.yml': foobar_cfg}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack.yml'])
        self.assertEqual(list(cfg.packages.items()), [
            ('foo',
             AptPackage(
                 'foo', _options=self.default_opts, config_file='mopack.yml')),
            ('bar',
             AptPackage(
                 'bar', _options=self.default_opts, config_file='mopack.yml')),
        ])

    def test_multiple_files(self):
        files = {'mopack-foo.yml': foo_cfg, 'mopack-bar.yml': bar_cfg}
        with mock.patch('builtins.open', mock_open_files(files)):
            # Filenames are in reversed order from file data, since Config
            # loads last-to-first.
            cfg = Config(['mopack-bar.yml', 'mopack-foo.yml'])
        self.assertEqual(list(cfg.packages.items()), [
            ('foo',
             AptPackage('foo',
                        remote='libfoo1-dev',
                        _options=self.default_opts,
                        config_file='mopack.yml')),
            ('bar',
             AptPackage('bar',
                        remote='libbar1-dev',
                        _options=self.default_opts,
                        config_file='mopack2.yml')),
        ])

    def test_directory(self):
        def exists(p):
            return os.path.basename(p) == 'dir'

        files = {
            'mopack.yml': foo_cfg,
            'mopack-local.yml': bar_cfg,
            'mopack-foobar.yml': foobar_cfg
        }
        with mock.patch('os.path.isdir', exists), \
             mock.patch('os.path.exists', return_value=True), \
             mock.patch('builtins.open', mock_open_files(files)):  # noqa
            # Filenames are in reversed order from file data, since Config
            # loads last-to-first.
            cfg = Config(['dir', 'mopack-foobar.yml'])
        self.assertEqual(list(cfg.packages.items()), [
            ('bar',
             AptPackage('bar',
                        remote='libbar1-dev',
                        _options=self.default_opts,
                        config_file='mopack2.yml')),
            ('foo',
             AptPackage(
                 'foo', _options=self.default_opts, config_file='mopack.yml')),
        ])

    def test_override(self):
        files = {'mopack-foo.yml': foo_cfg, 'mopack-foobar.yml': foobar_cfg}
        with mock.patch('builtins.open', mock_open_files(files)):
            # Filenames are in reversed order from file data, since Config
            # loads last-to-first.
            cfg = Config(['mopack-foobar.yml', 'mopack-foo.yml'])
        self.assertEqual(list(cfg.packages.items()), [
            ('foo',
             AptPackage('foo',
                        remote='libfoo1-dev',
                        _options=self.default_opts,
                        config_file='mopack2.yml')),
            ('bar',
             AptPackage(
                 'bar', _options=self.default_opts, config_file='mopack.yml')),
        ])

    def test_empty_packages(self):
        data = 'packages:'
        files = {'mopack.yml': data}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        self.assertEqual(cfg.options, opts)
        self.assertEqual(list(cfg.packages.items()), [])

    def test_packages(self):
        data = dedent("""
          packages:
            foo:
              source: apt
        """)
        files = {'mopack.yml': data}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        self.assertEqual(cfg.options, opts)

        pkg = AptPackage('foo', _options=opts, config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg)])

    def test_conditional_packages(self):
        data = dedent("""
          packages:
            foo:
              - if: false
                source: apt
              - source: conan
                remote: foo/1.2.3
        """)
        files = {'mopack.yml': data}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        opts.add('sources', 'conan')
        self.assertEqual(cfg.options, opts)

        pkg = ConanPackage('foo',
                           remote='foo/1.2.3',
                           _options=opts,
                           config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg)])

    def test_invalid_conditional_packages(self):
        data = dedent("""
          packages:
            foo:
              - source: apt
              - source: conan
                remote: foo/1.2.3
        """)
        files = {'mopack.yml': data}
        with self.assertRaises(YamlParseError), \
             mock.patch('builtins.open', mock_open_files(files)):  # noqa
            Config(['mopack.yml'])

    def test_empty_options(self):
        data = 'options:'
        files = {'mopack.yml': data}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        self.assertEqual(cfg.options, opts)
        self.assertEqual(list(cfg.packages.items()), [])

    def test_common_options(self):
        data = dedent("""
          options:
            target_platform: linux
            env:
              FOO: foo
          packages:
            foo:
              source: apt
        """)
        files = {'mopack.yml': data}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options()
        opts.common.target_platform = 'linux'
        opts.common.env = {'FOO': 'foo'}
        opts.common.finalize()
        self.assertEqual(cfg.options, opts)

        pkg = AptPackage('foo', _options=opts, config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg)])

    def test_multiple_common_options(self):
        data1 = dedent("""
          options:
            target_platform: linux
            env:
              FOO: foo
          packages:
            foo:
              source: apt
        """)
        data2 = dedent("""
          options:
            target_platform: windows
            env:
              FOO: bad
          packages:
            bar:
              source: apt
        """)

        files = {'mopack.yml': data1, 'mopack2.yml': data2}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack2.yml', 'mopack.yml'])
        cfg.finalize()

        opts = Options()
        opts.common.target_platform = 'linux'
        opts.common.env = {'FOO': 'foo'}
        opts.common.finalize()
        self.assertEqual(cfg.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = AptPackage('bar', _options=opts, config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg1),
                                                      ('bar', pkg2)])

    def test_builder_options(self):
        data = dedent("""
          options:
            builders:
              bfg9000:
                toolchain: toolchain.bfg
              goat:
                sound: baah
          packages:
            foo:
              source: apt
            bar:
              source: directory
              path: /path/to/src
              build: bfg9000
        """)
        files = {'mopack.yml': data}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        opts.add('builders', 'bfg9000')
        opts.builders['bfg9000'].toolchain = os.path.abspath('toolchain.bfg')
        self.assertEqual(cfg.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = DirectoryPackage('bar',
                                path=normpath('/path/to/src'),
                                build='bfg9000',
                                _options=opts,
                                config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg1),
                                                      ('bar', pkg2)])

    def test_multiple_builder_options(self):
        data1 = dedent("""
          options:
            builders:
              bfg9000:
                toolchain: toolchain.bfg
          packages:
            foo:
              source: apt
        """)
        data2 = dedent("""
          options:
            builders:
              bfg9000:
                toolchain: bad.bfg
          packages:
            bar:
              source: directory
              path: /path/to/src
              build: bfg9000
        """)

        files = {'mopack.yml': data1, 'mopack2.yml': data2}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack2.yml', 'mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        opts.add('builders', 'bfg9000')
        opts.builders['bfg9000'].toolchain = os.path.abspath('toolchain.bfg')
        self.assertEqual(cfg.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = DirectoryPackage('bar',
                                path=normpath('/path/to/src'),
                                build='bfg9000',
                                _options=opts,
                                config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg1),
                                                      ('bar', pkg2)])

    def test_source_options(self):
        data = dedent("""
          options:
            sources:
              conan:
                extra_args: foo
              goat:
                sound: baah
          packages:
            foo:
              source: apt
            bar:
              source: conan
              remote: bar/1.2.3
        """)
        files = {'mopack.yml': data}
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack.yml'])
        cfg.finalize()

        opts = Options.default()
        opts.add('sources', 'conan')
        opts.sources['conan'].extra_args.append('foo')
        self.assertEqual(cfg.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = ConanPackage('bar',
                            remote='bar/1.2.3',
                            _options=opts,
                            config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg1),
                                                      ('bar', pkg2)])

    def test_multiple_source_options(self):
        data1 = dedent("""
          options:
            sources:
              conan:
                extra_args: -B
        """)
        data2 = dedent("""
          options:
            sources:
              conan:
                extra_args: -C
                final: true
          packages:
            foo:
              source: apt
        """)
        data3 = dedent("""
          options:
            sources:
              conan:
                extra_args: -D
          packages:
            bar:
              source: conan
              remote: bar/1.2.3
        """)

        files = {
            'mopack.yml': data1,
            'mopack2.yml': data2,
            'mopack3.yml': data3
        }
        with mock.patch('builtins.open', mock_open_files(files)):
            cfg = Config(['mopack3.yml', 'mopack2.yml', 'mopack.yml'],
                         {'sources': {
                             'conan': {
                                 'extra_args': '-A'
                             }
                         }})
        cfg.finalize()

        opts = Options.default()
        opts.add('sources', 'conan')
        opts.sources['conan'].extra_args.extend(['-A', '-B', '-C'])
        self.assertEqual(cfg.options, opts)

        pkg1 = AptPackage('foo', _options=opts, config_file='mopack.yml')
        pkg2 = ConanPackage('bar',
                            remote='bar/1.2.3',
                            _options=opts,
                            config_file='mopack.yml')
        self.assertEqual(list(cfg.packages.items()), [('foo', pkg1),
                                                      ('bar', pkg2)])