class PackageTest(unittest.TestCase):
    def setUp(self):
        self.config = Config()
        self.config.cache_file = '/dev/null'
        self.cookbook = CookBook(self.config, False)

    def testSetGetConfig(self):
        self.assertEqual(self.config, self.cookbook.get_config())
        self.cookbook.set_config(None)
        self.assertIsNone(self.cookbook._config)

    def testCacheMissing(self):
        status = {'test': 'test'}
        self.cookbook.set_status(status)
        self.cookbook._restore_cache()
        self.assertEqual(self.cookbook.status, {})

    def testSaveCache(self):
        tmp = tempfile.NamedTemporaryFile()
        status = {'test': 'test'}
        self.cookbook.set_status(status)
        self.cookbook.get_config().cache_file = tmp.name
        self.cookbook.save()
        with open(self.cookbook._cache_file(self.config), 'rb') as f:
            loaded_status = pickle.load(f)
            self.assertEqual(status, loaded_status)

    def testLoad(self):
        tmp = tempfile.NamedTemporaryFile()
        status = {'test': 'test'}
        self.cookbook.get_config().cache_file = tmp.name
        with open(tmp.name, 'wb') as f:
            pickle.dump(status, f)
        self.cookbook._restore_cache()
        self.assertEqual(status, self.cookbook.status)

    def testAddGetRecipe(self):
        recipe = Recipe1(self.config)
        self.assertRaises(RecipeNotFoundError, self.cookbook.get_recipe,
                          recipe.name)
        self.cookbook.add_recipe(recipe)
        self.assertEqual(recipe, self.cookbook.recipes[recipe.name])
        self.assertEqual(recipe, self.cookbook.get_recipe(recipe.name))
        self.assertEqual(self.cookbook.get_recipes_list(), [recipe])

    def testGetRecipesStatus(self):
        recipe = Recipe1(self.config)
        self.cookbook._restore_cache()
        self.assertEqual(self.cookbook.status, {})
        self.cookbook.add_recipe(recipe)
        self.assertEqual(len(self.cookbook.status), 0)
        status = self.cookbook._recipe_status(recipe.name)
        self.assertEqual(len(self.cookbook.status), 1)
        self.assertEqual(status.steps, [])
        status.steps.append('1')
        status = self.cookbook._recipe_status(recipe.name)
        self.assertEqual(len(self.cookbook.status), 1)
        self.assertEqual(status.steps[0], '1')

    def testUpdateStatus(self):
        recipe = Recipe1(self.config)
        self.cookbook.add_recipe(recipe)
        self.cookbook._restore_cache()
        self.cookbook.update_step_status(recipe.name, 'fetch')
        status = self.cookbook._recipe_status(recipe.name)
        self.assertEqual(status.steps, ['fetch'])
        self.cookbook.update_step_status(recipe.name, 'build')
        status = self.cookbook._recipe_status(recipe.name)
        self.assertEqual(status.steps, ['fetch', 'build'])
        self.cookbook.update_step_status(recipe.name, 'install')
        status = self.cookbook._recipe_status(recipe.name)
        self.assertEqual(status.steps, ['fetch', 'build', 'install'])
        for step in ['fetch', 'build', 'install']:
            self.assertTrue(self.cookbook.step_done(recipe.name, step))

    def testBuildStatus(self):
        recipe = Recipe1(self.config)
        self.cookbook.add_recipe(recipe)
        self.cookbook._restore_cache()
        self.cookbook.update_build_status(recipe.name, '1.0')
        self.assertTrue(self.cookbook.status[recipe.name].needs_build)
        self.assertEqual(self.cookbook.status[recipe.name].built_version,
                         '1.0')
        self.cookbook.update_build_status(recipe.name, None)
        self.assertFalse(self.cookbook.status[recipe.name].needs_build)
        self.assertEqual(self.cookbook.status[recipe.name].built_version, None)

    def testResetRecipeStatus(self):
        recipe = Recipe1(self.config)
        self.cookbook.add_recipe(recipe)
        self.cookbook._restore_cache()
        self.cookbook.reset_recipe_status(recipe.name)
        status = self.cookbook._recipe_status(recipe.name)
        self.assertEqual(status.steps, [])
        self.assertTrue(self.cookbook.status[recipe.name].needs_build)
