8
8
from pathspec .util import normalize_file
9
9
from pygtrie import StringTrie
10
10
11
+ from dvc .exceptions import DvcException
11
12
from dvc .path_info import PathInfo
12
13
from dvc .pathspec_math import PatternInfo , merge_patterns
13
14
from dvc .system import System
16
17
logger = logging .getLogger (__name__ )
17
18
18
19
20
+ class OutOfWorkingSpaceError (DvcException ):
21
+ """Thrown when unable to acquire the lock for DVC repo."""
22
+
23
+
19
24
class DvcIgnore :
20
25
DVCIGNORE_FILE = ".dvcignore"
21
26
@@ -85,7 +90,9 @@ def _get_normalize_path(self, dirname, basename):
85
90
# NOTE: `os.path.join` is ~x5.5 slower
86
91
path = f"{ rel } { os .sep } { basename } "
87
92
else :
88
- return False
93
+ raise OutOfWorkingSpaceError (
94
+ f"`{ dirname } ` is out side of `{ self .dirname } `"
95
+ )
89
96
90
97
if not System .is_unix ():
91
98
path = normalize_file (path )
@@ -116,16 +123,13 @@ def _ignore_details(self, path, is_dir):
116
123
result = []
117
124
for ignore , pattern in zip (self .regex_pattern_list , self .pattern_list ):
118
125
regex = re .compile (ignore [0 ])
119
- # skip system pattern
120
- if not pattern .file_info :
121
- continue
122
- if is_dir :
123
- path_dir = f"{ path } /"
124
- if regex .match (path ) or regex .match (path_dir ):
125
- result .append (pattern .file_info )
126
- else :
127
- if regex .match (path ):
128
- result .append (pattern .file_info )
126
+ if regex .match (path ) or (is_dir and regex .match (f"{ path } /" )):
127
+ if not pattern .file_info :
128
+ raise OutOfWorkingSpaceError (
129
+ f"`{ path } ` is not in work space."
130
+ )
131
+ result .append (pattern .file_info )
132
+
129
133
return result
130
134
131
135
def __hash__ (self ):
@@ -233,10 +237,10 @@ def _update_sub_repo(self, root, dirs):
233
237
self .ignores_trie_tree [root ] = new_pattern
234
238
235
239
def __call__ (self , root , dirs , files ):
236
- ignore_pattern = self . _get_trie_pattern ( root )
237
- if ignore_pattern :
240
+ try :
241
+ ignore_pattern = self . _get_trie_pattern ( root )
238
242
return ignore_pattern (root , dirs , files )
239
- else :
243
+ except OutOfWorkingSpaceError :
240
244
return dirs , files
241
245
242
246
def _get_trie_pattern (self , dirname ):
@@ -246,8 +250,9 @@ def _get_trie_pattern(self, dirname):
246
250
247
251
prefix = self .ignores_trie_tree .longest_prefix (dirname ).key
248
252
if not prefix :
249
- # outside of the repo
250
- return None
253
+ raise OutOfWorkingSpaceError (
254
+ f"`{ dirname } ` is out side of `{ self .root_dir } `"
255
+ )
251
256
252
257
dirs = list (
253
258
takewhile (
@@ -264,14 +269,13 @@ def _get_trie_pattern(self, dirname):
264
269
return self .ignores_trie_tree .get (dirname )
265
270
266
271
def _is_ignored (self , path , is_dir = False ):
267
- if self ._outside_repo (path ):
268
- return True
269
- dirname , basename = os .path .split (os .path .normpath (path ))
270
- ignore_pattern = self ._get_trie_pattern (dirname )
271
- if ignore_pattern :
272
+ try :
273
+ self ._outside_repo (path )
274
+ dirname , basename = os .path .split (os .path .normpath (path ))
275
+ ignore_pattern = self ._get_trie_pattern (dirname )
272
276
return ignore_pattern .matches (dirname , basename , is_dir )
273
- else :
274
- return False
277
+ except OutOfWorkingSpaceError :
278
+ return True
275
279
276
280
def is_ignored_dir (self , path ):
277
281
path = os .path .abspath (path )
@@ -294,28 +298,29 @@ def _outside_repo(self, path):
294
298
[os .path .abspath (path ), self .root_dir ]
295
299
)
296
300
):
297
- return True
298
- return False
301
+ raise OutOfWorkingSpaceError (f"{ path } is out of { self .root_dir } " )
299
302
300
303
def check_ignore (self , targets ):
301
304
check_results = []
302
305
for target in targets :
303
306
full_target = os .path .abspath (target )
304
- if not self ._outside_repo (full_target ):
307
+ try :
308
+ self ._outside_repo (full_target )
305
309
dirname , basename = os .path .split (
306
310
os .path .normpath (full_target )
307
311
)
308
312
pattern = self ._get_trie_pattern (dirname )
309
- if pattern :
310
- matches = pattern .match_details (
311
- dirname , basename , os .path .isdir (full_target )
312
- )
313
+ matches = pattern .match_details (
314
+ dirname , basename , os .path .isdir (full_target )
315
+ )
313
316
314
- if matches :
315
- check_results .append (
316
- CheckIgnoreResult (target , True , matches )
317
- )
318
- continue
317
+ if matches :
318
+ check_results .append (
319
+ CheckIgnoreResult (target , True , matches )
320
+ )
321
+ continue
322
+ except OutOfWorkingSpaceError :
323
+ pass
319
324
check_results .append (CheckIgnoreResult (target , False , ["::" ]))
320
325
321
326
return check_results
0 commit comments