def test_remove_readonly(self): os.chmod(self.file, stat.S_IREAD | stat.S_IRGRP | stat.S_IROTH) with self.assertRaisesRegexp((IOError, OSError), "Permission denied"): save(self.file, "change the content") remove(self.file) self.assertFalse(os.path.exists(self.file)) self.assertTrue(os.path.exists(os.path.dirname(self.file)))
def test_load_empty_toolchain_args_in_default_dir(): save(CONAN_TOOLCHAIN_ARGS_FILE, "[%s]" % CONAN_TOOLCHAIN_ARGS_SECTION) try: config = load_toolchain_args() assert not config finally: remove(CONAN_TOOLCHAIN_ARGS_FILE)
def _filecopy(src, filename, dst): # https://github.com/conan-io/conan/issues/6556 # This is just a local convenience for "conan config install", using copyfile to avoid # copying with permissions that later cause bugs src = os.path.join(src, filename) dst = os.path.join(dst, filename) if os.path.exists(dst): remove(dst) shutil.copyfile(src, dst)
def _replace_scm_data_in_conanfile(conanfile_path, scm_data): # Parsing and replacing the SCM field content = load(conanfile_path) headers = [] if six.PY2: # Workaround for https://bugs.python.org/issue22221 lines_without_headers = [] lines = content.splitlines(True) for line in lines: if not lines_without_headers and line.startswith("#"): headers.append(line) else: lines_without_headers.append(line) content = ''.join(lines_without_headers) lines = content.splitlines(True) tree = ast.parse(content) to_replace = [] comments = [] for i_body, item in enumerate(tree.body): if isinstance(item, ast.ClassDef): statements = item.body for i, stmt in enumerate(item.body): if isinstance(stmt, ast.Assign) and len(stmt.targets) == 1: if isinstance(stmt.targets[0], ast.Name) and stmt.targets[0].id == "scm": try: if i + 1 == len(statements): # Last statement in my ClassDef if i_body + 1 == len(tree.body): # Last statement over all next_line = len(lines) else: next_line = tree.body[i_body+1].lineno - 1 else: next_line = statements[i+1].lineno - 1 next_line_content = lines[next_line].strip() if next_line_content.endswith('"""') or next_line_content.endswith("'''"): next_line += 1 except IndexError: next_line = stmt.lineno replace = [line for line in lines[(stmt.lineno-1):next_line]] to_replace.append("".join(replace).lstrip()) comments = [line.strip('\n') for line in replace if line.strip().startswith("#") or not line.strip()] break if len(to_replace) != 1: raise ConanException("The conanfile.py defines more than one class level 'scm' attribute") new_text = "scm = " + ",\n ".join(str(scm_data).split(",")) + "\n" if comments: new_text += '\n'.join(comments) + "\n" content = content.replace(to_replace[0], new_text) content = content if not headers else ''.join(headers) + content remove(conanfile_path) save(conanfile_path, content)
def _filecopy(src, filename, dst): # https://github.com/conan-io/conan/issues/6556 # This is just a local convenience for "conan config install", using copyfile to avoid # copying with permissions that later cause bugs src = os.path.join(src, filename) dst = os.path.join(dst, filename) # Clear the destination file if os.path.exists(dst): if os.path.isdir(dst): # dst was a directory and now src is a file rmdir(dst) else: remove(dst) shutil.copyfile(src, dst)
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 is_dirty(cached_path): if os.path.exists(cached_path): os.remove(cached_path) clean_dirty(cached_path) if os.path.exists(cached_path): # If exists but it is corrupted, it is removed. Note that v2 downloads # do not have checksums, this only works for user downloads try: check_checksum(cached_path, md5, sha1, sha256) except ConanException: logger.error("Cached file corrupt, redownloading") remove(cached_path) if not os.path.exists(cached_path): set_dirty(cached_path) self._file_downloader.download(url=url, file_path=cached_path, md5=md5, sha1=sha1, sha256=sha256, **kwargs) clean_dirty(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_bazel_command_with_config_values(): conanfile = ConanFileMock() args_file = os.path.join(conanfile.generators_folder, CONAN_TOOLCHAIN_ARGS_FILE) save( args_file, textwrap.dedent("""\ [%s] bazel_config=config bazelrc_path=/path/to/bazelrc """ % CONAN_TOOLCHAIN_ARGS_SECTION)) bazel = Bazel(conanfile) bazel.build(label='//test:label') # TODO: Create a context manager to remove the file remove(args_file) assert 'bazel --bazelrc=/path/to/bazelrc build --config=config //test:label' == str( conanfile.command)
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 _replace_scm_data_in_conanfile(conanfile_path, scm_data): # Parsing and replacing the SCM field content = load(conanfile_path) headers = [] if six.PY2: # Workaround for https://bugs.python.org/issue22221 lines_without_headers = [] lines = content.splitlines(True) for line in lines: if not lines_without_headers and line.startswith("#"): headers.append(line) else: lines_without_headers.append(line) content = ''.join(lines_without_headers) lines = content.splitlines(True) tree = ast.parse(content) to_replace = [] comments = [] class_line = None tab_size = 4 for i_body, item in enumerate(tree.body): if isinstance(item, ast.ClassDef): statements = item.body class_line = item.lineno for i, stmt in enumerate(item.body): if isinstance(stmt, ast.Assign) and len(stmt.targets) == 1: line = lines[stmt.lineno - 1] tab_size = len(line) - len(line.lstrip()) if isinstance(stmt.targets[0], ast.Name) and stmt.targets[0].id == "scm": try: if i + 1 == len(statements ): # Last statement in my ClassDef if i_body + 1 == len( tree.body): # Last statement over all next_line = len(lines) else: next_line = tree.body[i_body + 1].lineno - 1 else: next_line = statements[i + 1].lineno - 1 next_line_content = lines[next_line].strip() if (next_line_content.endswith('"""') or next_line_content.endswith("'''")): next_line += 1 except IndexError: next_line = stmt.lineno replace = [ line for line in lines[(stmt.lineno - 1):next_line] ] to_replace.append("".join(replace).lstrip()) comments = [ line.strip('\n') for line in replace if line.strip().startswith("#") or not line.strip() ] break if len(to_replace) > 1: raise ConanException( "The conanfile.py defines more than one class level 'scm' attribute" ) new_text = "scm = " + ",\n ".join(str(scm_data).split(",")) + "\n" if len(to_replace) == 0: # SCM exists, but not found in the conanfile, probably inherited from superclass # FIXME: This will inject the lines only the latest class declared in the conanfile tmp = lines[0:class_line] tmp.append("{}{}".format(" " * tab_size, new_text)) tmp.extend(lines[class_line:]) content = ''.join(tmp) else: if comments: new_text += '\n'.join(comments) + "\n" content = content.replace(to_replace[0], new_text) content = content if not headers else ''.join(headers) + content remove(conanfile_path) save(conanfile_path, content)
def reset_settings(self): if os.path.exists(self.settings_path): remove(self.settings_path) self.initialize_settings()
def reset_default_profile(self): if os.path.exists(self.default_profile_path): remove(self.default_profile_path) self.initialize_default_profile()
def reset_config(self): if os.path.exists(self.conan_conf_path): remove(self.conan_conf_path) self.initialize_config()
def test_remove(self): remove(self.file) self.assertFalse(os.path.exists(self.file)) self.assertTrue(os.path.exists(os.path.dirname(self.file)))