class PackageTest(unittest.TestCase):

    def setUp(self):
        self.config = Config()
        self.config.cache_file = '/dev/null'
        self.cookbook = CookBook(self.config, False)

    def testSetGetConfig(self):
        self.assertEquals(self.config, self.cookbook.get_config())
        self.cookbook.set_config(None)
        self.assertIsNone(self.cookbook._config)

    def testCacheMissing(self):
        status = {'test': 'test'}
        self.cookbook.set_status(status)
        self.cookbook._restore_cache()
        self.assertEquals(self.cookbook.status, {})

    def testSaveCache(self):
        tmp = tempfile.NamedTemporaryFile()
        status = {'test': 'test'}
        self.cookbook.set_status(status)
        self.cookbook.get_config().cache_file = tmp.name
        self.cookbook.save()
        with open(self.cookbook._cache_file(self.config), 'rb') as f:
            loaded_status = pickle.load(f)
            self.assertEquals(status, loaded_status)

    def testLoad(self):
        tmp = tempfile.NamedTemporaryFile()
        status = {'test': 'test'}
        self.cookbook.get_config().cache_file = tmp.name
        with open(tmp.name, 'wb') as f:
            pickle.dump(status, f)
        self.cookbook._restore_cache()
        self.assertEquals(status, self.cookbook.status)

    def testAddGetRecipe(self):
        recipe = Recipe1(self.config)
        self.failUnlessRaises(RecipeNotFoundError, self.cookbook.get_recipe,
                              recipe.name)
        self.cookbook.add_recipe(recipe)
        self.assertEquals(recipe, self.cookbook.recipes[recipe.name])
        self.assertEquals(recipe, self.cookbook.get_recipe(recipe.name))
        self.assertEquals(self.cookbook.get_recipes_list(), [recipe])

    def testGetRecipesStatus(self):
        recipe = Recipe1(self.config)
        self.cookbook._restore_cache()
        self.assertEquals(self.cookbook.status, {})
        self.cookbook.add_recipe(recipe)
        self.assertEquals(len(self.cookbook.status), 0)
        status = self.cookbook._recipe_status(recipe.name)
        self.assertEquals(len(self.cookbook.status), 1)
        self.assertEquals(status.steps, [])
        status.steps.append('1')
        status = self.cookbook._recipe_status(recipe.name)
        self.assertEquals(len(self.cookbook.status), 1)
        self.assertEquals(status.steps[0], '1')

    def testUpdateStatus(self):
        recipe = Recipe1(self.config)
        self.cookbook.add_recipe(recipe)
        self.cookbook._restore_cache()
        self.cookbook.update_step_status(recipe.name, 'fetch')
        status = self.cookbook._recipe_status(recipe.name)
        self.assertEquals(status.steps, ['fetch'])
        self.cookbook.update_step_status(recipe.name, 'build')
        status = self.cookbook._recipe_status(recipe.name)
        self.assertEquals(status.steps, ['fetch', 'build'])
        self.cookbook.update_step_status(recipe.name, 'install')
        status = self.cookbook._recipe_status(recipe.name)
        self.assertEquals(status.steps, ['fetch', 'build', 'install'])
        for step in ['fetch', 'build', 'install']:
            self.assertTrue(self.cookbook.step_done(recipe.name, step))

    def testBuildStatus(self):
        recipe = Recipe1(self.config)
        self.cookbook.add_recipe(recipe)
        self.cookbook._restore_cache()
        self.cookbook.update_build_status(recipe.name, True)
        self.assertTrue(self.cookbook.status[recipe.name].needs_build)
        self.cookbook.update_build_status(recipe.name, False)
        self.assertFalse(self.cookbook.status[recipe.name].needs_build)

    def testResetRecipeStatus(self):
        recipe = Recipe1(self.config)
        self.cookbook.add_recipe(recipe)
        self.cookbook._restore_cache()
        self.cookbook.reset_recipe_status(recipe.name)
        status = self.cookbook._recipe_status(recipe.name)
        self.assertEquals(status.steps, [])
        self.assertTrue(self.cookbook.status[recipe.name].needs_build)
