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
Example #2
0
    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!!")
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
    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)
Example #6
0
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)
Example #7
0
    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)
Example #8
0
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)
Example #9
0
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)
Example #10
0
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)
Example #11
0
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)
Example #12
0
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
Example #13
0
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!"
Example #14
0
    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"))
Example #15
0
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
Example #16
0
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
Example #17
0
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
Example #18
0
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)
Example #19
0
    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)
Example #20
0
    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)
Example #21
0
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"))
Example #23
0
    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:])
Example #24
0
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()
Example #25
0
    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)