99import locale
1010import platform
1111import re
12+ import subprocess
1213from datetime import datetime
1314from binaryornot .check import is_binary
1415import fosslight_util .constant as constant
1718from reuse import report
1819from reuse .project import Project
1920from reuse .report import ProjectReport
21+ from reuse .vcs import VCSStrategyGit
2022from fosslight_prechecker ._result import write_result_file , create_result_file , result_for_summary , ResultItem
2123from fosslight_prechecker ._constant import DEFAULT_EXCLUDE_EXTENSION , OSS_PKG_INFO_FILES , PKG_NAME
2224
2325is_windows = platform .system () == 'Windows'
2426REUSE_CONFIG_FILE = ".reuse/dep5"
2527DEFAULT_EXCLUDE_EXTENSION_FILES = [] # Exclude files from reuse
26- _turn_on_default_reuse_config = True
28+ _turn_on_exclude_config = True
2729_check_only_file_mode = False
2830error_items = []
2931_start_time = ""
3234logger = logging .getLogger (constant .LOGGER_NAME )
3335
3436
35- def find_oss_pkg_info (path ):
37+ def exclude_untracked_files (path ):
38+ global DEFAULT_EXCLUDE_EXTENSION_FILES
39+ try :
40+ cmd_result = subprocess .check_output (['git' , 'ls-files' , '-o' , f'{ path } ' ], universal_newlines = True )
41+ cmd_result = cmd_result .split ('\n ' )
42+ cmd_result .remove ('' )
43+ if not path .endswith ("/" ):
44+ path += "/"
45+ cmd_result = [file .replace (path , '' , 1 ) for file in cmd_result ]
46+ DEFAULT_EXCLUDE_EXTENSION_FILES .extend (cmd_result )
47+ except Exception as ex :
48+ logger .error (f"Error to get git untracked files : { ex } " )
49+
50+
51+ def exclude_gitignore_files (path ):
52+ global DEFAULT_EXCLUDE_EXTENSION_FILES
53+ try :
54+ cmd_result = subprocess .check_output (['git' ,
55+ 'ls-files' ,
56+ '-i' ,
57+ f"--exclude-from={ os .path .join (path , '.gitignore' )} " ],
58+ universal_newlines = True )
59+ cmd_result = cmd_result .split ('\n ' )
60+ cmd_result .remove ('' )
61+ if not path .endswith ("/" ):
62+ path += "/"
63+ cmd_result = [file .replace (path , '' , 1 ) for file in cmd_result ]
64+ DEFAULT_EXCLUDE_EXTENSION_FILES .extend (cmd_result )
65+ except Exception as ex :
66+ logger .error (f"Error to get git ignored files : { ex } " )
67+
68+
69+ def find_oss_pkg_info_and_exlcude_file (path ):
3670 global DEFAULT_EXCLUDE_EXTENSION_FILES
3771 oss_pkg_info = []
72+ git_present = shutil .which ("git" )
73+
74+ # Exlcude untracked files
75+ if _turn_on_exclude_config and git_present and VCSStrategyGit .in_repo (path ):
76+ exclude_untracked_files (path )
77+ # Exclude all files from .gitignore
78+ if os .path .isfile (os .path .join (path , '.gitignore' )):
79+ exclude_gitignore_files (path )
3880
3981 try :
4082 for root , dirs , files in os .walk (path ):
83+ for dir in dirs :
84+ # For hidden folders
85+ if dir .startswith ("." ):
86+ all_files_in_dir = [os .path .join (root , dir , file )
87+ for file in os .listdir (os .path .join (root , dir ))
88+ if os .path .isfile (os .path .join (root , dir , file ))]
89+ all_files_rel_path = [os .path .relpath (file , path ) for file in all_files_in_dir ]
90+ DEFAULT_EXCLUDE_EXTENSION_FILES .extend (all_files_rel_path )
91+
4192 for file in files :
4293 file_lower_case = file .lower ()
4394 file_abs_path = os .path .join (root , file )
@@ -46,6 +97,9 @@ def find_oss_pkg_info(path):
4697 if any (re .search (re_oss_pkg_pattern , file_lower_case ) for re_oss_pkg_pattern in OSS_PKG_INFO_FILES ) \
4798 or file_lower_case .startswith ("module_license_" ):
4899 oss_pkg_info .append (file_rel_path )
100+ # Exclude hidden files
101+ elif _turn_on_exclude_config and file .startswith ('.' ):
102+ DEFAULT_EXCLUDE_EXTENSION_FILES .append (file_rel_path )
49103 elif is_binary (file_abs_path ):
50104 if is_windows :
51105 file_rel_path = file_rel_path .replace (os .sep , '/' )
@@ -56,14 +110,14 @@ def find_oss_pkg_info(path):
56110 if is_windows :
57111 file_rel_path = file_rel_path .replace (os .sep , '/' )
58112 DEFAULT_EXCLUDE_EXTENSION_FILES .append (file_rel_path )
59-
60113 except Exception as ex :
61114 dump_error_msg (f"Error_FIND_OSS_PKG : { ex } " )
62115
63116 return oss_pkg_info
64117
65118
66119def create_reuse_dep5_file (path ):
120+ global DEFAULT_EXCLUDE_EXTENSION_FILES
67121 # Create .reuse/dep5 for excluding directories from reuse.
68122 _DEFAULT_CONFIG_PREFIX = "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/\n Upstream-Name: \
69123 reuse\n Upstream-Contact: Carmen Bianca Bakker <[email protected] >\n Source: https://github.com/fsfe/reuse-tool\n "@@ -86,7 +140,8 @@ def create_reuse_dep5_file(path):
86140 need_rollback = True
87141
88142 DEFAULT_EXCLUDE_EXTENSION_FILES .extend (_DEFAULT_EXCLUDE_FOLDERS )
89- for file_to_exclude in DEFAULT_EXCLUDE_EXTENSION_FILES :
143+ exclude_file_list = list (set (DEFAULT_EXCLUDE_EXTENSION_FILES ))
144+ for file_to_exclude in exclude_file_list :
90145 str_contents += f"\n Files: { file_to_exclude } \n Copyright: -\n License: -\n "
91146
92147 with open (reuse_config_file , "a" ) as f :
@@ -161,8 +216,8 @@ def precheck_for_project(path_to_find):
161216 missing_license = []
162217 missing_copyright = []
163218
164- oss_pkg_info_files = find_oss_pkg_info (path_to_find )
165- if _turn_on_default_reuse_config :
219+ oss_pkg_info_files = find_oss_pkg_info_and_exlcude_file (path_to_find )
220+ if _turn_on_exclude_config :
166221 need_rollback , temp_file_name , temp_dir_name = create_reuse_dep5_file (path_to_find )
167222
168223 try :
@@ -183,7 +238,7 @@ def precheck_for_project(path_to_find):
183238 except Exception as ex :
184239 dump_error_msg (f"Error prechecker lint: { ex } " , True )
185240
186- if _turn_on_default_reuse_config :
241+ if _turn_on_exclude_config :
187242 remove_reuse_dep5_file (need_rollback , temp_file_name , temp_dir_name )
188243 return missing_license , missing_copyright , oss_pkg_info_files , project , report
189244
@@ -234,7 +289,7 @@ def get_path_to_find(target_path, _check_only_file_mode):
234289
235290
236291def run_lint (target_path , disable , output_file_name , format = '' , need_log_file = True ):
237- global _turn_on_default_reuse_config , _check_only_file_mode , _start_time
292+ global _turn_on_exclude_config , _check_only_file_mode , _start_time
238293
239294 file_to_check_list = []
240295 _exit_code = 0
@@ -256,7 +311,7 @@ def run_lint(target_path, disable, output_file_name, format='', need_log_file=Tr
256311
257312 if os .path .isdir (path_to_find ):
258313 oss_pkg_info = []
259- _turn_on_default_reuse_config = not disable
314+ _turn_on_exclude_config = not disable
260315
261316 if need_log_file :
262317 # Use ProgressBar
@@ -268,6 +323,7 @@ def run_lint(target_path, disable, output_file_name, format='', need_log_file=Tr
268323 license_missing_files , copyright_missing_files , project = precheck_for_files (path_to_find , file_to_check_list )
269324 else :
270325 license_missing_files , copyright_missing_files , oss_pkg_info , project , report = precheck_for_project (path_to_find )
326+
271327 if need_log_file :
272328 timer .stop = True
273329
@@ -279,7 +335,8 @@ def run_lint(target_path, disable, output_file_name, format='', need_log_file=Tr
279335 _result_log ,
280336 _check_only_file_mode ,
281337 file_to_check_list ,
282- error_items )
338+ error_items ,
339+ DEFAULT_EXCLUDE_EXTENSION_FILES )
283340
284341 success , exit_code = write_result_file (result_file , output_extension , _exit_code ,
285342 result_item , _result_log , project , path_to_find )
0 commit comments