def _client(self, ro_file, ro_cache): client = TestClient() if ro_cache: client.run("config set general.read_only_cache=True") with client.chdir('recipe'): conanfile = """from conans import ConanFile class MyPkg(ConanFile): exports_sources = "*.h" def package(self): self.copy("*.h") def deploy(self): self.copy("*.h") """ client.save({"conanfile.py": conanfile, self.file_name: "my header"}) os.chmod(os.path.join(client.current_folder, self.file_name), 0o444 if ro_file else 0o644) client.run("create . Pkg/0.1@lasote/channel") return client
def build_cmake_install_test(self): client = TestClient() conanfile = """ from conans import ConanFile, CMake class AConan(ConanFile): settings = "os", "compiler", "build_type", "arch" def build(self): cmake = CMake(self) cmake.configure() cmake.install() """ cmake = """set(CMAKE_CXX_COMPILER_WORKS 1) project(Chat NONE) cmake_minimum_required(VERSION 2.8.12) install(FILES header.h DESTINATION include) """ client.save({CONANFILE: conanfile, "CMakeLists.txt": cmake, "header.h": "my header h!!"}) client.run("install .") client.run("build .") # Won't fail, by default the package_folder is build_folder/package header = load(os.path.join(client.current_folder, "package/include/header.h")) self.assertEqual(header, "my header h!!") client.save({CONANFILE: conanfile, "CMakeLists.txt": cmake, "header.h": "my header3 h!!"}, clean_first=True) client.run("install .") client.run("build -pf=mypkg ./conanfile.py") header = load(os.path.join(client.current_folder, "mypkg/include/header.h")) self.assertEqual(header, "my header3 h!!") client.save({CONANFILE: conanfile, "CMakeLists.txt": cmake, "header.h": "my header2 h!!"}, clean_first=True) with client.chdir("build"): client.run("install ..") client.run("build . -pf=mypkg -bf=build") header = load(os.path.join(client.current_folder, "mypkg/include/header.h")) self.assertEqual(header, "my header2 h!!")
def test_frameworks_exelinkflags(self, generator, use_components): # FIXME: Conan 2.0. 'cpp_info' object has a 'frameworks' key conanfile = textwrap.dedent(""" from conans import ConanFile class Recipe(ConanFile): settings = "os", "arch", "compiler", "build_type" options = {'use_components': [True, False]} default_options = {'use_components': False} def package_info(self): if not self.options.use_components: self.cpp_info.exelinkflags.extend(['-framework Foundation']) #self.cpp_info.frameworks.extend(['Foundation']) else: self.cpp_info.components["cmp"].exelinkflags.extend(['-framework Foundation']) #self.cpp_info.components["cmp"].frameworks.extend(['Foundation']) """) tp_cmakelists = textwrap.dedent(""" cmake_minimum_required(VERSION 3.0) project(test_package) include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup(TARGETS) if(USE_FIND_PACKAGE) message(">> USE_FIND_PACKAGE") find_package(name) add_executable(${PROJECT_NAME} test_package.cpp) if (USE_COMPONENTS) message(">> USE_COMPONENTS") target_link_libraries(${PROJECT_NAME} name::cmp) else() message(">> not USE_COMPONENTS") target_link_libraries(${PROJECT_NAME} name::name) endif() else() message(">> not USE_FIND_PACKAGE") add_executable(${PROJECT_NAME} test_package.cpp) target_link_libraries(${PROJECT_NAME} CONAN_PKG::name) endif() """) tp_conanfile = textwrap.dedent(""" from conans import ConanFile, CMake class TestPackage(ConanFile): settings = "os", "arch", "compiler", "build_type" generators = "cmake", "cmake_find_package" options = {'use_find_package': [True, False]} requires = "name/version" def build(self): cmake = CMake(self) cmake.definitions["USE_FIND_PACKAGE"] = self.options.use_find_package cmake.definitions["USE_COMPONENTS"] = self.options["name"].use_components cmake.configure() cmake.build() def test(self): pass """) tp_main = textwrap.dedent(""" int main() {} """) t = TestClient() t.save({ 'conanfile.py': conanfile, 'test_package/conanfile.py': tp_conanfile, 'test_package/CMakeLists.txt': tp_cmakelists, 'test_package/test_package.cpp': tp_main }) t.run("export conanfile.py name/version@") with t.chdir('test_package/build'): if generator == 'cmake': assert not use_components t.run( "install .. --build=missing" " -o name:use_components=False -o use_find_package=False") t.run("build ..") self.assertIn(">> not USE_FIND_PACKAGE", t.out) else: assert generator == 'cmake_find_package' t.run("install .. --build=missing" " -o name:use_components={} -o use_find_package=True". format(use_components)) t.run("build ..") self.assertIn(">> USE_FIND_PACKAGE", t.out) self.assertIn( ">> {}USE_COMPONENTS".format( "" if use_components else "not "), t.out) # Check we are using the framework link_txt = t.load( os.path.join('CMakeFiles', 'test_package.dir', 'link.txt')) self.assertIn("-framework Foundation", link_txt)
def test_cmake_paths_integration(self): """First package with own findHello0.cmake file""" client = TestClient() conanfile = """from conans import ConanFile class TestConan(ConanFile): name = "Hello0" version = "0.1" exports = "*" def package(self): self.copy(pattern="*", keep_path=False) """ files = { "conanfile.py": conanfile, "FindHello0.cmake": """ SET(Hello0_FOUND 1) MESSAGE("HELLO FROM THE Hello0 FIND PACKAGE!") MESSAGE("ROOT PATH: ${CONAN_HELLO0_ROOT}") """ } client.save(files) client.run("create . user/channel") # Directly using CMake as a consumer we can find it with the "cmake_paths" generator files = { "CMakeLists.txt": """ set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) project(MyHello CXX) cmake_minimum_required(VERSION 2.8) find_package(Hello0 REQUIRED) """ } client.save(files, clean_first=True) client.run("install Hello0/0.1@user/channel -g cmake_paths") self.assertTrue( os.path.exists( os.path.join(client.current_folder, "conan_paths.cmake"))) # Without the toolchain we cannot find the package build_dir = os.path.join(client.current_folder, "build") os.mkdir(build_dir) with client.chdir(build_dir): client.run_command("cmake ..", assert_error=True) shutil.rmtree(build_dir) # With the toolchain everything is ok os.mkdir(build_dir) with client.chdir(build_dir): client.run_command( "cmake .. -DCMAKE_TOOLCHAIN_FILE=../conan_paths.cmake") self.assertIn("HELLO FROM THE Hello0 FIND PACKAGE!", client.out) ref = ConanFileReference.loads("Hello0/0.1@user/channel") pref = PackageReference(ref, NO_SETTINGS_PACKAGE_ID) package_folder = client.cache.package_layout(ref).package(pref) # Check that the CONAN_HELLO0_ROOT has been replaced with the real abs path self.assertIn("ROOT PATH: %s" % package_folder.replace("\\", "/"), client.out) # Now try without toolchain but including the file files = { "CMakeLists.txt": """ set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) project(MyHello CXX) cmake_minimum_required(VERSION 2.8) include(${CMAKE_BINARY_DIR}/../conan_paths.cmake) find_package(Hello0 REQUIRED) """ } client.save(files, clean_first=True) os.mkdir(build_dir) client.run("install Hello0/0.1@user/channel -g cmake_paths") client.run_command("cmake .. ", cwd=build_dir) self.assertIn("HELLO FROM THE Hello0 FIND PACKAGE!", client.out)
def complete_multi_conf_build_test(self): client = TestClient() def files(name, depend=None): includes = ('#include "hello%s.h"' % depend) if depend else "" calls = ('hello%s();' % depend) if depend else "" deps = ('"Hello%s/0.1@lasote/stable"' % depend) if depend else "None" return { "conanfile.py": conanfile_build.format(deps=deps, name=name), "src/hello%s.h" % name: hello_h.format(name=name), "src/hello.cpp": hello_cpp.format(name=name, includes=includes, calls=calls), "src/CMakeLists.txt": cmake_multi.format(name=name) } client.save(files("C"), path=os.path.join(client.current_folder, "C")) client.save(files("B", "C"), path=os.path.join(client.current_folder, "B")) a = files("A", "B") a["src/CMakeLists.txt"] += ("add_executable(app main.cpp)\n" "target_link_libraries(app helloA)\n") a["src/main.cpp"] = main_cpp client.save(a, path=os.path.join(client.current_folder, "A")) project = dedent(""" editables: HelloB/0.1@lasote/stable: path: B HelloC/0.1@lasote/stable: path: C HelloA/0.1@lasote/stable: path: A layout: layout workspace_generator: cmake root: HelloA/0.1@lasote/stable """) layout = dedent(""" [build_folder] build [source_folder] src [includedirs] src [libdirs] build/{{settings.build_type}} """) metacmake = dedent(""" cmake_minimum_required(VERSION 3.3) project(MyProject CXX) include(${CMAKE_BINARY_DIR}/conanworkspace.cmake) conan_workspace_subdirectories() """) client.save({ "conanws.yml": project, "layout": layout, "CMakeLists.txt": metacmake }) build = os.path.join(client.current_folder, "build") with client.chdir("build"): client.run("workspace install ../conanws.yml") client.run("workspace install ../conanws.yml -s build_type=Debug") client.init_dynamic_vars() generator = "Visual Studio 15 Win64" client.runner('cmake .. -G "%s" -DCMAKE_BUILD_TYPE=Release' % generator, cwd=build) client.runner('cmake --build . --config Release', cwd=build) cmd_release = os.path.normpath("./A/build/Release/app") cmd_debug = os.path.normpath("./A/build/Debug/app") client.runner(cmd_release, cwd=client.current_folder) self.assertIn("Hello World C Release!", client.out) self.assertIn("Hello World B Release!", client.out) self.assertIn("Hello World A Release!", client.out) tools.replace_in_file(os.path.join(client.current_folder, "C/src/hello.cpp"), "Hello World", "Bye Moon", output=client.out) client.runner('cmake --build . --config Release', cwd=build) client.runner(cmd_release, cwd=client.current_folder) self.assertIn("Bye Moon C Release!", client.out) self.assertIn("Hello World B Release!", client.out) self.assertIn("Hello World A Release!", client.out) tools.replace_in_file(os.path.join(client.current_folder, "B/src/hello.cpp"), "Hello World", "Bye Moon", output=client.out) client.runner('cmake --build . --config Release', cwd=build) client.runner(cmd_release, cwd=client.current_folder) self.assertIn("Bye Moon C Release!", client.out) self.assertIn("Bye Moon B Release!", client.out) self.assertIn("Hello World A Release!", client.out) self.assertNotIn("Debug", client.out) client.runner('cmake .. -G "%s" -DCMAKE_BUILD_TYPE=Debug' % generator, cwd=build) # CMake configure will find the Release libraries, as we are in cmake-multi mode # Need to reset the output after that client.init_dynamic_vars() # Reset output client.runner('cmake --build . --config Debug', cwd=build) client.runner(cmd_debug, cwd=client.current_folder) self.assertIn("Bye Moon C Debug!", client.out) self.assertIn("Bye Moon B Debug!", client.out) self.assertIn("Hello World A Debug!", client.out) tools.replace_in_file(os.path.join(client.current_folder, "C/src/hello.cpp"), "Bye Moon", "Hello World", output=client.out) client.runner('cmake --build . --config Debug', cwd=build) client.runner(cmd_debug, cwd=client.current_folder) self.assertIn("Hello World C Debug!", client.out) self.assertIn("Bye Moon B Debug!", client.out) self.assertIn("Hello World A Debug!", client.out) self.assertNotIn("Release", client.out)
class Base(unittest.TestCase): conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake, CMakeToolchain class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "hello/0.1" generators = "cmake_find_package_multi" options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} def generate(self): tc = CMakeToolchain(self) tc.variables["MYVAR"] = "MYVAR_VALUE" tc.variables["MYVAR2"] = "MYVAR_VALUE2" tc.variables.debug["MYVAR_CONFIG"] = "MYVAR_DEBUG" tc.variables.release["MYVAR_CONFIG"] = "MYVAR_RELEASE" tc.variables.debug["MYVAR2_CONFIG"] = "MYVAR2_DEBUG" tc.variables.release["MYVAR2_CONFIG"] = "MYVAR2_RELEASE" tc.preprocessor_definitions["MYDEFINE"] = "MYDEF_VALUE" tc.preprocessor_definitions.debug["MYDEFINE_CONFIG"] = "MYDEF_DEBUG" tc.preprocessor_definitions.release["MYDEFINE_CONFIG"] = "MYDEF_RELEASE" tc.generate() def build(self): cmake = CMake(self) cmake.configure() cmake.build() """) lib_h = gen_function_h(name="app") lib_cpp = gen_function_cpp( name="app", msg="App", includes=["hello"], calls=["hello"], preprocessor=["MYVAR", "MYVAR_CONFIG", "MYDEFINE", "MYDEFINE_CONFIG"]) main = gen_function_cpp(name="main", includes=["app"], calls=["app"]) cmakelist = textwrap.dedent(""" cmake_minimum_required(VERSION 3.15) project(App C CXX) if(NOT CMAKE_TOOLCHAIN_FILE) message(FATAL ">> Not using toolchain") endif() message(">> CMAKE_GENERATOR_PLATFORM: ${CMAKE_GENERATOR_PLATFORM}") message(">> CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") message(">> CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") message(">> CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") message(">> CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}") message(">> CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") message(">> CMAKE_C_FLAGS_DEBUG: ${CMAKE_C_FLAGS_DEBUG}") message(">> CMAKE_C_FLAGS_RELEASE: ${CMAKE_C_FLAGS_RELEASE}") message(">> CMAKE_SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}") message(">> CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") message(">> CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}") message(">> CMAKE_CXX_EXTENSIONS: ${CMAKE_CXX_EXTENSIONS}") message(">> CMAKE_POSITION_INDEPENDENT_CODE: ${CMAKE_POSITION_INDEPENDENT_CODE}") message(">> CMAKE_SKIP_RPATH: ${CMAKE_SKIP_RPATH}") message(">> CMAKE_INSTALL_NAME_DIR: ${CMAKE_INSTALL_NAME_DIR}") message(">> CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}") message(">> CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}") message(">> BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}") get_directory_property(_COMPILE_DEFS DIRECTORY ${CMAKE_SOURCE_DIR} COMPILE_DEFINITIONS) message(">> COMPILE_DEFINITIONS: ${_COMPILE_DEFS}") find_package(hello REQUIRED) add_library(app_lib app_lib.cpp) target_link_libraries(app_lib PRIVATE hello::hello) target_compile_definitions(app_lib PRIVATE MYVAR="${MYVAR}") target_compile_definitions(app_lib PRIVATE MYVAR_CONFIG=${MYVAR_CONFIG}) add_executable(app app.cpp) target_link_libraries(app PRIVATE app_lib) """) def setUp(self): self.client = TestClient(path_with_spaces=True) conanfile = textwrap.dedent(""" from conans import ConanFile from conans.tools import save import os class Pkg(ConanFile): settings = "build_type" def package(self): save(os.path.join(self.package_folder, "include/hello.h"), '''#include <iostream> void hello(){std::cout<< "Hello: %s" <<std::endl;}''' % self.settings.build_type) """) self.client.save({"conanfile.py": conanfile}) self.client.run("create . hello/0.1@ -s build_type=Debug") self.client.run("create . hello/0.1@ -s build_type=Release") # Prepare the actual consumer package self.client.save({ "conanfile.py": self.conanfile, "CMakeLists.txt": self.cmakelist, "app.cpp": self.main, "app_lib.cpp": self.lib_cpp, "app.h": self.lib_h }) def _run_build(self, settings=None, options=None): # Build the profile according to the settings provided settings = settings or {} settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) options = " ".join("-o %s=%s" % (k, v) for k, v in options.items()) if options else "" # Run the configure corresponding to this test case build_directory = os.path.join(self.client.current_folder, "build").replace("\\", "/") with self.client.chdir(build_directory): self.client.run("install .. %s %s" % (settings, options)) install_out = self.client.out self.client.run("build ..") return install_out def _modify_code(self): lib_cpp = gen_function_cpp(name="app", msg="AppImproved", includes=["hello"], calls=["hello"], preprocessor=[ "MYVAR", "MYVAR_CONFIG", "MYDEFINE", "MYDEFINE_CONFIG" ]) self.client.save({"app_lib.cpp": lib_cpp}) content = self.client.load("CMakeLists.txt") content = content.replace(">>", "++>>") self.client.save({"CMakeLists.txt": content}) def _incremental_build(self, build_type=None): build_directory = os.path.join(self.client.current_folder, "build").replace("\\", "/") with self.client.chdir(build_directory): config = "--config %s" % build_type if build_type else "" self.client.run_command("cmake --build . %s" % config) def _run_app(self, build_type, bin_folder=False, msg="App", dyld_path=None): if dyld_path: build_directory = os.path.join(self.client.current_folder, "build").replace("\\", "/") command_str = 'DYLD_LIBRARY_PATH="%s" build/app' % build_directory else: command_str = "build/%s/app.exe" % build_type if bin_folder else "build/app" if platform.system() == "Windows": command_str = command_str.replace("/", "\\") self.client.run_command(command_str) self.assertIn("Hello: %s" % build_type, self.client.out) self.assertIn("%s: %s!" % (msg, build_type), self.client.out) self.assertIn("MYVAR: MYVAR_VALUE", self.client.out) self.assertIn("MYVAR_CONFIG: MYVAR_%s" % build_type.upper(), self.client.out) self.assertIn("MYDEFINE: MYDEF_VALUE", self.client.out) self.assertIn("MYDEFINE_CONFIG: MYDEF_%s" % build_type.upper(), self.client.out)
def build_different_folders_test(self): conanfile = """ import os from conans import ConanFile class AConan(ConanFile): generators = "cmake" def build(self): self.output.warn("Build folder=>%s" % self.build_folder) self.output.warn("Src folder=>%s" % self.source_folder) self.output.warn("Package folder=>%s" % self.package_folder) assert(os.path.exists(self.build_folder)) assert(os.path.exists(self.source_folder)) # package_folder will be created manually or by the CMake helper when local invocation assert(not os.path.exists(self.package_folder)) """ client = TestClient() client.save({CONANFILE: conanfile}) with client.chdir("build1"): client.run("install ..") # Try relative to cwd client.run("build . --build-folder build2 --install-folder build1 " "--package-folder build1/pkg") self.assertIn( "Build folder=>%s" % os.path.join(client.current_folder, "build2"), client.out) self.assertIn( "Package folder=>%s" % os.path.join(client.current_folder, "build1", "pkg"), client.out) self.assertIn("Src folder=>%s" % client.current_folder, client.out) # Try default package folder client.run( "build conanfile.py --build-folder build1 --package-folder package1" ) self.assertIn( "Build folder=>%s" % os.path.join(client.current_folder, "build1"), client.out) self.assertIn( "Package folder=>%s" % os.path.join(client.current_folder, "package"), client.out) self.assertIn("Src folder=>%s" % client.current_folder, client.out) # Try absolute package folder client.run("build . --build-folder build1 --package-folder '%s'" % os.path.join(client.current_folder, "mypackage")) self.assertIn( "Build folder=>%s" % os.path.join(client.current_folder, "build1"), client.out) self.assertIn( "Package folder=>%s" % os.path.join(client.current_folder, "mypackage"), client.out) self.assertIn("Src folder=>%s" % client.current_folder, client.out) # Try absolute build and relative package conanfile_dir = client.current_folder bdir = os.path.join(client.current_folder, "other/mybuild") with client.chdir(bdir): client.run("install '%s'" % conanfile_dir) client.run( "build ./conanfile.py --build-folder '%s' --package-folder relpackage" % bdir) self.assertIn( "Build folder=>%s" % os.path.join(client.current_folder, "other/mybuild"), client.out) self.assertIn( "Package folder=>%s" % os.path.join(client.current_folder, "relpackage"), client.out) self.assertIn("Src folder=>%s" % client.current_folder, client.out) # Try different source with client.chdir("other/build"): client.run("install ../..") # src is not created automatically, it makes no sense client.run("build . --source-folder '%s' --build-folder other/build" % os.path.join(client.current_folder, "mysrc"), assert_error=True) mkdir(os.path.join(client.current_folder, "mysrc")) client.run("build . --source-folder '%s' --build-folder other/build" % os.path.join(client.current_folder, "mysrc")) self.assertIn( "Build folder=>%s" % os.path.join(client.current_folder, "other", "build"), client.out) self.assertIn( "Package folder=>%s" % os.path.join(client.current_folder, "other", "build"), client.out) self.assertIn( "Src folder=>%s" % os.path.join(client.current_folder, "mysrc"), client.out)
class GitSCMTest(unittest.TestCase): def setUp(self): self.ref = ConanFileReference.loads("lib/0.1@user/channel") self.client = TestClient() def _commit_contents(self): self.client.run_command("git init .") self.client.run_command('git config user.email "*****@*****.**"') self.client.run_command('git config user.name "Your Name"') self.client.run_command("git add .") self.client.run_command('git commit -m "commiting"') def test_scm_other_type_ignored(self): conanfile = ''' from conans import ConanFile, tools class ConanLib(ConanFile): name = "lib" version = "0.1" scm = ["Other stuff"] def build(self): self.output.writeln("scm: {}".format(self.scm)) ''' self.client.save({"conanfile.py": conanfile}) # nothing breaks self.client.run("create . user/channel") self.assertIn("['Other stuff']", self.client.out) def test_repeat_clone_changing_subfolder(self): tmp = ''' from conans import ConanFile, tools class ConanLib(ConanFile): name = "lib" version = "0.1" scm = {{ "type": "git", "url": "{url}", "revision": "{revision}", "subfolder": "onesubfolder" }} ''' path, commit = create_local_git_repo({"myfile": "contents"}, branch="my_release") conanfile = tmp.format(url=path, revision=commit) self.client.save({ "conanfile.py": conanfile, "myfile.txt": "My file is copied" }) self.client.run("create . user/channel") conanfile = conanfile.replace('"onesubfolder"', '"othersubfolder"') self.client.save({"conanfile.py": conanfile}) self.client.run("create . user/channel") folder = self.client.cache.package_layout(self.ref).source() self.assertIn("othersubfolder", os.listdir(folder)) self.assertTrue( os.path.exists(os.path.join(folder, "othersubfolder", "myfile"))) def test_auto_filesystem_remote_git(self): # https://github.com/conan-io/conan/issues/3109 conanfile = base_git.format(directory="None", url=_quoted("auto"), revision="auto") repo = temp_folder() self.client.save( { "conanfile.py": conanfile, "myfile.txt": "My file is copied" }, repo) with self.client.chdir(repo): self.client.run_command("git init .") self.client.run_command('git config user.email "*****@*****.**"') self.client.run_command('git config user.name "Your Name"') self.client.run_command("git add .") self.client.run_command('git commit -m "commiting"') self.client.run_command('git clone "%s" .' % repo.replace('\\', '/')) self.client.run("export . user/channel") self.assertIn("WARN: Repo origin looks like a local path", self.client.out) os.remove(self.client.cache.package_layout(self.ref).scm_folder()) self.client.run("install lib/0.1@user/channel --build") self.assertIn("lib/0.1@user/channel: Getting sources from url:", self.client.out) def test_auto_git(self): curdir = get_cased_path(self.client.current_folder).replace("\\", "/") conanfile = base_git.format(directory="None", url=_quoted("auto"), revision="auto") self.client.save({ "conanfile.py": conanfile, "myfile.txt": "My file is copied" }) create_local_git_repo(folder=self.client.current_folder) self.client.run("export . user/channel", assert_error=True) self.assertIn("Repo origin cannot be deduced", self.client.out) self.client.run_command('git remote add origin https://myrepo.com.git') # Create the package, will copy the sources from the local folder self.client.run("create . user/channel") sources_dir = self.client.cache.package_layout(self.ref).scm_folder() self.assertEqual(load(sources_dir), curdir) self.assertIn("Repo origin deduced by 'auto': https://myrepo.com.git", self.client.out) self.assertIn("Revision deduced by 'auto'", self.client.out) self.assertIn("Getting sources from folder: %s" % curdir, self.client.out) self.assertIn("My file is copied", self.client.out) # check blank lines are respected in replacement self.client.run("get lib/0.1@user/channel") self.assertIn("""} def build(self):""", self.client.out) # Export again but now with absolute reference, so no pointer file is created nor kept git = Git(curdir) self.client.save({ "conanfile.py": base_git.format(url=_quoted(curdir), revision=git.get_revision()) }) self.client.run("create . user/channel") sources_dir = self.client.cache.package_layout(self.ref).scm_folder() self.assertFalse(os.path.exists(sources_dir)) self.assertNotIn("Repo origin deduced by 'auto'", self.client.out) self.assertNotIn("Revision deduced by 'auto'", self.client.out) self.assertIn("Getting sources from url: '%s'" % curdir, self.client.out) self.assertIn("My file is copied", self.client.out) def test_auto_subfolder(self): conanfile = base_git.replace( '"revision": "{revision}"', '"revision": "{revision}",\n ' '"subfolder": "mysub"') conanfile = conanfile.replace("short_paths = True", "short_paths = False") conanfile = conanfile.format(directory="None", url=_quoted("auto"), revision="auto") self.client.save({ "conanfile.py": conanfile, "myfile.txt": "My file is copied" }) create_local_git_repo(folder=self.client.current_folder) self.client.run_command('git remote add origin https://myrepo.com.git') self.client.run("create . user/channel") ref = ConanFileReference.loads("lib/0.1@user/channel") folder = self.client.cache.package_layout(ref).source() self.assertTrue( os.path.exists(os.path.join(folder, "mysub", "myfile.txt"))) self.assertFalse( os.path.exists(os.path.join(folder, "mysub", "conanfile.py"))) def test_auto_conanfile_no_root(self): """ Conanfile is not in the root of the repo: https://github.com/conan-io/conan/issues/3465 """ curdir = get_cased_path(self.client.current_folder).replace("\\", "/") conanfile = base_git.format(url=_quoted("auto"), revision="auto") self.client.save({ "conan/conanfile.py": conanfile, "myfile.txt": "content of my file" }) self._commit_contents() self.client.run_command('git remote add origin https://myrepo.com.git') # Create the package self.client.run("create conan/ user/channel") sources_dir = self.client.cache.package_layout(self.ref).scm_folder() self.assertEqual(load(sources_dir), curdir.replace('\\', '/')) # Root of git is 'curdir' def test_deleted_source_folder(self): path, _ = create_local_git_repo({"myfile": "contents"}, branch="my_release") curdir = self.client.current_folder.replace("\\", "/") conanfile = base_git.format(url=_quoted("auto"), revision="auto") self.client.save({ "conanfile.py": conanfile, "myfile.txt": "My file is copied" }) create_local_git_repo(folder=self.client.current_folder) self.client.run_command('git remote add origin "%s"' % path.replace("\\", "/")) self.client.run("export . user/channel") new_curdir = temp_folder() self.client.current_folder = new_curdir # delete old source, so it will try to checkout the remote because of the missing local dir rmdir(curdir) self.client.run("install lib/0.1@user/channel --build", assert_error=True) self.assertIn( "Getting sources from url: '%s'" % path.replace("\\", "/"), self.client.out) def test_excluded_repo_fies(self): conanfile = base_git.format(url=_quoted("auto"), revision="auto") conanfile = conanfile.replace("short_paths = True", "short_paths = False") path, _ = create_local_git_repo( { "myfile": "contents", "ignored.pyc": "bin", ".gitignore": """ *.pyc my_excluded_folder other_folder/excluded_subfolder """, "myfile.txt": "My file!", "my_excluded_folder/some_file": "hey Apple!", "other_folder/excluded_subfolder/some_file": "hey Apple!", "other_folder/valid_file": "!", "conanfile.py": conanfile }, branch="my_release") self.client.current_folder = path self.client.run_command('git remote add origin "%s"' % path.replace("\\", "/")) self.client.run("create . user/channel") self.assertIn("Copying sources to build folder", self.client.out) pref = PackageReference( ConanFileReference.loads("lib/0.1@user/channel"), NO_SETTINGS_PACKAGE_ID) bf = self.client.cache.package_layout(pref.ref).build(pref) self.assertTrue(os.path.exists(os.path.join(bf, "myfile.txt"))) self.assertTrue(os.path.exists(os.path.join(bf, "myfile"))) self.assertTrue(os.path.exists(os.path.join(bf, ".git"))) self.assertFalse(os.path.exists(os.path.join(bf, "ignored.pyc"))) self.assertFalse(os.path.exists(os.path.join(bf, "my_excluded_folder"))) self.assertTrue( os.path.exists(os.path.join(bf, "other_folder", "valid_file"))) self.assertFalse( os.path.exists( os.path.join(bf, "other_folder", "excluded_subfolder"))) def test_local_source(self): curdir = self.client.current_folder.replace("\\", "/") conanfile = base_git.format(url=_quoted("auto"), revision="auto") conanfile += """ def source(self): self.output.warn("SOURCE METHOD CALLED") """ self.client.save({ "conanfile.py": conanfile, "myfile.txt": "My file is copied" }) create_local_git_repo(folder=self.client.current_folder) self.client.save({"aditional_file.txt": "contents"}) self.client.run("source . --source-folder=./source") self.assertTrue( os.path.exists(os.path.join(curdir, "source", "myfile.txt"))) self.assertIn("SOURCE METHOD CALLED", self.client.out) # Even the not commited files are copied self.assertTrue( os.path.exists(os.path.join(curdir, "source", "aditional_file.txt"))) self.assertIn("Getting sources from folder: %s" % curdir, str(self.client.out).replace("\\", "/")) # Export again but now with absolute reference, so no pointer file is created nor kept git = Git(curdir.replace("\\", "/")) conanfile = base_git.format(url=_quoted(curdir.replace("\\", "/")), revision=git.get_revision()) conanfile += """ def source(self): self.output.warn("SOURCE METHOD CALLED") """ self.client.save({ "conanfile.py": conanfile, "myfile2.txt": "My file is copied" }) create_local_git_repo(folder=self.client.current_folder) self.client.run("source . --source-folder=./source2") # myfile2 is no in the specified commit self.assertFalse( os.path.exists(os.path.join(curdir, "source2", "myfile2.txt"))) self.assertTrue( os.path.exists(os.path.join(curdir, "source2", "myfile.txt"))) self.assertIn( "Getting sources from url: '%s'" % curdir.replace("\\", "/"), self.client.out) self.assertIn("SOURCE METHOD CALLED", self.client.out) def test_local_source_subfolder(self): curdir = self.client.current_folder conanfile = base_git.replace( '"revision": "{revision}"', '"revision": "{revision}",\n ' '"subfolder": "mysub"') conanfile = conanfile.format(url=_quoted("auto"), revision="auto") conanfile += """ def source(self): self.output.warn("SOURCE METHOD CALLED") """ self.client.save({ "conanfile.py": conanfile, "myfile.txt": "My file is copied" }) create_local_git_repo(folder=self.client.current_folder) self.client.run("source . --source-folder=./source") self.assertFalse( os.path.exists(os.path.join(curdir, "source", "myfile.txt"))) self.assertTrue( os.path.exists( os.path.join(curdir, "source", "mysub", "myfile.txt"))) self.assertIn("SOURCE METHOD CALLED", self.client.out) def test_install_checked_out(self): test_server = TestServer() self.servers = {"myremote": test_server} self.client = TestClient(servers=self.servers, users={"myremote": [("lasote", "mypass")]}) curdir = self.client.current_folder.replace("\\", "/") conanfile = base_git.format(url=_quoted("auto"), revision="auto") self.client.save({ "conanfile.py": conanfile, "myfile.txt": "My file is copied" }) create_local_git_repo(folder=self.client.current_folder) cmd = 'git remote add origin "%s"' % curdir self.client.run_command(cmd) self.client.run("export . lasote/channel") self.client.run("upload lib* -c") # Take other client, the old client folder will be used as a remote client2 = TestClient(servers=self.servers, users={"myremote": [("lasote", "mypass")]}) client2.run("install lib/0.1@lasote/channel --build") self.assertIn("My file is copied", client2.out) def test_source_removed_in_local_cache(self): conanfile = ''' from conans import ConanFile, tools class ConanLib(ConanFile): scm = { "type": "git", "url": "auto", "revision": "auto", } def build(self): contents = tools.load("myfile") self.output.warn("Contents: %s" % contents) ''' path, _ = create_local_git_repo( { "myfile": "contents", "conanfile.py": conanfile }, branch="my_release") self.client.current_folder = path self.client.run_command('git remote add origin https://myrepo.com.git') self.client.run("create . lib/1.0@user/channel") self.assertIn("Contents: contents", self.client.out) self.client.save({"myfile": "Contents 2"}) self.client.run("create . lib/1.0@user/channel") self.assertIn("Contents: Contents 2", self.client.out) self.assertIn( "Detected 'scm' auto in conanfile, trying to remove source folder", self.client.out) def test_submodule(self): subsubmodule, _ = create_local_git_repo({"subsubmodule": "contents"}) submodule, _ = create_local_git_repo({"submodule": "contents"}, submodules=[subsubmodule]) path, commit = create_local_git_repo({"myfile": "contents"}, branch="my_release", submodules=[submodule]) def _relative_paths(folder): submodule_path = os.path.join( folder, os.path.basename(os.path.normpath(submodule))) subsubmodule_path = os.path.join( submodule_path, os.path.basename(os.path.normpath(subsubmodule))) return submodule_path, subsubmodule_path # Check old (default) behaviour tmp = ''' from conans import ConanFile, tools class ConanLib(ConanFile): name = "lib" version = "0.1" scm = {{ "type": "git", "url": "{url}", "revision": "{revision}" }} ''' conanfile = tmp.format(url=path, revision=commit) self.client.save({"conanfile.py": conanfile}) self.client.run("create . user/channel") ref = ConanFileReference.loads("lib/0.1@user/channel") folder = self.client.cache.package_layout(ref).source() submodule_path, _ = _relative_paths(folder) self.assertTrue(os.path.exists(os.path.join(folder, "myfile"))) self.assertFalse( os.path.exists(os.path.join(submodule_path, "submodule"))) # Check invalid value tmp = ''' from conans import ConanFile, tools class ConanLib(ConanFile): name = "lib" version = "0.1" scm = {{ "type": "git", "url": "{url}", "revision": "{revision}", "submodule": "{submodule}" }} ''' conanfile = tmp.format(url=path, revision=commit, submodule="invalid") self.client.save({"conanfile.py": conanfile}) self.client.run("create . user/channel", assert_error=True) self.assertIn("Invalid 'submodule' attribute value in the 'scm'.", self.client.out) # Check shallow conanfile = tmp.format(url=path, revision=commit, submodule="shallow") self.client.save({"conanfile.py": conanfile}) self.client.run("create . user/channel") ref = ConanFileReference.loads("lib/0.1@user/channel") folder = self.client.cache.package_layout(ref).source() submodule_path, subsubmodule_path = _relative_paths(folder) self.assertTrue(os.path.exists(os.path.join(folder, "myfile"))) self.assertTrue( os.path.exists(os.path.join(submodule_path, "submodule"))) self.assertFalse( os.path.exists(os.path.join(subsubmodule_path, "subsubmodule"))) # Check recursive conanfile = tmp.format(url=path, revision=commit, submodule="recursive") self.client.save({"conanfile.py": conanfile}) self.client.run("create . user/channel") ref = ConanFileReference.loads("lib/0.1@user/channel") folder = self.client.cache.package_layout(ref).source() submodule_path, subsubmodule_path = _relative_paths(folder) self.assertTrue(os.path.exists(os.path.join(folder, "myfile"))) self.assertTrue( os.path.exists(os.path.join(submodule_path, "submodule"))) self.assertTrue( os.path.exists(os.path.join(subsubmodule_path, "subsubmodule"))) def test_scm_bad_filename(self): # Fixes: #3500 badfilename = "\xE3\x81\x82badfile.txt" path, _ = create_local_git_repo({"goodfile.txt": "good contents"}, branch="my_release") save( to_file_bytes(os.path.join(self.client.current_folder, badfilename)), "contents") self.client.run_command('git remote add origin "%s"' % path.replace("\\", "/"), cwd=path) conanfile = ''' import os from conans import ConanFile, tools class ConanLib(ConanFile): name = "lib" version = "0.1" scm = { "type": "git", "url": "auto", "revision": "auto" } def build(self): pass ''' self.client.current_folder = path self.client.save({"conanfile.py": conanfile}) self.client.run("create . user/channel") def test_source_method_export_sources_and_scm_mixed(self): path, _ = create_local_git_repo({"myfile": "contents"}, branch="my_release") conanfile = ''' import os from conans import ConanFile, tools class ConanLib(ConanFile): name = "lib" version = "0.1" exports_sources = "file.txt" scm = { "type": "git", "url": "%s", "revision": "my_release", "subfolder": "src/nested" } def source(self): self.output.warn("SOURCE METHOD CALLED") assert(os.path.exists("file.txt")) assert(os.path.exists(os.path.join("src", "nested", "myfile"))) tools.save("cosa.txt", "contents") def build(self): assert(os.path.exists("file.txt")) assert(os.path.exists("cosa.txt")) self.output.warn("BUILD METHOD CALLED") ''' % path self.client.save({ "conanfile.py": conanfile, "file.txt": "My file is copied" }) self.client.run("create . user/channel") self.assertIn("SOURCE METHOD CALLED", self.client.out) self.assertIn("BUILD METHOD CALLED", self.client.out) def scm_serialization_test(self): data = { "url": "myurl", "revision": "myrevision", "username": "******", "password": "******", "type": "git", "verify_ssl": True, "subfolder": "mysubfolder" } conanfile = namedtuple("ConanfileMock", "scm")(data) scm_data = SCMData(conanfile) the_json = str(scm_data) data2 = json.loads(the_json) self.assertEqual(data, data2) def test_git_delegated_function(self): conanfile = """ import os from conans import ConanFile from conans.client.tools.scm import Git def get_revision(): here = os.path.dirname(__file__) git = Git(here) return git.get_commit() def get_url(): def nested_url(): here = os.path.dirname(__file__) git = Git(here) return git.get_remote_url() return nested_url() class MyLib(ConanFile): name = "issue" version = "3831" scm = {'type': 'git', 'url': get_url(), 'revision': get_revision()} """ self.client.save({"conanfile.py": conanfile}) path, commit = create_local_git_repo(folder=self.client.current_folder) self.client.run_command('git remote add origin "%s"' % path.replace("\\", "/")) self.client.run("export . user/channel") ref = ConanFileReference.loads("issue/3831@user/channel") exported_conanfile = self.client.cache.package_layout(ref).conanfile() content = load(exported_conanfile) self.assertIn(commit, content) def test_delegated_python_code(self): client = TestClient() code_file = """ from conans.tools import Git from conans import ConanFile def get_commit(repo_path): git = Git(repo_path) return git.get_commit() class MyLib(ConanFile): pass """ client.save({"conanfile.py": code_file}) client.run("export . tool/0.1@user/testing") conanfile = """import os from conans import ConanFile, python_requires from conans.tools import load tool = python_requires("tool/0.1@user/testing") class MyLib(ConanFile): scm = {'type': 'git', 'url': '%s', 'revision': tool.get_commit(os.path.dirname(__file__))} def build(self): self.output.info("File: {}".format(load("file.txt"))) """ % client.current_folder.replace("\\", "/") client.save({"conanfile.py": conanfile, "file.txt": "hello!"}) path, commit = create_local_git_repo(folder=client.current_folder) client.run_command('git remote add origin "%s"' % path.replace("\\", "/")) client.run("export . pkg/0.1@user/channel") ref = ConanFileReference.loads("pkg/0.1@user/channel") exported_conanfile = client.cache.package_layout(ref).conanfile() content = load(exported_conanfile) self.assertIn(commit, content)
class CustomConfigurationTest(unittest.TestCase): conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMakeDeps class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "hello/0.1" def generate(self): cmake = CMakeDeps(self) cmake.configurations.append("ReleaseShared") if self.options["hello"].shared: cmake.configuration = "ReleaseShared" cmake.generate() def imports(self): config = str(self.settings.build_type) if self.options["hello"].shared: config = "ReleaseShared" self.copy("*.dll", src="bin", dst=config, keep_path=False) """) app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) cmakelist = textwrap.dedent(""" set(CMAKE_CONFIGURATION_TYPES Debug Release ReleaseShared CACHE STRING "Available build-types: Debug, Release and ReleaseShared") cmake_minimum_required(VERSION 2.8) project(App C CXX) set(CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR} ${CMAKE_PREFIX_PATH}) set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR} ${CMAKE_MODULE_PATH}) set(CMAKE_CXX_FLAGS_RELEASESHARED ${CMAKE_CXX_FLAGS_RELEASE}) set(CMAKE_C_FLAGS_RELEASESHARED ${CMAKE_C_FLAGS_RELEASE}) set(CMAKE_EXE_LINKER_FLAGS_RELEASESHARED ${CMAKE_EXE_LINKER_FLAGS_RELEASE}) find_package(hello REQUIRED) add_executable(app app.cpp) target_link_libraries(app PRIVATE hello::hello) """) def setUp(self): self.client = TestClient(path_with_spaces=False) self.client.run("new hello/0.1 -s") self.client.run("create . hello/0.1@ -s compiler.version=15 " "-s build_type=Release -o hello:shared=True") self.client.run("create . hello/0.1@ -s compiler.version=15 " "-s build_type=Release") # Prepare the actual consumer package self.client.save({ "conanfile.py": self.conanfile, "CMakeLists.txt": self.cmakelist, "app.cpp": self.app }) def test_generator_multi(self): settings = { "compiler": "Visual Studio", "compiler.version": "15", "arch": "x86_64", "build_type": "Release", } settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) # Run the configure corresponding to this test case with self.client.chdir('build'): self.client.run("install .. %s -o hello:shared=True" % settings) self.client.run("install .. %s -o hello:shared=False" % settings) self.assertTrue( os.path.isfile( os.path.join(self.client.current_folder, "helloTarget-releaseshared.cmake"))) self.assertTrue( os.path.isfile( os.path.join(self.client.current_folder, "helloTarget-release.cmake"))) self.client.run_command('cmake .. -G "Visual Studio 15 Win64"') self.client.run_command('cmake --build . --config Release') self.client.run_command(r"Release\\app.exe") self.assertIn("hello/0.1: Hello World Release!", self.client.out) self.assertIn("main: Release!", self.client.out) self.client.run_command('cmake --build . --config ReleaseShared') self.client.run_command(r"ReleaseShared\\app.exe") self.assertIn("hello/0.1: Hello World Release!", self.client.out) self.assertIn("main: Release!", self.client.out)
class CustomSettingsTest(unittest.TestCase): conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMakeDeps class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "hello/0.1" def generate(self): cmake = CMakeDeps(self) #cmake.configurations.append("MyRelease") # NOT NECESSARY!!! cmake.generate() """) app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) cmakelist = textwrap.dedent(""" set(CMAKE_CONFIGURATION_TYPES Debug Release MyRelease CACHE STRING "Available build-types: Debug, Release and MyRelease") cmake_minimum_required(VERSION 2.8) project(App C CXX) set(CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR} ${CMAKE_PREFIX_PATH}) set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR} ${CMAKE_MODULE_PATH}) set(CMAKE_CXX_FLAGS_MYRELEASE ${CMAKE_CXX_FLAGS_RELEASE}) set(CMAKE_C_FLAGS_MYRELEASE ${CMAKE_C_FLAGS_RELEASE}) set(CMAKE_EXE_LINKER_FLAGS_MYRELEASE ${CMAKE_EXE_LINKER_FLAGS_RELEASE}) find_package(hello REQUIRED) add_executable(app app.cpp) target_link_libraries(app PRIVATE hello::hello) """) def setUp(self): self.client = TestClient(path_with_spaces=False) settings = load(self.client.cache.settings_path) settings = settings.replace("Release", "MyRelease") save(self.client.cache.settings_path, settings) self.client.run("new hello/0.1 -s") cmake = self.client.load("src/CMakeLists.txt") cmake = cmake.replace( "cmake_minimum_required", """ set(CMAKE_CONFIGURATION_TYPES Debug MyRelease Release CACHE STRING "Types") cmake_minimum_required""") cmake = cmake.replace( "conan_basic_setup()", """ conan_basic_setup() set(CMAKE_CXX_FLAGS_MYRELEASE ${CMAKE_CXX_FLAGS_RELEASE}) set(CMAKE_C_FLAGS_MYRELEASE ${CMAKE_C_FLAGS_RELEASE}) set(CMAKE_EXE_LINKER_FLAGS_MYRELEASE ${CMAKE_EXE_LINKER_FLAGS_RELEASE}) """) self.client.save({"src/CMakeLists.txt": cmake}) self.client.run( "create . hello/0.1@ -s compiler.version=15 -s build_type=MyRelease" ) # Prepare the actual consumer package self.client.save({ "conanfile.py": self.conanfile, "CMakeLists.txt": self.cmakelist, "app.cpp": self.app }) def test_generator_multi(self): settings = { "compiler": "Visual Studio", "compiler.version": "15", "arch": "x86_64", "build_type": "MyRelease", } settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) # Run the configure corresponding to this test case build_directory = os.path.join(self.client.current_folder, "build").replace("\\", "/") with self.client.chdir(build_directory): self.client.run("install .. %s" % settings) self.assertTrue( os.path.isfile( os.path.join(self.client.current_folder, "helloTarget-myrelease.cmake"))) self.client.run_command('cmake .. -G "Visual Studio 15 Win64"') self.client.run_command('cmake --build . --config MyRelease') self.client.run_command(r"MyRelease\\app.exe") self.assertIn("hello/0.1: Hello World Release!", self.client.out) self.assertIn("main: Release!", self.client.out)
class Base(unittest.TestCase): conanfile = textwrap.dedent(""" from conans import ConanFile, CMake, CMakeToolchain class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "hello/0.1" generators = "cmake_find_package_multi" options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} def toolchain(self): tc = CMakeToolchain(self) tc.definitions["DEFINITIONS_BOTH"] = True tc.definitions.debug["DEFINITIONS_CONFIG"] = "Debug" tc.definitions.release["DEFINITIONS_CONFIG"] = "Release" tc.write_toolchain_files() def build(self): cmake = CMake(self) cmake.configure() cmake.build() """) lib_h = textwrap.dedent(""" #pragma once #ifdef WIN32 #define APP_LIB_EXPORT __declspec(dllexport) #else #define APP_LIB_EXPORT #endif APP_LIB_EXPORT void app(); """) lib_cpp = textwrap.dedent(""" #include <iostream> #include "app.h" #include "hello.h" void app() { std::cout << "Hello: " << HELLO_MSG <<std::endl; #ifdef NDEBUG std::cout << "App: Release!" <<std::endl; #else std::cout << "App: Debug!" <<std::endl; #endif std::cout << "DEFINITIONS_BOTH: " << DEFINITIONS_BOTH << "\\n"; std::cout << "DEFINITIONS_CONFIG: " << DEFINITIONS_CONFIG << "\\n"; } """) app = textwrap.dedent(""" #include "app.h" int main() { app(); } """) cmakelist = textwrap.dedent(""" cmake_minimum_required(VERSION 2.8) project(App C CXX) if(CONAN_TOOLCHAIN_INCLUDED AND CMAKE_VERSION VERSION_LESS "3.15") include("${CMAKE_BINARY_DIR}/conan_project_include.cmake") endif() if(NOT CMAKE_TOOLCHAIN_FILE) message(FATAL ">> Not using toolchain") endif() message(">> CMAKE_GENERATOR_PLATFORM: ${CMAKE_GENERATOR_PLATFORM}") message(">> CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") message(">> CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") message(">> CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") message(">> CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}") message(">> CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") message(">> CMAKE_C_FLAGS_DEBUG: ${CMAKE_C_FLAGS_DEBUG}") message(">> CMAKE_C_FLAGS_RELEASE: ${CMAKE_C_FLAGS_RELEASE}") message(">> CMAKE_SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}") message(">> CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") message(">> CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}") message(">> CMAKE_CXX_EXTENSIONS: ${CMAKE_CXX_EXTENSIONS}") message(">> CMAKE_POSITION_INDEPENDENT_CODE: ${CMAKE_POSITION_INDEPENDENT_CODE}") message(">> CMAKE_SKIP_RPATH: ${CMAKE_SKIP_RPATH}") message(">> CMAKE_INSTALL_NAME_DIR: ${CMAKE_INSTALL_NAME_DIR}") message(">> CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}") message(">> CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}") message(">> BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}") get_directory_property(_COMPILE_DEFS DIRECTORY ${CMAKE_SOURCE_DIR} COMPILE_DEFINITIONS) message(">> COMPILE_DEFINITIONS: ${_COMPILE_DEFS}") find_package(hello REQUIRED) add_library(app_lib app_lib.cpp) target_link_libraries(app_lib PRIVATE hello::hello) target_compile_definitions(app_lib PRIVATE DEFINITIONS_BOTH="${DEFINITIONS_BOTH}") target_compile_definitions(app_lib PRIVATE DEFINITIONS_CONFIG=${DEFINITIONS_CONFIG}) add_executable(app app.cpp) target_link_libraries(app PRIVATE app_lib) """) def setUp(self): self.client = TestClient(path_with_spaces=False) conanfile = textwrap.dedent(""" from conans import ConanFile from conans.tools import save import os class Pkg(ConanFile): settings = "build_type" def package(self): save(os.path.join(self.package_folder, "include/hello.h"), '#define HELLO_MSG "%s"' % self.settings.build_type) """) self.client.save({"conanfile.py": conanfile}) self.client.run("create . hello/0.1@ -s build_type=Debug") self.client.run("create . hello/0.1@ -s build_type=Release") # Prepare the actual consumer package self.client.save({"conanfile.py": self.conanfile, "CMakeLists.txt": self.cmakelist, "app.cpp": self.app, "app_lib.cpp": self.lib_cpp, "app.h": self.lib_h}) def _run_build(self, settings=None, options=None): # Build the profile according to the settings provided settings = settings or {} settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings.items() if v) options = " ".join("-o %s=%s" % (k, v) for k, v in options.items()) if options else "" # Run the configure corresponding to this test case build_directory = os.path.join(self.client.current_folder, "build").replace("\\", "/") with self.client.chdir(build_directory): self.client.run("install .. %s %s" % (settings, options)) install_out = self.client.out self.client.run("build ..") return install_out def _modify_code(self): content = self.client.load("app_lib.cpp") content = content.replace("App:", "AppImproved:") self.client.save({"app_lib.cpp": content}) content = self.client.load("CMakeLists.txt") content = content.replace(">>", "++>>") self.client.save({"CMakeLists.txt": content}) def _incremental_build(self, build_type=None): build_directory = os.path.join(self.client.current_folder, "build").replace("\\", "/") with self.client.chdir(build_directory): config = "--config %s" % build_type if build_type else "" self.client.run_command("cmake --build . %s" % config) def _run_app(self, build_type, bin_folder=False, msg="App", dyld_path=None): if dyld_path: build_directory = os.path.join(self.client.current_folder, "build").replace("\\", "/") command_str = 'DYLD_LIBRARY_PATH="%s" build/app' % build_directory else: command_str = "build\\%s\\app.exe" % build_type if bin_folder else "build/app" self.client.run_command(command_str) self.assertIn("Hello: %s" % build_type, self.client.out) self.assertIn("%s: %s!" % (msg, build_type), self.client.out) self.assertIn("DEFINITIONS_BOTH: True", self.client.out) self.assertIn("DEFINITIONS_CONFIG: %s" % build_type, self.client.out)
def test_build_requires(): # https://github.com/conan-io/conan/issues/9545 client = TestClient() package = "self.copy('*', src=str(self.settings.arch), dst='bin')" dep = GenConanfile().with_exports("*").with_settings("arch").with_package( package) consumer = textwrap.dedent(""" from conans import ConanFile from conan.tools.microsoft import MSBuild class Pkg(ConanFile): settings = "os", "compiler", "build_type", "arch" build_requires = "dep/0.1" generators = "MSBuildDeps", "MSBuildToolchain" def build(self): msbuild = MSBuild(self) msbuild.build("hello.sln") """) hello_vcxproj = textwrap.dedent(r"""<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> <Configuration>Release</Configuration> <Platform>Win32</Platform> </ProjectConfiguration> <ProjectConfiguration Include="Release|x64"> <Configuration>Release</Configuration> <Platform>x64</Platform> </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> <VCProjectVersion>15.0</VCProjectVersion> <ProjectGuid>{6F392A05-B151-490C-9505-B2A49720C4D9}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>MyProject</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <PlatformToolset>v141</PlatformToolset> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <PlatformToolset>v141</PlatformToolset> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="PropertySheets"> <Import Project="..\conandeps.props" /> </ImportGroup> <PropertyGroup Label="UserMacros" /> <ItemGroup> <CustomBuild Include="data.proto"> <FileType>Document</FileType> <Outputs>data.proto.h</Outputs> <Command>dep1tool</Command> </CustomBuild> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> </Project>""") hello_sln = textwrap.dedent(r""" Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.28307.757 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyProject", "MyProject\MyProject.vcxproj", "{6F392A05-B151-490C-9505-B2A49720C4D9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {6F392A05-B151-490C-9505-B2A49720C4D9}.Release|x64.ActiveCfg = Release|x64 {6F392A05-B151-490C-9505-B2A49720C4D9}.Release|x64.Build.0 = Release|x64 {6F392A05-B151-490C-9505-B2A49720C4D9}.Release|x86.ActiveCfg = Release|Win32 {6F392A05-B151-490C-9505-B2A49720C4D9}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DE6E462F-E299-4F9C-951A-F9404EB51521} EndGlobalSection EndGlobal """) client.save({ "dep/conanfile.py": dep, "dep/x86/dep1tool.bat": "@echo Invoking 32bit dep_1 build tool", "dep/x86_64/dep1tool.bat": "@echo Invoking 64bit dep_1 build tool", "consumer/conanfile.py": consumer, "consumer/hello.sln": hello_sln, "consumer/MyProject/MyProject.vcxproj": hello_vcxproj, "consumer/MyProject/data.proto": "dataproto" }) client.run("create dep dep/0.1@ -s arch=x86") client.run("create dep dep/0.1@ -s arch=x86_64") with client.chdir("consumer"): client.run( 'install . -s compiler="Visual Studio" -s compiler.version=15 ' " -s arch=x86_64 -s build_type=Release") assert "dep/0.1:c0519e2d9702ec12d057bb15adb7a02baaf18107 - Cache" in client.out deps_props = client.load("conandeps.props") assert "conan_dep_build.props" in deps_props client.run("build .") assert "Invoking 64bit dep_1 build tool" in client.out client.run( 'install . -s compiler="Visual Studio" -s compiler.version=15 ' " -s arch=x86 -s build_type=Release") client.run("build .") assert "Invoking 32bit dep_1 build tool" in client.out # Make sure it works with 2 profiles too client.run( 'install . -s compiler="Visual Studio" -s compiler.version=15 ' " -s arch=x86_64 -s build_type=Release -s:b os=Windows -s:h os=Windows" ) client.run("build .") assert "Invoking 64bit dep_1 build tool" in client.out
def test_transitive_consuming(): client = TestClient(path_with_spaces=False) # A regular library made with CMake with client.chdir("zlib"): client.run("new zlib/1.2.11 --template cmake_lib") conanfile = client.load("conanfile.py") conanfile += """ self.cpp_info.defines.append("MY_DEFINE=\\"MY_VALUE\\"") self.cpp_info.defines.append("MY_OTHER_DEFINE=2") if self.settings.os != "Windows": self.cpp_info.system_libs.append("m") else: self.cpp_info.system_libs.append("ws2_32") """ client.save({"conanfile.py": conanfile}) client.run("create .") # We prepare a consumer with Bazel (library openssl using zlib) and a test_package with an # example executable conanfile = textwrap.dedent(""" import os from conan import ConanFile from conan.tools.google import Bazel, bazel_layout from conan.tools.files import copy class OpenSSLConan(ConanFile): name = "openssl" version = "1.0" settings = "os", "compiler", "build_type", "arch" exports_sources = "main/*", "WORKSPACE" requires = "zlib/1.2.11" generators = "BazelToolchain", "BazelDeps" def layout(self): bazel_layout(self) def build(self): bazel = Bazel(self) bazel.configure() bazel.build(label="//main:openssl") def package(self): dest_bin = os.path.join(self.package_folder, "bin") dest_lib = os.path.join(self.package_folder, "lib") build = os.path.join(self.build_folder, "bazel-bin", "main") copy(self, "*.so", build, dest_bin, keep_path=False) copy(self, "*.dll", build, dest_bin, keep_path=False) copy(self, "*.dylib", build, dest_bin, keep_path=False) copy(self, "*.a", build, dest_lib, keep_path=False) copy(self, "*.lib", build, dest_lib, keep_path=False) copy(self, "*openssl.h", self.source_folder, os.path.join(self.package_folder, "include"), keep_path=False) def package_info(self): self.cpp_info.libs = ["openssl"] """) bazel_build = textwrap.dedent(""" load("@rules_cc//cc:defs.bzl", "cc_library") cc_library( name = "openssl", srcs = ["openssl.cpp"], hdrs = ["openssl.h"], deps = [ "@zlib//:zlib", ], ) """) openssl_c = textwrap.dedent(""" #include <iostream> #include "openssl.h" #include "zlib.h" #include <math.h> void openssl(){ std::cout << "Calling OpenSSL function with define " << MY_DEFINE << " and other define " << MY_OTHER_DEFINE << "\\n"; zlib(); // This comes from the systemlibs declared in the zlib sqrt(25); } """) openssl_c_win = textwrap.dedent(""" #include <iostream> #include "openssl.h" #include "zlib.h" #include <WinSock2.h> void openssl(){ SOCKET foo; // From the system library std::cout << "Calling OpenSSL function with define " << MY_DEFINE << " and other define " << MY_OTHER_DEFINE << "\\n"; zlib(); } """) openssl_h = textwrap.dedent(""" void openssl(); """) bazel_workspace = textwrap.dedent(""" load("@//:dependencies.bzl", "load_conan_dependencies") load_conan_dependencies() """) test_example = """#include "openssl.h" int main() {{ openssl(); }} """ test_conanfile = textwrap.dedent(""" import os from conan import ConanFile from conan.tools.google import Bazel, bazel_layout from conan.tools.build import cross_building class OpenSSLTestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" # VirtualBuildEnv and VirtualRunEnv can be avoided if "tools.env.virtualenv:auto_use" is defined # (it will be defined in Conan 2.0) generators = "BazelToolchain", "BazelDeps", "VirtualBuildEnv", "VirtualRunEnv" apply_env = False def requirements(self): self.requires(self.tested_reference_str) def build(self): bazel = Bazel(self) bazel.configure() bazel.build(label="//main:example") def layout(self): bazel_layout(self) def test(self): if not cross_building(self): cmd = os.path.join(self.cpp.build.bindirs[0], "main", "example") self.run(cmd, env="conanrun") """) test_bazel_build = textwrap.dedent(""" load("@rules_cc//cc:defs.bzl", "cc_binary") cc_binary( name = "example", srcs = ["example.cpp"], deps = [ "@openssl//:openssl", ], ) """) client.save({ "conanfile.py": conanfile, "main/BUILD": bazel_build, "main/openssl.cpp": openssl_c if platform.system() != "Windows" else openssl_c_win, "main/openssl.h": openssl_h, "WORKSPACE": bazel_workspace, "test_package/conanfile.py": test_conanfile, "test_package/main/example.cpp": test_example, "test_package/main/BUILD": test_bazel_build, "test_package/WORKSPACE": bazel_workspace }) client.run("create .") assert "Calling OpenSSL function with define MY_VALUE and other define 2" in client.out assert "zlib/1.2.11: Hello World Release!"
def test_native_export_multi(self): """ bye depends on hello. Both use find_package in their CMakeLists.txt The consumer depends on bye, using the cmake_find_package_multi generator """ c = TestClient() project_folder_name = "project_targets" assets_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "assets/cmake_find_package_multi") c.copy_from_assets(assets_path, ["bye", "hello", project_folder_name]) # Create packages for hello and bye for p in ("hello", "bye"): with c.chdir(p): for bt in ("Debug", "Release"): c.run("create . user/channel -s build_type={}".format(bt)) with c.chdir(project_folder_name): # Save conanfile and example conanfile = textwrap.dedent(""" [requires] bye/1.0@user/channel [generators] cmake_find_package_multi """) example_cpp = textwrap.dedent(""" #include <iostream> #include "bye.h" int main() { bye(); } """) c.save({"conanfile.txt": conanfile, "example.cpp": example_cpp}) mkdir("./build") with c.chdir("build"): for bt in ("Debug", "Release"): c.run( "install .. user/channel -s build_type={}".format(bt)) if platform.system() == "Windows": c.run_command('cmake .. -G "Visual Studio 15 Win64"') c.run_command('cmake --build . --config Debug') c.run_command('cmake --build . --config Release') c.run_command('Debug\\example.exe') self.assertIn("Hello World Debug!", c.out) self.assertIn("bye World Debug!", c.out) c.run_command('Release\\example.exe') self.assertIn("Hello World Release!", c.out) self.assertIn("bye World Release!", c.out) else: for bt in ("Debug", "Release"): c.run_command( 'cmake .. -DCMAKE_BUILD_TYPE={}'.format(bt)) c.run_command('cmake --build .') c.run_command('./example') self.assertIn("Hello World {}!".format(bt), c.out) self.assertIn("bye World {}!".format(bt), c.out) os.remove(os.path.join(c.current_folder, "example"))
def test_cmaketoolchain_path_find(package, find_package): """Test with user "Hello" and also ZLIB one, to check that package ZLIB has priority over the CMake system one Also, that user cmake files in the root are accessible via CMake include() """ client = TestClient() conanfile = textwrap.dedent(""" from conans import ConanFile class TestConan(ConanFile): exports = "*" def layout(self): pass def package(self): self.copy(pattern="*", keep_path=False) """) find = textwrap.dedent(""" SET({package}_FOUND 1) MESSAGE("HELLO FROM THE {package} FIND PACKAGE!") """).format(package=package) myowncmake = textwrap.dedent(""" MESSAGE("MYOWNCMAKE FROM {package}!") """).format(package=package) filename = "{}Config.cmake" if find_package == "config" else "Find{}.cmake" filename = filename.format(package) client.save({ "conanfile.py": conanfile, "{}".format(filename): find, "myowncmake.cmake": myowncmake }) client.run("create . {}/0.1@".format(package)) consumer = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) set(CMAKE_CXX_ABI_COMPILED 1) project(MyHello CXX) cmake_minimum_required(VERSION 3.15) find_package({package} REQUIRED) include(myowncmake) """).format(package=package) client.save({"CMakeLists.txt": consumer}, clean_first=True) client.run("install {}/0.1@ -g CMakeToolchain".format(package)) with client.chdir("build"): client.run_command( "cmake .. -DCMAKE_TOOLCHAIN_FILE=../conan_toolchain.cmake") assert "Conan: Target declared" not in client.out assert "HELLO FROM THE {package} FIND PACKAGE!".format( package=package) in client.out assert "MYOWNCMAKE FROM {package}!".format(package=package) in client.out # If using the CMakeDeps generator, the in-package .cmake will be ignored # But it is still possible to include(owncmake) client.run( "install {}/0.1@ -g CMakeToolchain -g CMakeDeps".format(package)) with client.chdir( "build2" ): # A clean folder, not the previous one, CMake cache doesnt affect client.run_command( "cmake .. -DCMAKE_TOOLCHAIN_FILE=../conan_toolchain.cmake") assert "Conan: Target declared '{package}::{package}'".format( package=package) in client.out assert "HELLO FROM THE {package} FIND PACKAGE!".format( package=package) not in client.out assert "MYOWNCMAKE FROM {package}!".format(package=package) in client.out
def test_cmaketoolchain_path_find_package_real_config(settings, find_root_path_modes): client = TestClient() conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake import os class TestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" exports_sources = "*" generators = "CMakeToolchain" def layout(self): pass def build(self): cmake = CMake(self) cmake.configure() def package(self): cmake = CMake(self) cmake.install() def package_info(self): self.cpp_info.builddirs.append(os.path.join("hello", "cmake")) """) cmake = textwrap.dedent(""" cmake_minimum_required(VERSION 3.15) project(MyHello NONE) add_library(hello INTERFACE) install(TARGETS hello EXPORT helloConfig) export(TARGETS hello NAMESPACE hello:: FILE "${CMAKE_CURRENT_BINARY_DIR}/helloConfig.cmake" ) install(EXPORT helloConfig DESTINATION "${CMAKE_INSTALL_PREFIX}/hello/cmake" NAMESPACE hello:: ) """) client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmake}) client.run("create . hello/0.1@ -pr:b default {}".format(settings)) consumer = textwrap.dedent(""" cmake_minimum_required(VERSION 3.15) project(MyHello NONE) find_package(hello REQUIRED) """) client.save({"CMakeLists.txt": consumer}, clean_first=True) client.run("install hello/0.1@ -g CMakeToolchain -pr:b default {}".format(settings)) with client.chdir("build"): client.run_command(_cmake_command_toolchain(find_root_path_modes)) # If it didn't fail, it found the helloConfig.cmake assert "Conan: Target declared" not in client.out # If using the CMakeDeps generator, the in-package .cmake will be ignored client.run("install hello/0.1@ -g CMakeToolchain -g CMakeDeps -pr:b default {}".format(settings)) with client.chdir("build2"): # A clean folder, not the previous one, CMake cache doesnt affect client.run_command(_cmake_command_toolchain(find_root_path_modes)) assert "Conan: Target declared 'hello::hello'" in client.out
def test_cmaketoolchain_path_find_real_config(): client = TestClient() conanfile = textwrap.dedent(""" from conans import ConanFile from conan.tools.cmake import CMake class TestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" exports = "*" generators = "CMakeToolchain" def layout(self): pass def build(self): cmake = CMake(self) cmake.configure() def package(self): cmake = CMake(self) cmake.install() """) cmake = textwrap.dedent(""" cmake_minimum_required(VERSION 3.15) project(MyHello NONE) add_library(hello INTERFACE) install(TARGETS hello EXPORT helloConfig) export(TARGETS hello NAMESPACE hello:: FILE "${CMAKE_CURRENT_BINARY_DIR}/helloConfig.cmake" ) install(EXPORT helloConfig DESTINATION "${CMAKE_INSTALL_PREFIX}/hello/cmake" NAMESPACE hello:: ) """) client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmake}) client.run("create . hello/0.1@") consumer = textwrap.dedent(""" project(MyHello NONE) cmake_minimum_required(VERSION 3.15) find_package(hello REQUIRED) """) client.save({"CMakeLists.txt": consumer}, clean_first=True) client.run("install hello/0.1@ -g CMakeToolchain") with client.chdir("build"): client.run_command( "cmake .. -DCMAKE_TOOLCHAIN_FILE=../conan_toolchain.cmake") # If it didn't fail, it found the helloConfig.cmake assert "Conan: Target declared" not in client.out # If using the CMakeDeps generator, the in-package .cmake will be ignored # But it is still possible to include(owncmake) client.run("install hello/0.1@ -g CMakeToolchain -g CMakeDeps") with client.chdir( "build2" ): # A clean folder, not the previous one, CMake cache doesnt affect client.run_command( "cmake .. -DCMAKE_TOOLCHAIN_FILE=../conan_toolchain.cmake") assert "Conan: Target declared 'hello::hello'" in client.out
class Base(unittest.TestCase): conanfile = textwrap.dedent(""" from conan.tools.google import Bazel from conans import ConanFile class App(ConanFile): name="test_bazel_app" version="0.0" settings = "os", "compiler", "build_type", "arch" generators = "BazelDeps", "BazelToolchain" exports_sources = "WORKSPACE", "app/*" def build(self): bazel = Bazel(self) bazel.configure() bazel.build(label="//app:main") def package(self): self.copy('*', src='bazel-bin') """) buildfile = textwrap.dedent(""" load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library") cc_library( name = "hello", srcs = ["hello.cpp"], hdrs = ["hello.h",], ) cc_binary( name = "main", srcs = ["main.cpp"], deps = [":hello"], ) """) lib_h = gen_function_h(name="hello") lib_cpp = gen_function_cpp(name="hello", msg="Hello", includes=["hello"]) main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"]) workspace_file = textwrap.dedent(""" load("@//bazel-build/conandeps:dependencies.bzl", "load_conan_dependencies") load_conan_dependencies() """) def setUp(self): self.client = TestClient(path_with_spaces=False ) # bazel doesn't work with paths with spaces conanfile = textwrap.dedent(""" from conans import ConanFile from conans.tools import save import os class Pkg(ConanFile): settings = "build_type" def package(self): save(os.path.join(self.package_folder, "include/hello.h"), '''#include <iostream> void hello(){std::cout<< "Hello: %s" <<std::endl;}''' % self.settings.build_type) """) self.client.save({"conanfile.py": conanfile}) self.client.run("create . hello/0.1@ -s build_type=Debug") self.client.run("create . hello/0.1@ -s build_type=Release") # Prepare the actual consumer package self.client.save({ "conanfile.py": self.conanfile, "WORKSPACE": self.workspace_file, "app/BUILD": self.buildfile, "app/main.cpp": self.main, "app/hello.cpp": self.lib_cpp, "app/hello.h": self.lib_h }) def _run_build(self): build_directory = os.path.join(self.client.current_folder, "bazel-build").replace("\\", "/") with self.client.chdir(build_directory): self.client.run("install .. ") install_out = self.client.out self.client.run("build ..") return install_out def _modify_code(self): lib_cpp = gen_function_cpp(name="hello", msg="HelloImproved", includes=["hello"]) self.client.save({"app/hello.cpp": lib_cpp}) def _incremental_build(self): with self.client.chdir(self.client.current_folder): self.client.run_command( "bazel build --explain=output.txt //app:main") def _run_app(self, bin_folder=False): command_str = "bazel-bin/app/main.exe" if bin_folder else "bazel-bin/app/main" if platform.system() == "Windows": command_str = command_str.replace("/", "\\") self.client.run_command(command_str)
def reuse_test(self): ref = ConanFileReference.loads("stringutil/0.1@lasote/stable") files = { 'conanfile.py': stringutil_conanfile, 'reverse.go': reverse, 'reverse_test.go': reverse_test, 'reverse.txt': reverse, 'hello/helloreverse.txt': reverse } files_without_conanfile = set(files.keys()) - set(["conanfile.py"]) self.client.save(files) self.client.run("export . lasote/stable") self.client.run("install %s --build missing" % str(ref)) # Check compilation ok package_ids = self.client.cache.package_layout(ref).conan_packages() self.assertEqual(len(package_ids), 1) pref = PackageReference(ref, package_ids[0]) self._assert_package_exists(pref, self.client.cache, files_without_conanfile) # Upload conans self.client.run("upload %s" % str(ref)) # Check that conans exists on server server_paths = self.servers["default"].server_store rev = server_paths.get_last_revision(ref).revision conan_path = server_paths.export(ref.copy_with_rev(rev)) self.assertTrue(os.path.exists(conan_path)) # Upload package self.client.run("upload %s -p %s" % (str(ref), str(package_ids[0]))) # Check library on server self._assert_package_exists_in_server(pref, server_paths, files_without_conanfile) # Now from other "computer" install the uploaded conans with same options (nothing) other_conan = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}) other_conan.run("install %s --build missing" % str(ref)) # Build should be empty build_path = other_conan.cache.package_layout(pref.ref).build(pref) self.assertFalse(os.path.exists(build_path)) # Lib should exist self._assert_package_exists(pref, other_conan.cache, files_without_conanfile) client_reuse = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}) files = {'conanfile.py': client_reusefile, 'src/hello/main.go': main} client_reuse.save(files) client_reuse.run("install . --build missing") with environment_append({ "PATH": ['$GOPATH/bin'], 'GOPATH': client_reuse.current_folder }): if platform.system() == "Windows": command = "hello" else: command = './hello' client_reuse.run_command('go install hello') with client_reuse.chdir("bin"): client_reuse.run_command(command) self.assertIn("Hello, Go!", client_reuse.out)
def test_git_helper_in_recipe(self): client = TestClient() git_repo = temp_folder() save(os.path.join(git_repo, "file.h"), "contents") with client.chdir(git_repo): client.run_command("git init .") client.run_command('git config user.email "*****@*****.**"') client.run_command('git config user.name "Your Name"') client.run_command("git checkout -b dev") client.run_command("git add .") client.run_command('git commit -m "comm"') conanfile = """ import os from conans import ConanFile, tools class HelloConan(ConanFile): name = "Hello" version = "0.1" exports_sources = "other" def source(self): git = tools.Git() git.clone("%s", "dev") def build(self): assert(os.path.exists("file.h")) """ % git_repo.replace("\\", "/") client.save({"conanfile.py": conanfile, "other": "hello"}) client.run("create . user/channel") # Now clone in a subfolder with later checkout conanfile = """ import os from conans import ConanFile, tools class HelloConan(ConanFile): name = "Hello" version = "0.1" exports_sources = "other" def source(self): tools.mkdir("src") git = tools.Git("./src") git.clone("%s") git.checkout("dev") def build(self): assert(os.path.exists(os.path.join("src", "file.h"))) """ % git_repo.replace("\\", "/") client.save({"conanfile.py": conanfile, "other": "hello"}) client.run("create . user/channel") # Base dir, with exports without subfolder and not specifying checkout fails conanfile = """ import os from conans import ConanFile, tools class HelloConan(ConanFile): name = "Hello" version = "0.1" exports_sources = "other" def source(self): git = tools.Git() git.clone("%s") def build(self): assert(os.path.exists("file.h")) """ % git_repo.replace("\\", "/") client.save({"conanfile.py": conanfile, "other": "hello"}) client.run("create . user/channel", assert_error=True) self.assertIn("specify a branch to checkout", client.out)
class ConfigInstallSchedTest(unittest.TestCase): def setUp(self): self.folder = temp_folder(path_with_spaces=False) save_files(self.folder, {"conan.conf": conanconf_interval}) self.client = TestClient() def test_config_install_sched_file(self): """ Config install can be executed without restriction """ self.client.run('config install "%s"' % self.folder) self.assertIn("Processing conan.conf", self.client.out) content = load(self.client.cache.conan_conf_path) self.assertEqual(1, content.count("config_install_interval")) self.assertIn("config_install_interval = 5m", content.splitlines()) self.assertTrue(os.path.exists(self.client.cache.config_install_file)) self.assertLess( os.path.getmtime(self.client.cache.config_install_file), time.time() + 1) def test_execute_more_than_once(self): """ Once executed by the scheduler, conan config install must executed again when invoked manually """ self.client.run('config install "%s"' % self.folder) self.assertIn("Processing conan.conf", self.client.out) self.client.run('config install "%s"' % self.folder) self.assertIn("Processing conan.conf", self.client.out) self.assertLess( os.path.getmtime(self.client.cache.config_install_file), time.time() + 1) def test_sched_timeout(self): """ Conan config install must be executed when the scheduled time reaches """ self.client.run('config install "%s"' % self.folder) self.client.run('config set general.config_install_interval=1m') self.assertNotIn("Processing conan.conf", self.client.out) past_time = int(time.time() - 120) # 120 seconds in the past os.utime(self.client.cache.config_install_file, (past_time, past_time)) self.client.run('search') # any command will fire it self.assertIn("Processing conan.conf", self.client.out) self.client.run('search') # not again, it was fired already self.assertNotIn("Processing conan.conf", self.client.out) self.client.run('config get general.config_install_interval') self.assertNotIn("Processing conan.conf", self.client.out) self.assertIn( "5m", self.client.out) # The previous 5 mins has been restored! def test_invalid_scheduler(self): """ An exception must be raised when conan_config.json is not listed """ self.client.run('config install "%s"' % self.folder) os.remove(self.client.cache.config_install_file) self.client.run('config get general.config_install_interval', assert_error=True) self.assertIn( "config_install_interval defined, but no config_install file", self.client.out) def test_invalid_time_interval(self): """ config_install_interval only accepts minutes, hours or days """ self.client.run('config set general.config_install_interval=1s') # Any conan invocation will fire the configuration error self.client.run('install .', assert_error=True) self.assertIn( "ERROR: Incorrect definition of general.config_install_interval: 1s", self.client.out) @pytest.mark.tool_git def test_config_install_remove_git_repo(self): """ config_install_interval must break when remote git has been removed """ with self.client.chdir(self.folder): self.client.run_command('git init .') self.client.run_command('git add .') self.client.run_command('git config user.name myname') self.client.run_command( 'git config user.email [email protected]') self.client.run_command('git commit -m "mymsg"') self.client.run('config install "%s/.git" --type git' % self.folder) self.assertIn("Processing conan.conf", self.client.out) self.assertIn("Repo cloned!", self.client.out) # git clone executed by scheduled task folder_name = self.folder new_name = self.folder + "_test" os.rename(self.folder, new_name) with patch("conans.client.command.is_config_install_scheduled", return_value=True): self.client.run("config --help", assert_error=True) # scheduled task has been executed. Without a remote, the user should fix the config self.assertIn( "ERROR: Failed conan config install: Can't clone repo", self.client.out) # restore the remote os.rename(new_name, folder_name) self.client.run("config --help") self.assertIn("Repo cloned!", self.client.out) @pytest.mark.tool_git def test_config_install_remove_config_repo(self): """ config_install_interval should not run when config list is empty """ with self.client.chdir(self.folder): self.client.run_command('git init .') self.client.run_command('git add .') self.client.run_command('git config user.name myname') self.client.run_command( 'git config user.email [email protected]') self.client.run_command('git commit -m "mymsg"') self.client.run('config install "%s/.git" --type git' % self.folder) self.assertIn("Processing conan.conf", self.client.out) self.assertIn("Repo cloned!", self.client.out) # force scheduled time for all commands with patch( "conans.client.conf.config_installer._is_scheduled_intervals", return_value=True): self.client.run("config --help") self.assertIn( "Repo cloned!", self.client.out) # git clone executed by scheduled task # config install must not run scheduled config self.client.run("config install --remove 0") self.assertEqual("", self.client.out) self.client.run("config install --list") self.assertEqual("", self.client.out) last_change = os.path.getmtime( self.client.cache.config_install_file) # without a config in configs file, scheduler only emits a warning self.client.run("help") self.assertIn( "WARN: Skipping scheduled config install, " "no config listed in config_install file", self.client.out) self.assertNotIn("Repo cloned!", self.client.out) # ... and updates the next schedule self.assertGreater( os.path.getmtime(self.client.cache.config_install_file), last_change) def test_config_fails_git_folder(self): # https://github.com/conan-io/conan/issues/8594 folder = os.path.join(temp_folder(), ".gitlab-conan", ".conan") client = TestClient(cache_folder=folder) with client.chdir(self.folder): client.run_command('git init .') client.run_command('git add .') client.run_command('git config user.name myname') client.run_command('git config user.email [email protected]') client.run_command('git commit -m "mymsg"') assert ".gitlab-conan" in client.cache_folder assert os.path.basename(client.cache_folder) == ".conan" conf = load(client.cache.conan_conf_path) assert "config_install_interval = 5m" not in conf client.run('config install "%s/.git" --type git' % self.folder) conf = load(client.cache.conan_conf_path) assert "config_install_interval = 5m" in conf dirs = os.listdir(client.cache.cache_folder) assert ".git" not in dirs
def test_native_export_multi(self): """ bye depends on hello. Both use find_package in their CMakeLists.txt The consumer depends on bye, using the cmake_find_package_multi generator """ c = TestClient() project_folder_name = "project_targets" c.copy_assets("cmake_find_package_multi", ["bye", "hello", project_folder_name]) # Create packages for hello and bye for p in ("hello", "bye"): for bt in ("Debug", "Release"): c.run("create {} user/channel -s build_type={}".format(p, bt)) with c.chdir(project_folder_name): # Save conanfile and example conanfile = textwrap.dedent(""" [requires] bye/1.0@user/channel [generators] cmake_find_package_multi """) example_cpp = gen_function_cpp(name="main", includes=["bye"], calls=["bye"]) c.save({"conanfile.txt": conanfile, "example.cpp": example_cpp}) with c.chdir("build"): for bt in ("Debug", "Release"): c.run( "install .. user/channel -s build_type={}".format(bt)) # Test that we are using find_dependency with the NO_MODULE option # to skip finding first possible FindBye somewhere self.assertIn( "find_dependency(hello REQUIRED NO_MODULE)", load(os.path.join(c.current_folder, "bye-config.cmake"))) if platform.system() == "Windows": c.run_command('cmake .. -G "Visual Studio 15 Win64"') c.run_command('cmake --build . --config Debug') c.run_command('cmake --build . --config Release') c.run_command('Debug\\example.exe') self.assertIn("Hello World Debug!", c.out) self.assertIn("bye World Debug!", c.out) c.run_command('Release\\example.exe') self.assertIn("Hello World Release!", c.out) self.assertIn("bye World Release!", c.out) else: for bt in ("Debug", "Release"): c.run_command( 'cmake .. -DCMAKE_BUILD_TYPE={}'.format(bt)) c.run_command('cmake --build .') c.run_command('./example') self.assertIn("Hello World {}!".format(bt), c.out) self.assertIn("bye World {}!".format(bt), c.out) os.remove(os.path.join(c.current_folder, "example"))
def reuse_test(self): self._export_upload("hello0/0.1@lasote/stable") self._export_upload("hello1/0.1@lasote/stable", 1, [0]) self._export_upload("hello2/0.1@lasote/stable", 2, [0]) self._export_upload("hello3/0.1@lasote/stable", 3, [1, 2]) client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}) ref = ConanFileReference.loads("hello4/0.2@lasote/stable") files3 = hello_conan_files(ref=ref, number=4, deps=[3], lang='go') client.save(files3) client.run("install . --build missing") client.run("build .") with environment_append({ "PATH": ['$GOPATH/bin'], 'GOPATH': client.current_folder }): with client.chdir("src"): client.run_command('go install hello4_main') if platform.system() == "Windows": command = "hello4_main" else: command = './hello4_main' with client.chdir("bin"): client.run_command(command) self.assertEqual( ['Hello 4', 'Hello 3', 'Hello 1', 'Hello 0', 'Hello 2', 'Hello 0'], str(client.out).splitlines()[-6:]) # Try to upload and reuse the binaries client.run("upload hello3/0.1@lasote/stable --all") self.assertEqual(str(client.out).count("Uploading package"), 1) client.run("upload hello1/0.1@lasote/stable --all") self.assertEqual(str(client.out).count("Uploading package"), 1) client.run("upload hello2/0.1@lasote/stable --all") self.assertEqual(str(client.out).count("Uploading package"), 1) client.run("upload hello0/0.1@lasote/stable --all") self.assertEqual(str(client.out).count("Uploading package"), 1) # client2 = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]}) ref = ConanFileReference.loads("hello4/0.2@lasote/stable") files3 = hello_conan_files(ref=ref, number=4, deps=[3], lang='go') client2.save(files3) client2.run("install . --build missing") with environment_append({ "PATH": ['$GOPATH/bin'], 'GOPATH': client2.current_folder }): with client2.chdir("src"): client2.run_command('go install hello4_main') if platform.system() == "Windows": command = "hello4_main" else: command = './hello4_main' with client2.chdir("bin"): client2.run_command(command) self.assertEqual( ['Hello 4', 'Hello 3', 'Hello 1', 'Hello 0', 'Hello 2', 'Hello 0'], str(client2.out).splitlines()[-6:])
class ConfigInstallTest(unittest.TestCase): def setUp(self): self.client = TestClient() save(os.path.join(self.client.cache.profiles_path, "default"), "#default profile empty") save(os.path.join(self.client.cache.profiles_path, "linux"), "#empty linux profile") def _create_profile_folder(self, folder=None): folder = folder or temp_folder(path_with_spaces=False) save_files(folder, {"settings.yml": settings_yml, "remotes.txt": remotes, "profiles/linux": linux_profile, "profiles/windows": win_profile, "hooks/dummy": "#hook dummy", "hooks/foo.py": "#hook foo", "hooks/custom/custom.py": "#hook custom", ".git/hooks/foo": "foo", "hooks/.git/hooks/before_push": "before_push", "config/conan.conf": conan_conf, "pylintrc": "#Custom pylint", "python/myfuncs.py": myfuncpy, "python/__init__.py": "" }) return folder def config_hooks_test(self): # Make sure the conan.conf hooks information is appended folder = temp_folder(path_with_spaces=False) conan_conf = textwrap.dedent(""" [hooks] foo custom/custom """) save_files(folder, {"config/conan.conf": conan_conf}) client = TestClient() client.run('config install "%s"' % folder) self.assertIn("Processing conan.conf", client.out) content = load(client.cache.conan_conf_path) self.assertEqual(1, content.count("foo")) self.assertEqual(1, content.count("custom/custom")) config = ConanClientConfigParser(client.cache.conan_conf_path) hooks = config.get_item("hooks") self.assertIn("foo", hooks) self.assertIn("custom/custom", hooks) self.assertIn("attribute_checker", hooks) client.run('config install "%s"' % folder) self.assertIn("Processing conan.conf", client.out) content = load(client.cache.conan_conf_path) self.assertEqual(1, content.count("foo")) self.assertEqual(1, content.count("custom/custom")) def _create_zip(self, zippath=None): folder = self._create_profile_folder() zippath = zippath or os.path.join(folder, "myconfig.zip") zipdir(folder, zippath) return zippath def _check(self, params): typ, uri, verify, args = [p.strip() for p in params.split(",")] configs = json.loads(load(self.client.cache.config_install_file)) config = _ConfigOrigin(configs[0]) self.assertEqual(config.type, typ) self.assertEqual(config.uri, uri) self.assertEqual(str(config.verify_ssl), verify) self.assertEqual(str(config.args), args) settings_path = self.client.cache.settings_path self.assertEqual(load(settings_path).splitlines(), settings_yml.splitlines()) remotes = self.client.cache.registry.load_remotes() self.assertEqual(list(remotes.values()), [Remote("myrepo1", "https://myrepourl.net", False), Remote("my-repo-2", "https://myrepo2.com", True), ]) self.assertEqual(sorted(os.listdir(self.client.cache.profiles_path)), sorted(["default", "linux", "windows"])) self.assertEqual(load(os.path.join(self.client.cache.profiles_path, "linux")).splitlines(), linux_profile.splitlines()) self.assertEqual(load(os.path.join(self.client.cache.profiles_path, "windows")).splitlines(), win_profile.splitlines()) conan_conf = ConanClientConfigParser(self.client.cache.conan_conf_path) self.assertEqual(conan_conf.get_item("log.run_to_output"), "False") self.assertEqual(conan_conf.get_item("log.run_to_file"), "False") self.assertEqual(conan_conf.get_item("log.level"), "10") self.assertEqual(conan_conf.get_item("general.compression_level"), "6") self.assertEqual(conan_conf.get_item("general.default_package_id_mode"), "full_package_mode") self.assertEqual(conan_conf.get_item("general.sysrequires_sudo"), "True") self.assertEqual(conan_conf.get_item("general.cpu_count"), "1") with six.assertRaisesRegex(self, ConanException, "'config_install' doesn't exist"): conan_conf.get_item("general.config_install") self.assertEqual(conan_conf.get_item("proxies.https"), "None") self.assertEqual(conan_conf.get_item("proxies.http"), "http://*****:*****@10.10.1.10:3128/") self.assertEqual("#Custom pylint", load(os.path.join(self.client.cache_folder, "pylintrc"))) self.assertEqual("", load(os.path.join(self.client.cache_folder, "python", "__init__.py"))) self.assertEqual("#hook dummy", load(os.path.join(self.client.cache_folder, "hooks", "dummy"))) self.assertEqual("#hook foo", load(os.path.join(self.client.cache_folder, "hooks", "foo.py"))) self.assertEqual("#hook custom", load(os.path.join(self.client.cache_folder, "hooks", "custom", "custom.py"))) self.assertFalse(os.path.exists(os.path.join(self.client.cache_folder, "hooks", ".git"))) self.assertFalse(os.path.exists(os.path.join(self.client.cache_folder, ".git"))) def reuse_python_test(self): zippath = self._create_zip() self.client.run('config install "%s"' % zippath) conanfile = """from conans import ConanFile from myfuncs import mycooladd a = mycooladd(1, 2) assert a == 3 class Pkg(ConanFile): def build(self): self.output.info("A is %s" % a) """ self.client.save({"conanfile.py": conanfile}) self.client.run("create . Pkg/0.1@user/testing") self.assertIn("A is 3", self.client.out) def install_file_test(self): """ should install from a file in current dir """ zippath = self._create_zip() self.client.run('config install "%s"' % zippath) self._check("file, %s, True, None" % zippath) self.assertTrue(os.path.exists(zippath)) def install_dir_test(self): """ should install from a dir in current dir """ folder = self._create_profile_folder() self.assertTrue(os.path.isdir(folder)) self.client.run('config install "%s"' % folder) self._check("dir, %s, True, None" % folder) def install_source_target_folders_test(self): folder = temp_folder() save_files(folder, {"subf/file.txt": "hello", "subf/subf/file2.txt": "bye"}) self.client.run('config install "%s" -sf=subf -tf=newsubf' % folder) content = load(os.path.join(self.client.cache_folder, "newsubf/file.txt")) self.assertEqual(content, "hello") content = load(os.path.join(self.client.cache_folder, "newsubf/subf/file2.txt")) self.assertEqual(content, "bye") def install_multiple_configs_test(self): folder = temp_folder() save_files(folder, {"subf/file.txt": "hello", "subf2/file2.txt": "bye"}) self.client.run('config install "%s" -sf=subf' % folder) content = load(os.path.join(self.client.cache_folder, "file.txt")) file2 = os.path.join(self.client.cache_folder, "file2.txt") self.assertEqual(content, "hello") self.assertFalse(os.path.exists(file2)) self.client.run('config install "%s" -sf=subf2' % folder) content = load(file2) self.assertEqual(content, "bye") save_files(folder, {"subf/file.txt": "HELLO!!", "subf2/file2.txt": "BYE!!"}) self.client.run('config install') content = load(os.path.join(self.client.cache_folder, "file.txt")) self.assertEqual(content, "HELLO!!") content = load(file2) self.assertEqual(content, "BYE!!") def test_dont_duplicate_configs(self): folder = temp_folder() save_files(folder, {"subf/file.txt": "hello"}) self.client.run('config install "%s" -sf=subf' % folder) self.client.run('config install "%s" -sf=subf' % folder) content = load(self.client.cache.config_install_file) self.assertEqual(1, content.count("subf")) self.client.run('config install "%s" -sf=other' % folder) content = load(self.client.cache.config_install_file) self.assertEqual(1, content.count("subf")) self.assertEqual(1, content.count("other")) def test_install_registry_txt_error(self): folder = temp_folder() save_files(folder, {"registry.txt": "myrepo1 https://myrepourl.net False"}) self.client.run('config install "%s"' % folder) self.assertIn("WARN: registry.txt has been deprecated. Migrating to remotes.json", self.client.out) self.client.run("remote list") self.assertEqual("myrepo1: https://myrepourl.net [Verify SSL: False]\n", self.client.out) def test_install_registry_json_error(self): folder = temp_folder() registry_json = {"remotes": [{"url": "https://server.conan.io", "verify_ssl": True, "name": "conan.io" }]} save_files(folder, {"registry.json": json.dumps(registry_json)}) self.client.run('config install "%s"' % folder) self.assertIn("WARN: registry.json has been deprecated. Migrating to remotes.json", self.client.out) self.client.run("remote list") self.assertEqual("conan.io: https://server.conan.io [Verify SSL: True]\n", self.client.out) def test_install_remotes_json_error(self): folder = temp_folder() save_files(folder, {"remotes.json": ""}) self.client.run('config install "%s"' % folder, assert_error=True) self.assertIn("ERROR: remotes.json install is not supported yet. Use 'remotes.txt'", self.client.out) def test_without_profile_folder(self): shutil.rmtree(self.client.cache.profiles_path) zippath = self._create_zip() self.client.run('config install "%s"' % zippath) self.assertEqual(sorted(os.listdir(self.client.cache.profiles_path)), sorted(["linux", "windows"])) self.assertEqual(load(os.path.join(self.client.cache.profiles_path, "linux")).splitlines(), linux_profile.splitlines()) def install_url_test(self): """ should install from a URL """ def my_download(obj, url, filename, **kwargs): # @UnusedVariable self._create_zip(filename) with patch.object(FileDownloader, 'download', new=my_download): self.client.run("config install http://myfakeurl.com/myconf.zip") self._check("url, http://myfakeurl.com/myconf.zip, True, None") # repeat the process to check self.client.run("config install http://myfakeurl.com/myconf.zip") self._check("url, http://myfakeurl.com/myconf.zip, True, None") def install_change_only_verify_ssl_test(self): def my_download(obj, url, filename, **kwargs): # @UnusedVariable self._create_zip(filename) with patch.object(FileDownloader, 'download', new=my_download): self.client.run("config install http://myfakeurl.com/myconf.zip") self._check("url, http://myfakeurl.com/myconf.zip, True, None") # repeat the process to check self.client.run("config install http://myfakeurl.com/myconf.zip --verify-ssl=False") self._check("url, http://myfakeurl.com/myconf.zip, False, None") def failed_install_repo_test(self): """ should install from a git repo """ self.client.run('config install notexistingrepo.git', assert_error=True) self.assertIn("ERROR: Can't clone repo", self.client.out) def failed_install_http_test(self): """ should install from a http zip """ self.client.run("config set general.retry_wait=0") self.client.run('config install httpnonexisting', assert_error=True) self.assertIn("ERROR: Error while installing config from httpnonexisting", self.client.out) def install_repo_test(self): """ should install from a git repo """ folder = self._create_profile_folder() with self.client.chdir(folder): self.client.run_command('git init .') self.client.run_command('git add .') self.client.run_command('git config user.name myname') self.client.run_command('git config user.email [email protected]') self.client.run_command('git commit -m "mymsg"') self.client.run('config install "%s/.git"' % folder) check_path = os.path.join(folder, ".git") self._check("git, %s, True, None" % check_path) def install_repo_relative_test(self): relative_folder = "./config" absolute_folder = os.path.join(self.client.current_folder, "config") mkdir(absolute_folder) folder = self._create_profile_folder(absolute_folder) with self.client.chdir(folder): self.client.run_command('git init .') self.client.run_command('git add .') self.client.run_command('git config user.name myname') self.client.run_command('git config user.email [email protected]') self.client.run_command('git commit -m "mymsg"') self.client.run('config install "%s/.git"' % relative_folder) self._check("git, %s, True, None" % os.path.join("%s" % folder, ".git")) def install_custom_args_test(self): """ should install from a git repo """ folder = self._create_profile_folder() with self.client.chdir(folder): self.client.run_command('git init .') self.client.run_command('git add .') self.client.run_command('git config user.name myname') self.client.run_command('git config user.email [email protected]') self.client.run_command('git commit -m "mymsg"') self.client.run('config install "%s/.git" --args="-c init.templateDir=value"' % folder) check_path = os.path.join(folder, ".git") self._check("git, %s, True, -c init.templateDir=value" % check_path) def force_git_type_test(self): client = TestClient() client.run('config install httpnonexisting --type=git', assert_error=True) self.assertIn("Can't clone repo", client.out) def reinstall_error_test(self): """ should use configured URL in conan.conf """ self.client.run("config install", assert_error=True) self.assertIn("Called config install without arguments", self.client.out) def removed_credentials_from_url_unit_test(self): """ Unit tests to remove credentials in netloc from url when using basic auth # https://github.com/conan-io/conan/issues/2324 """ url_without_credentials = r"https://server.com/resource.zip" url_with_credentials = r"https://*****:*****@server.com/resource.zip" url_hidden_password = r"https://*****:*****@server.com/resource.zip" # Check url is the same when not using credentials self.assertEqual(_hide_password(url_without_credentials), url_without_credentials) # Check password is hidden using url with credentials self.assertEqual(_hide_password(url_with_credentials), url_hidden_password) # Check that it works with other protocols ftp ftp_with_credentials = r"ftp://*****:*****@server.com/resurce.zip" ftp_hidden_password = r"ftp://*****:*****@server.com/resurce.zip" self.assertEqual(_hide_password(ftp_with_credentials), ftp_hidden_password) # Check function also works for file paths *unix/windows unix_file_path = r"/tmp/test" self.assertEqual(_hide_password(unix_file_path), unix_file_path) windows_file_path = r"c:\windows\test" self.assertEqual(_hide_password(windows_file_path), windows_file_path) # Check works with empty string self.assertEqual(_hide_password(''), '') def remove_credentials_config_installer_test(self): """ Functional test to check credentials are not displayed in output but are still present in conan configuration # https://github.com/conan-io/conan/issues/2324 """ fake_url_with_credentials = "http://*****:*****@myfakeurl.com/myconf.zip" fake_url_hidden_password = "******" def my_download(obj, url, filename, **kwargs): # @UnusedVariable self.assertEqual(url, fake_url_with_credentials) self._create_zip(filename) with patch.object(FileDownloader, 'download', new=my_download): self.client.run("config install %s" % fake_url_with_credentials) # Check credentials are not displayed in output self.assertNotIn(fake_url_with_credentials, self.client.out) self.assertIn(fake_url_hidden_password, self.client.out) # Check credentials still stored in configuration self._check("url, %s, True, None" % fake_url_with_credentials) def ssl_verify_test(self): fake_url = "https://fakeurl.com/myconf.zip" def download_verify_false(obj, url, filename, **kwargs): # @UnusedVariable self.assertFalse(obj.verify) self._create_zip(filename) def download_verify_true(obj, url, filename, **kwargs): # @UnusedVariable self.assertTrue(obj.verify) self._create_zip(filename) with patch.object(FileDownloader, 'download', new=download_verify_false): self.client.run("config install %s --verify-ssl=False" % fake_url) with patch.object(FileDownloader, 'download', new=download_verify_true): self.client.run("config install %s --verify-ssl=True" % fake_url) def test_git_checkout_is_possible(self): folder = self._create_profile_folder() with self.client.chdir(folder): self.client.run_command('git init .') self.client.run_command('git add .') self.client.run_command('git config user.name myname') self.client.run_command('git config user.email [email protected]') self.client.run_command('git commit -m "mymsg"') self.client.run_command('git checkout -b other_branch') save(os.path.join(folder, "hooks", "cust", "cust.py"), "") self.client.run_command('git add .') self.client.run_command('git commit -m "my file"') self.client.run_command('git tag 0.0.1') self.client.run_command('git checkout master') # Without checkout self.client.run('config install "%s/.git"' % folder) check_path = os.path.join(folder, ".git") self._check("git, %s, True, None" % check_path) file_path = os.path.join(self.client.cache.hooks_path, "cust", "cust.py") self.assertFalse(os.path.exists(file_path)) # With checkout tag and reuse url self.client.run('config install --args="-b 0.0.1"') check_path = os.path.join(folder, ".git") self._check("git, %s, True, -b 0.0.1" % check_path) self.assertTrue(os.path.exists(file_path)) # With checkout branch and reuse url self.client.run('config install --args="-b other_branch"') check_path = os.path.join(folder, ".git") self._check("git, %s, True, -b other_branch" % check_path) self.assertTrue(os.path.exists(file_path)) # Add changes to that branch and update with self.client.chdir(folder): self.client.run_command('git checkout other_branch') save(os.path.join(folder, "hooks", "other", "other.py"), "") self.client.run_command('git add .') self.client.run_command('git commit -m "my other file"') self.client.run_command('git checkout master') other_path = os.path.join(self.client.cache_folder, "hooks", "other", "other.py") self.assertFalse(os.path.exists(other_path)) self.client.run('config install') check_path = os.path.join(folder, ".git") self._check("git, %s, True, -b other_branch" % check_path) self.assertTrue(os.path.exists(other_path)) def test_config_install_requester(self): # https://github.com/conan-io/conan/issues/4169 http_server = StoppableThreadBottle() path = self._create_zip() from bottle import static_file @http_server.server.get("/myconfig.zip") def get_zip(): return static_file(os.path.basename(path), os.path.dirname(path)) http_server.run_server() self.client.run("config install http://localhost:%s/myconfig.zip" % http_server.port) self.assertIn("Unzipping", self.client.out) http_server.stop()
def build_different_folders_test(self): conanfile = """ import os from conans import ConanFile class AConan(ConanFile): generators = "cmake" def build(self): self.output.warn("Build folder=>%s" % self.build_folder) self.output.warn("Src folder=>%s" % self.source_folder) self.output.warn("Package folder=>%s" % self.package_folder) assert(os.path.exists(self.build_folder)) assert(os.path.exists(self.source_folder)) # package_folder will be created manually or by the CMake helper when local invocation assert(not os.path.exists(self.package_folder)) """ client = TestClient() client.save({CONANFILE: conanfile}) with client.chdir("build1"): client.run("install ..") # Try relative to cwd client.run("build . --build-folder build2 --install-folder build1 " "--package-folder build1/pkg") self.assertIn("Build folder=>%s" % os.path.join(client.current_folder, "build2"), client.out) self.assertIn("Package folder=>%s" % os.path.join(client.current_folder, "build1", "pkg"), client.out) self.assertIn("Src folder=>%s" % client.current_folder, client.out) # Try default package folder client.run("build conanfile.py --build-folder build1 --package-folder package1") self.assertIn("Build folder=>%s" % os.path.join(client.current_folder, "build1"), client.out) self.assertIn("Package folder=>%s" % os.path.join(client.current_folder, "package"), client.out) self.assertIn("Src folder=>%s" % client.current_folder, client.out) # Try absolute package folder client.run("build . --build-folder build1 --package-folder '%s'" % os.path.join(client.current_folder, "mypackage")) self.assertIn("Build folder=>%s" % os.path.join(client.current_folder, "build1"), client.out) self.assertIn("Package folder=>%s" % os.path.join(client.current_folder, "mypackage"), client.out) self.assertIn("Src folder=>%s" % client.current_folder, client.out) # Try absolute build and relative package conanfile_dir = client.current_folder bdir = os.path.join(client.current_folder, "other/mybuild") with client.chdir(bdir): client.run("install '%s'" % conanfile_dir) client.run("build ./conanfile.py --build-folder '%s' --package-folder relpackage" % bdir) self.assertIn("Build folder=>%s" % os.path.join(client.current_folder, "other/mybuild"), client.out) self.assertIn("Package folder=>%s" % os.path.join(client.current_folder, "relpackage"), client.out) self.assertIn("Src folder=>%s" % client.current_folder, client.out) # Try different source with client.chdir("other/build"): client.run("install ../..") error = client.run("build . --source-folder '%s' --build-folder other/build" % os.path.join(client.current_folder, "mysrc"), ignore_error=True) self.assertTrue(error) # src is not created automatically, it makes no sense mkdir(os.path.join(client.current_folder, "mysrc")) client.run("build . --source-folder '%s' --build-folder other/build" % os.path.join(client.current_folder, "mysrc")) self.assertIn("Build folder=>%s" % os.path.join(client.current_folder, "other", "build"), client.out) self.assertIn("Package folder=>%s" % os.path.join(client.current_folder, "other", "build"), client.out) self.assertIn("Src folder=>%s" % os.path.join(client.current_folder, "mysrc"), client.out)