def _get_exec_paths(): """Returns the list of paths for executable files and directories. On ChromeOS, most files are copied to the directories that are mounted with noexec option, but the files in the list returned by this function, or contained in a directory in the list, are copied to the directory mounted without noexec option, so that executables can be executed directly for testing. """ return sorted([ build_common.expand_path_placeholder(path) for path in _EXEC_PATTERNS ] + [toolchain.get_adb_path_for_chromeos()] + unittest_util.get_nacl_tools() + unittest_util.get_test_executables( test for test in unittest_util.get_all_tests() if not unittest_util.is_bionic_fundamental_test(test)))
def _get_exec_paths(): """Returns the list of paths for executable files and directories. On ChromeOS, most files are copied to the directories that are mounted with noexec option, but the files in the list returned by this function, or contained in a directory in the list, are copied to the directory mounted without noexec option, so that executables can be executed directly for testing. """ return sorted( [build_common.expand_path_placeholder(path) for path in _EXEC_PATTERNS] + [toolchain.get_adb_path_for_chromeos()] + unittest_util.get_nacl_tools() + unittest_util.get_test_executables( test for test in unittest_util.get_all_tests() if not unittest_util.is_bionic_fundamental_test(test) ) )
def _build_rsync_filter_list(self, source_paths, exclude_paths): """Builds rsync's filter options to send |source_paths|. Builds a list of command line arguments for rsync's filter option to send |source_paths| excluding |exclude_paths|. The rsync's filter is a bit complicated. Note: - The order of the rule is important. Earlier rule is stronger than rest. - In the rule, paths beginning with '/' matches with the paths relative to the copy source directory, otherwise it matches any component. For example, assuming the copy source directory is "source", "*.pyc" matches any files (or directories) whose name ends with .pyc, such as "source/test.pyc", "source/dir1/test.pyc", "source/dir2/main.pyc" and so on. - rsync traverses the paths recursively from top to bottom, and checks filters for each path. So, if a file needs to be sent, all its ancestors must be included. E.g., if a/b/c/d needs to be sent; --inlucde /a --include /a/b --include /a/b/c --include /a/b/c/d must be set. - If a directory path matches with the include pattern, all its descendants will be sent. So, in above case, /a/*, /a/b/*, /a/b/c* and all their descendants will be also sent. To avoid such a situation, this function also adds; --exclude /a/* --exclude /a/b/* --exclude /a/b/c/* --exclude /* after include rules (as weaker rules). Args: source_paths: a list of paths for files and directories to be sent. Please see rsync()'s docstring for more details. exclude_paths: a list of paths for files and directories to be excluded from the list of sending paths. Returns: a list of filter command line arguments for rsync. """ result = [] # 1) exclude all known editor temporary files and .pyc files. # Note that, to keep .pyc files generated in the remote machine, protect # then at first, otherwise these are removed every rsync execution. # If we update a '.py' file, the corresponding '.pyc' file should be # re-generated on execution automatically in remote host side. result.extend(['--filter', 'P *.pyc']) result.extend(itertools.chain.from_iterable( ('--exclude', pattern) for pattern in ( build_common.COMMON_EDITOR_TMP_FILE_PATTERNS + ['*.pyc']))) # 2) protect files downloaded and cached in remote machine. result.extend(itertools.chain.from_iterable( ('--filter', 'P %s' % build_common.expand_path_placeholder(pattern)) for pattern in _PROTECT_GLOB_TEMPLATE_LIST)) # 3) append all exclude paths. result.extend(itertools.chain.from_iterable( ('--exclude', '/' + path) for path in sorted(set(exclude_paths)))) # 4) append source paths as follows; # 4-1) Remove "redundant" paths. Here "redundant" means paths whose # anscestor is contained in the include paths. # 4-2) Then, append remaining paths and their anscestors. See docstring # for more details why anscestors are needed. # 4-3) Finally, exclude unnecessary files and directories. # Note: the "redundant" paths are removed at 1), so we can assume that # all paths here are leaves. source_paths = set(source_paths) # 4-1) Remove redundant paths. redundant_paths = [] for path in source_paths: for dirpath in itertools.islice(file_util.walk_ancestor(path), 1, None): if dirpath in source_paths: redundant_paths.append(path) break for path in redundant_paths: source_paths.discard(path) # 4-2) Build --include arguments. include_paths = set(itertools.chain.from_iterable( file_util.walk_ancestor(path) for path in source_paths)) result.extend(itertools.chain.from_iterable( ('--include', '/' + path) for path in sorted(include_paths))) # 4-3) Exclude unnecessary files. result.extend(itertools.chain.from_iterable( ('--exclude', '/%s/*' % path) for path in sorted(include_paths - source_paths))) result.extend(('--exclude', '/*')) return result
def _build_rsync_filter_list(self, source_paths, exclude_paths): """Builds rsync's filter options to send |source_paths|. Builds a list of command line arguments for rsync's filter option to send |source_paths| excluding |exclude_paths|. The rsync's filter is a bit complicated. Note: - The order of the rule is important. Earlier rule is stronger than rest. - In the rule, paths beginning with '/' matches with the paths relative to the copy source directory, otherwise it matches any component. For example, assuming the copy source directory is "source", "*.pyc" matches any files (or directories) whose name ends with .pyc, such as "source/test.pyc", "source/dir1/test.pyc", "source/dir2/main.pyc" and so on. - rsync traverses the paths recursively from top to bottom, and checks filters for each path. So, if a file needs to be sent, all its ancestors must be included. E.g., if a/b/c/d needs to be sent; --inlucde /a --include /a/b --include /a/b/c --include /a/b/c/d must be set. - If a directory path matches with the include pattern, all its descendants will be sent. So, in above case, /a/*, /a/b/*, /a/b/c* and all their descendants will be also sent. To avoid such a situation, this function also adds; --exclude /a/* --exclude /a/b/* --exclude /a/b/c/* --exclude /* after include rules (as weaker rules). Args: source_paths: a list of paths for files and directories to be sent. Please see rsync()'s docstring for more details. exclude_paths: a list of paths for files and directories to be excluded from the list of sending paths. Returns: a list of filter command line arguments for rsync. """ result = [] # 1) exclude all known editor temporary files and .pyc files. # Note that, to keep .pyc files generated in the remote machine, protect # then at first, otherwise these are removed every rsync execution. # If we update a '.py' file, the corresponding '.pyc' file should be # re-generated on execution automatically in remote host side. result.extend(['--filter', 'P *.pyc']) result.extend( itertools.chain.from_iterable( ('--exclude', pattern) for pattern in (build_common.COMMON_EDITOR_TMP_FILE_PATTERNS + ['*.pyc']))) # 2) protect files downloaded and cached in remote machine. result.extend( itertools.chain.from_iterable( ('--filter', 'P %s' % build_common.expand_path_placeholder(pattern)) for pattern in _PROTECT_GLOB_TEMPLATE_LIST)) # 3) append all exclude paths. result.extend( itertools.chain.from_iterable( ('--exclude', '/' + path) for path in sorted(set(exclude_paths)))) # 4) append source paths as follows; # 4-1) Remove "redundant" paths. Here "redundant" means paths whose # anscestor is contained in the include paths. # 4-2) Then, append remaining paths and their anscestors. See docstring # for more details why anscestors are needed. # 4-3) Finally, exclude unnecessary files and directories. # Note: the "redundant" paths are removed at 1), so we can assume that # all paths here are leaves. source_paths = set(source_paths) # 4-1) Remove redundant paths. redundant_paths = [] for path in source_paths: for dirpath in itertools.islice(file_util.walk_ancestor(path), 1, None): if dirpath in source_paths: redundant_paths.append(path) break for path in redundant_paths: source_paths.discard(path) # 4-2) Build --include arguments. include_paths = set( itertools.chain.from_iterable( file_util.walk_ancestor(path) for path in source_paths)) result.extend( itertools.chain.from_iterable( ('--include', '/' + path) for path in sorted(include_paths))) # 4-3) Exclude unnecessary files. result.extend( itertools.chain.from_iterable( ('--exclude', '/%s/*' % path) for path in sorted(include_paths - source_paths))) result.extend(('--exclude', '/*')) return result