2018-01-28 04:46:39 +08:00
|
|
|
#!/usr/bin/env python3
|
2018-03-21 03:00:02 +08:00
|
|
|
#
|
2018-04-04 21:35:41 +08:00
|
|
|
# This work is licensed under the GNU GPLv2 or later.
|
2018-03-21 03:00:02 +08:00
|
|
|
# See the COPYING file in the top-level directory.
|
|
|
|
|
2013-03-17 09:32:29 +08:00
|
|
|
|
|
|
|
import glob
|
2013-04-04 07:07:42 +08:00
|
|
|
import fnmatch
|
2013-03-17 09:32:29 +08:00
|
|
|
import os
|
2018-12-07 16:28:55 +08:00
|
|
|
import subprocess
|
2013-03-18 06:18:22 +08:00
|
|
|
import sys
|
|
|
|
import unittest
|
2013-03-17 09:32:29 +08:00
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
import distutils
|
|
|
|
import distutils.command.build
|
|
|
|
import distutils.command.install
|
2015-11-03 05:19:31 +08:00
|
|
|
import distutils.command.install_data
|
2015-11-03 06:06:46 +08:00
|
|
|
import distutils.command.install_egg_info
|
|
|
|
import distutils.command.sdist
|
2015-11-03 05:19:31 +08:00
|
|
|
import distutils.dist
|
|
|
|
import distutils.log
|
2015-11-03 06:06:46 +08:00
|
|
|
import distutils.sysconfig
|
2013-03-17 09:32:29 +08:00
|
|
|
|
2018-12-07 16:28:55 +08:00
|
|
|
|
2018-03-22 06:00:38 +08:00
|
|
|
if sys.version_info.major < 3:
|
|
|
|
print("virt-manager is python3 only. Run this as ./setup.py")
|
|
|
|
sys.exit(1)
|
|
|
|
|
2015-04-07 03:42:40 +08:00
|
|
|
from virtcli import CLIConfig
|
2013-03-17 09:32:29 +08:00
|
|
|
|
2016-04-19 04:42:12 +08:00
|
|
|
sysprefix = distutils.sysconfig.get_config_var("prefix")
|
|
|
|
|
2013-03-17 09:32:29 +08:00
|
|
|
|
2014-04-03 06:39:43 +08:00
|
|
|
# pylint: disable=attribute-defined-outside-init
|
|
|
|
|
2016-06-18 05:31:24 +08:00
|
|
|
_desktop_files = [
|
|
|
|
("share/applications", ["data/virt-manager.desktop.in"]),
|
|
|
|
]
|
|
|
|
_appdata_files = [
|
|
|
|
("share/appdata", ["data/virt-manager.appdata.xml.in"]),
|
|
|
|
]
|
|
|
|
|
|
|
|
|
2018-12-07 16:28:55 +08:00
|
|
|
def bash_completion_dir():
|
|
|
|
(sts, output) = subprocess.getstatusoutput(
|
|
|
|
'pkg-config --variable=completionsdir bash-completion')
|
|
|
|
return output if not sts and output else '/etc/bash_completion.d'
|
|
|
|
|
|
|
|
|
2013-04-04 07:07:42 +08:00
|
|
|
def _generate_potfiles_in():
|
|
|
|
def find(dirname, ext):
|
|
|
|
ret = []
|
2013-04-12 20:26:21 +08:00
|
|
|
for root, ignore, filenames in os.walk(dirname):
|
2013-04-04 07:07:42 +08:00
|
|
|
for filename in fnmatch.filter(filenames, ext):
|
|
|
|
ret.append(os.path.join(root, filename))
|
|
|
|
ret.sort(key=lambda s: s.lower())
|
|
|
|
return ret
|
|
|
|
|
2013-04-19 04:03:43 +08:00
|
|
|
scripts = ["virt-manager", "virt-install",
|
2014-09-07 06:05:43 +08:00
|
|
|
"virt-clone", "virt-convert", "virt-xml"]
|
2013-04-04 07:07:42 +08:00
|
|
|
|
|
|
|
potfiles = "\n".join(scripts) + "\n\n"
|
|
|
|
potfiles += "\n".join(find("virtManager", "*.py")) + "\n\n"
|
|
|
|
potfiles += "\n".join(find("virtcli", "*.py")) + "\n\n"
|
|
|
|
potfiles += "\n".join(find("virtconv", "*.py")) + "\n\n"
|
|
|
|
potfiles += "\n".join(find("virtinst", "*.py")) + "\n\n"
|
|
|
|
|
2016-06-18 05:31:24 +08:00
|
|
|
for ignore, filelist in _desktop_files + _appdata_files:
|
|
|
|
potfiles += "\n".join(filelist) + "\n"
|
|
|
|
potfiles += "\n"
|
|
|
|
|
2013-04-04 07:07:42 +08:00
|
|
|
potfiles += "\n".join(["[type: gettext/glade]" + f for
|
2016-06-18 05:31:24 +08:00
|
|
|
f in find("ui", "*.ui")]) + "\n\n"
|
2013-04-04 07:07:42 +08:00
|
|
|
|
|
|
|
return potfiles
|
|
|
|
|
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
class my_build_i18n(distutils.command.build.build):
|
2013-03-17 09:32:29 +08:00
|
|
|
"""
|
|
|
|
Add our desktop files to the list, saves us having to track setup.cfg
|
|
|
|
"""
|
2013-04-19 04:51:44 +08:00
|
|
|
user_options = [
|
|
|
|
('merge-po', 'm', 'merge po files against template'),
|
|
|
|
]
|
2013-03-17 09:32:29 +08:00
|
|
|
|
2013-04-19 04:51:44 +08:00
|
|
|
def initialize_options(self):
|
|
|
|
self.merge_po = False
|
|
|
|
def finalize_options(self):
|
|
|
|
pass
|
2013-03-17 09:32:29 +08:00
|
|
|
|
2013-04-04 07:07:42 +08:00
|
|
|
def run(self):
|
|
|
|
potfiles = _generate_potfiles_in()
|
|
|
|
potpath = "po/POTFILES.in"
|
|
|
|
|
|
|
|
try:
|
2017-05-06 02:16:59 +08:00
|
|
|
print("Writing %s" % potpath)
|
2017-05-06 02:19:54 +08:00
|
|
|
open(potpath, "w").write(potfiles)
|
2013-04-19 04:51:44 +08:00
|
|
|
self._run()
|
2013-04-04 07:07:42 +08:00
|
|
|
finally:
|
2017-05-06 02:16:59 +08:00
|
|
|
print("Removing %s" % potpath)
|
2013-04-04 07:07:42 +08:00
|
|
|
os.unlink(potpath)
|
|
|
|
|
2013-04-19 04:51:44 +08:00
|
|
|
def _run(self):
|
|
|
|
# Borrowed from python-distutils-extra
|
|
|
|
po_dir = "po"
|
|
|
|
|
|
|
|
# Update po(t) files and print a report
|
|
|
|
# We have to change the working dir to the po dir for intltool
|
|
|
|
cmd = ["intltool-update",
|
|
|
|
(self.merge_po and "-r" or "-p"), "-g", "virt-manager"]
|
|
|
|
|
|
|
|
wd = os.getcwd()
|
|
|
|
os.chdir("po")
|
|
|
|
self.spawn(cmd)
|
|
|
|
os.chdir(wd)
|
|
|
|
max_po_mtime = 0
|
|
|
|
for po_file in glob.glob("%s/*.po" % po_dir):
|
|
|
|
lang = os.path.basename(po_file[:-3])
|
|
|
|
mo_dir = os.path.join("build", "mo", lang, "LC_MESSAGES")
|
|
|
|
mo_file = os.path.join(mo_dir, "virt-manager.mo")
|
|
|
|
if not os.path.exists(mo_dir):
|
|
|
|
os.makedirs(mo_dir)
|
|
|
|
|
|
|
|
cmd = ["msgfmt", po_file, "-o", mo_file]
|
|
|
|
po_mtime = os.path.getmtime(po_file)
|
|
|
|
mo_mtime = (os.path.exists(mo_file) and
|
|
|
|
os.path.getmtime(mo_file)) or 0
|
|
|
|
if po_mtime > max_po_mtime:
|
|
|
|
max_po_mtime = po_mtime
|
|
|
|
if po_mtime > mo_mtime:
|
|
|
|
self.spawn(cmd)
|
|
|
|
|
|
|
|
targetpath = os.path.join("share/locale", lang, "LC_MESSAGES")
|
|
|
|
self.distribution.data_files.append((targetpath, (mo_file,)))
|
|
|
|
|
|
|
|
# merge .in with translation
|
2016-06-18 05:31:24 +08:00
|
|
|
for (file_set, switch) in [(_desktop_files, "-d"),
|
|
|
|
(_appdata_files, "-x")]:
|
2013-04-19 04:51:44 +08:00
|
|
|
for (target, files) in file_set:
|
|
|
|
build_target = os.path.join("build", target)
|
|
|
|
if not os.path.exists(build_target):
|
|
|
|
os.makedirs(build_target)
|
|
|
|
|
|
|
|
files_merged = []
|
|
|
|
for f in files:
|
|
|
|
if f.endswith(".in"):
|
|
|
|
file_merged = os.path.basename(f[:-3])
|
|
|
|
else:
|
|
|
|
file_merged = os.path.basename(f)
|
|
|
|
|
|
|
|
file_merged = os.path.join(build_target, file_merged)
|
|
|
|
cmd = ["intltool-merge", switch, po_dir, f,
|
|
|
|
file_merged]
|
|
|
|
mtime_merged = (os.path.exists(file_merged) and
|
|
|
|
os.path.getmtime(file_merged)) or 0
|
|
|
|
mtime_file = os.path.getmtime(f)
|
|
|
|
if (mtime_merged < max_po_mtime or
|
|
|
|
mtime_merged < mtime_file):
|
|
|
|
# Only build if output is older than input (.po,.in)
|
|
|
|
self.spawn(cmd)
|
|
|
|
files_merged.append(file_merged)
|
|
|
|
self.distribution.data_files.append((target, files_merged))
|
|
|
|
|
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
class my_build(distutils.command.build.build):
|
2013-03-17 09:32:29 +08:00
|
|
|
"""
|
|
|
|
Create simple shell wrappers for /usr/bin/ tools to point to /usr/share
|
|
|
|
Compile .pod file
|
|
|
|
"""
|
|
|
|
|
2013-03-18 07:32:19 +08:00
|
|
|
def _make_bin_wrappers(self):
|
|
|
|
cmds = ["virt-manager", "virt-install", "virt-clone",
|
2014-09-07 06:05:43 +08:00
|
|
|
"virt-convert", "virt-xml"]
|
2013-03-17 09:32:29 +08:00
|
|
|
|
2013-03-18 07:32:19 +08:00
|
|
|
if not os.path.exists("build"):
|
|
|
|
os.mkdir("build")
|
|
|
|
|
2013-03-17 09:32:29 +08:00
|
|
|
for app in cmds:
|
2015-04-07 03:42:40 +08:00
|
|
|
sharepath = os.path.join(CLIConfig.prefix,
|
|
|
|
"share", "virt-manager", app)
|
2013-03-17 09:32:29 +08:00
|
|
|
|
|
|
|
wrapper = "#!/bin/sh\n\n"
|
2013-03-18 07:32:19 +08:00
|
|
|
wrapper += "exec \"%s\" \"$@\"" % (sharepath)
|
|
|
|
|
|
|
|
newpath = os.path.abspath(os.path.join("build", app))
|
2017-05-06 02:16:59 +08:00
|
|
|
print("Generating %s" % newpath)
|
2017-05-06 02:19:54 +08:00
|
|
|
open(newpath, "w").write(wrapper)
|
2013-03-18 07:32:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
def _make_man_pages(self):
|
|
|
|
for path in glob.glob("man/*.pod"):
|
|
|
|
base = os.path.basename(path)
|
2014-09-07 06:05:43 +08:00
|
|
|
appname = os.path.splitext(base)[0]
|
2013-03-18 07:32:19 +08:00
|
|
|
newpath = os.path.join(os.path.dirname(path),
|
2014-09-07 06:05:43 +08:00
|
|
|
appname + ".1")
|
2013-03-18 07:32:19 +08:00
|
|
|
|
2017-05-06 02:16:59 +08:00
|
|
|
print("Generating %s" % newpath)
|
2013-08-19 04:04:54 +08:00
|
|
|
ret = os.system('pod2man '
|
2013-03-18 07:32:19 +08:00
|
|
|
'--center "Virtual Machine Manager" '
|
2013-08-19 04:04:54 +08:00
|
|
|
'--release %s --name %s '
|
2015-04-07 03:42:40 +08:00
|
|
|
'< %s > %s' % (CLIConfig.version,
|
2013-08-19 04:04:54 +08:00
|
|
|
appname.upper(),
|
|
|
|
path, newpath))
|
2013-03-18 07:32:19 +08:00
|
|
|
if ret != 0:
|
|
|
|
raise RuntimeError("Generating '%s' failed." % newpath)
|
|
|
|
|
|
|
|
if os.system("grep -IRq 'Hey!' man/") == 0:
|
|
|
|
raise RuntimeError("man pages have errors in them! "
|
|
|
|
"(grep for 'Hey!')")
|
|
|
|
|
2013-04-19 04:51:44 +08:00
|
|
|
def _build_icons(self):
|
|
|
|
for size in glob.glob(os.path.join("data/icons", "*")):
|
2013-03-17 09:32:29 +08:00
|
|
|
for category in glob.glob(os.path.join(size, "*")):
|
|
|
|
icons = []
|
2013-04-14 02:34:52 +08:00
|
|
|
for icon in glob.glob(os.path.join(category, "*")):
|
2013-04-19 04:51:44 +08:00
|
|
|
icons.append(icon)
|
2013-03-17 09:32:29 +08:00
|
|
|
if not icons:
|
|
|
|
continue
|
|
|
|
|
|
|
|
category = os.path.basename(category)
|
|
|
|
dest = ("share/icons/hicolor/%s/%s" %
|
|
|
|
(os.path.basename(size), category))
|
|
|
|
if category != "apps":
|
|
|
|
dest = dest.replace("share/", "share/virt-manager/")
|
|
|
|
|
2013-04-19 04:51:44 +08:00
|
|
|
self.distribution.data_files.append((dest, icons))
|
|
|
|
|
|
|
|
|
2018-12-07 16:28:55 +08:00
|
|
|
def _make_bash_completion_files(self):
|
|
|
|
scripts = ["virt-install", "virt-clone", "virt-convert", "virt-xml"]
|
|
|
|
path = "data/bash-completion"
|
|
|
|
for script in scripts:
|
|
|
|
print("Generating %s/%s" % (path, script))
|
|
|
|
ret = os.system('cp -f '
|
|
|
|
'%s/virtmanager %s/%s' % (path, path, script))
|
|
|
|
if ret != 0:
|
|
|
|
raise RuntimeError("Copying template file "
|
|
|
|
"%s/virtmanager to %s/%s' failed."
|
|
|
|
% (path, path, script))
|
|
|
|
|
|
|
|
ret = os.system('sed -i s/virtmanager/%s/ %s/%s'
|
|
|
|
% (script, path, script))
|
|
|
|
if ret != 0:
|
|
|
|
raise RuntimeError("Updating %s/%s' failed." % (path, script))
|
|
|
|
|
|
|
|
|
2013-04-19 04:51:44 +08:00
|
|
|
def run(self):
|
|
|
|
self._make_bin_wrappers()
|
|
|
|
self._make_man_pages()
|
|
|
|
self._build_icons()
|
2018-12-07 16:28:55 +08:00
|
|
|
self._make_bash_completion_files()
|
2013-04-19 04:51:44 +08:00
|
|
|
|
|
|
|
self.run_command("build_i18n")
|
2015-11-03 06:06:46 +08:00
|
|
|
distutils.command.build.build.run(self)
|
2013-03-17 09:32:29 +08:00
|
|
|
|
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
class my_egg_info(distutils.command.install_egg_info.install_egg_info):
|
2013-03-17 09:32:29 +08:00
|
|
|
"""
|
|
|
|
Disable egg_info installation, seems pointless for a non-library
|
|
|
|
"""
|
|
|
|
def run(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
class my_install(distutils.command.install.install):
|
2013-04-11 05:25:39 +08:00
|
|
|
"""
|
|
|
|
Error if we weren't 'configure'd with the correct install prefix
|
|
|
|
"""
|
|
|
|
def finalize_options(self):
|
|
|
|
if self.prefix is None:
|
2015-04-07 03:42:40 +08:00
|
|
|
if CLIConfig.prefix != sysprefix:
|
2017-05-06 02:16:59 +08:00
|
|
|
print("Using configured prefix=%s instead of sysprefix=%s" % (
|
|
|
|
CLIConfig.prefix, sysprefix))
|
2015-04-07 03:42:40 +08:00
|
|
|
self.prefix = CLIConfig.prefix
|
2015-09-24 07:29:13 +08:00
|
|
|
else:
|
2017-05-06 02:16:59 +08:00
|
|
|
print("Using sysprefix=%s" % sysprefix)
|
2015-09-24 07:29:13 +08:00
|
|
|
self.prefix = sysprefix
|
|
|
|
|
2015-04-07 03:42:40 +08:00
|
|
|
elif self.prefix != CLIConfig.prefix:
|
2014-02-12 23:30:48 +08:00
|
|
|
print("Install prefix=%s doesn't match configure prefix=%s\n"
|
|
|
|
"Pass matching --prefix to 'setup.py configure'" %
|
2015-04-07 03:42:40 +08:00
|
|
|
(self.prefix, CLIConfig.prefix))
|
2013-04-11 05:25:39 +08:00
|
|
|
sys.exit(1)
|
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
distutils.command.install.install.finalize_options(self)
|
2013-04-11 05:25:39 +08:00
|
|
|
|
2013-04-17 08:44:16 +08:00
|
|
|
|
2015-11-03 05:19:31 +08:00
|
|
|
class my_install_data(distutils.command.install_data.install_data):
|
|
|
|
def run(self):
|
|
|
|
distutils.command.install_data.install_data.run(self)
|
|
|
|
|
|
|
|
if not self.distribution.no_update_icon_cache:
|
|
|
|
distutils.log.info("running gtk-update-icon-cache")
|
|
|
|
icon_path = os.path.join(self.install_dir, "share/icons/hicolor")
|
|
|
|
self.spawn(["gtk-update-icon-cache", "-q", "-t", icon_path])
|
|
|
|
|
|
|
|
if not self.distribution.no_compile_schemas:
|
|
|
|
distutils.log.info("compiling gsettings schemas")
|
|
|
|
gschema_install = os.path.join(self.install_dir,
|
|
|
|
"share/glib-2.0/schemas")
|
|
|
|
self.spawn(["glib-compile-schemas", gschema_install])
|
|
|
|
|
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
class my_sdist(distutils.command.sdist.sdist):
|
2013-04-17 20:25:07 +08:00
|
|
|
description = "Update virt-manager.spec; build sdist-tarball."
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
f1 = open('virt-manager.spec.in', 'r')
|
|
|
|
f2 = open('virt-manager.spec', 'w')
|
|
|
|
for line in f1:
|
2015-04-07 03:42:40 +08:00
|
|
|
f2.write(line.replace('@VERSION@', CLIConfig.version))
|
2013-04-17 20:25:07 +08:00
|
|
|
f1.close()
|
|
|
|
f2.close()
|
2013-04-18 03:14:52 +08:00
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
distutils.command.sdist.sdist.run(self)
|
2013-04-17 20:25:07 +08:00
|
|
|
|
2013-04-11 05:25:39 +08:00
|
|
|
|
2013-03-17 09:32:29 +08:00
|
|
|
###################
|
|
|
|
# Custom commands #
|
|
|
|
###################
|
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
class my_rpm(distutils.core.Command):
|
2015-04-07 02:51:14 +08:00
|
|
|
user_options = []
|
2013-04-17 08:44:16 +08:00
|
|
|
description = "Build src and noarch rpms."
|
2013-03-17 09:32:29 +08:00
|
|
|
|
|
|
|
def initialize_options(self):
|
2015-04-07 02:51:14 +08:00
|
|
|
pass
|
2013-03-17 09:32:29 +08:00
|
|
|
def finalize_options(self):
|
2015-04-07 02:51:14 +08:00
|
|
|
pass
|
2013-03-17 09:32:29 +08:00
|
|
|
|
|
|
|
def run(self):
|
|
|
|
"""
|
|
|
|
Run sdist, then 'rpmbuild' the tar.gz
|
|
|
|
"""
|
|
|
|
self.run_command('sdist')
|
2013-04-17 08:44:16 +08:00
|
|
|
os.system('rpmbuild -ta --clean dist/virt-manager-%s.tar.gz' %
|
2015-04-07 03:42:40 +08:00
|
|
|
CLIConfig.version)
|
2013-03-17 09:32:29 +08:00
|
|
|
|
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
class configure(distutils.core.Command):
|
2013-03-17 09:32:29 +08:00
|
|
|
user_options = [
|
2013-04-11 05:25:39 +08:00
|
|
|
("prefix=", None, "installation prefix"),
|
2013-03-17 09:32:29 +08:00
|
|
|
("default-graphics=", None,
|
2013-05-28 06:51:12 +08:00
|
|
|
"Default graphics type (spice or vnc) (default=spice)"),
|
2015-04-07 04:29:28 +08:00
|
|
|
("default-hvs=", None,
|
|
|
|
"Comma separated list of hypervisors shown in 'Open Connection' "
|
|
|
|
"wizard. (default=all hvs)"),
|
2013-03-17 09:32:29 +08:00
|
|
|
|
|
|
|
]
|
|
|
|
description = "Configure the build, similar to ./configure"
|
|
|
|
|
|
|
|
def finalize_options(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def initialize_options(self):
|
2013-04-11 05:25:39 +08:00
|
|
|
self.prefix = sysprefix
|
2013-10-03 06:50:01 +08:00
|
|
|
self.default_graphics = None
|
2015-04-07 04:29:28 +08:00
|
|
|
self.default_hvs = None
|
2013-03-17 09:32:29 +08:00
|
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
template = ""
|
|
|
|
template += "[config]\n"
|
2013-04-11 05:25:39 +08:00
|
|
|
template += "prefix = %s\n" % self.prefix
|
2013-10-03 06:50:01 +08:00
|
|
|
if self.default_graphics is not None:
|
|
|
|
template += "default_graphics = %s\n" % self.default_graphics
|
2015-04-07 04:29:28 +08:00
|
|
|
if self.default_hvs is not None:
|
|
|
|
template += "default_hvs = %s\n" % self.default_hvs
|
2013-03-17 09:32:29 +08:00
|
|
|
|
2017-05-06 02:19:54 +08:00
|
|
|
open(CLIConfig.cfgpath, "w").write(template)
|
2017-05-06 02:16:59 +08:00
|
|
|
print("Generated %s" % CLIConfig.cfgpath)
|
2013-03-17 09:32:29 +08:00
|
|
|
|
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
class TestBaseCommand(distutils.core.Command):
|
2013-07-03 05:37:45 +08:00
|
|
|
user_options = [
|
|
|
|
('debug', 'd', 'Show debug output'),
|
2018-02-23 03:18:18 +08:00
|
|
|
('testverbose', None, 'Show verbose output'),
|
2013-07-14 04:32:46 +08:00
|
|
|
('coverage', 'c', 'Show coverage report'),
|
2014-02-04 04:53:54 +08:00
|
|
|
('regenerate-output', None, 'Regenerate test output'),
|
2013-07-14 04:32:46 +08:00
|
|
|
("only=", None,
|
|
|
|
"Run only testcases whose name contains the passed string"),
|
2015-09-07 06:37:49 +08:00
|
|
|
("testfile=", None, "Specific test file to run (e.g "
|
|
|
|
"validation, storage, ...)"),
|
2013-07-03 05:37:45 +08:00
|
|
|
]
|
2013-03-18 06:18:22 +08:00
|
|
|
|
|
|
|
def initialize_options(self):
|
|
|
|
self.debug = 0
|
2018-02-23 03:18:18 +08:00
|
|
|
self.testverbose = 0
|
2014-02-04 04:53:54 +08:00
|
|
|
self.regenerate_output = 0
|
2013-07-03 05:37:45 +08:00
|
|
|
self.coverage = 0
|
2013-07-14 04:32:46 +08:00
|
|
|
self.only = None
|
2013-03-18 06:18:22 +08:00
|
|
|
self._testfiles = []
|
|
|
|
self._dir = os.getcwd()
|
2015-09-07 06:37:49 +08:00
|
|
|
self.testfile = None
|
2018-01-08 20:07:55 +08:00
|
|
|
self._force_verbose = False
|
2018-01-09 07:00:14 +08:00
|
|
|
self._external_coverage = False
|
2013-03-18 06:18:22 +08:00
|
|
|
|
|
|
|
def finalize_options(self):
|
2016-06-12 03:52:08 +08:00
|
|
|
if self.only:
|
|
|
|
# Can do --only many-devices to match on the cli testcase
|
|
|
|
# for "virt-install-many-devices", despite the actual test
|
|
|
|
# function name not containing any '-'
|
|
|
|
self.only = self.only.replace("-", "_")
|
2013-03-18 06:18:22 +08:00
|
|
|
|
2015-09-07 06:37:49 +08:00
|
|
|
def _find_tests_in_dir(self, dirname, excludes):
|
|
|
|
testfiles = []
|
|
|
|
for t in sorted(glob.glob(os.path.join(self._dir, dirname, '*.py'))):
|
|
|
|
base = os.path.basename(t)
|
|
|
|
if base in excludes + ["__init__.py"]:
|
|
|
|
continue
|
|
|
|
|
|
|
|
if self.testfile:
|
|
|
|
check = os.path.basename(self.testfile)
|
|
|
|
if base != check and base != (check + ".py"):
|
|
|
|
continue
|
|
|
|
|
|
|
|
testfiles.append('.'.join(
|
|
|
|
dirname.split("/") + [os.path.splitext(base)[0]]))
|
|
|
|
|
|
|
|
if not testfiles:
|
|
|
|
raise RuntimeError("--testfile didn't catch anything")
|
|
|
|
return testfiles
|
|
|
|
|
2013-03-18 06:18:22 +08:00
|
|
|
def run(self):
|
2018-01-08 20:03:25 +08:00
|
|
|
cov = None
|
|
|
|
if self.coverage:
|
2013-03-18 06:18:22 +08:00
|
|
|
import coverage
|
2018-01-09 07:00:14 +08:00
|
|
|
omit = ["/usr/*", "/*/tests/*"]
|
2013-07-03 05:37:45 +08:00
|
|
|
cov = coverage.coverage(omit=omit)
|
|
|
|
cov.erase()
|
2018-01-09 07:00:14 +08:00
|
|
|
if not self._external_coverage:
|
|
|
|
cov.start()
|
2013-07-03 05:37:45 +08:00
|
|
|
|
|
|
|
import tests as testsmodule
|
2018-01-09 06:05:55 +08:00
|
|
|
testsmodule.utils.clistate.regenerate_output = bool(
|
|
|
|
self.regenerate_output)
|
2018-01-09 07:00:14 +08:00
|
|
|
testsmodule.utils.clistate.use_coverage = bool(cov)
|
2018-02-23 02:46:24 +08:00
|
|
|
testsmodule.utils.clistate.debug = bool(self.debug)
|
|
|
|
testsmodule.setup_logging()
|
|
|
|
testsmodule.setup_cli_imports()
|
2013-03-18 06:18:22 +08:00
|
|
|
|
2018-01-08 21:44:54 +08:00
|
|
|
# This makes the test runner report results before exiting from ctrl-c
|
|
|
|
unittest.installHandler()
|
2013-03-18 06:18:22 +08:00
|
|
|
|
2013-07-14 04:32:46 +08:00
|
|
|
tests = unittest.TestLoader().loadTestsFromNames(self._testfiles)
|
|
|
|
if self.only:
|
|
|
|
newtests = []
|
|
|
|
for suite1 in tests:
|
|
|
|
for suite2 in suite1:
|
|
|
|
for testcase in suite2:
|
|
|
|
if self.only in str(testcase):
|
|
|
|
newtests.append(testcase)
|
|
|
|
|
|
|
|
if not newtests:
|
2017-05-06 02:16:59 +08:00
|
|
|
print("--only didn't find any tests")
|
2013-07-14 04:32:46 +08:00
|
|
|
sys.exit(1)
|
|
|
|
tests = unittest.TestSuite(newtests)
|
2017-05-06 02:16:59 +08:00
|
|
|
print("Running only:")
|
2013-07-14 04:32:46 +08:00
|
|
|
for test in newtests:
|
2017-05-06 02:16:59 +08:00
|
|
|
print("%s" % test)
|
2017-07-10 19:48:30 +08:00
|
|
|
print("")
|
2013-07-14 04:32:46 +08:00
|
|
|
|
2018-01-08 20:07:55 +08:00
|
|
|
verbosity = 1
|
2018-02-23 03:18:18 +08:00
|
|
|
if self.debug or self.testverbose or self._force_verbose:
|
2018-01-08 20:07:55 +08:00
|
|
|
verbosity = 2
|
|
|
|
t = unittest.TextTestRunner(verbosity=verbosity)
|
2013-07-14 04:32:46 +08:00
|
|
|
|
2013-03-18 06:18:22 +08:00
|
|
|
try:
|
|
|
|
result = t.run(tests)
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
sys.exit(1)
|
|
|
|
|
2018-01-08 20:03:25 +08:00
|
|
|
if cov:
|
2018-01-09 07:00:14 +08:00
|
|
|
if self._external_coverage:
|
|
|
|
cov.load()
|
|
|
|
else:
|
|
|
|
cov.stop()
|
|
|
|
cov.save()
|
2013-07-03 05:37:45 +08:00
|
|
|
|
|
|
|
err = int(bool(len(result.failures) > 0 or
|
|
|
|
len(result.errors) > 0))
|
2018-01-08 20:03:25 +08:00
|
|
|
if cov and not err:
|
2013-07-03 05:37:45 +08:00
|
|
|
cov.report(show_missing=False)
|
|
|
|
sys.exit(err)
|
2013-03-18 06:18:22 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestCommand(TestBaseCommand):
|
|
|
|
description = "Runs a quick unit test suite"
|
|
|
|
|
|
|
|
def initialize_options(self):
|
|
|
|
TestBaseCommand.initialize_options(self)
|
|
|
|
|
|
|
|
def finalize_options(self):
|
|
|
|
TestBaseCommand.finalize_options(self)
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
'''
|
|
|
|
Finds all the tests modules in tests/, and runs them.
|
|
|
|
'''
|
2018-02-21 01:33:57 +08:00
|
|
|
excludes = ["dist.py", "test_urls.py", "test_inject.py"]
|
2015-09-07 06:37:49 +08:00
|
|
|
testfiles = self._find_tests_in_dir("tests", excludes)
|
2013-03-18 06:18:22 +08:00
|
|
|
|
2015-04-22 08:12:37 +08:00
|
|
|
# Put clitest at the end, since it takes the longest
|
|
|
|
for f in testfiles[:]:
|
|
|
|
if "clitest" in f:
|
|
|
|
testfiles.remove(f)
|
|
|
|
testfiles.append(f)
|
|
|
|
|
|
|
|
# Always want to put checkprops at the end to get accurate results
|
|
|
|
for f in testfiles[:]:
|
|
|
|
if "checkprops" in f:
|
|
|
|
testfiles.remove(f)
|
2018-01-06 07:14:23 +08:00
|
|
|
if not self.testfile:
|
2015-04-22 08:12:37 +08:00
|
|
|
testfiles.append(f)
|
|
|
|
|
2013-03-18 06:18:22 +08:00
|
|
|
self._testfiles = testfiles
|
|
|
|
TestBaseCommand.run(self)
|
|
|
|
|
|
|
|
|
2015-09-07 06:37:49 +08:00
|
|
|
class TestUI(TestBaseCommand):
|
|
|
|
description = "Run UI dogtails tests"
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
self._testfiles = self._find_tests_in_dir("tests/uitests", [])
|
2018-01-08 20:07:55 +08:00
|
|
|
self._force_verbose = True
|
2018-01-09 07:00:14 +08:00
|
|
|
self._external_coverage = True
|
2015-09-07 06:37:49 +08:00
|
|
|
TestBaseCommand.run(self)
|
|
|
|
|
|
|
|
|
2013-03-18 06:18:22 +08:00
|
|
|
class TestURLFetch(TestBaseCommand):
|
|
|
|
description = "Test fetching kernels and isos from various distro trees"
|
|
|
|
|
|
|
|
def initialize_options(self):
|
|
|
|
TestBaseCommand.initialize_options(self)
|
|
|
|
self.path = ""
|
|
|
|
|
|
|
|
def finalize_options(self):
|
|
|
|
TestBaseCommand.finalize_options(self)
|
|
|
|
origpath = str(self.path)
|
|
|
|
if not origpath:
|
|
|
|
self.path = []
|
|
|
|
else:
|
|
|
|
self.path = origpath.split(",")
|
|
|
|
|
|
|
|
def run(self):
|
2013-09-26 06:52:41 +08:00
|
|
|
self._testfiles = ["tests.test_urls"]
|
2013-03-18 06:18:22 +08:00
|
|
|
TestBaseCommand.run(self)
|
|
|
|
|
|
|
|
|
2013-09-29 02:42:37 +08:00
|
|
|
class TestInitrdInject(TestBaseCommand):
|
|
|
|
description = "Test initrd inject with real kernels, fetched from URLs"
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
self._testfiles = ["tests.test_inject"]
|
|
|
|
TestBaseCommand.run(self)
|
|
|
|
|
|
|
|
|
2018-02-21 01:33:57 +08:00
|
|
|
class TestDist(TestBaseCommand):
|
|
|
|
description = "Tests to run before cutting a release"
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
self._testfiles = ["tests.dist"]
|
|
|
|
TestBaseCommand.run(self)
|
|
|
|
|
|
|
|
|
2018-05-22 03:42:49 +08:00
|
|
|
class CheckSpell(distutils.core.Command):
|
|
|
|
user_options = []
|
|
|
|
description = "Check code for common misspellings"
|
|
|
|
|
|
|
|
def initialize_options(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def finalize_options(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
try:
|
|
|
|
import codespell_lib
|
|
|
|
except ImportError:
|
|
|
|
raise ImportError('codespell is not installed')
|
|
|
|
|
|
|
|
files = ["setup.py", "virt-install", "virt-clone",
|
|
|
|
"virt-convert", "virt-xml", "virt-manager",
|
|
|
|
"virtcli", "virtinst", "virtconv", "virtManager",
|
|
|
|
"tests"]
|
|
|
|
# pylint: disable=protected-access
|
|
|
|
codespell_lib._codespell.main(
|
|
|
|
'-I', 'tests/codespell_dict.txt',
|
|
|
|
'--skip', '*.pyc,*.zip,*.vmdk,*.iso,*.xml', *files)
|
|
|
|
|
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
class CheckPylint(distutils.core.Command):
|
2017-09-09 17:08:31 +08:00
|
|
|
user_options = [
|
|
|
|
("jobs=", "j", "use multiple processes to speed up Pylint"),
|
|
|
|
]
|
2017-07-24 16:26:47 +08:00
|
|
|
description = "Check code using pylint and pycodestyle"
|
2013-04-11 04:02:28 +08:00
|
|
|
|
|
|
|
def initialize_options(self):
|
2017-09-09 17:08:31 +08:00
|
|
|
self.jobs = None
|
|
|
|
|
2013-04-11 04:02:28 +08:00
|
|
|
def finalize_options(self):
|
2017-09-09 17:08:31 +08:00
|
|
|
if self.jobs:
|
|
|
|
self.jobs = int(self.jobs)
|
2013-04-11 04:02:28 +08:00
|
|
|
|
|
|
|
def run(self):
|
2018-03-02 16:01:21 +08:00
|
|
|
import pylint.lint
|
2018-03-02 16:01:25 +08:00
|
|
|
import pycodestyle
|
2018-03-02 16:01:21 +08:00
|
|
|
|
2014-09-07 06:05:43 +08:00
|
|
|
files = ["setup.py", "virt-install", "virt-clone",
|
2014-01-19 23:37:14 +08:00
|
|
|
"virt-convert", "virt-xml", "virt-manager",
|
2013-04-11 04:02:28 +08:00
|
|
|
"virtcli", "virtinst", "virtconv", "virtManager",
|
2013-04-19 04:03:43 +08:00
|
|
|
"tests"]
|
2013-04-11 04:02:28 +08:00
|
|
|
|
|
|
|
output_format = sys.stdout.isatty() and "colorized" or "text"
|
|
|
|
|
2017-07-24 16:26:47 +08:00
|
|
|
print("running pycodestyle")
|
2018-03-02 16:01:25 +08:00
|
|
|
style_guide = pycodestyle.StyleGuide(
|
|
|
|
config_file='tests/pycodestyle.cfg',
|
|
|
|
paths=files
|
|
|
|
)
|
|
|
|
report = style_guide.check_files()
|
|
|
|
if style_guide.options.count:
|
|
|
|
sys.stderr.write(str(report.total_errors) + '\n')
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2017-05-06 02:16:59 +08:00
|
|
|
print("running pylint")
|
2018-03-02 16:01:21 +08:00
|
|
|
pylint_opts = [
|
|
|
|
"--rcfile", "tests/pylint.cfg",
|
|
|
|
"--output-format=%s" % output_format,
|
2018-10-25 20:37:42 +08:00
|
|
|
]
|
2017-09-09 17:08:31 +08:00
|
|
|
if self.jobs:
|
2018-03-02 16:01:21 +08:00
|
|
|
pylint_opts += ["--jobs=%d" % self.jobs]
|
|
|
|
|
|
|
|
pylint.lint.Run(files + pylint_opts)
|
2015-09-14 03:07:23 +08:00
|
|
|
|
2013-04-11 04:02:28 +08:00
|
|
|
|
2015-11-03 05:19:31 +08:00
|
|
|
class VMMDistribution(distutils.dist.Distribution):
|
|
|
|
global_options = distutils.dist.Distribution.global_options + [
|
|
|
|
("no-update-icon-cache", None, "Don't run gtk-update-icon-cache"),
|
|
|
|
("no-compile-schemas", None, "Don't compile gsettings schemas"),
|
|
|
|
]
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
self.no_update_icon_cache = False
|
|
|
|
self.no_compile_schemas = False
|
|
|
|
distutils.dist.Distribution.__init__(self, *args, **kwargs)
|
|
|
|
|
|
|
|
|
2015-11-03 06:06:46 +08:00
|
|
|
distutils.core.setup(
|
2013-04-14 02:34:52 +08:00
|
|
|
name="virt-manager",
|
2015-04-07 03:42:40 +08:00
|
|
|
version=CLIConfig.version,
|
2013-04-14 02:34:52 +08:00
|
|
|
author="Cole Robinson",
|
|
|
|
author_email="virt-tools-list@redhat.com",
|
|
|
|
url="http://virt-manager.org",
|
|
|
|
license="GPLv2+",
|
2013-03-17 09:32:29 +08:00
|
|
|
|
2013-03-18 07:32:19 +08:00
|
|
|
# These wrappers are generated in our custom build command
|
2013-04-14 02:34:52 +08:00
|
|
|
scripts=([
|
2013-03-18 07:32:19 +08:00
|
|
|
"build/virt-manager",
|
|
|
|
"build/virt-clone",
|
|
|
|
"build/virt-install",
|
2014-01-19 23:37:14 +08:00
|
|
|
"build/virt-convert",
|
|
|
|
"build/virt-xml"]),
|
2013-03-17 09:32:29 +08:00
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
data_files=[
|
2013-03-18 07:32:19 +08:00
|
|
|
("share/virt-manager/", [
|
|
|
|
"virt-manager",
|
|
|
|
"virt-install",
|
|
|
|
"virt-clone",
|
|
|
|
"virt-convert",
|
2014-01-19 23:37:14 +08:00
|
|
|
"virt-xml",
|
2013-03-18 07:32:19 +08:00
|
|
|
]),
|
2013-04-18 05:39:25 +08:00
|
|
|
("share/glib-2.0/schemas",
|
|
|
|
["data/org.virt-manager.virt-manager.gschema.xml"]),
|
2013-03-17 09:32:29 +08:00
|
|
|
("share/virt-manager/ui", glob.glob("ui/*.ui")),
|
|
|
|
|
2013-03-18 07:32:19 +08:00
|
|
|
("share/man/man1", [
|
|
|
|
"man/virt-manager.1",
|
|
|
|
"man/virt-install.1",
|
|
|
|
"man/virt-clone.1",
|
2014-01-19 23:37:14 +08:00
|
|
|
"man/virt-convert.1",
|
|
|
|
"man/virt-xml.1"
|
2013-03-18 07:32:19 +08:00
|
|
|
]),
|
2013-03-17 09:32:29 +08:00
|
|
|
|
|
|
|
("share/virt-manager/virtManager", glob.glob("virtManager/*.py")),
|
2013-03-18 07:32:19 +08:00
|
|
|
|
2013-04-11 05:13:02 +08:00
|
|
|
("share/virt-manager/virtcli",
|
2013-04-15 00:51:22 +08:00
|
|
|
glob.glob("virtcli/*.py") + glob.glob("virtcli/cli.cfg")),
|
2013-03-18 07:32:19 +08:00
|
|
|
("share/virt-manager/virtinst", glob.glob("virtinst/*.py")),
|
2018-04-09 00:40:04 +08:00
|
|
|
("share/virt-manager/virtinst/devices", glob.glob("virtinst/devices/*.py")),
|
|
|
|
("share/virt-manager/virtinst/domain", glob.glob("virtinst/domain/*.py")),
|
2013-03-18 07:32:19 +08:00
|
|
|
("share/virt-manager/virtconv", glob.glob("virtconv/*.py")),
|
2018-12-07 16:28:55 +08:00
|
|
|
|
|
|
|
(bash_completion_dir(), glob.glob("data/bash-completion/virt-*")),
|
2013-04-19 04:03:43 +08:00
|
|
|
],
|
2013-03-17 09:32:29 +08:00
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
cmdclass={
|
2013-03-17 09:32:29 +08:00
|
|
|
'build': my_build,
|
|
|
|
'build_i18n': my_build_i18n,
|
2013-04-11 05:25:39 +08:00
|
|
|
|
2013-04-17 20:25:07 +08:00
|
|
|
'sdist': my_sdist,
|
2013-04-11 05:25:39 +08:00
|
|
|
'install': my_install,
|
2015-11-03 05:19:31 +08:00
|
|
|
'install_data': my_install_data,
|
2013-03-17 09:32:29 +08:00
|
|
|
'install_egg_info': my_egg_info,
|
|
|
|
|
|
|
|
'configure': configure,
|
|
|
|
|
2013-04-11 04:02:28 +08:00
|
|
|
'pylint': CheckPylint,
|
2018-05-22 03:42:49 +08:00
|
|
|
'codespell': CheckSpell,
|
2013-03-17 09:32:29 +08:00
|
|
|
'rpm': my_rpm,
|
2013-03-18 06:18:22 +08:00
|
|
|
'test': TestCommand,
|
2015-09-07 06:37:49 +08:00
|
|
|
'test_ui': TestUI,
|
2017-08-05 14:39:32 +08:00
|
|
|
'test_urls': TestURLFetch,
|
|
|
|
'test_initrd_inject': TestInitrdInject,
|
2018-02-21 01:33:57 +08:00
|
|
|
'test_dist': TestDist,
|
2015-11-03 05:19:31 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
distclass=VMMDistribution,
|
2013-03-17 09:32:29 +08:00
|
|
|
)
|