def _install(self, references): self._output.info("Installing build requires: [%s]" % ", ".join(str(r) for r in references)) conanfile = self._loader.load_virtual( references, None, scope_options=False) # No need current path # FIXME: Forced update=True, build_mode, Where to define it? update = False local_search = None if update else self._search_manager resolver = RequireResolver(self._output, local_search, self._remote_proxy) graph_builder = DepsGraphBuilder(self._remote_proxy, self._output, self._loader, resolver) deps_graph = graph_builder.load(conanfile) registry = RemoteRegistry(self._client_cache.registry, self._output) Printer(self._output).print_graph(deps_graph, registry) # Make sure we recursively do not propagate the "*" pattern build_requires = copy.copy(self) build_requires._build_requires = self._build_requires.copy() build_requires._build_requires.pop("*", None) build_requires._build_requires.pop("&!", None) installer = ConanInstaller(self._client_cache, self._output, self._remote_proxy, build_requires) installer.install(deps_graph, self._build_modes, self._current_path) self._output.info("Installed build requires: [%s]" % ", ".join(str(r) for r in references)) return deps_graph
def _get_graph(self, reference, current_path, remote, options, settings, filename, update, check_updates, manifest_manager, scopes, package_settings, env, package_env): loader = self._loader(current_path, settings, package_settings, options, scopes, env, package_env) # Not check for updates for info command, it'll be checked when dep graph is built remote_proxy = ConanProxy(self._client_cache, self._user_io, self._remote_manager, remote, update=update, check_updates=check_updates, manifest_manager=manifest_manager) if isinstance(reference, ConanFileReference): project_reference = None conanfile = loader.load_virtual(reference, current_path) is_txt = True else: conanfile_path = reference project_reference = "PROJECT" output = ScopedOutput(project_reference, self._user_io.out) try: if filename and filename.endswith(".txt"): raise NotFoundException("") conan_file_path = os.path.join(conanfile_path, filename or CONANFILE) conanfile = loader.load_conan(conan_file_path, output, consumer=True) is_txt = False if conanfile.name is not None and conanfile.version is not None: project_reference = "%s/%s@" % (conanfile.name, conanfile.version) project_reference += "PROJECT" except NotFoundException: # Load requirements.txt conan_path = os.path.join(conanfile_path, filename or CONANFILE_TXT) conanfile = loader.load_conan_txt(conan_path, output) is_txt = True # build deps graph and install it local_search = None if update else self._search_manager resolver = RequireResolver(self._user_io.out, local_search, remote_proxy) builder = DepsGraphBuilder(remote_proxy, self._user_io.out, loader, resolver) deps_graph = builder.load(None, conanfile) # These lines are so the conaninfo stores the correct complete info if is_txt: conanfile.info.settings = loader._settings.values conanfile.info.full_settings = loader._settings.values conanfile.info.scope = self._current_scopes conanfile.cpp_info = CppInfo(current_path) conanfile.env_info = EnvInfo(current_path) registry = RemoteRegistry(self._client_cache.registry, self._user_io.out) return (builder, deps_graph, project_reference, registry, conanfile, remote_proxy, loader)
class VersionRangesTest(unittest.TestCase): def setUp(self): self.output = TestBufferConanOutput() self.loader = ConanFileLoader(None, Settings.loads(""), Profile()) self.retriever = Retriever(self.loader, self.output) self.remote_search = MockSearchRemote() self.resolver = RequireResolver(self.output, self.retriever, self.remote_search) self.builder = DepsGraphBuilder(self.retriever, self.output, self.loader, self.resolver) for v in ["0.1", "0.2", "0.3", "1.1", "1.1.2", "1.2.1", "2.1", "2.2.1"]: say_content = """ from conans import ConanFile class SayConan(ConanFile): name = "Say" version = "%s" """ % v say_ref = ConanFileReference.loads("Say/%s@memsharded/testing" % v) self.retriever.conan(say_ref, say_content) def root(self, content): root_conan = self.retriever.root(content) deps_graph = self.builder.load(root_conan) return deps_graph def test_local_basic(self): for expr, solution in [(">0.0", "2.2.1"), (">0.1,<1", "0.3"), (">0.1,<1||2.1", "2.1"), ("", "2.2.1"), ("~0", "0.3"), ("~=1", "1.2.1"), ("~1.1", "1.1.2"), ("~=2", "2.2.1"), ("~=2.1", "2.1"), ]: deps_graph = self.root(hello_content % expr) self.assertEqual(2, len(deps_graph.nodes)) hello = _get_nodes(deps_graph, "Hello")[0] say = _get_nodes(deps_graph, "Say")[0] self.assertEqual(_get_edges(deps_graph), {Edge(hello, say)}) self.assertEqual(hello.conan_ref, None) conanfile = hello.conanfile self.assertEqual(conanfile.version, "1.2") self.assertEqual(conanfile.name, "Hello") say_ref = ConanFileReference.loads("Say/%s@memsharded/testing" % solution) self.assertEqual(conanfile.requires, Requirements(str(say_ref))) def test_remote_basic(self): self.resolver._local_search = None remote_packages = [] for v in ["0.1", "0.2", "0.3", "1.1", "1.1.2", "1.2.1", "2.1", "2.2.1"]: say_ref = ConanFileReference.loads("Say/%s@memsharded/testing" % v) remote_packages.append(say_ref) self.remote_search.packages = remote_packages self.test_local_basic() @parameterized.expand([("", "0.3", None, None), ('"Say/1.1@memsharded/testing"', "1.1", False, False), ('"Say/0.2@memsharded/testing"', "0.2", False, True), ('("Say/1.1@memsharded/testing", "override")', "1.1", True, False), ('("Say/0.2@memsharded/testing", "override")', "0.2", True, True), # ranges ('"Say/[<=1.2]@memsharded/testing"', "1.2.1", False, False), ('"Say/[>=0.2,<=1.0]@memsharded/testing"', "0.3", False, True), ('("Say/[<=1.2]@memsharded/testing", "override")', "1.2.1", True, False), ('("Say/[>=0.2,<=1.0]@memsharded/testing", "override")', "0.3", True, True), ]) def transitive_test(self, version_range, solution, override, valid): hello_text = hello_content % ">0.1, <1" hello_ref = ConanFileReference.loads("Hello/1.2@memsharded/testing") self.retriever.conan(hello_ref, hello_text) chat_content = """ from conans import ConanFile class ChatConan(ConanFile): name = "Chat" version = "2.3" requires = "Hello/1.2@memsharded/testing", %s """ deps_graph = self.root(chat_content % version_range) hello = _get_nodes(deps_graph, "Hello")[0] say = _get_nodes(deps_graph, "Say")[0] chat = _get_nodes(deps_graph, "Chat")[0] edges = {Edge(hello, say), Edge(chat, hello)} if override is not None: self.assertIn("override", self.output) else: self.assertNotIn("override", self.output) if override is False: edges = {Edge(hello, say), Edge(chat, say), Edge(chat, hello)} if valid is True: self.assertIn(" valid", self.output) elif valid is False: self.assertIn("not valid", self.output) self.assertEqual(3, len(deps_graph.nodes)) self.assertEqual(_get_edges(deps_graph), edges) self.assertEqual(hello.conan_ref, hello_ref) conanfile = hello.conanfile self.assertEqual(conanfile.version, "1.2") self.assertEqual(conanfile.name, "Hello") say_ref = ConanFileReference.loads("Say/%s@memsharded/testing" % solution) self.assertEqual(conanfile.requires, Requirements(str(say_ref))) def duplicated_error_test(self): content = """ from conans import ConanFile class Log3cppConan(ConanFile): name = "log4cpp" version = "1.1.1" """ log4cpp_ref = ConanFileReference.loads("log4cpp/1.1.1@memsharded/testing") self.retriever.conan(log4cpp_ref, content) content = """ from conans import ConanFile class LoggerInterfaceConan(ConanFile): name = "LoggerInterface" version = "0.1.1" def requirements(self): self.requires("log4cpp/[~1.1]@memsharded/testing") """ logiface_ref = ConanFileReference.loads("LoggerInterface/0.1.1@memsharded/testing") self.retriever.conan(logiface_ref, content) content = """ from conans import ConanFile class OtherConan(ConanFile): name = "other" version = "2.0.11549" requires = "LoggerInterface/[~0.1]@memsharded/testing" """ other_ref = ConanFileReference.loads("other/2.0.11549@memsharded/testing") self.retriever.conan(other_ref, content) content = """ from conans import ConanFile class Project(ConanFile): requires = "LoggerInterface/[~0.1]@memsharded/testing", "other/[~2.0]@memsharded/testing" """ deps_graph = self.root(content) log4cpp = _get_nodes(deps_graph, "log4cpp")[0] logger_interface = _get_nodes(deps_graph, "LoggerInterface")[0] other = _get_nodes(deps_graph, "other")[0] self.assertEqual(4, len(deps_graph.nodes)) self.assertEqual(log4cpp.conan_ref, log4cpp_ref) conanfile = log4cpp.conanfile self.assertEqual(conanfile.version, "1.1.1") self.assertEqual(conanfile.name, "log4cpp") self.assertEqual(logger_interface.conan_ref, logiface_ref) conanfile = logger_interface.conanfile self.assertEqual(conanfile.version, "0.1.1") self.assertEqual(conanfile.name, "LoggerInterface") self.assertEqual(other.conan_ref, other_ref) conanfile = other.conanfile self.assertEqual(conanfile.version, "2.0.11549") self.assertEqual(conanfile.name, "other")