def create_package(conanfile, build_folder, package_folder, output): """ copies built artifacts, libs, headers, data, etc from build_folder to package folder """ mkdir(package_folder) # Make the copy of all the patterns output.info("Copying files to %s" % (package_folder)) conanfile.copy = FileCopier(build_folder, package_folder) def wrap(dst_folder): def new_method(pattern, src=""): conanfile.copy(pattern, dst_folder, src) return new_method conanfile.copy_headers = wrap(DEFAULT_INCLUDE) conanfile.copy_libs = wrap(DEFAULT_LIB) conanfile.copy_bins = wrap(DEFAULT_BIN) conanfile.copy_res = wrap(DEFAULT_RES) try: conanfile.package() conanfile.copy.execute() except Exception as e: os.chdir(build_folder) try: rmdir(package_folder) except Exception as e_rm: output.error("Unable to remove package folder %s\n%s" % (package_folder, str(e_rm))) output.warn("**** Please delete it manually ****") raise ConanException("%s: %s" % (conanfile.name, str(e))) _create_aux_files(build_folder, package_folder) output.success("Created '%s' package." % os.path.basename(package_folder))
def source_local_command_test(self): c1 = conanfile % {"no_copy_source": False, "source_with_infos": False, "local_command": True} self.client.save({"conanfile.py": c1}, clean_first=True) self.client.run("source .") c1 = conanfile % {"no_copy_source": True, "source_with_infos": False, "local_command": True} self.client.save({"conanfile.py": c1}, clean_first=True) self.client.run("source .") c1 = conanfile % {"no_copy_source": False, "source_with_infos": True, "local_command": True} self.client.save({"conanfile.py": c1}, clean_first=True) error = self.client.run("source .", ignore_error=True) self.assertTrue(error) self.assertIn("self.deps_user_info not defined. If you need it for a " "local command run 'conan install'", self.client.out) # Now use infos to get the deps_cpp_info self.client.run("install . --build missing") self.client.run("source .") # Default folder, not needed to specify --install-folder # Install in different location c1 = conanfile % {"no_copy_source": False, "source_with_infos": True, "local_command": True} self.client.save({"conanfile.py": c1}, clean_first=True) old_dir = self.client.current_folder build_dir = os.path.join(self.client.current_folder, "build1") mkdir(build_dir) self.client.current_folder = build_dir self.client.run("install .. ") self.client.current_folder = old_dir self.client.run("source . --install-folder=build1")
def child_build_test(self): client = TestClient() build_folder = os.path.join(client.current_folder, "build") mkdir(build_folder) package_folder = os.path.join(build_folder, "package") mkdir(package_folder) client.save({"conanfile.py": conanfile, "file.h": "file_h_contents!"}) client.current_folder = build_folder client.run("install ..") client.run("build ..") client.current_folder = package_folder client.run("package ../.. --build-folder=../") self._assert_pkg(package_folder) rmdir(package_folder) # IMPORTANT: Symptom that package + package_folder is not fitting # well now. (To discuss) # But I think now you choose you way to develop, local or cache, if you use conan export-pkg # you are done, if you use package() you need the "conan project" feature client.current_folder = build_folder client.run("export-pkg .. Pkg/0.1@lasote/testing --source-folder=.. ") ref = ConanFileReference.loads("Pkg/0.1@lasote/testing") cache_package_folder = client.client_cache.packages(ref) cache_package_folder = os.path.join(cache_package_folder, os.listdir(cache_package_folder)[0]) self._assert_pkg(cache_package_folder)
def local_flow_test(self): """Use 'conan package' to process locally the package method""" client = TestClient() conanfile_template = """ from conans import ConanFile class MyConan(ConanFile): def package(self): self.copy(pattern="*.h", dst="include", src="include") """ files = {"include/file.h": "foo", CONANFILE: conanfile_template} client.save(files) origin_folder = client.current_folder client.run("install -g env -g txt") client.run("source") client.run("build") client.run("package .", ignore_error=True) self.assertIn("ERROR: Cannot 'conan package' to the build folder", client.user_io.out) package_folder = os.path.join(origin_folder, "package") mkdir(package_folder) client.current_folder = package_folder client.run('package ..') content = load(os.path.join(client.current_folder, "include/file.h")) self.assertEqual(content, "foo")
def read_profile(profile_name, cwd, default_folder): """ Will look for "profile_name" in disk if profile_name is absolute path, in current folder if path is relative or in the default folder otherwise. return: a Profile object """ if not profile_name: return None, None if os.path.isabs(profile_name): profile_path = profile_name folder = os.path.dirname(profile_name) elif cwd and os.path.exists(os.path.join(cwd, profile_name)): # relative path name profile_path = os.path.abspath(os.path.join(cwd, profile_name)) folder = os.path.dirname(profile_path) else: if not os.path.exists(default_folder): mkdir(default_folder) profile_path = os.path.join(default_folder, profile_name) folder = default_folder try: text = load(profile_path) except IOError: if os.path.exists(folder): profiles = [name for name in os.listdir(folder) if not os.path.isdir(name)] else: profiles = [] current_profiles = ", ".join(profiles) or "[]" raise ConanException("Specified profile '%s' doesn't exist.\nExisting profiles: " "%s" % (profile_name, current_profiles)) try: return _load_profile(text, profile_path, default_folder) except ConanException as exc: raise ConanException("Error reading '%s' profile: %s" % (profile_name, exc))
def get_recipe_sources(self, conan_reference, export_folder, export_sources_folder, remote): t1 = time.time() def filter_function(urls): file_url = urls.get(EXPORT_SOURCES_TGZ_NAME) if file_url: urls = {EXPORT_SOURCES_TGZ_NAME: file_url} else: return None return urls urls = self._call_remote(remote, "get_recipe_urls", conan_reference) urls = filter_function(urls) if not urls: return conan_reference zipped_files = self._call_remote(remote, "download_files_to_folder", urls, export_folder) duration = time.time() - t1 log_recipe_sources_download(conan_reference, duration, remote, zipped_files) if not zipped_files: mkdir(export_sources_folder) # create the folder even if no source files return unzip_and_get_files(zipped_files, export_sources_folder, EXPORT_SOURCES_TGZ_NAME) c_src_path = os.path.join(export_sources_folder, EXPORT_SOURCES_DIR_OLD) if os.path.exists(c_src_path): merge_directories(c_src_path, export_sources_folder) rmdir(c_src_path) touch_folder(export_sources_folder)
def get_recipe_sources(self, conan_reference, export_folder, remote): t1 = time.time() def filter_function(urls): file_url = urls.get(EXPORT_SOURCES_TGZ_NAME) if file_url: urls = {EXPORT_SOURCES_TGZ_NAME: file_url} else: return None return urls zipped_files = self._call_remote(remote, "get_recipe", conan_reference, export_folder, filter_function) duration = time.time() - t1 log_recipe_sources_download(conan_reference, duration, remote, zipped_files) sources_folder = os.path.join(export_folder, EXPORT_SOURCES_DIR) if not zipped_files: mkdir(sources_folder) # create the folder even if no source files return unzip_and_get_files(zipped_files, export_folder, EXPORT_SOURCES_TGZ_NAME) for dirname, _, filenames in os.walk(sources_folder): for fname in filenames: touch(os.path.join(dirname, fname))
def _process_folder(folder, client_cache, output): for root, dirs, files in os.walk(folder): for f in files: if f == "settings.yml": output.info("Installing settings.yml") settings_path = client_cache.settings_path shutil.copy(os.path.join(root, f), settings_path) elif f == "conan.conf": output.info("Processing conan.conf") conan_conf = client_cache.conan_config _handle_conan_conf(conan_conf, os.path.join(root, f)) elif f == "remotes.txt": output.info("Defining remotes") registry_path = client_cache.registry _handle_remotes(registry_path, os.path.join(root, f), output) else: relpath = os.path.relpath(root, folder) target_folder = os.path.join(client_cache.conan_folder, relpath) mkdir(target_folder) output.info("Copying file %s to %s" % (f, target_folder)) shutil.copy(os.path.join(root, f), target_folder) for d in dirs: if d == "profiles": output.info("Installing profiles") profiles_path = client_cache.profiles_path _handle_profiles(os.path.join(root, d), profiles_path, output) break dirs[:] = [d for d in dirs if d not in ("profiles", ".git")]
def configuration_install(item, client_cache, output, verify_ssl): tmp_folder = os.path.join(client_cache.conan_folder, "tmp_config_install") # necessary for Mac OSX, where the temp folders in /var/ are symlinks to /private/var/ tmp_folder = os.path.realpath(tmp_folder) mkdir(tmp_folder) try: if item is None: try: item = client_cache.conan_config.get_item("general.config_install") except ConanException: raise ConanException("Called config install without arguments and " "'general.config_install' not defined in conan.conf") if item.endswith(".git"): _process_git_repo(item, client_cache, output, tmp_folder, verify_ssl) elif os.path.exists(item): # is a local file _process_zip_file(item, client_cache, output, tmp_folder) elif item.startswith("http"): _process_download(item, client_cache, output, tmp_folder, verify_ssl) else: raise ConanException("I don't know how to process %s" % item) finally: if item: client_cache.conan_config.set_item("general.config_install", item) rmdir(tmp_folder)
def __init__(self, base_path=None, read_permissions=None, write_permissions=None, users=None, base_url=None, plugins=None, server_version=None, min_client_compatible_version=None, server_capabilities=None): plugins = plugins or [] if not base_path: base_path = temp_folder() if server_capabilities is None: server_capabilities = SERVER_CAPABILITIES # Default enabled if not os.path.exists(base_path): raise Exception("Base path not exist! %s") # Define storage_folder, if not, it will be readed from conf file and pointed to real user home self.storage_folder = os.path.join(base_path, ".conan_server", "data") mkdir(self.storage_folder) server_config = migrate_and_get_server_config(base_path, self.storage_folder) if TestServerLauncher.port == 0: TestServerLauncher.port = server_config.port # Encode and Decode signature for Upload and Download service updown_auth_manager = JWTUpDownAuthManager(server_config.updown_secret, server_config.authorize_timeout) self.file_manager = get_file_manager(server_config, public_url=base_url, updown_auth_manager=updown_auth_manager) self.search_manager = DiskSearchManager(SimplePaths(server_config.disk_storage_path)) # Prepare some test users if not read_permissions: read_permissions = server_config.read_permissions read_permissions.append(("private_library/1.0.0@private_user/testing", "*")) read_permissions.append(("*/*@*/*", "*")) if not write_permissions: write_permissions = server_config.write_permissions if not users: users = dict(server_config.users) users[TESTING_REMOTE_PRIVATE_USER] = TESTING_REMOTE_PRIVATE_PASS authorizer = BasicAuthorizer(read_permissions, write_permissions) authenticator = BasicAuthenticator(users) credentials_manager = JWTCredentialsManager(server_config.jwt_secret, server_config.jwt_expire_time) logger.debug("Storage path: %s" % self.storage_folder) self.port = TestServerLauncher.port self.ra = ConanServer(self.port, credentials_manager, updown_auth_manager, authorizer, authenticator, self.file_manager, self.search_manager, server_version, min_client_compatible_version, server_capabilities) for plugin in plugins: self.ra.api_v1.install(plugin)
def execute_export(conanfile, origin_folder, destination_folder, output, filename=None): def classify_patterns(patterns): patterns = patterns or [] included, excluded = [], [] for p in patterns: if p.startswith("!"): excluded.append(p[1:]) else: included.append(p) return included, excluded included_exports, excluded_exports = classify_patterns(conanfile.exports) included_sources, excluded_sources = classify_patterns(conanfile.exports_sources) try: os.unlink(os.path.join(origin_folder, CONANFILE + 'c')) except: pass copier = FileCopier(origin_folder, destination_folder) for pattern in included_exports: copier(pattern, links=True, excludes=excluded_exports) # create directory for sources, and import them export_sources_dir = os.path.join(destination_folder, EXPORT_SOURCES_DIR) mkdir(export_sources_dir) copier = FileCopier(origin_folder, export_sources_dir) for pattern in included_sources: copier(pattern, links=True, excludes=excluded_sources) package_output = ScopedOutput("%s export" % output.scope, output) copier.report(package_output) shutil.copy2(os.path.join(origin_folder, filename or CONANFILE), os.path.join(destination_folder, CONANFILE))
def child_build_test(self): client = TestClient() repo_folder = client.current_folder build_folder = os.path.join(client.current_folder, "build") mkdir(build_folder) package_folder = os.path.join(build_folder, "package") mkdir(package_folder) client.save({"conanfile.py": conanfile_out}) client.current_folder = build_folder client.run("install ..") client.run("source ..") client.run("build .. --source-folder=.") client.current_folder = package_folder client.run("package ../.. --build-folder=../") self._assert_pkg(package_folder) rmdir(package_folder) client.current_folder = repo_folder client.run("export-pkg . Pkg/0.1@lasote/testing -bf=./build") ref = ConanFileReference.loads("Pkg/0.1@lasote/testing") cache_package_folder = client.client_cache.packages(ref) cache_package_folder = os.path.join(cache_package_folder, os.listdir(cache_package_folder)[0]) self._assert_pkg(cache_package_folder)
def test_paths(self): """Unit test of path_exists""" tmp_dir = temp_folder() new_path = os.path.join(tmp_dir, "CapsDir") mkdir(new_path) self.assertTrue(path_exists(new_path, tmp_dir)) self.assertFalse(path_exists(os.path.join(tmp_dir, "capsdir"), tmp_dir))
def local_package_build_test(self): """Use 'conan package' to process locally the package method""" client = TestClient() conanfile_template = """ from conans import ConanFile class MyConan(ConanFile): def package(self): self.copy(pattern="*.h", dst="include", src="include") """ files = {"include/file.h": "foo", CONANFILE: conanfile_template} client.save(files) origin_folder = client.current_folder build_folder = os.path.join(client.current_folder, "build") mkdir(build_folder) client.current_folder = build_folder client.run("install .. -g env -g txt") client.run("source ..") client.run("build ..") client.current_folder = temp_folder() client.run('package "%s/build"' % origin_folder) content = load(os.path.join(client.current_folder, "include/file.h")) self.assertEqual(content, "foo")
def install_with_profile_test(self): # Test for https://github.com/conan-io/conan/pull/2043 conanfile = """from conans import ConanFile class TestConan(ConanFile): settings = "os" def requirements(self): self.output.info("PKGOS=%s" % self.settings.os) """ client = TestClient() client.save({"conanfile.py": conanfile}) client.run("profile new myprofile") client.run("profile update settings.os=Linux myprofile") client.run("install . -pr=myprofile --build") self.assertIn("PKGOS=Linux", client.out) mkdir(os.path.join(client.current_folder, "myprofile")) client.run("install . -pr=myprofile") client.run("profile new myotherprofile") client.run("profile update settings.os=FreeBSD myotherprofile") client.run("install . -pr=myotherprofile") self.assertIn("PKGOS=FreeBSD", client.out) client.save({"myotherprofile": "Some garbage without sense [garbage]"}) client.run("install . -pr=myotherprofile") self.assertIn("PKGOS=FreeBSD", client.out) error = client.run("install . -pr=./myotherprofile", ignore_error=True) self.assertTrue(error) self.assertIn("Error parsing the profile", client.out)
def build(self): options = [] options.append('-DGEOGRAPHICLIB_LIB_TYPE=%s' % self.lib_type()) options.append('-DGEOGRAPHICLIB_PRECISION=%s' % self.options.precision) cmake = CMake(self.settings) files.mkdir('build') self.run('cd build && cmake %s %s ../distrib' % (' '.join(options), cmake.command_line)) self.run('cmake --build build %s' % cmake.build_config)
def install(self, args=None, build_dir=None): if not self._conanfile.should_install: return mkdir(self._conanfile.package_folder) if not self.definitions.get("CMAKE_INSTALL_PREFIX"): raise ConanException("CMAKE_INSTALL_PREFIX not defined for 'cmake.install()'\n" "Make sure 'package_folder' is defined") self.build(args=args, build_dir=build_dir, target="install")
def save(self, files, path=None, clean_first=False): """ helper metod, will store files in the current folder param files: dict{filename: filecontents} """ path = path or self.current_folder if clean_first: shutil.rmtree(self.current_folder, ignore_errors=True) save_files(path, files) if not files: mkdir(self.current_folder)
def chdir(self, newdir): old_dir = self.current_folder if not os.path.isabs(newdir): newdir = os.path.join(old_dir, newdir) mkdir(newdir) self.current_folder = newdir try: yield finally: self.current_folder = old_dir
def prepare_for_package(the_client): the_client.save({"src/header.h": "contents"}, clean_first=True) the_client.run("new lib/1.0 -s") # don't need build method tools.replace_in_file(os.path.join(client.current_folder, "conanfile.py"), "def build", "def skip_build") the_client.run("install . --install-folder build") mkdir(os.path.join(client.current_folder, "build2"))
def setUp(self): self.updown_auth_manager = JWTUpDownAuthManager("secret", timedelta(seconds=1)) self.storage_dir = temp_folder() self.service = FileUploadDownloadService(self.updown_auth_manager, self.storage_dir) self.disk_path = os.path.join(self.storage_dir, "dir", "other") self.relative_file_path = "dir/other/thefile.txt" self.absolute_file_path = os.path.join(self.disk_path, "thefile.txt") mkdir(self.disk_path) self.content = "the content"
def _handle_profiles(source_folder, target_folder, output): mkdir(target_folder) for root, _, files in os.walk(source_folder): relative_path = os.path.relpath(root, source_folder) if relative_path == ".": relative_path = "" for f in files: profile = os.path.join(relative_path, f) output.info(" Installing profile %s" % profile) shutil.copy(os.path.join(root, f), os.path.join(target_folder, profile))
def imports_build_folder_test(self): self.client.save({"conanfile.txt": test1}, clean_first=True) tmp = self.client.current_folder self.client.current_folder = os.path.join(self.client.current_folder, "build") mkdir(self.client.current_folder) self.client.run("install .. --no-imports") self.client.current_folder = tmp self.client.run("imports . --install-folder=build --import-folder=.") files = os.listdir(self.client.current_folder) self.assertIn("file1.txt", files) self.assertIn("file2.txt", files)
def disk_storage_path(self): """If adapter is disk, means the directory for storage""" try: ret = conan_expand_user(self._get_conf_server_string("disk_storage_path")) except ConanException: # If storage_path is not defined, use the current dir # So tests use test folder instead of user/.conan_server ret = os.path.dirname(self.config_filename) ret = os.path.normpath(ret) # Convert to O.S paths mkdir(ret) return ret
def create_package(conanfile, source_folder, build_folder, package_folder, install_folder, output, local=False, copy_info=False): """ copies built artifacts, libs, headers, data, etc. from build_folder to package folder """ mkdir(package_folder) # Make the copy of all the patterns output.info("Generating the package") output.info("Package folder %s" % package_folder) try: package_output = ScopedOutput("%s package()" % output.scope, output) output.highlight("Calling package()") conanfile.package_folder = package_folder conanfile.source_folder = source_folder conanfile.install_folder = install_folder conanfile.build_folder = build_folder def recipe_has(attribute): return attribute in conanfile.__class__.__dict__ if source_folder != build_folder: conanfile.copy = FileCopier(source_folder, package_folder, build_folder) with conanfile_exception_formatter(str(conanfile), "package"): with tools.chdir(source_folder): conanfile.package() copy_done = conanfile.copy.report(package_output) if not copy_done and recipe_has("package"): output.warn("No files copied from source folder!") conanfile.copy = FileCopier(build_folder, package_folder) with tools.chdir(build_folder): with conanfile_exception_formatter(str(conanfile), "package"): conanfile.package() copy_done = conanfile.copy.report(package_output) if not copy_done and recipe_has("build") and recipe_has("package"): output.warn("No files copied from build folder!") except Exception as e: if not local: os.chdir(build_folder) try: rmdir(package_folder) except Exception as e_rm: output.error("Unable to remove package folder %s\n%s" % (package_folder, str(e_rm))) output.warn("**** Please delete it manually ****") if isinstance(e, ConanExceptionInUserConanfileMethod): raise raise ConanException(e) _create_aux_files(install_folder, package_folder, conanfile, copy_info) output.success("Package '%s' created" % os.path.basename(package_folder))
def build(self, conanfile_path, source_folder, build_folder, package_folder, install_folder, test=False, should_configure=True, should_build=True, should_install=True): """ Call to build() method saved on the conanfile.py param conanfile_path: path to a conanfile.py """ logger.debug("Building in %s" % build_folder) logger.debug("Conanfile in %s" % conanfile_path) try: # Append env_vars to execution environment and clear when block code ends output = ScopedOutput(("%s (test package)" % test) if test else "Project", self._user_io.out) conan_file = self._load_consumer_conanfile(conanfile_path, install_folder, output, deps_info_required=True) except NotFoundException: # TODO: Auto generate conanfile from requirements file raise ConanException("'%s' file is needed for build.\n" "Create a '%s' and move manually the " "requirements and generators from '%s' file" % (CONANFILE, CONANFILE, CONANFILE_TXT)) if test: try: conan_file.requires.add(test) except ConanException: pass conan_file.should_configure = should_configure conan_file.should_build = should_build conan_file.should_install = should_install try: mkdir(build_folder) os.chdir(build_folder) conan_file.build_folder = build_folder conan_file.source_folder = source_folder conan_file.package_folder = package_folder conan_file.install_folder = install_folder with get_env_context_manager(conan_file): output.highlight("Running build()") with conanfile_exception_formatter(str(conan_file), "build"): conan_file.build() if test: output.highlight("Running test()") with conanfile_exception_formatter(str(conan_file), "test"): conan_file.test() except ConanException: raise # Raise but not let to reach the Exception except (not print traceback) except Exception: import traceback trace = traceback.format_exc().split('\n') raise ConanException("Unable to build it successfully\n%s" % '\n'.join(trace[3:]))
def build_folder_reading_infos_test(self): conanfile = ''' import os from conans import ConanFile class ConanLib(ConanFile): name = "Hello" version = "0.1" def package_info(self): self.cpp_info.cppflags.append("FLAG") self.env_info.MYVAR = "foo" self.user_info.OTHERVAR = "bar" ''' client = TestClient() client.save({CONANFILE: conanfile}) client.run("export . conan/testing") conanfile = ''' import os from conans import ConanFile from conans.util.files import save class ConanLib(ConanFile): requires="Hello/0.1@conan/testing" def source(self): assert(os.getcwd() == self.source_folder) self.output.info("FLAG=%s" % self.deps_cpp_info["Hello"].cppflags[0]) self.output.info("MYVAR=%s" % self.deps_env_info["Hello"].MYVAR) self.output.info("OTHERVAR=%s" % self.deps_user_info["Hello"].OTHERVAR) self.output.info("CURDIR=%s" % os.getcwd()) ''' # First, failing source() client.save({CONANFILE: conanfile}, clean_first=True) build_folder = os.path.join(client.current_folder, "build") src_folder = os.path.join(client.current_folder, "src") mkdir(build_folder) mkdir(src_folder) client.run("source . --install-folder='%s' --source-folder='%s'" % (build_folder, src_folder), ignore_error=True) self.assertIn("self.deps_cpp_info not defined.", client.out) client.run("install . --install-folder build --build ") client.run("source conanfile.py --install-folder='%s' --source-folder='%s'" % (build_folder, src_folder), ignore_error=True) self.assertIn("FLAG=FLAG", client.out) self.assertIn("MYVAR=foo", client.out) self.assertIn("OTHERVAR=bar", client.out) self.assertIn("CURDIR=%s" % src_folder, client.out)
def basic_test(self, no_copy_source, cmake_install): client = TestClient() if not cmake_install: package_code = """ def package(self): self.copy("*.h", src="src", dst="include") """ else: package_code = "cmake.install()" conanfile = """from conans import ConanFile, CMake, load import os class Conan(ConanFile): settings = "os", "compiler", "arch", "build_type" exports_sources = "src/*" no_copy_source = {} def build(self): cmake = CMake(self) cmake.configure(source_folder="src", cache_build_folder="build") cmake.build() {} def package_info(self): self.output.info("HEADER %s" % load(os.path.join(self.package_folder, "include/header.h"))) """.format(no_copy_source, package_code) cmake = """set(CMAKE_CXX_COMPILER_WORKS 1) project(Chat NONE) cmake_minimum_required(VERSION 2.8.12) file(READ header.h MYCONTENTS) message(STATUS "HEADER CMAKE CONTENTS ${MYCONTENTS}") install(FILES header.h DESTINATION include) """ client.save({"conanfile.py": conanfile, "src/CMakeLists.txt": cmake, "src/header.h": "//myheader.h"}) client.run("create . Hello/0.1@lasote/channel") self.assertIn("Hello/0.1@lasote/channel: HEADER //myheader.h", client.out) self.assertIn("-- HEADER CMAKE CONTENTS //myheader.h", client.out) # Now local flow build_folder = os.path.join(client.current_folder, "build") mkdir(build_folder) client.current_folder = build_folder client.run("install ..") client.run("build ..") # same as --build-folder=. --source-folder=.. self.assertIn("-- HEADER CMAKE CONTENTS //myheader.h", client.out) if not cmake_install: client.run("package ..") # same as --build-folder=. --source-folder=.. self.assertTrue(os.path.exists(os.path.join(build_folder, "conaninfo.txt"))) self.assertTrue(os.path.exists(os.path.join(build_folder, "conanbuildinfo.txt"))) self.assertEqual(load(os.path.join(build_folder, "package/include/header.h")), "//myheader.h")
def parallel_folders_test(self): client = TestClient() repo_folder = os.path.join(client.current_folder, "recipe") src_folder = os.path.join(client.current_folder, "src") build_folder = os.path.join(client.current_folder, "build") package_folder = os.path.join(build_folder, "package") mkdir(repo_folder) mkdir(src_folder) mkdir(build_folder) mkdir(package_folder) client.current_folder = repo_folder # equivalent to git clone recipe client.save({"conanfile.py": conanfile_out}) client.current_folder = build_folder client.run("install ../recipe") client.current_folder = src_folder client.run("install ../recipe") client.run("source ../recipe") client.current_folder = build_folder client.run("build ../recipe --source-folder=../src") client.current_folder = package_folder client.run("package ../../recipe --source-folder=../../src --build-folder=../") self._assert_pkg(package_folder) client.current_folder = repo_folder client.run("export . lasote/testing") client.run("export-pkg . Pkg/0.1@lasote/testing -bf=../build/package") ref = ConanFileReference.loads("Pkg/0.1@lasote/testing") cache_package_folder = client.client_cache.packages(ref) cache_package_folder = os.path.join(cache_package_folder, os.listdir(cache_package_folder)[0]) self._assert_pkg(cache_package_folder)
def disk_storage_path(self): """If adapter is disk, means the directory for storage""" if self.env_config["disk_storage_path"]: ret = self.env_config["disk_storage_path"] else: try: ret = os.path.expanduser(self._get_file_conf("server", "disk_storage_path")) except ConanException: # If storage_path is not defined in file, use the current dir # So tests use test folder instead of user/.conan_server ret = os.path.dirname(self.config_filename) ret = os.path.normpath(ret) # Convert to O.S paths mkdir(ret) return ret
def testNotAllowedEncodingPassword(self): tmp_dir = temp_folder() server_conf = """ [server] jwt_secret: 534534534 jwt_expire_minutes: 120 ssl_enabled: False port: 9300 public_port: host_name: localhost store_adapter: disk authorize_timeout: 1800 disk_storage_path: ~/.conan_server/data disk_authorize_timeout: 1800 updown_secret: tbsiGzeEygYSCcNrSYcuzmZr [write_permissions] [users] demo: %s """ server_dir = os.path.join(tmp_dir, ".conan_server") mkdir(server_dir) conf_path = os.path.join(server_dir, "server.conf") save(conf_path, server_conf % "cönan") server_config = ConanServerConfigParser(tmp_dir) with self.assertRaisesRegexp(ConanException, "Password contains invalid characters. Only ASCII encoding is supported"): server_config.users save(conf_path, server_conf % "manol ito!@") server_config = ConanServerConfigParser(tmp_dir) self.assertEquals(server_config.users, {"demo": "manol ito!@"}) # Now test from ENV server_config = ConanServerConfigParser(tmp_dir, environment={"CONAN_SERVER_USERS": "demo: cönan"}) with self.assertRaisesRegexp(ConanException, "Password contains invalid characters. Only ASCII encoding is supported"): server_config.users server_config = ConanServerConfigParser(tmp_dir, environment={"CONAN_SERVER_USERS": "demo:manolito!@"}) self.assertEquals(server_config.users, {"demo": "manolito!@"})
def config_source(export_folder, export_source_folder, src_folder, conanfile, output, conanfile_path, reference, hook_manager, cache): """ Implements the sources configuration when a package is going to be built in the local cache. """ def remove_source(raise_error=True): output.warn("This can take a while for big packages") try: rmdir(src_folder) except BaseException as e_rm: set_dirty(src_folder) msg = str(e_rm) if six.PY2: msg = str(e_rm).decode( "latin1") # Windows prints some chars in latin1 output.error("Unable to remove source folder %s\n%s" % (src_folder, msg)) output.warn("**** Please delete it manually ****") if raise_error or isinstance(e_rm, KeyboardInterrupt): raise ConanException("Unable to remove source folder") sources_pointer = cache.package_layout(reference).scm_folder() local_sources_path = load(sources_pointer) if os.path.exists( sources_pointer) else None if is_dirty(src_folder): output.warn("Trying to remove corrupted source folder") remove_source() elif conanfile.build_policy_always: output.warn( "Detected build_policy 'always', trying to remove source folder") remove_source() elif local_sources_path and os.path.exists(local_sources_path): output.warn( "Detected 'scm' auto in conanfile, trying to remove source folder") remove_source() if not os.path.exists(src_folder): # No source folder, need to get it set_dirty(src_folder) mkdir(src_folder) _run_source(conanfile, conanfile_path, src_folder, hook_manager, reference, cache, export_folder, export_source_folder, local_sources_path) clean_dirty(src_folder) # Everything went well, remove DIRTY flag
def run_package_method(conanfile, package_id, hook_manager, conanfile_path, ref, copy_info=False): """ calls the recipe "package()" method - Assigns folders to conanfile.package_folder, source_folder, install_folder, build_folder - Calls pre-post package hook - Prepares FileCopier helper for self.copy """ if conanfile.package_folder == conanfile.build_folder: raise ConanException("Cannot 'conan package' to the build folder. " "--build-folder and package folder can't be the same") mkdir(conanfile.package_folder) output = conanfile.output # Make the copy of all the patterns output.info("Generating the package") output.info("Package folder %s" % conanfile.package_folder) with get_env_context_manager(conanfile): return _call_package(conanfile, package_id, hook_manager, conanfile_path, ref, copy_info)
def setUp(self): self.client = self._get_client() conan_digest = FileTreeManifest('123123123', {}) self.conan_ref = ConanFileReference.loads("Hello/1.2.1@frodo/stable") reg_folder = self.client.paths.export(self.conan_ref) self.client.run('upload %s' % str(self.conan_ref), ignore_error=True) self.assertIn("There is no local conanfile exported as %s" % str(self.conan_ref), self.client.user_io.out) files = hello_source_files() self.client.save(files, path=reg_folder) self.client.save({CONANFILE: myconan1, "include/math/lib1.h": "//copy", "my_lib/debug/libd.a": "//copy", "my_data/readme.txt": "//copy", "my_bin/executable": "//copy"}, path=reg_folder) conan_digest.save(reg_folder) mkdir(self.client.client_cache.export_sources(self.conan_ref)) self.package_ref = PackageReference(self.conan_ref, "myfakeid") self.server_pack_folder = self.test_server.paths.package(self.package_ref) package_folder = self.client.paths.package(self.package_ref) save(os.path.join(package_folder, "include", "lib1.h"), "//header") save(os.path.join(package_folder, "lib", "my_lib", "libd.a"), "//lib") save(os.path.join(package_folder, "res", "shares", "readme.txt"), "//res") save(os.path.join(package_folder, "bin", "my_bin", "executable"), "//bin") save(os.path.join(package_folder, CONANINFO), "info") save(os.path.join(package_folder, CONAN_MANIFEST), "manifest") os.chmod(os.path.join(package_folder, "bin", "my_bin", "executable"), os.stat(os.path.join(package_folder, "bin", "my_bin", "executable")).st_mode | stat.S_IRWXU) package_path = self.client.client_cache.package(self.package_ref) expected_manifest = FileTreeManifest.create(package_path) expected_manifest.save(package_folder) self.server_reg_folder = self.test_server.paths.export(self.conan_ref) self.assertFalse(os.path.exists(self.server_reg_folder)) self.assertFalse(os.path.exists(self.server_pack_folder))
def build(self): files.mkdir(self.build_dir) with tools.chdir(self.build_dir): cmake = CMake(self) cmake.definitions["BUILD_SHARED_LIBS"] = "OFF" cmake.definitions["BUILD_STATIC_LIBS"] = "ON" cmake.definitions["QTCOLORWIDGETS_DESIGNER_PLUGIN"] = "OFF" cmake.definitions["CMAKE_INSTALL_PREFIX"] = "" if tools.os_info.is_macos: cmake.definitions["CMAKE_MACOSX_RPATH"] = "ON" cmake.definitions["CMAKE_PREFIX_PATH"] = "/usr/local/opt/qt" cmake.definitions[ "CMAKE_SHARED_LINKER_FLAGS"] = "-headerpad_max_install_names" # cmake.configure(source_dir="..", build_dir=".") self.run("cmake --debug-output %s %s" % ("..", cmake.command_line)) cmake.build(build_dir=".") os.system("make install DESTDIR=./install")
def _run_source(conanfile, conanfile_path, hook_manager, reference, cache, get_sources_from_exports): """Execute the source core functionality, both for local cache and user space, in order: - Calling pre_source hook - Getting sources from SCM - Getting sources from exported folders in the local cache - Clean potential TGZ and other files in the local cache - Executing the recipe source() method - Calling post_source hook """ src_folder = conanfile.source_folder if hasattr(conanfile, "layout") \ else conanfile.folders.base_source mkdir(src_folder) with tools.chdir(src_folder): try: with get_env_context_manager(conanfile): hook_manager.execute("pre_source", conanfile=conanfile, conanfile_path=conanfile_path, reference=reference) output = conanfile.output output.info('Configuring sources in %s' % src_folder) get_sources_from_exports() if cache: # Clear the conanfile.py to avoid errors cloning git repositories. _clean_source_folder(src_folder) with conanfile_exception_formatter(conanfile.display_name, "source"): with conan_v2_property(conanfile, 'settings', "'self.settings' access in source() method is deprecated"): with conan_v2_property(conanfile, 'options', "'self.options' access in source() method is deprecated"): conanfile.source() hook_manager.execute("post_source", conanfile=conanfile, conanfile_path=conanfile_path, reference=reference) except ConanExceptionInUserConanfileMethod: raise except Exception as e: raise ConanException(e)
def _link_folders(src, dst, linked_folders): for linked_folder in linked_folders: link = os.readlink(os.path.join(src, linked_folder)) dst_link = os.path.join(dst, linked_folder) try: # Remove the previous symlink os.remove(dst_link) except OSError: pass # link is a string relative to linked_folder # e.g.: os.symlink("test/bar", "./foo/test_link") will create a link to foo/test/bar in ./foo/test_link mkdir(os.path.dirname(dst_link)) os.symlink(link, dst_link) # Remove empty links for linked_folder in linked_folders: dst_link = os.path.join(dst, linked_folder) abs_path = os.path.realpath(dst_link) if not os.path.exists(abs_path): os.remove(dst_link)
def write_chunks(chunks, path): ret = None downloaded_size = range_start if path: mkdir(os.path.dirname(path)) mode = "ab" if range_start else "wb" with open(path, mode) as file_handler: for chunk in chunks: assert ((six.PY3 and isinstance(chunk, bytes)) or (six.PY2 and isinstance(chunk, str))) file_handler.write(chunk) downloaded_size += len(chunk) else: ret_data = bytearray() for chunk in chunks: ret_data.extend(chunk) downloaded_size += len(chunk) ret = bytes(ret_data) return ret, downloaded_size
def complete_recipe_sources(remote_manager, client_cache, registry, conanfile, conan_reference): sources_folder = client_cache.export_sources(conan_reference, conanfile.short_paths) if os.path.exists(sources_folder): return None if not hasattr(conanfile, "exports_sources"): mkdir(sources_folder) return None # If not path to sources exists, we have a problem, at least an empty folder # should be there current_remote = registry.get_ref(conan_reference) if not current_remote: raise ConanException("Error while trying to get recipe sources for %s. " "No remote defined" % str(conan_reference)) export_path = client_cache.export(conan_reference) remote_manager.get_recipe_sources(conan_reference, export_path, sources_folder, current_remote)
def configure(self, conan_file, args=None, defs=None, source_dir=None, build_dir=None): args = args or [] defs = defs or {} source_dir = source_dir or conan_file.conanfile_directory self.build_dir = build_dir or self.build_dir or conan_file.conanfile_directory mkdir(self.build_dir) arg_list = _join_arguments([ self.command_line, _args_to_string(args), _vars_to_string(defs), _args_to_string([source_dir]) ]) command = "cd %s && cmake %s" % (_args_to_string([self.build_dir]), arg_list) if platform.system() == "Windows" and self.generator == "MinGW Makefiles": with clean_sh_from_path(): conan_file.run(command) else: conan_file.run(command)
def build(self): with tools.chdir(self.src_dir): files.mkdir(self.build_dir) with tools.chdir(self.build_dir): build_dir_path = os.getcwd() if self.settings.os != "Windows": env_build = AutoToolsBuildEnvironment(self) with tools.environment_append(env_build.vars): self.run("./configure --prefix=%s" % build_dir_path) self.run("make") self.run("make install") else: cmake = CMake(self.settings) shared = "-DBUILD_SHARED_LIBS=ON" if self.options.shared else "-DBUILD_SHARED_LIBS=OFF -DNGHTTP2_STATICLIB=1" ext_flag = "-DENABLE_EXAMPLES=0" with tools.chdir(self.build_dir): self.run("cmake .. %s %s %s" % (cmake.command_line, shared, ext_flag)) self.run("cmake --build . %s" % cmake.build_config)
def get_recipe_sources(self, conan_reference, export_folder, export_sources_folder, remote): t1 = time.time() zipped_files = self._call_remote(remote, "get_recipe_sources", conan_reference, export_folder) if not zipped_files: mkdir(export_sources_folder) # create the folder even if no source files return conan_reference duration = time.time() - t1 log_recipe_sources_download(conan_reference, duration, remote.name, zipped_files) unzip_and_get_files(zipped_files, export_sources_folder, EXPORT_SOURCES_TGZ_NAME) c_src_path = os.path.join(export_sources_folder, EXPORT_SOURCES_DIR_OLD) if os.path.exists(c_src_path): merge_directories(c_src_path, export_sources_folder) rmdir(c_src_path) touch_folder(export_sources_folder) return conan_reference
def _process_file(directory, filename, config, cache, output, folder): if filename == "settings.yml": output.info("Installing settings.yml") _filecopy(directory, filename, cache.cache_folder) elif filename == "conan.conf": output.info("Processing conan.conf") _handle_conan_conf(cache.config, os.path.join(directory, filename)) elif filename == "remotes.txt": output.info("Defining remotes from remotes.txt") _handle_remotes(cache, os.path.join(directory, filename)) elif filename in ("registry.txt", "registry.json"): try: os.remove(cache.remotes_path) except OSError: pass finally: _filecopy(directory, filename, cache.cache_folder) migrate_registry_file(cache, output) elif filename == "remotes.json": # Fix for Conan 2.0 raise ConanException( "remotes.json install is not supported yet. Use 'remotes.txt'") else: # This is ugly, should be removed in Conan 2.0 if filename in ("README.md", "LICENSE.txt"): output.info("Skip %s" % filename) else: relpath = os.path.relpath(directory, folder) if config.target_folder: target_folder = os.path.join(cache.cache_folder, config.target_folder, relpath) else: target_folder = os.path.join(cache.cache_folder, relpath) if os.path.exists(target_folder): if os.path.isfile( target_folder ): # Existed as a file and now should be a folder remove(target_folder) mkdir(target_folder) output.info("Copying file %s to %s" % (filename, target_folder)) _filecopy(directory, filename, target_folder)
def _process_folder(config, folder, cache, output): if config.source_folder: folder = os.path.join(folder, config.source_folder) for root, dirs, files in walk(folder): dirs[:] = [d for d in dirs if d != ".git"] if ".git" in root: continue for f in files: if f == "settings.yml": output.info("Installing settings.yml") _filecopy(root, f, cache.cache_folder) elif f == "conan.conf": output.info("Processing conan.conf") _handle_conan_conf(cache.config, os.path.join(root, f)) elif f == "remotes.txt": output.info("Defining remotes from remotes.txt") _handle_remotes(cache, os.path.join(root, f)) elif f in ("registry.txt", "registry.json"): try: os.remove(cache.remotes_path) except OSError: pass finally: _filecopy(root, f, cache.cache_folder) migrate_registry_file(cache, output) elif f == "remotes.json": # Fix for Conan 2.0 raise ConanException("remotes.json install is not supported yet. Use 'remotes.txt'") else: # This is ugly, should be removed in Conan 2.0 if root == folder and f in ("README.md", "LICENSE.txt"): output.info("Skip %s" % f) continue relpath = os.path.relpath(root, folder) if config.target_folder: target_folder = os.path.join(cache.cache_folder, config.target_folder, relpath) else: target_folder = os.path.join(cache.cache_folder, relpath) mkdir(target_folder) output.info("Copying file %s to %s" % (f, target_folder)) _filecopy(root, f, target_folder)
def basic_test(self, no_copy_source): # meson > py 3.4 if sys.version_info[0] < 3 or sys.version_info[1] < 5: return client = TestClient() conanfile = """from conans import ConanFile, Meson, load import os class Conan(ConanFile): settings = "os", "compiler", "arch", "build_type" exports_sources = "src/*" no_copy_source = {} def build(self): meson = Meson(self) meson.configure(source_folder="src", cache_build_folder="build") meson.build() def package(self): self.copy("*.h", src="src", dst="include") def package_info(self): self.output.info("HEADER %s" % load(os.path.join(self.package_folder, "include/header.h"))) """.format(no_copy_source) meson = """project('hello', 'cpp', version : '0.1.0', default_options : ['cpp_std=c++11']) """ client.save({"conanfile.py": conanfile, "src/meson.build": meson, "src/header.h": "//myheader.h"}) client.run("create %s Hello/0.1@lasote/channel" % path_dot()) self.assertIn("Hello/0.1@lasote/channel: HEADER //myheader.h", client.out) # Now local flow build_folder = os.path.join(client.current_folder, "build") mkdir(build_folder) client.current_folder = build_folder client.run("install ..") client.run("build ..") client.run("package ..") self.assertTrue(os.path.exists(os.path.join(build_folder, "conaninfo.txt"))) self.assertTrue(os.path.exists(os.path.join(build_folder, "conanbuildinfo.txt"))) self.assertEqual(load(os.path.join(build_folder, "package/include/header.h")), "//myheader.h")
def prepare_build(self): if self.build_reference != self._package_reference and \ os.path.exists(self.build_folder) and hasattr(self._conan_file, "build_id"): self._skip_build = True return # build_id is not caching the build folder, so actually rebuild the package _handle_system_requirements(self._conan_file, self._package_reference, self._client_cache, self._out) export_folder = self._client_cache.export(self._conan_ref) export_source_folder = self._client_cache.export_sources(self._conan_ref, self._conan_file.short_paths) try: rmdir(self.build_folder) rmdir(self.package_folder) except OSError as e: raise ConanException("%s\n\nCouldn't remove folder, might be busy or open\n" "Close any app using it, and retry" % str(e)) self._out.info('Building your package in %s' % self.build_folder) sources_pointer = self._client_cache.scm_folder(self._conan_ref) local_sources_path = load(sources_pointer) if os.path.exists(sources_pointer) else None config_source(export_folder, export_source_folder, local_sources_path, self.source_folder, self._conan_file, self._out) self._out.info('Copying sources to build folder') if getattr(self._conan_file, 'no_copy_source', False): mkdir(self.build_folder) self._conan_file.source_folder = self.source_folder else: if platform.system() == "Windows" and os.getenv("CONAN_USER_HOME_SHORT") != "None": from conans.util.windows import ignore_long_path_files ignore = ignore_long_path_files(self.source_folder, self.build_folder, self._out) else: ignore = None shutil.copytree(self.source_folder, self.build_folder, symlinks=True, ignore=ignore) logger.debug("Copied to %s", self.build_folder) logger.debug("Files copied %s", os.listdir(self.build_folder)) self._conan_file.source_folder = self.build_folder
def read_file(profile_name, cwd, default_folder): """ Will look for "profile_name" in disk if profile_name is absolute path, in current folder if path is relative or in the default folder otherwise. return: a Profile object """ if not profile_name: return None if os.path.isabs(profile_name): profile_path = profile_name folder = os.path.dirname(profile_name) elif profile_name.startswith("."): # relative path name profile_path = os.path.abspath(os.path.join(cwd, profile_name)) folder = os.path.dirname(profile_path) else: folder = default_folder if not os.path.exists(folder): mkdir(folder) profile_path = os.path.join(folder, profile_name) try: text = load(profile_path) except IOError: if os.path.exists(folder): profiles = [ name for name in os.listdir(folder) if not os.path.isdir(name) ] else: profiles = [] current_profiles = ", ".join(profiles) or "[]" raise ConanException( "Specified profile '%s' doesn't exist.\nExisting profiles: " "%s" % (profile_name, current_profiles)) try: text = text.replace("$PROFILE_DIR", os.path.abspath( folder)) # Allows PYTHONPATH=$PROFILE_DIR/pythontools return Profile.loads(text) except ConanException as exc: raise ConanException("Error reading '%s' profile: %s" % (profile_name, exc))
def test_transitive_editables(self): # https://github.com/conan-io/conan/issues/4445 client = TestClient() conanfileC = TestConanFile("LibC", "0.1") client.save({"conanfile.py": str(conanfileC)}) client.run("editable add . LibC/0.1@user/testing") client2 = TestClient(client.cache_folder) conanfileB = TestConanFile("LibB", "0.1", requires=["LibC/0.1@user/testing"]) client2.save({"conanfile.py": str(conanfileB)}) client2.run("create . user/testing") conanfileA = TestConanFile("LibA", "0.1", requires=["LibB/0.1@user/testing", "LibC/0.1@user/testing"]) client2.save({"conanfile.py": str(conanfileA)}) client2.run("install .") client2.current_folder = os.path.join(client2.current_folder, "build") mkdir(client2.current_folder) client2.run("install ..")
def test_recipe_exists(self): layout = self.cache.package_layout(self.ref) self.assertFalse(layout.recipe_exists()) mkdir(layout.export()) self.assertTrue(layout.recipe_exists()) # But if ref has revision and it doesn't match, it doesn't exist with layout.update_metadata() as metadata: metadata.clear() ref2 = self.ref.copy_with_rev("revision") layout2 = self.cache.package_layout(ref2) self.assertFalse(layout2.recipe_exists()) # Fake the metadata and check again with layout.update_metadata() as metadata: metadata.recipe.revision = "revision" self.assertTrue(layout2.recipe_exists())
def get_recipe_sources(self, ref, export_folder, export_sources_folder, remote): assert ref.revision, "get_recipe_sources requires RREV" t1 = time.time() zipped_files = self._call_remote(remote, "get_recipe_sources", ref, export_folder) if not zipped_files: mkdir(export_sources_folder) # create the folder even if no source files return duration = time.time() - t1 log_recipe_sources_download(ref, duration, remote.name, zipped_files) unzip_and_get_files(zipped_files, export_sources_folder, EXPORT_SOURCES_TGZ_NAME, output=self._output) # REMOVE in Conan 2.0 c_src_path = os.path.join(export_sources_folder, EXPORT_SOURCES_DIR_OLD) if os.path.exists(c_src_path): merge_directories(c_src_path, export_sources_folder) rmdir(c_src_path) touch_folder(export_sources_folder)
def _handle_hooks(src_hooks_path, dst_hooks_path, output): """ Copies files to the hooks folder overwriting the files that are in the same path (shutil.copytree fails on doing this), skips git related files (.git, .gitmodule...) and outputs the copied files :param src_hooks_path: Folder where the hooks come from :param dst_hooks_path: Folder where the hooks should finally go :param output: Output to indicate the files copied """ for root, dirs, files in walk(src_hooks_path): if ".git" in root: continue relpath = os.path.relpath(root, src_hooks_path) for f in files: if ".git" not in f: dst = os.path.join(dst_hooks_path, relpath) mkdir(dst) shutil.copy(os.path.join(root, f), dst) output.info(" - %s" % relpath)
def test_recipe_exists(self): layout = self.cache.package_layout(self.ref) self.assertFalse(layout.recipe_exists()) mkdir(self.cache.export(self.ref)) self.assertTrue(layout.recipe_exists()) # But if ref has revision and it doesn't match, it doesn't exist save(os.path.join(self.cache.conan(self.ref), "metadata.json"), PackageMetadata().dumps()) ref2 = self.ref.copy_with_rev("revision") layout2 = self.cache.package_layout(ref2) self.assertFalse(layout2.recipe_exists()) # Fake the metadata and check again with layout.update_metadata() as metadata: metadata.recipe.revision = "revision" self.assertTrue(layout2.recipe_exists())
def get_recipe_sources(self, ref, layout, remote): assert ref.revision, "get_recipe_sources requires RREV" t1 = time.time() download_folder = layout.download_export() export_sources_folder = layout.export_sources() zipped_files = self._call_remote(remote, "get_recipe_sources", ref, download_folder) if not zipped_files: mkdir(export_sources_folder ) # create the folder even if no source files return duration = time.time() - t1 log_recipe_sources_download(ref, duration, remote.name, zipped_files) tgz_file = zipped_files[EXPORT_SOURCES_TGZ_NAME] check_compressed_files(EXPORT_SOURCES_TGZ_NAME, zipped_files) uncompress_file(tgz_file, export_sources_folder, output=self._output) touch_folder(export_sources_folder)
def install_reference(self, reference, settings=None, options=None, env=None, remote=None, verify=None, manifests=None, manifests_interactive=None, build=None, profile_name=None, update=False, generators=None, install_folder=None, cwd=None): cwd = cwd or os.getcwd() install_folder = _make_abs_path(install_folder, cwd) manifests = _parse_manifests_arguments(verify, manifests, manifests_interactive, cwd) manifest_folder, manifest_interactive, manifest_verify = manifests profile = profile_from_args(profile_name, settings, options, env, cwd, self._client_cache) if not generators: # We don't want the default txt generators = False mkdir(install_folder) self._manager.install(reference=reference, install_folder=install_folder, remote=remote, profile=profile, build_modes=build, update=update, manifest_folder=manifest_folder, manifest_verify=manifest_verify, manifest_interactive=manifest_interactive, generators=generators, install_reference=True)
def path_shortener(path, short_paths): """ short_paths is 4-state: False: Never shorten the path True: Always shorten the path, create link if not existing None: Use shorten path only if already exists, not create """ if short_paths is False or os.getenv("CONAN_USER_HOME_SHORT") == "None": return path link = os.path.join(path, CONAN_LINK) if os.path.exists(link): return load(link) elif short_paths is None: return path if os.path.exists(path): rmdir(path) short_home = os.getenv("CONAN_USER_HOME_SHORT") if not short_home: drive = os.path.splitdrive(path)[0] short_home = os.path.join(drive, os.sep, ".conan") mkdir(short_home) # Workaround for short_home living in NTFS file systems. Give full control permission to current user to avoid # access problems in cygwin/msys2 windows subsystems when using short_home folder try: username = os.getenv("USERDOMAIN") domainname = "%s\%s" % (username, os.environ["USERNAME"]) if username else os.environ["USERNAME"] cmd = r'cacls %s /E /G "%s":F' % (short_home, domainname) subprocess.check_output(cmd, stderr=subprocess.STDOUT) # Ignoring any returned output, make command quiet except subprocess.CalledProcessError: # cmd can fail if trying to set ACL in non NTFS drives, ignoring it. pass redirect = tempfile.mkdtemp(dir=short_home, prefix="") # This "1" is the way to have a non-existing directory, so commands like # shutil.copytree() to it, works. It can be removed without compromising the # temp folder generator and conan-links consistency redirect = os.path.join(redirect, "1") save(link, redirect) return redirect
def build(self): with tools.chdir(os.path.join(self.source_folder, self.ZIP_FOLDER_NAME)): for filename in ['zconf.h', 'zconf.h.cmakein', 'zconf.h.in']: tools.replace_in_file(filename, '#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */', '#if defined(HAVE_UNISTD_H) && (1-HAVE_UNISTD_H-1 != 0)') tools.replace_in_file(filename, '#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */', '#if defined(HAVE_STDARG_H) && (1-HAVE_STDARG_H-1 != 0)') files.mkdir("_build") with tools.chdir("_build"): if not tools.os_info.is_windows: env_build = AutoToolsBuildEnvironment(self) if self.settings.arch in ["x86", "x86_64"] and self.settings.compiler in ["apple-clang", "clang", "gcc"]: env_build.flags.append('-mstackrealign') env_build.fpic = True if self.settings.os == "Macos": old_str = '-install_name $libdir/$SHAREDLIBM' new_str = '-install_name $SHAREDLIBM' tools.replace_in_file("../configure", old_str, new_str) if self.settings.os == "Windows": # Cross building to Linux tools.replace_in_file("../configure", 'LDSHAREDLIBC="${LDSHAREDLIBC--lc}"', 'LDSHAREDLIBC=""') # Zlib configure doesnt allow this parameters if self.settings.os == "Windows" and tools.os_info.is_linux: # Let our profile to declare what is needed. tools.replace_in_file("../win32/Makefile.gcc", 'LDFLAGS = $(LOC)', '') tools.replace_in_file("../win32/Makefile.gcc", 'AS = $(CC)', '') tools.replace_in_file("../win32/Makefile.gcc", 'AR = $(PREFIX)ar', '') tools.replace_in_file("../win32/Makefile.gcc", 'CC = $(PREFIX)gcc', '') tools.replace_in_file("../win32/Makefile.gcc", 'RC = $(PREFIX)windres', '') self.run("cd .. && make -f win32/Makefile.gcc") else: env_build.configure("../", build=False, host=False, target=False) env_build.make() else: cmake = CMake(self) cmake.configure(build_dir=".") cmake.build(build_dir=".")
def config_source(export_folder, export_source_folder, scm_sources_folder, src_folder, conanfile, output, conanfile_path, reference, hook_manager, cache): """ Implements the sources configuration when a package is going to be built in the local cache. """ def remove_source(raise_error=True): output.warn("This can take a while for big packages") try: rmdir(src_folder) except BaseException as e_rm: set_dirty(src_folder) msg = str(e_rm) if six.PY2: msg = str(e_rm).decode("latin1") # Windows prints some chars in latin1 output.error("Unable to remove source folder %s\n%s" % (src_folder, msg)) output.warn("**** Please delete it manually ****") if raise_error or isinstance(e_rm, KeyboardInterrupt): raise ConanException("Unable to remove source folder") if is_dirty(src_folder): output.warn("Trying to remove corrupted source folder") remove_source() elif conanfile.build_policy_always: output.warn("Detected build_policy 'always', trying to remove source folder") remove_source() if not os.path.exists(src_folder): # No source folder, need to get it with set_dirty_context_manager(src_folder): mkdir(src_folder) def get_sources_from_exports(): # First of all get the exported scm sources (if auto) or clone (if fixed) _run_cache_scm(conanfile, scm_sources_folder, src_folder, output) # so self exported files have precedence over python_requires ones merge_directories(export_folder, src_folder) # Now move the export-sources to the right location merge_directories(export_source_folder, src_folder) _run_source(conanfile, conanfile_path, src_folder, hook_manager, reference, cache, get_sources_from_exports=get_sources_from_exports)
def download(self, url, file_path=None, md5=None, sha1=None, sha256=None, **kwargs): """ compatible interface of FileDownloader + checksum """ checksum = sha256 or sha1 or md5 # If it is a user download, it must contain a checksum assert (not self._user_download) or (self._user_download and checksum) h = self._get_hash(url, checksum) with self._lock(h): cached_path = os.path.join(self._cache_folder, h) if not os.path.exists(cached_path): self._file_downloader.download(url=url, file_path=cached_path, md5=md5, sha1=sha1, sha256=sha256, **kwargs) else: # specific check for corrupted cached files, will raise, but do nothing more # user can report it or "rm -rf cache_folder/path/to/file" try: check_checksum(cached_path, md5, sha1, sha256) except ConanException as e: raise ConanException( "%s\nCached downloaded file corrupted: %s" % (str(e), cached_path)) if file_path is not None: file_path = os.path.abspath(file_path) mkdir(os.path.dirname(file_path)) shutil.copy2(cached_path, file_path) else: with open(cached_path, 'rb') as handle: tmp = handle.read() return tmp
def test_package_folder_errors(self): # https://github.com/conan-io/conan/issues/2350 conanfile = """from conans import ConanFile class HelloPythonConan(ConanFile): pass """ client = TestClient() client.save({CONANFILE: conanfile}) mkdir(os.path.join(client.current_folder, "pkg")) client.run("export-pkg . Hello/0.1@lasote/stable -pf=pkg -bf=.", assert_error=True) self.assertIn("ERROR: package folder definition incompatible with build and source folders", client.out) client.run("export-pkg . Hello/0.1@lasote/stable -pf=pkg -sf=.", assert_error=True) self.assertIn("ERROR: package folder definition incompatible with build and source folders", client.out) client.run("export-pkg . Hello/0.1@lasote/stable -pf=pkg") self.assertIn("Hello/0.1@lasote/stable: WARN: No files copied from package folder!", client.out)
def configure(self, conan_file, args=None, vars=None, source_dir=None, build_dir=None): args = args or [] vars = vars or {} source_dir = source_dir or conan_file.conanfile_directory self.build_dir = build_dir or self.build_dir or conan_file.conanfile_directory mkdir(self.build_dir) arg_list = _join_arguments([ self.command_line, _args_to_string(args), _vars_to_string(vars), _args_to_string([source_dir]) ]) command = "cd %s && cmake %s" % (_args_to_string([self.build_dir ]), arg_list) conan_file.run(command)