2009-01-19 17:55:00 +00:00
|
|
|
#
|
2009-10-25 13:57:39 +01:00
|
|
|
# misc.py - misc functions for the Ubuntu Developer Tools scripts.
|
2009-01-19 17:55:00 +00:00
|
|
|
#
|
2010-12-24 12:00:03 +02:00
|
|
|
# Copyright (C) 2008, Jonathan Davies <jpds@ubuntu.com>,
|
|
|
|
# 2008-2009, Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com>,
|
|
|
|
# 2010, Stefano Rivera <stefanor@ubuntu.com>
|
2011-06-11 05:05:35 -07:00
|
|
|
# 2011, Evan Broder <evan@ebroder.net>
|
2009-01-19 17:55:00 +00:00
|
|
|
#
|
2009-10-25 13:57:39 +01:00
|
|
|
# ##################################################################
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or
|
|
|
|
# modify it under the terms of the GNU General Public License
|
|
|
|
# as published by the Free Software Foundation; either version 3
|
|
|
|
# of the License, or (at your option) any later version.
|
2010-12-02 09:33:54 +02:00
|
|
|
#
|
2009-10-25 13:57:39 +01:00
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
2009-01-19 17:55:00 +00:00
|
|
|
#
|
2009-10-25 13:57:39 +01:00
|
|
|
# See file /usr/share/common-licenses/GPL for more details.
|
2009-01-19 17:55:00 +00:00
|
|
|
#
|
2009-10-25 13:57:39 +01:00
|
|
|
# ##################################################################
|
2009-01-19 17:55:00 +00:00
|
|
|
|
|
|
|
# Modules.
|
2011-02-13 16:15:24 +02:00
|
|
|
import locale
|
2009-01-19 17:55:00 +00:00
|
|
|
import os
|
2011-02-13 16:15:24 +02:00
|
|
|
import sys
|
2019-09-11 13:38:04 -03:00
|
|
|
from subprocess import check_output, CalledProcessError
|
2009-01-19 17:55:00 +00:00
|
|
|
|
2011-06-25 17:53:44 +02:00
|
|
|
import distro_info
|
|
|
|
|
2010-03-20 19:45:04 +01:00
|
|
|
from ubuntutools.lp.udtexceptions import PocketDoesNotExistError
|
|
|
|
|
2011-06-11 05:05:35 -07:00
|
|
|
_system_distribution_chain = []
|
2017-05-01 00:20:03 +02:00
|
|
|
|
|
|
|
|
2011-06-11 05:05:35 -07:00
|
|
|
def system_distribution_chain():
|
|
|
|
""" system_distribution_chain() -> [string]
|
|
|
|
|
|
|
|
Detect the system's distribution as well as all of its parent
|
|
|
|
distributions and return them as a list of strings, with the
|
|
|
|
system distribution first (and the greatest grandparent last). If
|
|
|
|
the distribution chain can't be determined, print an error message
|
|
|
|
and return an empty list.
|
|
|
|
"""
|
|
|
|
global _system_distribution_chain
|
|
|
|
if len(_system_distribution_chain) == 0:
|
|
|
|
try:
|
2019-09-11 13:38:04 -03:00
|
|
|
vendor = check_output(('dpkg-vendor', '--query', 'Vendor'),
|
|
|
|
encoding='utf-8').strip()
|
|
|
|
_system_distribution_chain.append(vendor)
|
|
|
|
except CalledProcessError:
|
2017-05-01 00:20:03 +02:00
|
|
|
print('Error: Could not determine what distribution you are running.')
|
2011-06-11 05:05:35 -07:00
|
|
|
return []
|
|
|
|
|
|
|
|
while True:
|
|
|
|
try:
|
2019-09-11 13:38:04 -03:00
|
|
|
parent = check_output((
|
|
|
|
'dpkg-vendor', '--vendor', _system_distribution_chain[-1],
|
|
|
|
'--query', 'Parent'), encoding='utf-8').strip()
|
|
|
|
except CalledProcessError:
|
|
|
|
# Vendor has no parent
|
|
|
|
break
|
|
|
|
_system_distribution_chain.append(parent)
|
2011-06-11 05:05:35 -07:00
|
|
|
|
|
|
|
return _system_distribution_chain
|
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2009-10-25 13:57:39 +01:00
|
|
|
def system_distribution():
|
|
|
|
""" system_distro() -> string
|
2010-12-02 09:33:54 +02:00
|
|
|
|
2009-10-25 13:57:39 +01:00
|
|
|
Detect the system's distribution and return it as a string. If the
|
|
|
|
name of the distribution can't be determined, print an error message
|
|
|
|
and return None.
|
|
|
|
"""
|
2011-06-11 05:05:35 -07:00
|
|
|
return system_distribution_chain()[0]
|
2009-10-25 13:57:39 +01:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2009-10-25 13:57:39 +01:00
|
|
|
def host_architecture():
|
|
|
|
""" host_architecture -> string
|
2010-12-02 09:33:54 +02:00
|
|
|
|
2010-09-20 18:12:39 +02:00
|
|
|
Detect the host's architecture and return it as a string. If the
|
|
|
|
architecture can't be determined, print an error message and return None.
|
2009-10-25 13:57:39 +01:00
|
|
|
"""
|
2010-12-02 09:33:54 +02:00
|
|
|
|
2019-09-11 13:38:04 -03:00
|
|
|
try:
|
|
|
|
arch = check_output(('dpkg', '--print-architecture'),
|
|
|
|
encoding='utf-8').strip()
|
|
|
|
except CalledProcessError:
|
|
|
|
arch = None
|
2010-12-02 09:33:54 +02:00
|
|
|
|
2019-09-11 13:38:04 -03:00
|
|
|
if not arch or 'not found' in arch:
|
|
|
|
print('Error: Not running on a Debian based system; '
|
|
|
|
'could not detect its architecture.')
|
2009-10-25 13:57:39 +01:00
|
|
|
return None
|
2010-12-02 09:33:54 +02:00
|
|
|
|
2019-09-11 13:38:04 -03:00
|
|
|
return arch
|
2009-10-25 13:57:39 +01:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2009-01-19 17:55:00 +00:00
|
|
|
def readlist(filename, uniq=True):
|
2009-10-25 13:57:39 +01:00
|
|
|
""" readlist(filename, uniq) -> list
|
2010-12-02 09:33:54 +02:00
|
|
|
|
2009-10-25 13:57:39 +01:00
|
|
|
Read a list of words from the indicated file. If 'uniq' is True, filter
|
|
|
|
out duplicated words.
|
|
|
|
"""
|
2010-12-02 09:33:54 +02:00
|
|
|
|
2009-01-19 17:55:00 +00:00
|
|
|
if not os.path.isfile(filename):
|
2014-12-18 20:34:04 +00:00
|
|
|
print('File "%s" does not exist.' % filename)
|
2009-01-19 17:55:00 +00:00
|
|
|
return False
|
2010-12-02 09:33:54 +02:00
|
|
|
|
2009-01-19 17:55:00 +00:00
|
|
|
content = open(filename).read().replace('\n', ' ').replace(',', ' ')
|
2010-12-02 09:33:54 +02:00
|
|
|
|
2009-01-19 17:55:00 +00:00
|
|
|
if not content.strip():
|
2014-12-18 20:34:04 +00:00
|
|
|
print('File "%s" is empty.' % filename)
|
2009-01-19 17:55:00 +00:00
|
|
|
return False
|
2010-12-02 09:33:54 +02:00
|
|
|
|
2009-01-19 17:55:00 +00:00
|
|
|
items = [item for item in content.split() if item]
|
2010-12-02 09:33:54 +02:00
|
|
|
|
2009-01-19 17:55:00 +00:00
|
|
|
if uniq:
|
|
|
|
items = list(set(items))
|
2010-12-02 09:33:54 +02:00
|
|
|
|
2009-01-19 17:55:00 +00:00
|
|
|
return items
|
2010-03-20 19:45:04 +01:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2011-11-23 01:45:49 +02:00
|
|
|
def split_release_pocket(release, default='Release'):
|
2010-03-20 19:45:04 +01:00
|
|
|
'''Splits the release and pocket name.
|
|
|
|
|
|
|
|
If the argument doesn't contain a pocket name then the 'Release' pocket
|
|
|
|
is assumed.
|
|
|
|
|
|
|
|
Returns the release and pocket name.
|
|
|
|
'''
|
2011-11-23 01:45:49 +02:00
|
|
|
pocket = default
|
2010-03-20 19:45:04 +01:00
|
|
|
|
|
|
|
if release is None:
|
|
|
|
raise ValueError('No release name specified')
|
|
|
|
|
|
|
|
if '-' in release:
|
2011-09-08 16:40:29 +02:00
|
|
|
(release, pocket) = release.rsplit('-', 1)
|
2010-03-20 19:45:04 +01:00
|
|
|
pocket = pocket.capitalize()
|
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
if pocket not in ('Release', 'Security', 'Updates', 'Proposed', 'Backports'):
|
|
|
|
raise PocketDoesNotExistError("Pocket '%s' does not exist." % pocket)
|
2010-03-20 19:45:04 +01:00
|
|
|
|
|
|
|
return (release, pocket)
|
2011-02-13 16:15:24 +02:00
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2011-02-13 16:15:24 +02:00
|
|
|
def require_utf8():
|
|
|
|
'''Can be called by programs that only function in UTF-8 locales'''
|
|
|
|
if locale.getpreferredencoding() != 'UTF-8':
|
2017-05-01 00:20:03 +02:00
|
|
|
print("This program only functions in a UTF-8 locale. Aborting.", file=sys.stderr)
|
2011-02-13 16:15:24 +02:00
|
|
|
sys.exit(1)
|
2011-06-11 06:04:09 -07:00
|
|
|
|
|
|
|
|
|
|
|
_vendor_to_distroinfo = {"Debian": distro_info.DebianDistroInfo,
|
|
|
|
"Ubuntu": distro_info.UbuntuDistroInfo}
|
2017-05-01 00:20:03 +02:00
|
|
|
|
|
|
|
|
2011-06-11 06:04:09 -07:00
|
|
|
def vendor_to_distroinfo(vendor):
|
|
|
|
""" vendor_to_distroinfo(string) -> DistroInfo class
|
|
|
|
|
|
|
|
Convert a string name of a distribution into a DistroInfo subclass
|
|
|
|
representing that distribution, or None if the distribution is
|
|
|
|
unknown.
|
|
|
|
"""
|
|
|
|
return _vendor_to_distroinfo.get(vendor)
|
|
|
|
|
2017-05-01 00:20:03 +02:00
|
|
|
|
2011-06-11 06:04:09 -07:00
|
|
|
def codename_to_distribution(codename):
|
|
|
|
""" codename_to_distribution(string) -> string
|
|
|
|
|
|
|
|
Finds a given release codename in your distribution's genaology
|
|
|
|
(i.e. looking at the current distribution and its parents), or
|
|
|
|
print an error message and return None if it can't be found
|
|
|
|
"""
|
2011-09-08 18:21:57 +02:00
|
|
|
for distro in system_distribution_chain() + ["Ubuntu", "Debian"]:
|
2011-06-11 06:04:09 -07:00
|
|
|
info = vendor_to_distroinfo(distro)
|
|
|
|
if not info:
|
|
|
|
continue
|
|
|
|
|
2011-06-15 00:01:49 +02:00
|
|
|
if info().valid(codename):
|
2011-06-11 06:04:09 -07:00
|
|
|
return distro
|