def test_msvc_visual_incompatible(): conanfile = GenConanfile().with_settings("os", "compiler", "build_type", "arch") client = TestClient() profile = textwrap.dedent(""" [settings] os=Windows compiler=msvc compiler.version=191 compiler.runtime=dynamic compiler.cppstd=14 build_type=Release arch=x86_64 """) client.save({"conanfile.py": conanfile, "profile": profile}) client.run('create . pkg/0.1@ -s os=Windows -s compiler="Visual Studio" -s compiler.version=15 ' '-s compiler.runtime=MD -s build_type=Release -s arch=x86_64') client.run("install pkg/0.1@ -pr=profile") assert "Using compatible package" in client.out new_config = "core.package_id:msvc_visual_incompatible=1" save(client.cache.new_config_path, new_config) client.run("install pkg/0.1@ -pr=profile", assert_error=True) assert "ERROR: Missing prebuilt package for 'pkg/0.1'" in client.out
def test_upload_parallel_success(self): """Upload 2 packages in parallel with success""" client = TestClient(default_server_user=True) client.save({"conanfile.py": GenConanfile()}) client.run('create . lib0/1.0@user/channel') self.assertIn( "lib0/1.0@user/channel: Package '{}' created".format( NO_SETTINGS_PACKAGE_ID), client.out) client.run('create . lib1/1.0@user/channel') self.assertIn( "lib1/1.0@user/channel: Package '{}' created".format( NO_SETTINGS_PACKAGE_ID), client.out) client.run('user -p password -r default user') client.run('upload lib* --parallel -c --all -r default') self.assertIn("Uploading lib0/1.0@user/channel to remote 'default'", client.out) self.assertIn("Uploading lib1/1.0@user/channel to remote 'default'", client.out) client.run('search lib0/1.0@user/channel -r default') self.assertIn("lib0/1.0@user/channel", client.out) client.run('search lib1/1.0@user/channel -r default') self.assertIn("lib1/1.0@user/channel", client.out)
def cmake_paths_contents_test(self): ref1 = ConanFileReference.loads("lib1/1.0@conan/stable") ref2 = ConanFileReference.loads("lib2/1.0@conan/stable") client = TurboTestClient() pref1 = client.create(ref1) pref2 = client.create(ref2, conanfile=GenConanfile().with_requirement(ref1)) client.run("install {} -g cmake_paths".format(ref2)) pfolder1 = client.cache.package_layout( pref1.ref).package(pref1).replace("\\", "/") pfolder2 = client.cache.package_layout( pref2.ref).package(pref2).replace("\\", "/") contents = client.load("conan_paths.cmake") expected = 'set(CONAN_LIB2_ROOT "{pfolder2}")\r\n' \ 'set(CONAN_LIB1_ROOT "{pfolder1}")\r\n' \ 'set(CMAKE_MODULE_PATH "{pfolder2}/"\r\n\t\t\t"{pfolder1}/" ' \ '${{CMAKE_MODULE_PATH}} ${{CMAKE_CURRENT_LIST_DIR}})\r\n' \ 'set(CMAKE_PREFIX_PATH "{pfolder2}/"\r\n\t\t\t"{pfolder1}/" ' \ '${{CMAKE_PREFIX_PATH}} ${{CMAKE_CURRENT_LIST_DIR}})' if platform.system() != "Windows": expected = expected.replace("\r", "") self.assertEqual(expected.format(pfolder1=pfolder1, pfolder2=pfolder2), contents)
def basic_parallel_download_test(self): client = TestClient(default_server_user=True) threads = 1 # At the moment, not really parallel until output implements mutex counter = 4 client.run("config set general.parallel_download=%s" % threads) client.save({"conanfile.py": GenConanfile().with_option("myoption", '"ANY"')}) for i in range(counter): client.run("create . pkg/0.1@user/testing -o pkg:myoption=%s" % i) client.run("upload * --all --confirm") client.run("remove * -f") # Lets download the packages client.run("download pkg/0.1@user/testing") self.assertIn("Downloading binary packages in %s parallel threads" % threads, client.out) self.assertIn("pkg/0.1@user/testing: Package installed " "74ca4e392408c388db596b086fca5ebf64d825c0", client.out) self.assertIn("pkg/0.1@user/testing: Package installed " "522dbc702b9cc2b582607ad6525f32ebd1442be5", client.out) self.assertIn("pkg/0.1@user/testing: Package installed " "11997e24a862625b5e4753858f71aaf81a58a9b4", client.out) self.assertIn("pkg/0.1@user/testing: Package installed " "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", client.out)
def test_conditional_env_var(self): client = TestClient() client.save({"conanfile.py": GenConanfile()}) client.run("create . dep_recipe/1.0@") client.run("create . dep_profile/1.0@") conanfile = textwrap.dedent(""" from conans import ConanFile import os class Pkg(ConanFile): def build_requirements(self): if os.getenv("USE_DEP"): self.build_requires("dep_recipe/1.0") """) client.save({"conanfile.py": conanfile, "profile": "[build_requires]\ndep_profile/1.0"}) with environment_append({"USE_DEP": "1"}): client.run("lock create conanfile.py --name=pkg --version=1.0 -pr=profile") lock = client.load("conan.lock") self.assertIn("dep_recipe/1.0", lock) self.assertIn("dep_profile/1.0", lock) client.run("create . pkg/1.0@ --lockfile=conan.lock", assert_error=True) self.assertIn("ERROR: 'pkg/1.0' locked requirement 'dep_recipe/1.0' not found", client.out)
def test_compatible_setting(self): c = TestClient() conanfile = textwrap.dedent(""" from conan import ConanFile class Pkg(ConanFile): name = "pkg" version = "0.1" settings = "os", "compiler" def compatibility(self): if self.settings.compiler == "gcc" and self.settings.compiler.version == "4.9": return [{"settings": [("compiler.version", v)]} for v in ("4.8", "4.7", "4.6")] def package_info(self): self.output.info("PackageInfo!: Gcc version: %s!" % self.settings.compiler.version) """) profile = textwrap.dedent(""" [settings] os = Linux compiler=gcc compiler.version=4.9 compiler.libcxx=libstdc++ """) c.save({"conanfile.py": conanfile, "myprofile": profile}) # Create package with gcc 4.8 c.run("create . -pr=myprofile -s compiler.version=4.8") assert "pkg/0.1: Package '22c594d7fed4994c59a1eacb24ff6ff48bc5c51c' created" in c.out # package can be used with a profile gcc 4.9 falling back to 4.8 binary c.save({"conanfile.py": GenConanfile().with_require("pkg/0.1")}) c.run("install . -pr=myprofile") assert "pkg/0.1: PackageInfo!: Gcc version: 4.8!" in c.out assert "pkg/0.1:22c594d7fed4994c59a1eacb24ff6ff48bc5c51c" in c.out assert "pkg/0.1: Already installed!" in c.out
def compatible_setting_test(self): client = TestClient() conanfile = textwrap.dedent(""" from conans import ConanFile class Pkg(ConanFile): settings = "os", "compiler" def package_id(self): if self.settings.compiler == "gcc" and self.settings.compiler.version == "4.9": for version in ("4.8", "4.7", "4.6"): compatible_pkg = self.info.clone() compatible_pkg.settings.compiler.version = version self.compatible_packages.append(compatible_pkg) def package_info(self): self.output.info("PackageInfo!: Gcc version: %s!" % self.settings.compiler.version) """) profile = textwrap.dedent(""" [settings] os = Linux compiler=gcc compiler.version=4.9 compiler.libcxx=libstdc++ """) client.save({"conanfile.py": conanfile, "myprofile": profile}) # Create package with gcc 4.8 client.run("create . pkg/0.1@user/stable -pr=myprofile -s compiler.version=4.8") self.assertIn("pkg/0.1@user/stable: Package '22c594d7fed4994c59a1eacb24ff6ff48bc5c51c'" " created", client.out) # package can be used with a profile gcc 4.9 falling back to 4.8 binary client.save({"conanfile.py": GenConanfile().with_require_plain("pkg/0.1@user/stable")}) client.run("install . -pr=myprofile") self.assertIn("pkg/0.1@user/stable: PackageInfo!: Gcc version: 4.8!", client.out) self.assertIn("pkg/0.1@user/stable:22c594d7fed4994c59a1eacb24ff6ff48bc5c51c", client.out) self.assertIn("pkg/0.1@user/stable: Already installed!", client.out)
def test_collect_libs(self): conanfile = textwrap.dedent(""" from conans import ConanFile class Pkg(ConanFile): exports_sources = "*" def package(self): self.copy("*", dst="lib") def package_info(self): from conans import tools self.cpp_info.libs = tools.collect_libs(self) """) client = TestClient() lib_name = "mylibname.%s" % ("a" if platform.system() != "Windows" else "lib") client.save({"conanfile.py": conanfile, lib_name: ""}) client.run("create . mylib/0.1@user/channel") # reusing the binary already in cache client.save( { "conanfile.py": GenConanfile().with_require("mylib/0.1@user/channel") }, clean_first=True) client.run('install . -g cmake') conanbuildinfo = client.load("conanbuildinfo.cmake") self.assertIn("set(CONAN_LIBS_MYLIB mylibname)", conanbuildinfo) self.assertIn("set(CONAN_LIBS mylibname ${CONAN_LIBS})", conanbuildinfo) # rebuilding the binary in cache client.run('remove "*" -p -f') client.run('install . --build -g cmake') conanbuildinfo = client.load("conanbuildinfo.cmake") self.assertIn("set(CONAN_LIBS_MYLIB mylibname)", conanbuildinfo) self.assertIn("set(CONAN_LIBS mylibname ${CONAN_LIBS})", conanbuildinfo)
def test_transitive_py_requires(self): # https://github.com/conan-io/conan/issues/5529 client = TestClient() client.save({"conanfile.py": GenConanfile()}) client.run("export . base/1.0@user/channel") conanfile = textwrap.dedent(""" from conans import ConanFile class PackageInfo(ConanFile): python_requires = "base/1.0@user/channel" """) client.save({"conanfile.py": conanfile}) client.run("export . helper/1.0@user/channel") conanfile = textwrap.dedent(""" from conans import ConanFile class MyConanfileBase(ConanFile): python_requires = "helper/1.0@user/channel" """) client.save({"conanfile.py": conanfile}) client.run("install . pkg/0.1@user/channel") lockfile = client.load("conan.lock") if client.cache.config.revisions_enabled: self.assertIn( "base/1.0@user/channel#f3367e0e7d170aa12abccb175fee5f97", lockfile) self.assertIn( "helper/1.0@user/channel#539219485c7a9e8e19561db523512b39", lockfile) else: self.assertIn("base/1.0@user/channel", lockfile) self.assertIn("helper/1.0@user/channel", lockfile) client.run("source .") self.assertIn( "conanfile.py (pkg/0.1@user/channel): Configuring sources in", client.out)
def test_compatible_lockfile(self): # https://github.com/conan-io/conan/issues/9002 client = TestClient() conanfile = textwrap.dedent(""" from conans import ConanFile class Pkg(ConanFile): settings = "os" def package_id(self): if self.settings.os == "Windows": compatible_pkg = self.info.clone() compatible_pkg.settings.os = "Linux" self.compatible_packages.append(compatible_pkg) def package_info(self): self.output.info("PackageInfo!: OS: %s!" % self.settings.os) """) client.save({"conanfile.py": conanfile}) client.run("create . pkg/0.1@user/stable -s os=Linux") self.assertIn("pkg/0.1@user/stable: PackageInfo!: OS: Linux!", client.out) self.assertIn( "pkg/0.1@user/stable: Package 'cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31'" " created", client.out) client.save({ "conanfile.py": GenConanfile().with_require("pkg/0.1@user/stable") }) client.run( "lock create conanfile.py -s os=Windows --lockfile-out=deps.lock") client.run("install conanfile.py --lockfile=deps.lock") self.assertIn("pkg/0.1@user/stable: PackageInfo!: OS: Linux!", client.out) self.assertIn( "pkg/0.1@user/stable:cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31", client.out) self.assertIn("pkg/0.1@user/stable: Already installed!", client.out)
def test_dont_conflict_private(self, private_first): liba_ref = ConanFileReference.loads("liba/0.1@user/testing") liba_ref2 = ConanFileReference.loads("liba/0.2@user/testing") libb_ref = ConanFileReference.loads("libb/0.1@user/testing") libc_ref = ConanFileReference.loads("libc/0.1@user/testing") self._cache_recipe(liba_ref, GenConanfile().with_name("liba").with_version("0.1")) self._cache_recipe(liba_ref2, GenConanfile().with_name("liba").with_version("0.2")) self._cache_recipe(libb_ref, GenConanfile().with_name("libb").with_version("0.1") .with_require(liba_ref, private=True)) if private_first: self._cache_recipe(libc_ref, GenConanfile().with_name("libc").with_version("0.1") .with_require(liba_ref2, private=True) .with_require(libb_ref)) else: self._cache_recipe(libc_ref, GenConanfile().with_name("libc").with_version("0.1") .with_require(libb_ref) .with_require(liba_ref2, private=True)) deps_graph = self.build_graph(GenConanfile().with_name("app").with_version("0.1") .with_require(libc_ref)) self.assertEqual(5, len(deps_graph.nodes)) app = deps_graph.root libc = app.dependencies[0].dst if private_first: liba2 = libc.dependencies[0].dst libb = libc.dependencies[1].dst else: libb = libc.dependencies[0].dst liba2 = libc.dependencies[1].dst liba1 = libb.dependencies[0].dst self._check_node(app, "app/0.1@", deps=[libc], build_deps=[], dependents=[], closure=[libc, libb]) closure = [liba2, libb] if private_first else [libb, liba2] self._check_node(libc, "libc/0.1@user/testing#123", deps=[libb, liba2], build_deps=[], dependents=[app], closure=closure) self._check_node(libb, "libb/0.1@user/testing#123", deps=[liba1], build_deps=[], dependents=[libc], closure=[liba1]) self._check_node(liba1, "liba/0.1@user/testing#123", deps=[], build_deps=[], dependents=[libb], closure=[]) self._check_node(liba2, "liba/0.2@user/testing#123", deps=[], build_deps=[], dependents=[libc], closure=[])
def test_export_filter(self): self.client.save({CONANFILE: GenConanfile("openssl", "2.0.1")}) self.client.run("export . lasote/stable") ref = ConanFileReference.loads('openssl/2.0.1@lasote/stable') reg_path = self.client.cache.package_layout(ref).export() self.assertEqual(sorted(os.listdir(reg_path)), [CONANFILE, CONAN_MANIFEST]) content = """ from conans import ConanFile class OpenSSLConan(ConanFile): name = "openssl" version = "2.0.1" exports = ('*.txt', '*.h') """ self.client.save({CONANFILE: content}) self.client.run("export . lasote/stable") self.assertEqual( sorted(os.listdir(reg_path)), ['CMakeLists.txt', CONANFILE, CONAN_MANIFEST, 'helloHello0.h']) # Now exports being a list instead a tuple content = """ from conans import ConanFile class OpenSSLConan(ConanFile): name = "openssl" version = "2.0.1" exports = ['*.txt', '*.h'] """ self.client.save({CONANFILE: content}) self.client.run("export . lasote/stable") self.assertEqual( sorted(os.listdir(reg_path)), ['CMakeLists.txt', CONANFILE, CONAN_MANIFEST, 'helloHello0.h'])
def failed_assert_test(self): # https://github.com/conan-io/conan/issues/5685 client = TestClient() client.save({"conanfile.py": GenConanfile()}) client.run("export . common/1.0@test/test") req = textwrap.dedent(""" from conans import ConanFile class BuildReqConan(ConanFile): requires = "common/1.0@test/test" """) client.save({"conanfile.py": req}) client.run("export . req/1.0@test/test") client.run("export . build_req/1.0@test/test") build_req_req = textwrap.dedent(""" from conans import ConanFile class BuildReqConan(ConanFile): requires = "common/1.0@test/test" build_requires = "build_req/1.0@test/test" """) client.save({"conanfile.py": build_req_req}) client.run("export . build_req_req/1.0@test/test") consumer = textwrap.dedent(""" [requires] req/1.0@test/test [build_requires] build_req_req/1.0@test/test """) client.save({"conanfile.txt": consumer}, clean_first=True) client.run("install . --build=missing") # This used to assert and trace, now it works self.assertIn( "conanfile.txt: Applying build-requirement: build_req_req/1.0@test/test", client.out)
def test_override(self): self.client.save({"conanfile.py": GenConanfile()}) self.client.run("export . libA/1.0@user/channel") # It is necessary to create libA/2.0 to have a conflict, otherwise it is missing self.client.run("export . libA/2.0@user/channel") for req_method in (False, True): self._save(req_method, ["libA/1.0@user/channel"]) self.client.run("export . libB/1.0@user/channel") self._save(req_method, ["libA/2.0@user/channel"]) self.client.run("export . libC/1.0@user/channel") self._save(req_method, ["libB/1.0@user/channel", "libC/1.0@user/channel"]) self.client.run("info .", assert_error=True) self.assertIn( "Requirement libA/2.0@user/channel conflicts with " "already defined libA/1.0@user/channel", self.client.out) self._save(req_method, [ "libB/1.0@user/channel", "libC/1.0@user/channel", ("libA/1.0@user/channel", "override") ]) self.client.run("info .") self.assertIn("libA/2.0@user/channel overridden", self.client.out)
def test_install_without_ref(self): client = TestClient(default_server_user=True) client.save({"conanfile.py": GenConanfile("lib", "1.0")}) client.run('create .') self.assertIn( "lib/1.0: Package '{}' created".format(NO_SETTINGS_PACKAGE_ID), client.out) client.run('upload lib/1.0 -c --all') self.assertIn("Uploaded conan recipe 'lib/1.0' to 'default'", client.out) client.run('remove "*" -f') # This fails, Conan thinks this is a path client.run('install lib/1.0', assert_error=True) fake_path = os.path.join(client.current_folder, "lib", "1.0") self.assertIn("Conanfile not found at {}".format(fake_path), client.out) # Try this syntax to upload too client.run('install lib/1.0@') client.run('upload lib/1.0@ -c --all')
def setUp(self): revisions_enabled = get_env("TESTING_REVISIONS_ENABLED", False) self.server = TestServer([("*/*@*/*", "*")], [("*/*@*/*", "*")]) self.client = TestClient(servers={"default": self.server}) self.client.save({"conanfile.py": GenConanfile()}) self.client.run("create . Pkg/0.1@user/testing") self.client.run("upload * --all --confirm -r default") # Check files are uploded in this order: conan_package.tgz, conaninfo.txt, conanmanifest.txt order1 = str(self.client.out).find("Uploading conan_package.tgz") order2 = str(self.client.out).find("Uploading conaninfo.txt", order1) order3 = str(self.client.out).find("Uploading conanmanifest.txt", order2) self.assertTrue(order1 < order2 < order3) rrev = "f3367e0e7d170aa12abccb175fee5f97" if revisions_enabled else "0" pref_str = "Pkg/0.1@user/testing#%s" % rrev prev = "83c38d3b4e5f1b8450434436eec31b00" if revisions_enabled else "0" self.pref = pref = PackageReference(ConanFileReference.loads(pref_str), NO_SETTINGS_PACKAGE_ID, prev) self.manifest_path = self.server.server_store.get_package_file_path( pref, "conanmanifest.txt") self.info_path = self.server.server_store.get_package_file_path( pref, "conaninfo.txt") self.tgz_path = self.server.server_store.get_package_file_path( pref, "conan_package.tgz")
def local_build_test(self): client = TestClient() client.save({"conanfile.py": "var=42\n" + str(GenConanfile())}) client.run("export . tool/0.1@user/channel") conanfile = textwrap.dedent(""" from conans import ConanFile class MyConanfileBase(ConanFile): python_requires = "tool/0.1@user/channel" def source(self): self.output.info("Pkg1 source: %s" % self.python_requires["tool"].module.var) def build(self): self.output.info("Pkg1 build: %s" % self.python_requires["tool"].module.var) def package(self): self.output.info("Pkg1 package: %s" % self.python_requires["tool"].module.var) """) client.save({"conanfile.py": conanfile}) client.run("source .") self.assertIn("conanfile.py: Pkg1 source: 42", client.out) client.run("install .") client.run("build .") self.assertIn("conanfile.py: Pkg1 build: 42", client.out) client.run("package .") self.assertIn("conanfile.py: Pkg1 package: 42", client.out) client.run("export-pkg . pkg1/0.1@user/testing")
def upload_without_user_channel_test(self): server = TestServer(users={"user": "******"}, write_permissions=[("*/*@*/*", "*")]) servers = {"default": server} client = TestClient(servers=servers, users={"default": [("user", "password")]}) client.save({"conanfile.py": GenConanfile()}) client.run('create . lib/1.0@') self.assertIn("lib/1.0: Package '{}' created".format(NO_SETTINGS_PACKAGE_ID), client.out) client.run('upload lib/1.0 -c --all') self.assertIn("Uploaded conan recipe 'lib/1.0' to 'default'", client.out) # Verify that in the remote it is stored as "_" pref = PackageReference.loads("lib/1.0@#0:{}#0".format(NO_SETTINGS_PACKAGE_ID)) path = server.server_store.export(pref.ref) self.assertIn("/lib/1.0/_/_/0/export", path.replace("\\", "/")) path = server.server_store.package(pref) self.assertIn("/lib/1.0/_/_/0/package", path.replace("\\", "/")) # Should be possible with explicit package client.run('upload lib/1.0:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9') self.assertIn("Uploading package 1/1: 5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 to 'default'", client.out)
def remove_locks_test(self): client = TestClient() client.save({ "conanfile.py": GenConanfile().with_name("Hello").with_version("0.1") }) client.run("create . lasote/testing") self.assertNotIn('does not contain a number!', client.out) ref = ConanFileReference.loads("Hello/0.1@lasote/testing") conan_folder = client.cache.package_layout(ref).base_folder() self.assertIn("locks", os.listdir(conan_folder)) self.assertTrue(os.path.exists(conan_folder + ".count")) self.assertTrue(os.path.exists(conan_folder + ".count.lock")) client.run("remove * --locks", assert_error=True) self.assertIn("ERROR: Specifying a pattern is not supported", client.out) client.run("remove", assert_error=True) self.assertIn( 'ERROR: Please specify a pattern to be removed ("*" for all)', client.out) client.run("remove --locks") self.assertNotIn("locks", os.listdir(conan_folder)) self.assertFalse(os.path.exists(conan_folder + ".count")) self.assertFalse(os.path.exists(conan_folder + ".count.lock"))
def test_partial_lock_option_conanfile_configure(self): # when 'LibA:myoption' is locked, it is used, even if other packages define it. client = self.client client.save({ "conanfile.py": GenConanfile().with_require("LibA/1.0").with_default_option( "LibA:myoption", True) }) client.run("create . LibB/1.0@") client.run("lock create --reference=LibB/1.0 --lockfile-out=libb.lock") libc = textwrap.dedent(""" from conans import ConanFile class LibC(ConanFile): requires = "LibA/1.0" def configure(self): self.options["LibA"].myoption = False """) client.save({"conanfile.py": libc}) client.run("create . LibC/1.0@") self.assertIn( "LibA/1.0:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache", client.out) self._check()
def build_missing_test(self): # https://github.com/conan-io/conan/issues/6133 client = TestClient() conanfile = textwrap.dedent(""" from conans import ConanFile class Conan(ConanFile): settings = "os" def package_id(self): if self.settings.os == "Windows": compatible = self.info.clone() compatible.settings.os = "Linux" self.compatible_packages.append(compatible) """) client.save({"conanfile.py": conanfile}) client.run("create . pkg/0.1@user/testing -s os=Linux") client.save({"conanfile.py": GenConanfile().with_require_plain("pkg/0.1@user/testing")}) client.run("install . -s os=Windows --build=missing") self.assertIn("pkg/0.1@user/testing:cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31 - Cache", client.out) self.assertIn("pkg/0.1@user/testing: Already installed!", client.out)
def test_private_dont_skip(self): liba_ref = ConanFileReference.loads("LibA/0.1@conan/stable") client = TestClient() client.save({ "conanfile.py": GenConanfile().with_name("LibA").with_version( "0.1").with_package_info( cpp_info={"libs": ["mylibLibA0.1lib"]}, env_info={"MYENV": ["myenvLibA0.1env"]}) }) client.run("create . LibA/0.1@conan/stable") client.save({ "conanfile.py": GenConanfile().with_name("LibB").with_version("0.1").with_require( liba_ref) }) client.run("create . LibB/0.1@conan/stable") client.save({ "conanfile.py": GenConanfile().with_name("LibC").with_version("0.1").with_require( liba_ref, private=True) }) client.run("create . LibC/0.1@conan/stable") for requires in (["LibB/0.1@conan/stable", "LibC/0.1@conan/stable"], ["LibC/0.1@conan/stable", "LibB/0.1@conan/stable"]): conanfile = GenConanfile().with_name("LibD").with_version("0.1") for it in requires: ref = ConanFileReference.loads(it) conanfile = conanfile.with_require(ref) client.save({"conanfile.py": conanfile}) client.run("install . -g cmake") self.assertIn( "LibA/0.1@conan/stable:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache", client.out) conanbuildinfo = client.load("conanbuildinfo.cmake") self.assertIn("set(CONAN_LIBS mylibLibA0.1lib ${CONAN_LIBS})", conanbuildinfo)
def test_version_ranges_revisions_update(self): # https://github.com/conan-io/conan/issues/7333 client = TestClient(default_server_user=True) client.save({"conanfile.py": GenConanfile()}) client.run("create . PkgA/0.1@") self.assertIn("PkgA/0.1: Exported revision: f3367e0e7d170aa12abccb175fee5f97", client.out) client.run("upload * --all --confirm") client.run("search PkgA/0.1@ --revisions -r=default") self.assertIn("f3367e0e7d170aa12abccb175fee5f97", client.out) client2 = TestClient(servers=client.servers, users=client.users) client2.save({"conanfile.py": GenConanfile("PkgA")}) client2.run("create . PkgA/0.2@") client2.run("upload * --all --confirm") client2.save({"conanfile.py": GenConanfile("PkgA", "0.2").with_build_msg("Building")}) time.sleep(1) client2.run("create . ") self.assertIn("PkgA/0.2: Exported revision: 5e8148093372278be4e8d8e831d8bdb6", client2.out) client2.run("upload * --all --confirm") client2.run("search PkgA/0.2@ --revisions -r=default") self.assertIn("5e8148093372278be4e8d8e831d8bdb6", client2.out) self.assertIn("8ec297bab84c88218d1db36ffea97d0e", client2.out) client.save({"conanfile.py": GenConanfile("PkgB", "0.1").with_require("PkgA/[>=0.1]")}) client.run("lock create conanfile.py --update --lockfile-out=conan.lock") self.assertIn("PkgA/0.2: Downloaded recipe revision 5e8148093372278be4e8d8e831d8bdb6", client.out) lockfile = client.load("conan.lock") self.assertIn("5e8148093372278be4e8d8e831d8bdb6", lockfile) # Put again the old revision locally client.run("remove * -f") client.save({"conanfile.py": GenConanfile()}) client.run("create . PkgA/0.1@") self.assertIn("PkgA/0.1: Exported revision: f3367e0e7d170aa12abccb175fee5f97", client.out) client.save({"conanfile.py": GenConanfile("PkgB", "0.1").with_require("PkgA/[>=0.1]")}) client.run("install . --lockfile=conan.lock") self.assertIn("PkgA/0.2: Downloaded recipe revision 5e8148093372278be4e8d8e831d8bdb6", client.out)
def test_install_reference_not_conanbuildinfo(client): client.save({"conanfile.py": GenConanfile("Hello", "0.1").with_setting("os")}) client.run("create . conan/stable") client.save({}, clean_first=True) client.run("install Hello/0.1@conan/stable") assert not os.path.exists(os.path.join(client.current_folder, "conanbuildinfo.txt"))
def test_build_requires_not_needed(self): client = TestClient() client.save({ 'tool/conanfile.py': GenConanfile(), 'libA/conanfile.py': GenConanfile().with_build_requires("tool/1.0"), 'App/conanfile.py': GenConanfile().with_require("libA/1.0") }) client.run("create tool tool/1.0@") client.run("create libA libA/1.0@") client.run("create App app/1.0@") # Create the full lock create client.run( "lock create --reference=app/1.0@ --build --lockfile-out=conan.lock" ) lock = json.loads(client.load("conan.lock"))["graph_lock"]["nodes"] app = lock["1"] liba = lock["2"] tool = lock["3"] if client.cache.config.revisions_enabled: self.assertEqual(app["ref"], "app/1.0#ac2e355bf59f54e838c9d2f1d8d1126c") self.assertEqual(liba["ref"], "libA/1.0#3fb401b4f9169fab06be253aa3fbcc1b") self.assertEqual(tool["ref"], "tool/1.0#f3367e0e7d170aa12abccb175fee5f97") else: self.assertEqual(app["ref"], "app/1.0") self.assertEqual(liba["ref"], "libA/1.0") self.assertEqual(tool["ref"], "tool/1.0") self.assertEqual(app["package_id"], "8a4d75100b721bfde375a978c780bf3880a22bab") self.assertIsNone(app.get("prev")) self.assertEqual(liba["package_id"], "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") self.assertIsNone(liba.get("prev")) self.assertEqual(tool["package_id"], "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9") self.assertIsNone(tool.get("prev")) client.run("lock build-order conan.lock --json=bo.json") bo0 = client.load("bo.json") if client.cache.config.revisions_enabled: tool = "tool/1.0@#f3367e0e7d170aa12abccb175fee5f97" liba = "libA/1.0@#3fb401b4f9169fab06be253aa3fbcc1b" app = "app/1.0@#ac2e355bf59f54e838c9d2f1d8d1126c" else: tool = "tool/1.0@" liba = "libA/1.0@" app = "app/1.0@" expected = [ [[tool, "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", "host", "3"]], [[liba, "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", "host", "2"]], [[app, "8a4d75100b721bfde375a978c780bf3880a22bab", "host", "1"]] ] self.assertEqual(expected, json.loads(bo0)) client.run("create libA libA/2.0@ --lockfile=conan.lock", assert_error=True) self.assertIn("ERROR: Couldn't find 'libA/2.0' in lockfile", client.out) # Instead we export it and create a new lock create client.run("export libA libA/2.0@") client.run( "lock create --reference=app/1.0@ --build=missing --lockfile-out=new.lock" ) new = client.load("new.lock") self.assertNotIn("libA/2.0", new) client.run("lock build-order new.lock --json=bo.json") self.assertEqual(json.loads(client.load("bo.json")), [])
def test_build_requires_should_be_locked(self): # https://github.com/conan-io/conan/issues/5807 # this is the recommended approach, build_requires should be locked from the beginning client = TestClient() client.save({ "zlib.py": GenConanfile(), "harfbuzz.py": GenConanfile().with_require("fontconfig/1.0"), "fontconfig.py": GenConanfile(), "ffmpeg.py": GenConanfile().with_build_requires("fontconfig/1.0", "harfbuzz/1.0"), "variant.py": GenConanfile().with_requires("ffmpeg/1.0", "fontconfig/1.0", "harfbuzz/1.0", "zlib/1.0") }) client.run("export zlib.py zlib/1.0@") client.run("export fontconfig.py fontconfig/1.0@") client.run("export harfbuzz.py harfbuzz/1.0@") client.run("export ffmpeg.py ffmpeg/1.0@") # Building the graphlock we get the message client.run("lock create variant.py --build cascade --build outdated " "--lockfile-out=conan.lock") if client.cache.config.revisions_enabled: fmpe = "ffmpeg/1.0#5522e93e2abfbd455e6211fe4d0531a2" font = "fontconfig/1.0#f3367e0e7d170aa12abccb175fee5f97" harf = "harfbuzz/1.0#3172f5e84120f235f75f8dd90fdef84f" zlib = "zlib/1.0#f3367e0e7d170aa12abccb175fee5f97" expected = [[[ 'fontconfig/1.0@#f3367e0e7d170aa12abccb175fee5f97', '5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9', 'host', '2' ], [ 'zlib/1.0@#f3367e0e7d170aa12abccb175fee5f97', '5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9', 'host', '4' ]], [[ 'harfbuzz/1.0@#3172f5e84120f235f75f8dd90fdef84f', 'ea61889683885a5517800e8ebb09547d1d10447a', 'host', '3' ]], [[ 'ffmpeg/1.0@#5522e93e2abfbd455e6211fe4d0531a2', '5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9', 'host', '1' ]]] else: fmpe = "ffmpeg/1.0" font = "fontconfig/1.0" harf = "harfbuzz/1.0" zlib = "zlib/1.0" expected = [[[ 'fontconfig/1.0@', '5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9', 'host', '2' ], [ 'zlib/1.0@', '5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9', 'host', '4' ]], [[ 'harfbuzz/1.0@', 'ea61889683885a5517800e8ebb09547d1d10447a', 'host', '3' ]], [[ 'ffmpeg/1.0@', '5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9', 'host', '1' ]]] lock1 = client.load("conan.lock") lock = json.loads(lock1) nodes = lock["graph_lock"]["nodes"] self.assertEqual(7, len(nodes)) self.assertEqual(fmpe, nodes["1"]["ref"]) self.assertEqual(["5", "6"], nodes["1"]["build_requires"]) self.assertEqual(font, nodes["2"]["ref"]) self.assertEqual(harf, nodes["3"]["ref"]) self.assertEqual(zlib, nodes["4"]["ref"]) self.assertEqual(font, nodes["5"]["ref"]) self.assertEqual(harf, nodes["6"]["ref"]) client.run("lock build-order conan.lock --json=bo.json") self.assertNotIn("cannot be found in lockfile", client.out) lock2 = client.load("conan.lock") self.assertEqual(lock2, lock1) build_order = json.loads(client.load("bo.json")) self.assertEqual(expected, build_order)
def transitive_build_not_locked_test(self, export): # https://github.com/conan-io/conan/issues/5727 client = TestClient() client.save({ "dep/conanfile.py": GenConanfile(), "pkg/conanfile.py": GenConanfile().with_build_requires("dep/0.1"), "app/conanfile.py": GenConanfile().with_require("pkg/0.1") }) if export: client.run("export dep dep/0.1@") client.run("export pkg pkg/0.1@") client.run("export app app/0.1@") # Necessary for build-requires client.run( "lock create --reference app/0.1@ --build=missing --lockfile-out=conan.lock" ) else: client.run("create dep dep/0.1@") client.run("create pkg pkg/0.1@") client.run("create app app/0.1@") client.run( "lock create --reference=app/0.1@ --build --lockfile-out=conan.lock" ) locked = json.loads(client.load("conan.lock"))["graph_lock"]["nodes"] if client.cache.config.revisions_enabled: build_order = [[[ "dep/0.1@#f3367e0e7d170aa12abccb175fee5f97", "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", "host", "3" ]], [[ "pkg/0.1@#1364f701b47130c7e38f04c5e5fab985", "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", "host", "2" ]], [[ "app/0.1@#5e0af887c3e9391c872773734ccd2ca0", "a925a8281740e4cb4bcad9cf41ecc4c215210604", "host", "1" ]]] prev_dep = "83c38d3b4e5f1b8450434436eec31b00" prev_pkg = "5d3d587702b55a456c9b6b71e5f40cfa" prev_app = "eeb6de9b69fb0905e15788315f77a8e2" else: build_order = [[[ "dep/0.1@", "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", "host", "3" ]], [[ "pkg/0.1@", "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", "host", "2" ]], [[ "app/0.1@", "a925a8281740e4cb4bcad9cf41ecc4c215210604", "host", "1" ]]] prev_dep = "0" prev_pkg = "0" prev_app = "0" for level in build_order: for item in level: ref, package_id, _, lockid = item ref = ref.replace("@", "") node = locked[lockid] self.assertEqual(node["ref"], ref) self.assertEqual(node["package_id"], package_id) self.assertEqual( node.get("prev"), None) # PREV is not defined yet, only exported client.run("lock build-order conan.lock --json=bo.json") jsonbo = json.loads(client.load("bo.json")) self.assertEqual(build_order, jsonbo) # prev is None, --build needs to be explicit or it will fail if export: client.run("install app/0.1@ --lockfile=conan.lock", assert_error=True) self.assertIn("Missing prebuilt package for 'app/0.1', 'pkg/0.1'", client.out) # Build one by one client.run( "install {0} --lockfile=conan.lock --lockfile-out=conan.lock " "--build={0}".format(build_order[0][0][0])) self.assertIn( "dep/0.1:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Build", client.out) locked = json.loads(client.load("conan.lock"))["graph_lock"]["nodes"] node = locked["3"] self.assertEqual(node.get("prev"), prev_dep) node = locked["2"] self.assertEqual(node.get("prev"), None) # PREV is not defined yet, only exported node = locked["1"] self.assertEqual(node.get("prev"), None) # PREV is not defined yet, only exported client.run("lock build-order conan.lock --json=bo.json") jsonbo = json.loads(client.load("bo.json")) self.assertEqual(build_order[1:], jsonbo) client.run("install pkg/0.1@ --lockfile=conan.lock --build", assert_error=True) self.assertIn( "Cannot build 'dep/0.1#f3367e0e7d170aa12abccb175fee5f97' because it is " "already locked in the input lockfile", client.out) client.run( "install {0} --lockfile=conan.lock --lockfile-out=conan.lock " "--build={0}".format(build_order[1][0][0])) self.assertIn( "dep/0.1:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache", client.out) self.assertIn( "pkg/0.1:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Build", client.out) locked = json.loads(client.load("conan.lock"))["graph_lock"]["nodes"] node = locked["3"] self.assertEqual(node.get("prev"), prev_dep) node = locked["2"] self.assertEqual(node.get("prev"), prev_pkg) node = locked["1"] self.assertEqual(node.get("prev"), None) # PREV is not defined yet, only exported client.run("lock build-order conan.lock --json=bo.json") jsonbo = json.loads(client.load("bo.json")) self.assertEqual(build_order[2:], jsonbo) client.run("install app/0.1@ --lockfile=conan.lock --build", assert_error=True) self.assertIn( "Cannot build 'pkg/0.1#1364f701b47130c7e38f04c5e5fab985' because it is " "already locked in the input lockfile", client.out) client.run( "install {0} --lockfile=conan.lock --lockfile-out=conan.lock " "--build={0}".format(build_order[2][0][0])) self.assertNotIn("dep/0.1", client.out) self.assertIn( "pkg/0.1:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache", client.out) self.assertIn( "app/0.1:a925a8281740e4cb4bcad9cf41ecc4c215210604 - Build", client.out) locked = json.loads(client.load("conan.lock"))["graph_lock"]["nodes"] node = locked["3"] self.assertEqual(node.get("prev"), prev_dep) node = locked["2"] self.assertEqual(node.get("prev"), prev_pkg) node = locked["1"] self.assertEqual(node.get("prev"), prev_app) # New build order, nothing else to do client.run("lock build-order conan.lock --json=bo.json") jsonbo = json.loads(client.load("bo.json")) self.assertEqual([], jsonbo)
def transitive_build_not_locked_test(self, export): # https://github.com/conan-io/conan/issues/5727 client = TestClient() client.save({ "dep/conanfile.py": GenConanfile(), "pkg/conanfile.py": GenConanfile().with_require("dep/0.1"), "app/conanfile.py": GenConanfile().with_require("pkg/0.1") }) if export: client.run("export dep dep/0.1@") client.run("export pkg pkg/0.1@") client.run("export app app/0.1@") client.run( "lock create --reference=app/0.1@ --lockfile-out=conan.lock") else: client.run("create dep dep/0.1@") client.run("create pkg pkg/0.1@") client.run("create app app/0.1@") client.run( "lock create --reference=app/0.1@ --build --lockfile-out=conan.lock" ) locked = json.loads(client.load("conan.lock"))["graph_lock"]["nodes"] if client.cache.config.revisions_enabled: build_order = [[[ "dep/0.1@#f3367e0e7d170aa12abccb175fee5f97", "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", "host", "3" ]], [[ "pkg/0.1@#447b56f0334b7e2a28aa86e218c8b3bd", "0b3845ce7fd8c0b4e46566097797bd872cb5bcf6", "host", "2" ]], [[ "app/0.1@#5e0af887c3e9391c872773734ccd2ca0", "745ccd40fd696b66b0cb160fd5251a533563bbb4", "host", "1" ]]] prev_dep = "83c38d3b4e5f1b8450434436eec31b00" prev_pkg = "bcde0c25612a6d296cf2cab2c264054d" prev_app = "9f30558ce471f676e3e06b633aabcf99" else: build_order = [[[ "dep/0.1@", "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9", "host", "3" ]], [[ "pkg/0.1@", "0b3845ce7fd8c0b4e46566097797bd872cb5bcf6", "host", "2" ]], [[ "app/0.1@", "745ccd40fd696b66b0cb160fd5251a533563bbb4", "host", "1" ]]] prev_dep = "0" prev_pkg = "0" prev_app = "0" for level in build_order: for item in level: ref, package_id, _, lockid = item ref = ref.replace("@", "") node = locked[lockid] self.assertEqual(node["ref"], ref) self.assertEqual(node["package_id"], package_id) self.assertEqual( node.get("prev"), None) # PREV is not defined yet, only exported client.run("lock build-order conan.lock --json=bo.json") jsonbo = json.loads(client.load("bo.json")) self.assertEqual(build_order, jsonbo) if export: client.run("install app/0.1@ --lockfile=conan.lock", assert_error=True) self.assertIn( "Missing prebuilt package for 'app/0.1', 'dep/0.1', 'pkg/0.1'", client.out) # Build one by one client.run( "install {0} --lockfile=conan.lock --lockfile-out=conan.lock" " --build={0}".format(build_order[0][0][0])) self.assertIn( "dep/0.1:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Build", client.out) locked = json.loads(client.load("conan.lock"))["graph_lock"]["nodes"] node = locked["3"] self.assertEqual(node.get("prev"), prev_dep) node = locked["2"] self.assertEqual(node.get("prev"), None) # PREV is not defined yet, only exported node = locked["1"] self.assertEqual(node.get("prev"), None) # PREV is not defined yet, only exported client.run("lock build-order conan.lock --json=bo.json") jsonbo = json.loads(client.load("bo.json")) self.assertEqual(build_order[1:], jsonbo) client.run("install pkg/0.1@ --lockfile=conan.lock --build", assert_error=True) self.assertIn( "Cannot build 'dep/0.1#f3367e0e7d170aa12abccb175fee5f97' because it is " "already locked in the input lockfile", client.out) client.run( "install {0} --lockfile=conan.lock --lockfile-out=conan.lock " "--build={0}".format(build_order[1][0][0])) self.assertIn( "dep/0.1:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache", client.out) self.assertIn( "pkg/0.1:0b3845ce7fd8c0b4e46566097797bd872cb5bcf6 - Build", client.out) locked = json.loads(client.load("conan.lock"))["graph_lock"]["nodes"] node = locked["3"] self.assertEqual(node.get("prev"), prev_dep) node = locked["2"] self.assertEqual(node.get("prev"), prev_pkg) node = locked["1"] self.assertEqual(node.get("prev"), None) # PREV is not defined yet, only exported client.run("lock build-order conan.lock --json=bo.json") jsonbo = json.loads(client.load("bo.json")) self.assertEqual(build_order[2:], jsonbo) client.run("install app/0.1@ --lockfile=conan.lock --build", assert_error=True) self.assertIn( "Cannot build 'dep/0.1#f3367e0e7d170aa12abccb175fee5f97' because it is " "already locked in the input lockfile", client.out) client.run( "install {0} --lockfile=conan.lock --lockfile-out=conan.lock " "--build={0}".format(build_order[2][0][0])) self.assertIn( "dep/0.1:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache", client.out) self.assertIn( "pkg/0.1:0b3845ce7fd8c0b4e46566097797bd872cb5bcf6 - Cache", client.out) self.assertIn( "app/0.1:745ccd40fd696b66b0cb160fd5251a533563bbb4 - Build", client.out) locked = json.loads(client.load("conan.lock"))["graph_lock"]["nodes"] node = locked["3"] self.assertEqual(node.get("prev"), prev_dep) node = locked["2"] self.assertEqual(node.get("prev"), prev_pkg) node = locked["1"] self.assertEqual(node.get("prev"), prev_app) # New build order, nothing else to do client.run("lock build-order conan.lock --json=bo.json") jsonbo = json.loads(client.load("bo.json")) self.assertEqual([], jsonbo)
def export_with_name_and_version_test(self): client = TestClient() client.save({"conanfile.py": GenConanfile()}) client.run('export . lib/1.0@') self.assertIn("lib/1.0: A new conanfile.py version was exported", client.out)
class GraphLockVersionRangeNoUserChannelTest(unittest.TestCase): # This is exactly the same as above, but not using user/channel in packages # https://github.com/conan-io/conan/issues/5873 consumer = GenConanfile().with_name("PkgB").with_version("0.1")\ .with_require_plain("PkgA/[>=0.1]") pkg_b_revision = "afa95143c0c11c46ad57670e1e0a0aa0" pkg_b_id = "5bf1ba84b5ec8663764a406f08a7f9ae5d3d5fb5" pkg_b_package_revision = "#f97ac3d1bee62d55a35085dd42fa847a" modified_pkg_b_revision = "3bb0f77004b0afde1620c714630aa515" modified_pkg_b_package_revision = "#7f92394bbc66cc7f9d403e764b88bac0" graph_lock_command = "install ." def setUp(self): client = TestClient() self.client = client client.save({ "conanfile.py": GenConanfile().with_name("PkgA").with_version("0.1") }) client.run("create .") # Use a consumer with a version range client.save({"conanfile.py": str(self.consumer)}) client.run(self.graph_lock_command) self._check_lock("PkgB/0.1@") # If we create a new PkgA version client.save({ "conanfile.py": GenConanfile().with_name("PkgA").with_version("0.2") }) client.run("create .") client.save({"conanfile.py": str(self.consumer)}) def _check_lock(self, ref_b, rev_b=""): lock_file = load(os.path.join(self.client.current_folder, LOCKFILE)) lock_file_json = json.loads(lock_file) self.assertEqual(2, len(lock_file_json["graph_lock"]["nodes"])) self.assertIn( "PkgA/0.1#fa090239f8ba41ad559f8e934494ee2a:" "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9#0d561e10e25511b9bfa339d06360d7c1", lock_file) self.assertIn( '"%s:%s%s"' % (repr(ConanFileReference.loads(ref_b)), self.pkg_b_id, rev_b), lock_file) def install_info_lock_test(self): # Normal install will use it (use install-folder to not change graph-info) client = self.client client.run("install . -if=tmp") # Output graph_info to temporary self.assertIn("PkgA/0.2", client.out) self.assertNotIn("PkgA/0.1", client.out) # Locked install will use PkgA/0.1 # To use the stored graph_info.json, it has to be explicit in "--install-folder" client.run("install . -g=cmake --lockfile") self._check_lock("PkgB/0.1@") self.assertIn("PkgA/0.1", client.out) self.assertNotIn("PkgA/0.2", client.out) cmake = client.load("conanbuildinfo.cmake") self.assertIn("PkgA/0.1/_/_", cmake) self.assertNotIn("PkgA/0.2/_/_", cmake) # Info also works client.run("info . --lockfile") self.assertIn("PkgA/0.1", client.out) self.assertNotIn("PkgA/0.2", client.out) def install_ref_lock_test(self): client = self.client client.run("install PkgA/[>=0.1]@ -if=tmp") self.assertIn("PkgA/0.2: Already installed!", client.out) self.assertNotIn("PkgA/0.1", client.out) # Explicit one client.run("install PkgA/0.1@ --install-folder=.") self.assertIn("PkgA/0.1: Already installed!", client.out) self.assertNotIn("PkgA/0.2", client.out) # Range locked one client.run("install PkgA/[>=0.1]@ --lockfile") self.assertIn("PkgA/0.1: Already installed!", client.out) self.assertNotIn("PkgA/0.2", client.out) def export_lock_test(self): # locking a version range at export self.client.run("export . --lockfile") self._check_lock("PkgB/0.1#%s" % self.pkg_b_revision) def create_lock_test(self): # Create is also possible client = self.client client.run("create . PkgB/0.1@ --lockfile") self.assertIn("PkgA/0.1", client.out) self.assertNotIn("PkgA/0.2", client.out) self._check_lock("PkgB/0.1#%s" % self.pkg_b_revision, self.pkg_b_package_revision) def create_test_lock_test(self): # Create is also possible client = self.client test_conanfile = textwrap.dedent(""" from conans import ConanFile class Test(ConanFile): def test(self): pass """) client.save({ "conanfile.py": str(self.consumer), "test_package/conanfile.py": test_conanfile }) client.run("create . PkgB/0.1@ --lockfile") self.assertIn("PkgA/0.1", client.out) self.assertNotIn("PkgA/0.2", client.out) self._check_lock("PkgB/0.1#%s" % self.pkg_b_revision, self.pkg_b_package_revision) def export_pkg_test(self): client = self.client client.run("export-pkg . PkgB/0.1@ --lockfile") self._check_lock("PkgB/0.1#%s" % self.pkg_b_revision, self.pkg_b_package_revision) # Same, but modifying also PkgB Recipe client.save({"conanfile.py": str(self.consumer) + "\n#comment"}) client.run("export-pkg . PkgB/0.1@ --lockfile --force") self._check_lock("PkgB/0.1@#%s" % self.modified_pkg_b_revision, self.modified_pkg_b_package_revision)