/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/bedding.py

  • Committer: Robert Collins
  • Date: 2005-12-24 02:20:45 UTC
  • mto: (1185.50.57 bzr-jam-integration)
  • mto: This revision was merged to the branch mainline in revision 1550.
  • Revision ID: robertc@robertcollins.net-20051224022045-14efc8dfa0e1a4e9
Start tests for api usage.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2014, 2016 Canonical Ltd
2
 
# Copyright (C) 2019 Breezy developers
3
 
#
4
 
# This program is free software; you can redistribute it and/or modify
5
 
# it under the terms of the GNU General Public License as published by
6
 
# the Free Software Foundation; either version 2 of the License, or
7
 
# (at your option) any later version.
8
 
#
9
 
# This program is distributed in the hope that it will be useful,
10
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
# GNU General Public License for more details.
13
 
#
14
 
# You should have received a copy of the GNU General Public License
15
 
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 
 
18
 
"""Functions for deriving user configuration from system environment."""
19
 
 
20
 
import os
21
 
import sys
22
 
 
23
 
from .lazy_import import lazy_import
24
 
lazy_import(globals(), """
25
 
from breezy import (
26
 
    osutils,
27
 
    trace,
28
 
    win32utils,
29
 
    )
30
 
""")
31
 
from . import (
32
 
    errors,
33
 
    )
34
 
 
35
 
 
36
 
def ensure_config_dir_exists(path=None):
37
 
    """Make sure a configuration directory exists.
38
 
 
39
 
    This makes sure that the directory exists.
40
 
    On windows, since configuration directories are 2 levels deep,
41
 
    it makes sure both the directory and the parent directory exists.
42
 
    """
43
 
    if path is None:
44
 
        path = config_dir()
45
 
    if not os.path.isdir(path):
46
 
        parent_dir = os.path.dirname(path)
47
 
        if not os.path.isdir(parent_dir):
48
 
            trace.mutter(
49
 
                'creating config parent directory: %r', parent_dir)
50
 
            os.mkdir(parent_dir)
51
 
            osutils.copy_ownership_from_path(parent_dir)
52
 
        trace.mutter('creating config directory: %r', path)
53
 
        os.mkdir(path)
54
 
        osutils.copy_ownership_from_path(path)
55
 
 
56
 
 
57
 
def bazaar_config_dir():
58
 
    """Return per-user configuration directory as unicode string
59
 
 
60
 
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
61
 
    and Linux.  On Mac OS X and Linux, if there is a $XDG_CONFIG_HOME/bazaar
62
 
    directory, that will be used instead
63
 
 
64
 
    TODO: Global option --config-dir to override this.
65
 
    """
66
 
    base = os.environ.get('BZR_HOME')
67
 
    if sys.platform == 'win32':
68
 
        if base is None:
69
 
            base = win32utils.get_appdata_location()
70
 
        if base is None:
71
 
            base = win32utils.get_home_location()
72
 
        return osutils.pathjoin(base, 'bazaar', '2.0')
73
 
    if base is None:
74
 
        xdg_dir = os.environ.get('XDG_CONFIG_HOME')
75
 
        if xdg_dir is None:
76
 
            xdg_dir = osutils.pathjoin(osutils._get_home_dir(), ".config")
77
 
        xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
78
 
        if osutils.isdir(xdg_dir):
79
 
            trace.mutter(
80
 
                "Using configuration in XDG directory %s." % xdg_dir)
81
 
            return xdg_dir
82
 
        base = osutils._get_home_dir()
83
 
    return osutils.pathjoin(base, ".bazaar")
84
 
 
85
 
 
86
 
def _config_dir():
87
 
    """Return per-user configuration directory as unicode string
88
 
 
89
 
    By default this is %APPDATA%/breezy on Windows, $XDG_CONFIG_HOME/breezy on
90
 
    Mac OS X and Linux. If the breezy config directory doesn't exist but
91
 
    the bazaar one (see bazaar_config_dir()) does, use that instead.
92
 
    """
