1
# Copyright (C) 2006-2010 Canonical Ltd
1
# Copyright (C) 2006-2011 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Lists of ignore files, etc."""
20
from io import BytesIO
21
from cStringIO import StringIO
24
from .lazy_import import lazy_import
25
lazy_import(globals(), """
30
from trace import warning
32
# ~/.bazaar/ignore will be filled out using
36
# ~/.config/breezy/ignore will be filled out using
33
37
# this ignore list, if it does not exist
34
38
# please keep these sorted (in C locale order) to aid merging
48
53
def parse_ignore_file(f):
49
54
"""Read in all of the lines in the file and turn it into an ignore list
51
Continue in the case of utf8 decoding errors, and emit a warning when
52
such and error is found. Optimise for the common case -- no decoding
56
Continue in the case of utf8 decoding errors, and emit a warning when
57
such and error is found. Optimise for the common case -- no decoding
60
65
except UnicodeDecodeError:
61
66
# Otherwise go though line by line and pick out the 'good'
63
lines = ignore_file.split('\n')
68
lines = ignore_file.split(b'\n')
65
70
for line_number, line in enumerate(lines):
67
72
unicode_lines.append(line.decode('utf-8'))
68
73
except UnicodeDecodeError:
69
74
# report error about line (idx+1)
70
warning('.bzrignore: On Line #%d, malformed utf8 character. '
71
'Ignoring line.' % (line_number+1))
76
'.bzrignore: On Line #%d, malformed utf8 character. '
77
'Ignoring line.' % (line_number + 1))
73
79
# Append each line to ignore list if it's not a comment line
74
80
for line in unicode_lines:
82
88
def get_user_ignores():
83
89
"""Get the list of user ignored files, possibly creating it."""
84
path = config.user_ignore_config_filename()
90
path = bedding.user_ignore_config_path()
85
91
patterns = set(USER_DEFAULTS)
87
93
f = open(path, 'rb')
88
except (IOError, OSError), e:
94
except (IOError, OSError) as e:
89
95
# open() shouldn't return an IOError without errno, but just in case
90
96
err = getattr(e, 'errno', None)
91
97
if err not in (errno.ENOENT,):
95
101
# since get_* should be a safe operation
97
103
_set_user_ignores(USER_DEFAULTS)
98
except (IOError, OSError), e:
99
if e.errno not in (errno.EPERM,):
104
except EnvironmentError as e:
105
if e.errno not in (errno.EPERM, errno.ENOENT):
113
119
write to the user ignore file.
114
120
This is mostly used for testing, since it would be
115
121
bad form to rewrite a user's ignore list.
116
bzrlib only writes this file if it does not exist.
122
breezy only writes this file if it does not exist.
118
ignore_path = config.user_ignore_config_filename()
119
config.ensure_config_dir_exists()
124
ignore_path = bedding.user_ignore_config_path()
125
bedding.ensure_config_dir_exists()
121
127
# Create an empty file
122
f = open(ignore_path, 'wb')
128
with open(ignore_path, 'wb') as f:
124
129
for pattern in patterns:
125
f.write(pattern.encode('utf8') + '\n')
130
f.write(pattern.encode('utf8') + b'\n')
130
133
def add_unique_user_ignores(new_ignores):
147
f = open(config.user_ignore_config_filename(), 'ab')
150
with open(bedding.user_ignore_config_path(), 'ab') as f:
149
151
for pattern in to_add:
150
f.write(pattern.encode('utf8') + '\n')
152
f.write(pattern.encode('utf8') + b'\n')
189
189
# read in the existing ignores set
190
ifn = tree.abspath(bzrlib.IGNORE_FILENAME)
190
ifn = tree.abspath(tree._format.ignore_filename)
191
191
if tree.has_filename(ifn):
192
with open(ifn, 'rb') as f:
194
193
file_contents = f.read()
195
# figure out what kind of line endings are used
196
newline = getattr(f, 'newlines', None)
197
if type(newline) is tuple:
199
elif newline is None:
194
if file_contents.find(b'\r\n') != -1:
207
sio = StringIO(file_contents)
200
newline = os.linesep.encode()
202
with BytesIO(file_contents) as sio:
209
203
ignores = parse_ignore_file(sio)
213
205
# write out the updated ignores set
214
f = atomicfile.AtomicFile(ifn, 'wb')
206
with atomicfile.AtomicFile(ifn, 'wb') as f:
216
207
# write the original contents, preserving original line endings
217
f.write(newline.join(file_contents.split('\n')))
218
if len(file_contents) > 0 and not file_contents.endswith('\n'):
208
f.write(file_contents)
209
if len(file_contents) > 0 and not file_contents.endswith(b'\n'):
220
211
for pattern in name_pattern_list:
221
if not pattern in ignores:
212
if pattern not in ignores:
222
213
f.write(pattern.encode('utf-8'))
228
if not tree.path2id(bzrlib.IGNORE_FILENAME):
229
tree.add([bzrlib.IGNORE_FILENAME])
216
if not tree.is_versioned(tree._format.ignore_filename):
217
tree.add([tree._format.ignore_filename])