mirror of
https://github.com/miurahr/aqtinstall.git
synced 2025-12-17 20:54:38 +03:00
Merge pull request #249 from miurahr/topic-drop-cuteci
Drop feature to install old versions
This commit is contained in:
@@ -9,7 +9,6 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
Added
|
||||
-----
|
||||
* Support for installation of old versions(#236, #239)
|
||||
* Add -c/--config option to specify custom settings.ini(#246)
|
||||
* Document for settings.ini configuration parameters(#246)
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ include pyproject.toml
|
||||
include tox.ini
|
||||
recursive-include aqt *.ini
|
||||
recursive-include aqt *.json
|
||||
recursive-include aqt *.qs
|
||||
recursive-include aqt *.yml
|
||||
recursive-include ci *.7z
|
||||
recursive-include ci *.ini
|
||||
|
||||
256
aqt/cuteci.py
256
aqt/cuteci.py
@@ -1,256 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2021 Hiroshi Miura <miurahr@linux.com>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
# the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# --------------------------------------------------------------------------------
|
||||
# Original license of component
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2019 Adrien Gavignet
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
from logging import getLogger
|
||||
|
||||
import requests
|
||||
from requests.adapters import HTTPAdapter
|
||||
from urllib3 import Retry
|
||||
|
||||
from aqt.exceptions import ArchiveDownloadError
|
||||
from aqt.helper import altlink, downloadBinaryFile, getUrl
|
||||
|
||||
WORKING_DIR = os.getcwd()
|
||||
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
DEFAULT_INSTALL_SCRIPT = os.path.join(CURRENT_DIR, "install-qt.qs")
|
||||
BLOCKSIZE = 1048576
|
||||
|
||||
|
||||
class DeployCuteCI:
|
||||
"""
|
||||
Class in charge of Qt deployment
|
||||
"""
|
||||
|
||||
def __init__(self, version, os_name, base, timeout):
|
||||
self.major_minor = version[: version.rfind(".")]
|
||||
self.timeout = timeout
|
||||
if os_name == "linux":
|
||||
arch = "x64"
|
||||
ext = "run"
|
||||
elif os_name == "mac":
|
||||
arch = "x64"
|
||||
ext = "dmg"
|
||||
else:
|
||||
arch = "x86"
|
||||
ext = "exe"
|
||||
if self.major_minor in [
|
||||
"5.11",
|
||||
"5.10",
|
||||
"5.8",
|
||||
"5.7",
|
||||
"5.6",
|
||||
"5.5",
|
||||
"5.4",
|
||||
"5.3",
|
||||
"5.2",
|
||||
]:
|
||||
folder = "new_archive"
|
||||
else:
|
||||
folder = "archive"
|
||||
self.installer_url = "{0}/{1}/qt/{2}/{3}/qt-opensource-{4}-{5}-{6}.{7}".format(
|
||||
base, folder, self.major_minor, version, os_name, arch, version, ext
|
||||
)
|
||||
self.md5sums_url = (
|
||||
self.installer_url[: self.installer_url.rfind("/")] + "/" + "md5sums.txt"
|
||||
)
|
||||
|
||||
def _get_version(self, path):
|
||||
# qt-opensource-windows-x86-5.12.2.exe
|
||||
# qt-opensource-mac-x64-5.12.2.dmg
|
||||
# qt-opensource-linux-x64-5.12.2.run
|
||||
basename = os.path.basename(path)
|
||||
res = re.search(r"-(\d+\.\d+.\d+)\.", basename)
|
||||
if res is None:
|
||||
raise Exception(
|
||||
"Cannot get version from `{}` filename (expects name like: `qt-opensource-linux-x64-5.12.2.run`)".format(
|
||||
basename
|
||||
)
|
||||
)
|
||||
res.group(1)
|
||||
return res.group(1)
|
||||
|
||||
def get_archive_name(self):
|
||||
return self.installer_url[self.installer_url.rfind("/") + 1 :]
|
||||
|
||||
def _get_md5(self, archive, timeout):
|
||||
expected_md5 = None
|
||||
r_text = getUrl(self.md5sums_url, timeout, self.logger)
|
||||
for line in r_text.split("\n"):
|
||||
rec = line.split(" ")
|
||||
if archive in rec:
|
||||
expected_md5 = rec[0]
|
||||
return expected_md5
|
||||
|
||||
def check_archive(self):
|
||||
archive = self.get_archive_name()
|
||||
if os.path.exists(archive):
|
||||
timeout = (3.5, 3.5)
|
||||
expected_md5 = self._get_md5(archive, timeout)
|
||||
if expected_md5 is not None:
|
||||
checksum = hashlib.md5()
|
||||
with open(archive, "rb") as f:
|
||||
data = f.read(BLOCKSIZE)
|
||||
while len(data) > 0:
|
||||
checksum.update(data)
|
||||
data = f.read(BLOCKSIZE)
|
||||
if (
|
||||
checksum.hexdigest() == expected_md5
|
||||
and os.stat(archive).st_mode & stat.S_IEXEC
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
def download_installer(self, response_timeout: int = 30):
|
||||
"""
|
||||
Download Qt if possible, also verify checksums.
|
||||
|
||||
:raises Exception: in case of failure
|
||||
"""
|
||||
logger = getLogger("aqt")
|
||||
url = self.installer_url
|
||||
archive = self.get_archive_name()
|
||||
timeout = (3.5, response_timeout)
|
||||
logger.info("Download Qt %s", url)
|
||||
#
|
||||
expected_md5 = self._get_md5(archive, timeout)
|
||||
downloadBinaryFile(url, archive, "md5", expected_md5, timeout, logger)
|
||||
with requests.Session() as session:
|
||||
retry = Retry(connect=5, backoff_factor=0.5)
|
||||
adapter = HTTPAdapter(max_retries=retry)
|
||||
session.mount("http://", adapter)
|
||||
session.mount("https://", adapter)
|
||||
try:
|
||||
r = session.get(
|
||||
url, allow_redirects=False, stream=True, timeout=timeout
|
||||
)
|
||||
if r.status_code == 302:
|
||||
newurl = altlink(r.url, r.headers["Location"], logger=logger)
|
||||
logger.info("Redirected URL: {}".format(newurl))
|
||||
r = session.get(newurl, stream=True, timeout=timeout)
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
logger.error("Connection error: %s" % e.args)
|
||||
raise e
|
||||
except requests.exceptions.Timeout as e:
|
||||
logger.error("Connection timeout: %s" % e.args)
|
||||
raise e
|
||||
else:
|
||||
checksum = hashlib.md5()
|
||||
try:
|
||||
with open(archive, "wb") as fd:
|
||||
for chunk in r.iter_content(chunk_size=8196):
|
||||
fd.write(chunk)
|
||||
checksum.update(chunk)
|
||||
if expected_md5 is not None:
|
||||
if checksum.hexdigest() != expected_md5:
|
||||
raise ArchiveDownloadError(
|
||||
"Download file is corrupted! Check sum error."
|
||||
)
|
||||
except Exception as e:
|
||||
exc = sys.exc_info()
|
||||
logger.error("Download error: %s" % exc[1])
|
||||
raise e
|
||||
os.chmod(archive, os.stat(archive).st_mode | stat.S_IEXEC)
|
||||
return archive
|
||||
|
||||
def run_installer(self, archive, packages, destdir, keep_tools):
|
||||
"""
|
||||
Install Qt.
|
||||
|
||||
:param list: packages to install
|
||||
:param str destdir: install directory
|
||||
:param keep_tools: if True, keep Qt Tools after installation
|
||||
:param bool verbose: enable verbosity
|
||||
:raises Exception: in case of failure
|
||||
"""
|
||||
logger = getLogger("aqt")
|
||||
env = os.environ.copy()
|
||||
env["PACKAGES"] = ",".join(packages)
|
||||
env["DESTDIR"] = destdir
|
||||
install_script = os.path.join(CURRENT_DIR, "install-qt.qs")
|
||||
installer_path = os.path.join(WORKING_DIR, archive)
|
||||
cmd = [installer_path, "--script", install_script, "--verbose"]
|
||||
if self.major_minor in ["5.11", "5.10"]:
|
||||
cmd.extend(["--platform", "minimal"])
|
||||
logger.info("Running installer %s", cmd)
|
||||
try:
|
||||
subprocess.run(cmd, timeout=self.timeout, env=env, check=True)
|
||||
except subprocess.CalledProcessError as cpe:
|
||||
if cpe.returncode == 3:
|
||||
pass
|
||||
logger.error("Installer error: %d" % cpe.returncode)
|
||||
if cpe.stdout is not None:
|
||||
logger.error(cpe.stdout)
|
||||
if cpe.stderr is not None:
|
||||
logger.error(cpe.stderr)
|
||||
raise cpe
|
||||
except subprocess.TimeoutExpired as te:
|
||||
logger.error("Installer timeout expired: {}" % self.timeout)
|
||||
if te.stdout is not None:
|
||||
logger.error(te.stdout)
|
||||
if te.stderr is not None:
|
||||
logger.error(te.stderr)
|
||||
raise te
|
||||
if not keep_tools:
|
||||
logger.info("Cleaning destdir")
|
||||
files = os.listdir(destdir)
|
||||
for name in files:
|
||||
fullpath = os.path.join(destdir, name)
|
||||
if re.match(r"\d+\.\d+.\d+", name):
|
||||
# Qt stands in X.Y.Z dir, skip it
|
||||
logger.info("Keep %s", fullpath)
|
||||
continue
|
||||
if os.path.isdir(fullpath):
|
||||
shutil.rmtree(fullpath)
|
||||
else:
|
||||
os.remove(fullpath)
|
||||
logger.info("Remove %s", fullpath)
|
||||
@@ -1,136 +0,0 @@
|
||||
function debugObject(object) {
|
||||
var lines = [];
|
||||
for (var i in object) {
|
||||
lines.push([i, object[i]].join(" "));
|
||||
}
|
||||
console.log(lines.join(","));
|
||||
}
|
||||
|
||||
function Controller() {
|
||||
// Not empty dir is no problem.
|
||||
installer.setMessageBoxAutomaticAnswer("OverwriteTargetDirectory", QMessageBox.Yes);
|
||||
// If Qt is already installed in dir, acknowlegde the error but situation is stuck.
|
||||
installer.setMessageBoxAutomaticAnswer("TargetDirectoryInUse", QMessageBox.Ok);
|
||||
// Allow to quit the installer when listing packages.
|
||||
installer.setMessageBoxAutomaticAnswer("cancelInstallation", QMessageBox.Yes);
|
||||
}
|
||||
|
||||
Controller.prototype.WelcomePageCallback = function() {
|
||||
console.log("Welcome Page");
|
||||
var widget = gui.currentPageWidget();
|
||||
widget.completeChanged.connect(function() {
|
||||
// For some reason, this page needs some delay.
|
||||
gui.clickButton(buttons.NextButton);
|
||||
});
|
||||
}
|
||||
|
||||
Controller.prototype.CredentialsPageCallback = function() {
|
||||
console.log("Credentials Page");
|
||||
|
||||
var login = installer.environmentVariable("QTLOGIN");
|
||||
var password = installer.environmentVariable("QTPASSWORD");
|
||||
|
||||
if (login === "" || password === "") {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
var widget = gui.currentPageWidget();
|
||||
widget.loginWidget.EmailLineEdit.setText(login);
|
||||
widget.loginWidget.PasswordLineEdit.setText(password);
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.IntroductionPageCallback = function() {
|
||||
console.log("Introduction Page");
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.TargetDirectoryPageCallback = function() {
|
||||
console.log("Target Directory Page");
|
||||
var installDir = installer.environmentVariable("DESTDIR");
|
||||
if (installDir) {
|
||||
// If not present we assume we want to list packages.
|
||||
var widget = gui.currentPageWidget();
|
||||
widget.TargetDirectoryLineEdit.setText(installDir);
|
||||
}
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.ComponentSelectionPageCallback = function() {
|
||||
console.log("Component Selection Page");
|
||||
|
||||
var components = installer.components();
|
||||
console.log("Available packages: " + components.length);
|
||||
var packages = ["===LIST OF PACKAGES==="];
|
||||
for (var i = 0 ; i < components.length ;i++) {
|
||||
packages.push(components[i].name + " " + components[i].displayName);
|
||||
}
|
||||
packages.push("===END OF PACKAGES===");
|
||||
console.log(packages.join("\n"));
|
||||
|
||||
if (installer.environmentVariable("LIST_PACKAGE_ONLY")) {
|
||||
// Early exit
|
||||
gui.clickButton(buttons.CancelButton);
|
||||
return;
|
||||
}
|
||||
|
||||
wantedPackages = installer.environmentVariable("PACKAGES").split(",");
|
||||
console.log("Trying to install ", wantedPackages);
|
||||
|
||||
var widget = gui.currentPageWidget();
|
||||
widget.deselectAll();
|
||||
|
||||
for (var i in wantedPackages) {
|
||||
name = wantedPackages[i];
|
||||
var found = false;
|
||||
for (var j in components) {
|
||||
if (components[j].name === name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
console.log("Select " + name);
|
||||
widget.selectComponent(name);
|
||||
} else {
|
||||
console.log("Package " + name + " not found");
|
||||
}
|
||||
}
|
||||
widget.deselectComponent("qt.tools.qtcreator");
|
||||
widget.deselectComponent("qt.tools.doc");
|
||||
widget.deselectComponent("qt.tools.examples");
|
||||
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.LicenseAgreementPageCallback = function() {
|
||||
console.log("Accept License Agreement Page");
|
||||
var widget = gui.currentPageWidget();
|
||||
widget.AcceptLicenseRadioButton.setChecked(true);
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.ReadyForInstallationPageCallback = function() {
|
||||
console.log("Ready For Installation Page");
|
||||
gui.clickButton(buttons.CommitButton);
|
||||
}
|
||||
|
||||
Controller.prototype.PerformInstallationPageCallback = function() {
|
||||
console.log("Perform Installation Page");
|
||||
installer.installationFinished.connect(function() {
|
||||
console.log("Installation finished");
|
||||
gui.clickButton(buttons.NextButton);
|
||||
});
|
||||
}
|
||||
|
||||
Controller.prototype.FinishedPageCallback = function() {
|
||||
console.log("Finished Page");
|
||||
var widget = gui.currentPageWidget();
|
||||
if (widget.LaunchQtCreatorCheckBoxForm) {
|
||||
widget.LaunchQtCreatorCheckBoxForm.launchQtCreatorCheckBox.setChecked(false);
|
||||
} else if (widget.RunItCheckBox) {
|
||||
widget.RunItCheckBox.setChecked(false);
|
||||
}
|
||||
gui.clickButton(buttons.FinishButton);
|
||||
}
|
||||
@@ -33,13 +33,11 @@ import subprocess
|
||||
import time
|
||||
from logging import getLogger
|
||||
|
||||
import appdirs
|
||||
from packaging.version import Version, parse
|
||||
from texttable import Texttable
|
||||
|
||||
import aqt
|
||||
from aqt.archives import PackagesList, QtArchives, SrcDocExamplesArchives, ToolArchives
|
||||
from aqt.cuteci import DeployCuteCI
|
||||
from aqt.exceptions import (
|
||||
ArchiveConnectionError,
|
||||
ArchiveDownloadError,
|
||||
@@ -298,48 +296,6 @@ class Cli:
|
||||
)
|
||||
)
|
||||
|
||||
def run_offline_installer(self, args):
|
||||
"""Run online_installer subcommand"""
|
||||
start_time = time.perf_counter()
|
||||
self.show_aqt_version()
|
||||
os_name = args.host
|
||||
qt_version = args.qt_version
|
||||
arch = args.arch
|
||||
output_dir = args.outputdir
|
||||
if output_dir is None:
|
||||
base_dir = os.getcwd()
|
||||
else:
|
||||
base_dir = os.path.realpath(output_dir)
|
||||
if args.timeout is not None:
|
||||
timeout = args.timeout
|
||||
else:
|
||||
timeout = 300
|
||||
if args.base is not None:
|
||||
base = args.base
|
||||
else:
|
||||
base = self.settings.baseurl
|
||||
qt_ver_num = qt_version.replace(".", "")
|
||||
packages = ["qt.qt5.{}.{}".format(qt_ver_num, arch)]
|
||||
if args.archives is not None:
|
||||
packages.extend(args.archives)
|
||||
#
|
||||
qa = os.path.join(appdirs.user_data_dir("Qt", None), "qtaccount.ini")
|
||||
if not os.path.exists(qa):
|
||||
self.logger.warning("Cannot find {}".format(qa))
|
||||
cuteci = DeployCuteCI(qt_version, os_name, base, timeout)
|
||||
if not cuteci.check_archive():
|
||||
archive = cuteci.download_installer()
|
||||
else:
|
||||
self.logger.info("Reuse existent installer archive.")
|
||||
archive = cuteci.get_archive_name()
|
||||
cuteci.run_installer(archive, packages, base_dir, True)
|
||||
self.logger.info("Finished installation")
|
||||
self.logger.info(
|
||||
"Time elapsed: {time:.8f} second".format(
|
||||
time=time.perf_counter() - start_time
|
||||
)
|
||||
)
|
||||
|
||||
def _run_src_doc_examples(self, flavor, args):
|
||||
start_time = time.perf_counter()
|
||||
self.show_aqt_version()
|
||||
@@ -681,54 +637,6 @@ class Cli:
|
||||
list_parser.set_defaults(func=self.run_list)
|
||||
self._set_common_argument(list_parser)
|
||||
#
|
||||
old_install = subparsers.add_parser(
|
||||
"offline_installer",
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
description="Install Qt using offiline installer. It requires downloading installer binary(500-1500MB).\n"
|
||||
"Please help you for patience to wait downloding."
|
||||
"It can accept environment variables:\n"
|
||||
" QTLOGIN: qt account login name\n"
|
||||
" QTPASSWORD: qt account password\n",
|
||||
)
|
||||
old_install.add_argument(
|
||||
"qt_version", help='Qt version in the format of "5.X.Y"'
|
||||
)
|
||||
old_install.add_argument(
|
||||
"host", choices=["linux", "mac", "windows"], help="host os name"
|
||||
)
|
||||
old_install.add_argument(
|
||||
"arch",
|
||||
help="\ntarget linux/desktop: gcc_64"
|
||||
"\ntarget mac/desktop: clang_64"
|
||||
"\nwindows/desktop: win64_msvc2017_64, win32_msvc2017"
|
||||
"\n win64_msvc2015_64, win32_msvc2015",
|
||||
)
|
||||
old_install.add_argument(
|
||||
"--archives",
|
||||
nargs="*",
|
||||
help="Specify packages to install.",
|
||||
)
|
||||
old_install.add_argument(
|
||||
"-O",
|
||||
"--outputdir",
|
||||
nargs="?",
|
||||
help="Target output directory(default current directory)",
|
||||
)
|
||||
old_install.add_argument(
|
||||
"-b",
|
||||
"--base",
|
||||
nargs="?",
|
||||
help="Specify mirror base url such as http://mirrors.ocf.berkeley.edu/qt/, "
|
||||
"where 'online' folder exist.",
|
||||
)
|
||||
old_install.add_argument(
|
||||
"--timeout",
|
||||
nargs="?",
|
||||
type=float,
|
||||
help="Specify timeout for offline installer processing.(default: 300 sec)",
|
||||
)
|
||||
old_install.set_defaults(func=self.run_offline_installer)
|
||||
#
|
||||
help_parser = subparsers.add_parser("help")
|
||||
help_parser.set_defaults(func=self.show_help)
|
||||
parser.set_defaults(func=self.show_help)
|
||||
|
||||
29
docs/cli.rst
29
docs/cli.rst
@@ -121,29 +121,6 @@ Tool installation commands
|
||||
You may need to looking for version number at https://download.qt.io/online/qtsdkrepository/
|
||||
|
||||
|
||||
Experimental commands
|
||||
---------------------
|
||||
|
||||
.. program:: aqt
|
||||
|
||||
.. option:: offline_installer <Qt version> <target OS> <target architecture> --archives [<package>, ...]
|
||||
|
||||
[Experimental, Advanced] install Qt library specified version and target using offline installer.
|
||||
When specify old versions that has already become end-of-life, aqt download
|
||||
the installer from a proper server repository. A command intend to support version from 5.2 to 5.11.
|
||||
User may need to set environment variable QTLOGIN and QTPASSWORD properly or
|
||||
place qtaccount.ini file at proper place.
|
||||
|
||||
User should specify proper package names. Otherwise it may install default
|
||||
packages.
|
||||
|
||||
A feature is considered as very experimental.
|
||||
|
||||
.. option:: --archives <list of archives>
|
||||
|
||||
archive packages to install. Expected values will be shown on log message.
|
||||
|
||||
|
||||
Command examples
|
||||
================
|
||||
|
||||
@@ -207,9 +184,3 @@ Example: Show help message
|
||||
.. code-block:: bash
|
||||
|
||||
aqt help
|
||||
|
||||
Example: install old version
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
aqt offline_installer 5.11.2 linux gcc_64
|
||||
@@ -5,7 +5,7 @@ def test_cli_help(capsys):
|
||||
expected = "".join(
|
||||
[
|
||||
"usage: aqt [-h] [-c CONFIG] [--logging-conf LOGGING_CONF] [--logger LOGGER]\n",
|
||||
" {install,doc,examples,src,tool,list,offline_installer,help} ...\n",
|
||||
" {install,doc,examples,src,tool,list,help} ...\n",
|
||||
"\n",
|
||||
"Installer for Qt SDK.\n",
|
||||
"\n",
|
||||
@@ -20,7 +20,7 @@ def test_cli_help(capsys):
|
||||
"subcommands:\n",
|
||||
" Valid subcommands\n",
|
||||
"\n",
|
||||
" {install,doc,examples,src,tool,list,offline_installer,help}\n",
|
||||
" {install,doc,examples,src,tool,list,help}\n",
|
||||
" subcommand for aqt Qt installer\n",
|
||||
]
|
||||
)
|
||||
@@ -68,7 +68,7 @@ def test_cli_launch_with_no_argument(capsys):
|
||||
expected = "".join(
|
||||
[
|
||||
"usage: aqt [-h] [-c CONFIG] [--logging-conf LOGGING_CONF] [--logger LOGGER]\n",
|
||||
" {install,doc,examples,src,tool,list,offline_installer,help} ...\n",
|
||||
" {install,doc,examples,src,tool,list,help} ...\n",
|
||||
"\n",
|
||||
"Installer for Qt SDK.\n",
|
||||
"\n",
|
||||
@@ -83,7 +83,7 @@ def test_cli_launch_with_no_argument(capsys):
|
||||
"subcommands:\n",
|
||||
" Valid subcommands\n",
|
||||
"\n",
|
||||
" {install,doc,examples,src,tool,list,offline_installer,help}\n",
|
||||
" {install,doc,examples,src,tool,list,help}\n",
|
||||
" subcommand for aqt Qt installer\n",
|
||||
]
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user