Пример #3
0
class BuildTools (BootstrapperBase, Fetch):

    BUILD_TOOLS = ['automake', 'autoconf', 'libtool', 'pkg-config',
                   'orc-tool', 'gettext-m4', 'meson']
    PLAT_BUILD_TOOLS = {
        Platform.DARWIN: ['intltool', 'sed', 'gperf', 'bison', 'flex',
                          'moltenvk-tools'],
        # MSYS already ships with bison, flex, m4 on Windows
        Platform.WINDOWS: ['intltool', 'gperf', 'nasm'],
        Platform.LINUX: ['intltool-m4'],
    }

    def __init__(self, config, offline):
        BootstrapperBase.__init__(self, config, offline)

        if self.config.target_platform in (Platform.IOS, Platform.WINDOWS):
            # Used by ffmpeg and x264 on iOS, and by openn264 on Windows-ARM64
            self.BUILD_TOOLS.append('gas-preprocessor')

        if self.config.platform == Platform.WINDOWS:
            # We must not run automake/autoconf/libtoolize when building on
            # windows because they hang on the Windows CI runner
            self.BUILD_TOOLS.remove('gettext-m4')
            self.BUILD_TOOLS.remove('automake')
            self.BUILD_TOOLS.remove('autoconf')
            self.BUILD_TOOLS.remove('libtool')

        if self.config.variants.uwp:
            # UWP config does not build any autotools recipes
            self.PLAT_BUILD_TOOLS[Platform.WINDOWS].remove('intltool')
            self.PLAT_BUILD_TOOLS[Platform.WINDOWS].remove('gperf')

        if self.config.target_platform != Platform.LINUX and not \
           self.config.prefix_is_executable():
            # For glib-mkenums and glib-genmarshal
            self.BUILD_TOOLS.append('glib-tools')
        self.BUILD_TOOLS += self.config.extra_build_tools
        self._setup_env()

    def check_build_tools(self):
        '''
        Check whether the build tools we have are new enough, and if not, build
        them ourselves. On Windows, we always build nasm ourselves, and we tell
        the user to install CMake using the installer.
        '''
        ret = []
        if self.config.platform in (Platform.LINUX, Platform.DARWIN):
            # need cmake > 3.10.2 for out-of-source-tree builds.
            tool, found, newer = shell.check_tool_version('cmake' ,'3.10.2', env=None)
            if not newer:
                ret.append('cmake')
            # dav1d requires nasm >=2.13.02
            tool, found, newer = shell.check_tool_version('nasm', '2.13.02', env=None)
            if not newer:
                ret.append('nasm')
        return ret

    def _setup_env(self):
        self.cookbook = CookBook(self.config.build_tools_config, offline=self.offline)
        self.recipes = self.BUILD_TOOLS
        self.recipes += self.PLAT_BUILD_TOOLS.get(self.config.platform, [])

    def insert_python_site(self):
        try:
            import setuptools.version as stv
        except ImportError:
            return

        version = stv.__version__.split('.', 1)
        if len(version) < 1 or int(version[0]) < 49:
            return

        m.warning('detected setuptools >= 49.0.0, installing fallback site.py file. '
            'See https://github.com/pypa/setuptools/issues/2295')

        # Since python-setuptools 49.0.0, site.py is not installed by
        # easy_install/setup.py anymore which breaks python installs outside
        # the system prefix.
        # https://github.com/pypa/setuptools/issues/2295
        #
        # Install the previously installed site.py ourselves as a workaround
        config = self.cookbook.get_config()

        py_prefix = sysconfig.get_path('purelib', vars={'base': ''})
        # Must strip \/ to ensure that the path is relative
        py_prefix = PurePath(config.prefix) / PurePath(py_prefix.strip('\\/'))
        src_file = os.path.join(os.path.dirname(__file__), 'site-patch.py')
        shutil.copy(src_file, py_prefix / 'site.py')

    def start(self, jobs=0):
        self.insert_python_site()

        # Check and these at the last minute because we may have installed them
        # in system bootstrap
        self.recipes += self.check_build_tools()
        oven = Oven(self.recipes, self.cookbook, jobs=jobs)
        oven.start_cooking()

    def fetch_recipes(self, jobs):
        Fetch.fetch(self.cookbook, self.recipes, False, False, False, False, jobs)