93
 
    # TODO: Global option --config-dir to override this.
94
 
    base = os.environ.get('BRZ_HOME')
95
 
    if sys.platform == 'win32':
96
 
        if base is None:
97
 
            base = win32utils.get_appdata_location()
98
 
        if base is None:
99
 
            base = win32utils.get_home_location()
100
 
    if base is None:
101
 
        base = os.environ.get('XDG_CONFIG_HOME')
102
 
        if base is None:
103
 
            base = osutils.pathjoin(osutils._get_home_dir(), ".config")
104
 
    breezy_dir = osutils.pathjoin(base, 'breezy')
105
 
    if osutils.isdir(breezy_dir):
106
 
        return (breezy_dir, 'breezy')
107
 
    # If the breezy directory doesn't exist, but the bazaar one does, use that:
108
 
    bazaar_dir = bazaar_config_dir()
109
 
    if osutils.isdir(bazaar_dir):
110
 
        trace.mutter(
111
 
            "Using Bazaar configuration directory (%s)", bazaar_dir)
112
 
        return (bazaar_dir, 'bazaar')
113
 
    return (breezy_dir, 'breezy')
114
 
 
115
 
 
116
 
def config_dir():
117
 
    """Return per-user configuration directory as unicode string
118
 
 
119
 
    By default this is %APPDATA%/breezy on Windows, $XDG_CONFIG_HOME/breezy on
120
 
    Mac OS X and Linux. If the breezy config directory doesn't exist but
121
 
    the bazaar one (see bazaar_config_dir()) does, use that instead.
122
 
    """
123
 
    return _config_dir()[0]
124
 
 
125
 
 
126
 
def config_path():
127
 
    """Return per-user configuration ini file filename."""
128
 
    path, kind = _config_dir()
129
 
    if kind == 'bazaar':
130
 
        return osutils.pathjoin(path, 'bazaar.conf')
131
 
    else:
132
 
        return osutils.pathjoin(path, 'breezy.conf')
133
 
 
134
 
 
135
 
def locations_config_path():
136
 
    """Return per-user configuration ini file filename."""
137
 
    return osutils.pathjoin(config_dir(), 'locations.conf')
138
 
 
139
 
 
140
 
def authentication_config_path():
141
 
    """Return per-user authentication ini file filename."""
142
 
    return osutils.pathjoin(config_dir(), 'authentication.conf')
143
 
 
144
 
 
145
 
def user_ignore_config_path():
146
 
    """Return per-user authentication ini file filename."""
147
 
    return osutils.pathjoin(config_dir(), 'ignore')
148
 
 
149
 
 
150
 
def crash_dir():
151
 
    """Return the directory name to store crash files.
152
 
 
153
 
    This doesn't implicitly create it.
154
 
 
155
 
    On Windows it's in the config directory; elsewhere it's /var/crash
156
 
    which may be monitored by apport.  It can be overridden by
157
 
    $APPORT_CRASH_DIR.
158
 
    """
159
 
    if sys.platform == 'win32':
160
 
        return osutils.pathjoin(config_dir(), 'Crash')
161
 
    else:
162
 
        # XXX: hardcoded in apport_python_hook.py; therefore here too -- mbp
163
 
        # 2010-01-31
164
 
        return os.environ.get('APPORT_CRASH_DIR', '/var/crash')
165
 
 
166
 
 
167
 
def cache_dir():
168
 
    """Return the cache directory to use."""
169
 
    base = os.environ.get('BRZ_HOME')
170
 
    if sys.platform in "win32":
171
 
        if base is None:
172
 
            base = win32utils.get_local_appdata_location()
173
 
        if base is None:
174
 
            base = win32utils.get_home_location()
175
 
    else:
176
 
        base = os.environ.get('XDG_CACHE_HOME')
177
 
        if base is None:
178
 
            base = osutils.pathjoin(osutils._get_home_dir(), ".cache")
179
 
 
180
 
    cache_dir = osutils.pathjoin(base, "breezy")
