def load_consumer_conanfile(self, conanfile_path, info_folder, output, deps_info_required=False): """loads a conanfile for local flow: source, imports, package, build """ profile = read_conaninfo_profile( info_folder) or self._client_cache.default_profile cache_settings = self._client_cache.settings.copy() cache_settings.values = profile.settings_values # We are recovering state from captured profile from conaninfo, remove not defined cache_settings.remove_undefined() processed_profile = ProcessedProfile(cache_settings, profile, None) if conanfile_path.endswith(".py"): conanfile = self._loader.load_conanfile( conanfile_path, output, consumer=True, local=True, processed_profile=processed_profile) else: conanfile = self._loader.load_conanfile_txt( conanfile_path, output, processed_profile) load_deps_info(info_folder, conanfile, required=deps_info_required) return conanfile
def load_imports_arguments_test(self): file_content = ''' [imports] OpenCV/bin, * -> ./bin # I need this binaries OpenCV/lib, * -> ./lib @ root_package=Pkg OpenCV/data, * -> ./data @ root_package=Pkg, folder=True # Irrelevant docs, * -> ./docs @ root_package=Pkg, folder=True, ignore_case=True, excludes="a b c" # Other licenses, * -> ./licenses @ root_package=Pkg, folder=True, ignore_case=True, excludes="a b c", keep_path=False # Other ''' tmp_dir = temp_folder() file_path = os.path.join(tmp_dir, "file.txt") save(file_path, file_content) loader = ConanFileLoader(None, None, None) ret = loader.load_conanfile_txt(file_path, None, ProcessedProfile()) ret.copy = Mock() ret.imports() expected = [ call(u'*', u'./bin', u'OpenCV/bin', None, False, False, None, True), call(u'*', u'./lib', u'OpenCV/lib', u'Pkg', False, False, None, True), call(u'*', u'./data', u'OpenCV/data', u'Pkg', True, False, None, True), call(u'*', u'./docs', u'docs', u'Pkg', True, True, [u'"a', u'b', u'c"'], True), call(u'*', u'./licenses', u'licenses', u'Pkg', True, True, [u'"a', u'b', u'c"'], False) ] self.assertEqual(ret.copy.call_args_list, expected)
def test_package_settings(self): # CREATE A CONANFILE TO LOAD tmp_dir = temp_folder() conanfile_path = os.path.join(tmp_dir, "conanfile.py") conanfile = """from conans import ConanFile class MyTest(ConanFile): requires = {} name = "MyPackage" version = "1.0" settings = "os" """ save(conanfile_path, conanfile) # Apply windows for MyPackage profile = Profile() profile.package_settings = { "MyPackage": OrderedDict([("os", "Windows")]) } loader = ConanFileLoader(None, None, ConanPythonRequire(None, None)) recipe = loader.load_conanfile( conanfile_path, None, ProcessedProfile(Settings({"os": ["Windows", "Linux"]}), profile)) self.assertEquals(recipe.settings.os, "Windows") # Apply Linux for MyPackage profile.package_settings = { "MyPackage": OrderedDict([("os", "Linux")]) } recipe = loader.load_conanfile( conanfile_path, None, ProcessedProfile(Settings({"os": ["Windows", "Linux"]}), profile)) self.assertEquals(recipe.settings.os, "Linux") # If the package name is different from the conanfile one, it wont apply profile.package_settings = { "OtherPACKAGE": OrderedDict([("os", "Linux")]) } recipe = loader.load_conanfile( conanfile_path, None, ProcessedProfile(Settings({"os": ["Windows", "Linux"]}), profile)) self.assertIsNone(recipe.settings.os.value)
def load_graph(self, reference, create_reference, profile, build_mode, check_updates, update, remote_name, recorder, workspace): def _inject_require(conanfile, reference): """ test_package functionality requires injecting the tested package as requirement before running the install """ require = conanfile.requires.get(reference.name) if require: require.conan_reference = require.range_reference = reference else: conanfile.requires(str(reference)) conanfile._conan_user = reference.user conanfile._conan_channel = reference.channel # Computing the full dependency graph cache_settings = self._client_cache.settings.copy() cache_settings.values = profile.settings_values settings_preprocessor.preprocess(cache_settings) processed_profile = ProcessedProfile(cache_settings, profile, create_reference) if isinstance(reference, list): # Install workspace with multiple root nodes conanfile = self._loader.load_virtual(reference, processed_profile) elif isinstance(reference, ConanFileReference): # create without test_package and install <ref> conanfile = self._loader.load_virtual([reference], processed_profile) else: output = ScopedOutput("PROJECT", self._output) if reference.endswith(".py"): conanfile = self._loader.load_conanfile(reference, output, processed_profile, consumer=True) if create_reference: # create with test_package _inject_require(conanfile, create_reference) else: conanfile = self._loader.load_conanfile_txt( reference, output, processed_profile) build_mode = BuildMode(build_mode, self._output) root_node = Node(None, conanfile) deps_graph = self._load_graph( root_node, check_updates, update, build_mode=build_mode, remote_name=remote_name, profile_build_requires=profile.build_requires, recorder=recorder, workspace=workspace, processed_profile=processed_profile) build_mode.report_matches() return deps_graph, conanfile, cache_settings
def _build_and_check(self, tmp_dir, file_path, text_file, msg): loader = ConanFileLoader(None, None, ConanPythonRequire(None, None)) ret = loader.load_conanfile(file_path, None, ProcessedProfile()) curdir = os.path.abspath(os.curdir) os.chdir(tmp_dir) try: ret.build() finally: os.chdir(curdir) content = load(text_file) self.assertEquals(content, msg)
def load_consumer_conanfile(self, conanfile_path, info_folder, deps_info_required=False, test=None): """loads a conanfile for local flow: source, imports, package, build """ try: graph_info = GraphInfo.load(info_folder) except IOError: # Only if file is missing # This is very dirty, should be removed for Conan 2.0 (source() method only) profile = self._cache.default_profile profile.process_settings(self._cache) name, version, user, channel = None, None, None, None else: name, version, user, channel, _ = graph_info.root profile = graph_info.profile profile.process_settings(self._cache, preprocess=False) # This is the hack of recovering the options from the graph_info profile.options.update(graph_info.options) processed_profile = ProcessedProfile(profile, None) if conanfile_path.endswith(".py"): conanfile = self._loader.load_consumer( conanfile_path, processed_profile=processed_profile, test=test, name=name, version=version, user=user, channel=channel) with get_env_context_manager(conanfile, without_python=True): with conanfile_exception_formatter(str(conanfile), "config_options"): conanfile.config_options() with conanfile_exception_formatter(str(conanfile), "configure"): conanfile.configure() conanfile.settings.validate() # All has to be ok! conanfile.options.validate() else: conanfile = self._loader.load_conanfile_txt( conanfile_path, processed_profile) load_deps_info(info_folder, conanfile, required=deps_info_required) return conanfile
def requires_init_test(self): loader = ConanFileLoader(None, None, ConanPythonRequire(None, None)) tmp_dir = temp_folder() conanfile_path = os.path.join(tmp_dir, "conanfile.py") conanfile = """from conans import ConanFile class MyTest(ConanFile): requires = {} def requirements(self): self.requires("MyPkg/0.1@user/channel") """ for requires in ("''", "[]", "()", "None"): save(conanfile_path, conanfile.format(requires)) result = loader.load_conanfile( conanfile_path, output=None, consumer=True, processed_profile=ProcessedProfile()) result.requirements() self.assertEqual("MyPkg/0.1@user/channel", str(result.requires))
def load_simple_graph(self, reference, profile, recorder): # Loads a graph without computing the binaries. It is necessary for # export-pkg command, not hitting the server # # https://github.com/conan-io/conan/issues/3432 builder = DepsGraphBuilder(self._proxy, self._output, self._loader, self._resolver, workspace=None, recorder=recorder) processed_profile = ProcessedProfile(profile, create_reference=None) conanfile = self._loader.load_virtual([reference], processed_profile) root_node = Node(None, conanfile, recipe=RECIPE_VIRTUAL) graph = builder.load_graph(root_node, check_updates=False, update=False, remote_name=None, processed_profile=processed_profile) return graph
def inherit_short_paths_test(self): loader = ConanFileLoader(None, None, ConanPythonRequire(None, None)) tmp_dir = temp_folder() conanfile_path = os.path.join(tmp_dir, "conanfile.py") conanfile = """from base_recipe import BasePackage class Pkg(BasePackage): pass """ base_recipe = """from conans import ConanFile class BasePackage(ConanFile): short_paths = True """ save(conanfile_path, conanfile) save(os.path.join(tmp_dir, "base_recipe.py"), base_recipe) conan_file = loader.load_class(conanfile_path) self.assertEqual(conan_file.short_paths, True) result = loader.load_conanfile(conanfile_path, output=None, consumer=True, processed_profile=ProcessedProfile()) self.assertEqual(result.short_paths, True)
def load_simple_graph(self, reference, profile, recorder): # Loads a graph without computing the binaries. It is necessary for # export-pkg command, not hitting the server # # https://github.com/conan-io/conan/issues/3432 builder = DepsGraphBuilder(self._proxy, self._output, self._loader, self._resolver, workspace=None, recorder=recorder) cache_settings = self._client_cache.settings.copy() cache_settings.values = profile.settings_values settings_preprocessor.preprocess(cache_settings) processed_profile = ProcessedProfile(cache_settings, profile, create_reference=None) conanfile = self._loader.load_virtual([reference], processed_profile) graph = builder.load_graph(conanfile, check_updates=False, update=False, remote_name=None, processed_profile=processed_profile) return graph
def load_graph(self, reference, create_reference, graph_info, build_mode, check_updates, update, remote_name, recorder, apply_build_requires=True): def _inject_require(conanfile, ref): """ test_package functionality requires injecting the tested package as requirement before running the install """ require = conanfile.requires.get(ref.name) if require: require.ref = require.range_ref = ref else: conanfile.requires(str(ref)) conanfile._conan_user = ref.user conanfile._conan_channel = ref.channel # Computing the full dependency graph profile = graph_info.profile processed_profile = ProcessedProfile(profile, create_reference) ref = None if isinstance(reference, list): # Install workspace with multiple root nodes conanfile = self._loader.load_virtual(reference, processed_profile, scope_options=False) root_node = Node(ref, conanfile, recipe=RECIPE_VIRTUAL) elif isinstance(reference, ConanFileReference): if not self._cache.config.revisions_enabled and reference.revision is not None: raise ConanException("Revisions not enabled in the client, specify a " "reference without revision") # create without test_package and install <ref> conanfile = self._loader.load_virtual([reference], processed_profile) root_node = Node(ref, conanfile, recipe=RECIPE_VIRTUAL) else: path = reference if path.endswith(".py"): test = str(create_reference) if create_reference else None conanfile = self._loader.load_consumer(path, processed_profile, test=test, name=graph_info.root.name, version=graph_info.root.version, user=graph_info.root.user, channel=graph_info.root.channel) if create_reference: # create with test_package _inject_require(conanfile, create_reference) ref = ConanFileReference(conanfile.name, conanfile.version, conanfile._conan_user, conanfile._conan_channel, validate=False) else: conanfile = self._loader.load_conanfile_txt(path, processed_profile, ref=graph_info.root) root_node = Node(ref, conanfile, recipe=RECIPE_CONSUMER) build_mode = BuildMode(build_mode, self._output) deps_graph = self._load_graph(root_node, check_updates, update, build_mode=build_mode, remote_name=remote_name, profile_build_requires=profile.build_requires, recorder=recorder, processed_profile=processed_profile, apply_build_requires=apply_build_requires) # THIS IS NECESSARY to store dependencies options in profile, for consumer # FIXME: This is a hack. Might dissapear if the graph for local commands is always recomputed graph_info.options = root_node.conanfile.options.values version_ranges_output = self._resolver.output if version_ranges_output: self._output.success("Version ranges solved") for msg in version_ranges_output: self._output.info(" %s" % msg) self._output.writeln("") build_mode.report_matches() return deps_graph, conanfile
def load_conan_txt_test(self): file_content = '''[requires] OpenCV/2.4.10@phil/stable OpenCV2/2.4.10@phil/stable [build_requires] MyPkg/1.0.0@phil/stable [generators] one two [imports] OpenCV/bin, * -> ./bin # I need this binaries OpenCV/lib, * -> ./lib [options] OpenCV:use_python=True OpenCV:other_option=False OpenCV2:use_python2=1 OpenCV2:other_option=Cosa ''' tmp_dir = temp_folder() file_path = os.path.join(tmp_dir, "file.txt") save(file_path, file_content) loader = ConanFileLoader(None, None, None) ret = loader.load_conanfile_txt(file_path, None, ProcessedProfile()) options1 = OptionsValues.loads("""OpenCV:use_python=True OpenCV:other_option=False OpenCV2:use_python2=1 OpenCV2:other_option=Cosa""") requirements = Requirements() requirements.add("OpenCV/2.4.10@phil/stable") requirements.add("OpenCV2/2.4.10@phil/stable") build_requirements = [] build_requirements.append("MyPkg/1.0.0@phil/stable") self.assertEquals(ret.requires, requirements) self.assertEquals(ret.build_requires, build_requirements) self.assertEquals(ret.generators, ["one", "two"]) self.assertEquals(ret.options.values.dumps(), options1.dumps()) ret.copy = Mock() ret.imports() self.assertTrue(ret.copy.call_args_list, [('*', './bin', 'OpenCV/bin'), ('*', './lib', 'OpenCV/lib')]) # Now something that fails file_content = '''[requires] OpenCV/2.4.104phil/stable ''' tmp_dir = temp_folder() file_path = os.path.join(tmp_dir, "file.txt") save(file_path, file_content) loader = ConanFileLoader(None, None, None) with self.assertRaisesRegexp(ConanException, "Wrong package recipe reference(.*)"): loader.load_conanfile_txt(file_path, None, ProcessedProfile()) file_content = '''[requires] OpenCV/2.4.10@phil/stable111111111111111111111111111111111111111111111111111111111111111 [imports] OpenCV/bin/* - ./bin ''' tmp_dir = temp_folder() file_path = os.path.join(tmp_dir, "file.txt") save(file_path, file_content) loader = ConanFileLoader(None, None, None) with self.assertRaisesRegexp(ConanException, "is too long. Valid names must contain"): loader.load_conanfile_txt(file_path, None, ProcessedProfile())
def test_processed_profile(profile=None, settings=None): if profile is None: profile = Profile() if profile.processed_settings is None: profile.processed_settings = settings or Settings() return ProcessedProfile(profile=profile)
def complete_test(self): """ basic installation of a new conans """ client = TestClient() client.init_dynamic_vars() files = hello_source_files() conan_ref = ConanFileReference.loads("Hello/1.2.1@frodo/stable") reg_folder = client.paths.export(conan_ref) client.save(files, path=reg_folder) client.save( { CONANFILE: myconan1, "infos/%s" % CONANINFO: "//empty", "include/no_copy/lib0.h": "NO copy", "include/math/lib1.h": "copy", "include/math/lib2.h": "copy", "include/physics/lib.hpp": "copy", "my_lib/debug/libd.a": "copy", "my_data/readme.txt": "copy", "my_data/readme.md": "NO copy", "contrib/math/math.h": "copy", "contrib/physics/gravity.h": "copy", "contrib/contrib.h": "copy", "include/opencv/opencv.hpp": "copy", "include/opencv2/opencv2.hpp": "copy", "modules/simu/src/simu.cpp": "NO copy", "modules/simu/include/opencv2/simu/simu.hpp": "copy", "modules/3D/doc/readme.md": "NO copy", "modules/3D/include/opencv2/3D/3D.hpp": "copy", "modules/dev/src/dev.cpp": "NO copy", "modules/dev/include/opencv2/dev/dev.hpp": "copy", "modules/opencv_mod.hpp": "copy" }, path=reg_folder) conanfile_path = os.path.join(reg_folder, CONANFILE) package_ref = PackageReference(conan_ref, "myfakeid") build_folder = client.paths.build(package_ref) package_folder = client.paths.package(package_ref) install_folder = os.path.join(build_folder, "infos") shutil.copytree(reg_folder, build_folder) output = ScopedOutput("", TestBufferConanOutput()) loader = ConanFileLoader(None, None, ConanPythonRequire(None, None)) conanfile = loader.load_conanfile(conanfile_path, None, ProcessedProfile()) create_package(conanfile, None, build_folder, build_folder, package_folder, install_folder, output, client.hook_manager, conanfile_path, conan_ref, copy_info=True) # test build folder self.assertTrue(os.path.exists(build_folder)) self.assertTrue(os.path.exists(os.path.join(package_folder, CONANINFO))) # test pack folder self.assertTrue(os.path.exists(package_folder)) def exist(rel_path): return os.path.exists(os.path.join(package_folder, rel_path)) # Expected files self.assertTrue(exist("include/lib1.h")) self.assertTrue(exist("include/lib2.h")) self.assertTrue(exist("include/physics/lib.hpp")) self.assertTrue(exist("include/contrib/math/math.h")) self.assertTrue(exist("include/contrib/physics/gravity.h")) self.assertTrue(exist("include/contrib/contrib.h")) self.assertTrue(exist("include/opencv/opencv.hpp")) self.assertTrue(exist("include/opencv2/opencv2.hpp")) self.assertTrue(exist("include/opencv2/simu/simu.hpp")) self.assertTrue(exist("include/opencv2/3D/3D.hpp")) self.assertTrue(exist("include/opencv2/dev/dev.hpp")) self.assertTrue(exist("lib/my_lib/libd.a")) self.assertTrue(exist("res/shares/readme.txt")) # Not expected files self.assertFalse(exist("include/opencv2/opencv_mod.hpp")) self.assertFalse(exist("include/opencv2/simu.hpp")) self.assertFalse(exist("include/opencv2/3D.hpp")) self.assertFalse(exist("include/opencv2/dev.hpp")) self.assertFalse(exist("include/modules/simu/src/simu.cpp")) self.assertFalse(exist("include/modules/3D/doc/readme.md")) self.assertFalse(exist("include/modules/dev/src/dev.cpp")) self.assertFalse(exist("include/opencv2/opencv_mod.hpp")) self.assertFalse(exist("include/include/no_copy/lib0.h")) self.assertFalse(exist("res/my_data/readme.md"))
def root(self, content, update=False): processed_profile = ProcessedProfile() root_conan = self.retriever.root(content, processed_profile) deps_graph = self.builder.load_graph(root_conan, update, update, None, processed_profile) return deps_graph
def load_graph(self, reference, create_reference, graph_info, build_mode, check_updates, update, remote_name, recorder, workspace): def _inject_require(conanfile, reference): """ test_package functionality requires injecting the tested package as requirement before running the install """ require = conanfile.requires.get(reference.name) if require: require.conan_reference = require.range_reference = reference else: conanfile.requires(str(reference)) conanfile._conan_user = reference.user conanfile._conan_channel = reference.channel # Computing the full dependency graph profile = graph_info.profile cache_settings = profile.processed_settings processed_profile = ProcessedProfile(profile, create_reference) if isinstance(reference, list): # Install workspace with multiple root nodes conanfile = self._loader.load_virtual(reference, processed_profile) elif isinstance(reference, ConanFileReference): # create without test_package and install <ref> conanfile = self._loader.load_virtual([reference], processed_profile) else: output = ScopedOutput("PROJECT", self._output) if reference.endswith(".py"): conanfile = self._loader.load_conanfile(reference, output, processed_profile, consumer=True) if create_reference: # create with test_package _inject_require(conanfile, create_reference) else: conanfile = self._loader.load_conanfile_txt( reference, output, processed_profile) build_mode = BuildMode(build_mode, self._output) root_node = Node(None, conanfile) deps_graph = self._load_graph( root_node, check_updates, update, build_mode=build_mode, remote_name=remote_name, profile_build_requires=profile.build_requires, recorder=recorder, workspace=workspace, processed_profile=processed_profile) # THIS IS NECESSARY to store dependencies options in profile, for consumer # FIXME: This is a hack. Might dissapear if the graph for local commands is always recomputed graph_info.options = root_node.conanfile.options.values version_ranges_output = self._resolver.output if version_ranges_output: self._output.success("Version ranges solved") for msg in version_ranges_output: self._output.info(" %s" % msg) self._output.writeln("") build_mode.report_matches() return deps_graph, conanfile, cache_settings