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