181
 
 
182
 
    # GZ 2019-06-15: Move responsibility for ensuring dir exists elsewhere?
183
 
    if not os.path.exists(cache_dir):
184
 
        os.makedirs(cache_dir)
185
 
 
186
 
    return cache_dir
187
 
 
188
 
 
189
 
def _get_default_mail_domain(mailname_file='/etc/mailname'):
190
 
    """If possible, return the assumed default email domain.
191
 
 
192
 
    :returns: string mail domain, or None.
193
 
    """
194
 
    if sys.platform == 'win32':
195
 
        # No implementation yet; patches welcome
196
 
        return None
197
 
    try:
198
 
        f = open(mailname_file)
199
 
    except (IOError, OSError):
200
 
        return None
201
 
    try:
202
 
        domain = f.readline().strip()
203
 
        return domain
204
 
    finally:
205
 
        f.close()
206
 
 
207
 
 
208
 
def default_email():
209
 
    v = os.environ.get('BRZ_EMAIL')
210
 
    if v:
211
 
        return v
212
 
    v = os.environ.get('EMAIL')
213
 
    if v:
214
 
        return v
215
 
    name, email = _auto_user_id()
216
 
    if name and email:
217
 
        return u'%s <%s>' % (name, email)
218
 
    elif email:
219
 
        return email
220
 
    raise errors.NoWhoami()
221
 
 
222
 
 
223
 
def _auto_user_id():
224
 
    """Calculate automatic user identification.
225
 
 
226
 
    :returns: (realname, email), either of which may be None if they can't be
227
 
    determined.
228
 
 
229
 
    Only used when none is set in the environment or the id file.
230
 
 
231
 
    This only returns an email address if we can be fairly sure the
232
 
    address is reasonable, ie if /etc/mailname is set on unix.
233
 
 
234
 
    This doesn't use the FQDN as the default domain because that may be
235
 
    slow, and it doesn't use the hostname alone because that's not normally
236
 
    a reasonable address.
237
 
    """
238
 
    if sys.platform == 'win32':
239
 
        # No implementation to reliably determine Windows default mail
240
 
        # address; please add one.
241
 
        return None, None
242
 
 
243
 
    default_mail_domain = _get_default_mail_domain()
244
 
    if not default_mail_domain:
245
 
        return None, None
246
 
 
247
 
    import pwd
248
 
    uid = os.getuid()
249
 
    try:
250
 
        w = pwd.getpwuid(uid)
251
 
    except KeyError:
252
 
        trace.mutter('no passwd entry for uid %d?' % uid)
253
 
        return None, None
254
 
 
255
 
    # we try utf-8 first, because on many variants (like Linux),
256
 
    # /etc/passwd "should" be in utf-8, and because it's unlikely to give
257
 
    # false positives.  (many users will have their user encoding set to
258
 
    # latin-1, which cannot raise UnicodeError.)
259
 
    gecos = w.pw_gecos
260
 
    if isinstance(gecos, bytes):
261
 
        try:
262
 
            gecos = gecos.decode('utf-8')
263
 
            encoding = 'utf-8'
264
 
        except UnicodeError:
265
 
            try:
266
 
                encoding = osutils.get_user_encoding()
267
 
                gecos = gecos.decode(encoding)
268
 
            except UnicodeError:
269
 
                trace.mutter("cannot decode passwd entry %s" % w)
270
 
                return None, None
271
 
 
272
 
    username = w.pw_name
273
 
    if isinstance(username, bytes):
274
 
        try:
275
 
            username = username.decode(encoding)
276
 
        except UnicodeError:
277
 
            trace.mutter("cannot decode passwd entry %s" % w)
278
 
            return None, None
279
 
 
280
 
    comma = gecos.find(',')
281
 
    if comma == -1:
282
 
        realname = gecos
283
 
    else:
284
 
        realname = gecos[:comma]
285
 
 
286
 
    return realname, (username + '@' + default_mail_domain)