1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# 4# Copyright (c) 2025 Huawei Device Co., Ltd. 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import os 18import shutil 19import stat 20import argparse 21from pathlib import Path 22 23 24def should_skip_file(file_path, patterns) -> bool: 25 for pattern in patterns: 26 if pattern.startswith("*.") and file_path.endswith(pattern[1:]): 27 return True 28 if file_path.endswith(pattern): 29 return True 30 return False 31 32 33def copy_with_permissions(src, dst): 34 shutil.copy2(src, dst) 35 src_stat = os.stat(src) 36 os.chmod(dst, src_stat.st_mode) 37 38 39def copy_directory_excluding_files(base_dir, output_dir): 40 base_path = Path(base_dir) 41 output_path = Path(output_dir) 42 43 if output_path.exists(): 44 shutil.rmtree(output_path) 45 output_path.mkdir(parents=True) 46 47 if base_path.exists(): 48 base_stat = os.stat(base_path) 49 os.chmod(output_path, base_stat.st_mode) 50 51 excluded_patterns = [ 52 "*.taihe.mark", 53 "lib/taihe/compiler/taihe/cli/tryit.py", 54 "bin/taihe-tryit" 55 ] 56 57 for root, dirs, files in os.walk(base_dir): 58 root_path = Path(root) 59 relative_path = root_path.relative_to(base_path) 60 dest_dir = output_path / relative_path 61 62 dest_dir.mkdir(parents=True, exist_ok=True) 63 if root_path.exists(): 64 dir_stat = os.stat(root_path) 65 os.chmod(dest_dir, dir_stat.st_mode) 66 67 for file in files: 68 src_file = root_path / file 69 dest_file = dest_dir / file 70 file_rel_path = (relative_path / file).as_posix() 71 72 if not should_skip_file(file_rel_path, excluded_patterns): 73 copy_with_permissions(src_file, dest_file) 74 75 76if __name__ == "__main__": 77 parser = argparse.ArgumentParser( 78 description="Copy directory tree while preserving permissions and excluding specific files" 79 ) 80 parser.add_argument("--input_dir", required=True, help="Source directory to copy") 81 parser.add_argument("--output_dir", required=True, help="Destination directory") 82 args = parser.parse_args() 83 84 copy_directory_excluding_files(args.input_dir, args.output_dir) 85