Repository: miurahr/aqtinstall

Issue:
Bug in install-src
I am trying to install the source files for QtWebEngine, linux desktop 5.9.9 gcc_64. However, this is what I get:

```
cradcore@localhost: ~ $ aqt install-src -m qtwebengine -O /dev-tools linux desktop 5.9.9
aqtinstall(aqt) v2.0.2 on Python 3.8.10 [CPython GCC 9.3.0]
The packages ['qtwebengine'] were not found while parsing XML of package information!
==============================Suggested follow-up:==============================
* Please use 'aqt list-qt linux desktop --modules 5.9.9 <arch>' to show modules available.
cradcore@localhost: ~ $ aqt list-qt linux desktop --modules 5.9.9 gcc_64
qtcharts qtdatavis3d qtnetworkauth qtpurchasing qtremoteobjects qtscript qtspeech qtvirtualkeyboard qtwebengine
```

It seems to not find qtwebengine when trying to install, but correctly lists it as a module 

Discussion:

Patch:
diff --git a/aqt/archives.py b/aqt/archives.py
index bfc7bfb..c5c9286 100644
--- a/aqt/archives.py
+++ b/aqt/archives.py
@@ -351,6 +351,16 @@ class SrcDocExamplesArchives(QtArchives):
         """
         return TargetConfig("src_doc_examples", self.target, self.arch, self.os_name)
 
+    def help_msg(self, missing_modules: Iterable[str]) -> Iterable[str]:
+        cmd_type = "example" if self.flavor == "examples" else self.flavor
+        base_cmd = f"aqt list-{cmd_type} {self.os_name} {self.version}"
+        mods = f"Please use '{base_cmd} --modules' to show modules available."
+        has_non_base_pkg: bool = len(list(missing_modules)) > 1
+        messages = []
+        if has_non_base_pkg:
+            messages.append(mods)
+        return messages
+
 
 class ToolArchives(QtArchives):
     """Hold tool archive package list
diff --git a/aqt/helper.py b/aqt/helper.py
index ecb98eb..8ccce59 100644
--- a/aqt/helper.py
+++ b/aqt/helper.py
@@ -376,6 +376,15 @@ class SettingsClass:
     def print_stacktrace_on_error(self):
         return self.config.getboolean("aqt", "print_stacktrace_on_error", fallback=False)
 
+    @property
+    def min_module_size(self):
+        """
+        Some modules in the Qt repository contain only empty directories.
+        We have found that these modules are no more than 40 bytes after decompression.
+        This setting is used to filter out these empty modules in `list-*` output.
+        """
+        return self.config.getint("aqt", "min_module_size", fallback=41)
+
 
 Settings = SettingsClass()
 
diff --git a/aqt/installer.py b/aqt/installer.py
index 64d295e..7c96e1a 100644
--- a/aqt/installer.py
+++ b/aqt/installer.py
@@ -331,7 +331,9 @@ class Cli:
         self.show_aqt_version()
         if args.is_legacy:
             self._warn_on_deprecated_command(old_name=cmd_name, new_name=f"install-{cmd_name}")
-        target = args.target
+        elif getattr(args, "target", None) is not None:
+            self._warn_on_deprecated_parameter("target", args.target)
+        target = "desktop"  # The only valid target for src/doc/examples is "desktop"
         os_name = args.host
         if hasattr(args, "qt_version_spec"):
             qt_version = str(Cli._determine_qt_version(args.qt_version_spec, os_name, target, arch=""))
@@ -357,7 +359,7 @@ class Cli:
         if EXT7Z and sevenzip is None:
             # override when py7zr is not exist
             sevenzip = self._set_sevenzip(Settings.zipcmd)
-        modules = args.modules
+        modules = getattr(args, "modules", None)  # `--modules` is invalid for `install-src`
         archives = args.archives
         all_extra = True if modules is not None and "all" in modules else False
         if not self._check_qt_arg_versions(qt_version):
@@ -530,6 +532,16 @@ class Cli:
         )
         show_list(meta)
 
+    def run_list_src_doc_examples(self, args: argparse.ArgumentParser, cmd_type: str):
+        target = "desktop"  # The only valid target for src/doc/examples is "desktop"
+        version = Cli._determine_qt_version(args.qt_version_spec, args.host, target, arch="")
+        is_fetch_modules: bool = getattr(args, "modules", False)
+        meta = MetadataFactory(
+            archive_id=ArchiveId("qt", args.host, target, "src_doc_examples"),
+            src_doc_examples_query=(cmd_type, version, is_fetch_modules),
+        )
+        show_list(meta)
+
     def show_help(self, args=None):
         """Display help message"""
         self.parser.print_help()
@@ -570,6 +582,7 @@ class Cli:
             "\n                                        android_x86, android_armv7",
         )
         self._set_module_options(install_qt_parser)
+        self._set_archive_options(install_qt_parser)
         install_qt_parser.add_argument(
             "--noarchives",
             action="store_true",
@@ -605,6 +618,13 @@ class Cli:
             f"In the future, please use the command '{new_name}' instead."
         )
 
+    def _warn_on_deprecated_parameter(self, parameter_name: str, value: str):
+        self.logger.warning(
+            f"Warning: The parameter '{parameter_name}' with value '{value}' is deprecated and marked for "
+            f"removal in a future version of aqt.\n"
+            f"In the future, please omit this parameter."
+        )
+
     def _make_all_parsers(self, subparsers: argparse._SubParsersAction):
         deprecated_msg = "This command is deprecated and marked for removal in a future version of aqt."
 
@@ -614,24 +634,42 @@ class Cli:
             p = subparsers.add_parser(cmd, description=description, **kwargs)
             set_parser_cmd(p, is_legacy=is_legacy)
 
-        def make_parser_sde(cmd: str, desc: str, is_legacy: bool, action, is_add_kde: bool):
+        def make_parser_sde(cmd: str, desc: str, is_legacy: bool, action, is_add_kde: bool, is_add_modules: bool = True):
             description = f"{desc} {deprecated_msg}" if is_legacy else desc
             parser = subparsers.add_parser(cmd, description=description)
             parser.set_defaults(func=action, is_legacy=is_legacy)
-            self._set_common_arguments(parser, is_legacy=is_legacy)
+            self._set_common_arguments(parser, is_legacy=is_legacy, is_target_deprecated=True)
             self._set_common_options(parser)
-            self._set_module_options(parser)
+            if is_add_modules:
+                self._set_module_options(parser)
+            self._set_archive_options(parser)
             if is_add_kde:
                 parser.add_argument("--kde", action="store_true", help="patching with KDE patch kit.")
 
+        def make_parser_list_sde(cmd: str, desc: str, cmd_type: str):
+            parser = subparsers.add_parser(cmd, description=desc)
+            parser.add_argument("host", choices=["linux", "mac", "windows"], help="host os name")
+            parser.add_argument(
+                "qt_version_spec",
+                metavar="(VERSION | SPECIFICATION)",
+                help='Qt version in the format of "5.X.Y" or SimpleSpec like "5.X" or "<6.X"',
+            )
+            parser.set_defaults(func=lambda args: self.run_list_src_doc_examples(args, cmd_type))
+
+            if cmd_type != "src":
+                parser.add_argument("-m", "--modules", action="store_true", help="Print list of available modules")
+
         make_parser_it("install-qt", "Install Qt.", False, self._set_install_qt_parser, argparse.RawTextHelpFormatter)
         make_parser_it("install-tool", "Install tools.", False, self._set_install_tool_parser, None)
         make_parser_sde("install-doc", "Install documentation.", False, self.run_install_doc, False)
         make_parser_sde("install-example", "Install examples.", False, self.run_install_example, False)
-        make_parser_sde("install-src", "Install source.", False, self.run_install_src, True)
+        make_parser_sde("install-src", "Install source.", False, self.run_install_src, True, is_add_modules=False)
 
         self._make_list_qt_parser(subparsers)
         self._make_list_tool_parser(subparsers)
+        make_parser_list_sde("list-doc", "List documentation archives available (use with install-doc)", "doc")
+        make_parser_list_sde("list-example", "List example archives available (use with install-example)", "examples")
+        make_parser_list_sde("list-src", "List source archives available (use with install-src)", "src")
 
         make_parser_it("install", "Install Qt.", True, self._set_install_qt_parser, argparse.RawTextHelpFormatter)
         make_parser_it("tool", "Install tools.", True, self._set_install_tool_parser, None)
@@ -806,21 +844,33 @@ class Cli:
 
     def _set_module_options(self, subparser):
         subparser.add_argument("-m", "--modules", nargs="*", help="Specify extra modules to install")
+
+    def _set_archive_options(self, subparser):
         subparser.add_argument(
             "--archives",
             nargs="*",
             help="Specify subset packages to install (Default: all standard and extra modules).",
         )
 
-    def _set_common_arguments(self, subparser, *, is_legacy: bool):
+    def _set_common_arguments(self, subparser, *, is_legacy: bool, is_target_deprecated: bool = False):
         """
         Legacy commands require that the version comes before host and target.
         Non-legacy commands require that the host and target are before the version.
+        install-src/doc/example commands do not require a "target" argument anymore, as of 11/22/2021
         """
         if is_legacy:
             subparser.add_argument("qt_version", help='Qt version in the format of "5.X.Y"')
         subparser.add_argument("host", choices=["linux", "mac", "windows"], help="host os name")
-        subparser.add_argument("target", choices=["desktop", "winrt", "android", "ios"], help="target sdk")
+        if is_target_deprecated:
+            subparser.add_argument(
+                "target",
+                choices=["desktop", "winrt", "android", "ios"],
+                nargs="?",
+                help="Ignored. This parameter is deprecated and marked for removal in a future release. "
+                "It is present here for backwards compatibility.",
+            )
+        else:
+            subparser.add_argument("target", choices=["desktop", "winrt", "android", "ios"], help="target sdk")
         if not is_legacy:
             subparser.add_argument(
                 "qt_version_spec",
diff --git a/aqt/metadata.py b/aqt/metadata.py
index b2b8130..f5044d4 100644
--- a/aqt/metadata.py
+++ b/aqt/metadata.py
@@ -366,6 +366,7 @@ class MetadataFactory:
         extensions_ver: Optional[str] = None,
         architectures_ver: Optional[str] = None,
         archives_query: Optional[List[str]] = None,
+        src_doc_examples_query: Optional[Tuple[str, Version, bool]] = None,
         tool_name: Optional[str] = None,
         is_long_listing: bool = False,
     ):
@@ -419,6 +420,14 @@ class MetadataFactory:
             self.request_type = "archives for modules" if len(archives_query) > 2 else "archives for qt"
             version, arch, modules = archives_query[0], archives_query[1], archives_query[2:]
             self._action = lambda: self.fetch_archives(self._to_version(version), arch, modules)
+        elif src_doc_examples_query:
+            cmd_type, version, is_modules_query = src_doc_examples_query
+            if is_modules_query:
+                self.request_type = f"modules for {cmd_type}"
+                self._action = lambda: self.fetch_modules_sde(cmd_type, version)
+            else:
+                self.request_type = f"archives for {cmd_type}"
+                self._action = lambda: self.fetch_archives_sde(cmd_type, version)
         else:
             self.request_type = "versions"
             self._action = self.fetch_versions
@@ -615,9 +624,13 @@ class MetadataFactory:
 
     @staticmethod
     def _has_nonempty_downloads(element: ElementTree.Element) -> bool:
-        """Returns True if the element has an empty '<DownloadableArchives/>' tag"""
+        """Returns True if the element has a nonempty '<DownloadableArchives/>' tag"""
         downloads = element.find("DownloadableArchives")
-        return downloads is not None and downloads.text
+        update_file = element.find("UpdateFile")
+        if downloads is None or update_file is None:
+            return False
+        uncompressed_size = int(update_file.attrib["UncompressedSize"])
+        return downloads.text and uncompressed_size >= Settings.min_module_size
 
     def _get_qt_version_str(self, version: Version) -> str:
         """Returns a Qt version, without dots, that works in the Qt repo urls and Updates.xml files"""
@@ -664,6 +677,31 @@ class MetadataFactory:
                 modules.add(module)
         return sorted(modules)
 
+    def fetch_modules_sde(self, cmd_type: str, version: Version) -> List[str]:
+        """Returns list of modules for src/doc/examples"""
+        assert (
+            cmd_type in ("doc", "examples") and self.archive_id.target == "desktop"
+        ), "Internal misuse of fetch_modules_sde"
+        self.validate_extension(version)
+        qt_ver_str = self._get_qt_version_str(version)
+        modules_meta = self._fetch_module_metadata(self.archive_id.to_folder(qt_ver_str))
+        # pattern: Match all names "qt.qt5.12345.doc.(\w+)
+        pattern = re.compile(r"^qt\.(qt" + str(version.major) + r"\.)?" + qt_ver_str + r"\." + cmd_type + r"\.(.+)$")
+
+        modules: List[str] = []
+        for name in modules_meta:
+            _match = pattern.match(name)
+            if _match:
+                modules.append(_match.group(2))
+        return modules
+
+    def fetch_archives_sde(self, cmd_type: str, version: Version) -> List[str]:
+        """Returns list of archives for src/doc/examples"""
+        assert (
+            cmd_type in ("src", "doc", "examples") and self.archive_id.target == "desktop"
+        ), "Internal misuse of fetch_archives_sde"
+        return self.fetch_archives(version, cmd_type, [])
+
     def fetch_archives(self, version: Version, arch: str, modules: List[str]) -> List[str]:
         qt_version_str = self._get_qt_version_str(version)
         nonempty = MetadataFactory._has_nonempty_downloads
diff --git a/aqt/settings.ini b/aqt/settings.ini
index d165c08..3f8760b 100644
--- a/aqt/settings.ini
+++ b/aqt/settings.ini
@@ -7,6 +7,7 @@ baseurl: https://download.qt.io
 print_stacktrace_on_error: False
 always_keep_archives: False
 archive_download_location: .
+min_module_size: 41
 
 [requests]
 connection_timeout: 3.5
diff --git a/ci/generate_azure_pipelines_matrices.py b/ci/generate_azure_pipelines_matrices.py
index 987ca7f..fb99f33 100644
--- a/ci/generate_azure_pipelines_matrices.py
+++ b/ci/generate_azure_pipelines_matrices.py
@@ -201,10 +201,15 @@ linux_build_jobs.extend(
             subarchives="qtbase qttools qt icu",
         ),
         BuildJob(
-            "install-src", "6.1.0", "linux", "desktop", "gcc_64", "gcc_64", subarchives="qt"
+            "install-src", "6.1.0", "linux", "desktop", "gcc_64", "gcc_64", subarchives="qtlottie"
         ),
         BuildJob(
-            "install-doc", "6.1.0", "linux", "desktop", "gcc_64", "gcc_64", subarchives="qtdoc"
+            "install-doc", "6.1.0", "linux", "desktop", "gcc_64", "gcc_64",
+            subarchives="qtdoc qtlottieanimation", module="qtlottie"
+        ),
+        BuildJob(
+            "install-example", "6.1.0", "linux", "desktop", "gcc_64", "gcc_64",
+            subarchives="qtdoc qtcharts", module="qtcharts"
         ),
         # test for list commands
         BuildJob('list', '5.15.2', 'linux', 'desktop', 'gcc_64', '', spec="<6", list_options={
diff --git a/ci/steps.yml b/ci/steps.yml
index 3244208..1b43472 100644
--- a/ci/steps.yml
+++ b/ci/steps.yml
@@ -108,12 +108,28 @@ steps:
         fi
         aqt list-qt $(HOST) $(TARGET) $ext --arch $(QT_VERSION)                 # print architectures for version/host/target
         aqt list-qt $(HOST) $(TARGET) $ext --spec "$(SPEC)" --arch latest
+
+        # list-src/doc/example
+        aqt list-src $(HOST) $(QT_VERSION)                                      # print source archives available for host/desktop/version
+        aqt list-doc $(HOST) $(QT_VERSION)                                      # print docs archives available for host/desktop/version
+        aqt list-doc $(HOST) $(QT_VERSION) --modules                            # print docs modules available for host/desktop/version
+        aqt list-example $(HOST) $(QT_VERSION)                                  # print example archives available for host/desktop/version
+        aqt list-example $(HOST) $(QT_VERSION) --modules                        # print example modules available for host/desktop/version
       fi
       if [[ "$(SUBCOMMAND)" == "install-src" ]]; then
         python -m aqt $(SUBCOMMAND) $(HOST) $(TARGET) $(QT_VERSION) --archives $(SUBARCHIVES)
+        ls -lh ./$(QT_VERSION)/Src/*/
       fi
-      if [[ "$(SUBCOMMAND)" == "install-doc" ]]; then
-        python -m aqt $(SUBCOMMAND) $(HOST) $(TARGET) $(QT_VERSION) --archives $(SUBARCHIVES)
+      if [[ "$(SUBCOMMAND)" =~ ^install-(doc|example)$ ]]; then
+        opt=""
+        if [[ "$(MODULE)" != "" ]]; then
+          opt+=" -m $(MODULE)"
+        fi
+        python -m aqt $(SUBCOMMAND) $(HOST) $(TARGET) $(QT_VERSION) --archives $(SUBARCHIVES) $opt
+
+        # Docs install to ./Docs/Qt-6.1.0/qtdoc/
+        # Examples install to ./Examples/Qt-6.1.0/demos
+        ls -lh ./*/Qt-$(QT_VERSION)/*/
       fi
       if [[ "$(SUBCOMMAND)" == "install-tool" ]]; then
         opt=""
@@ -249,7 +265,12 @@ steps:
       export PATH=$(QT_BINDIR):$PATH
       qmake $(Build.BinariesDirectory)/tests/redditclient
       make
-    condition: and(eq( variables['TARGET'], 'desktop'), or(eq(variables['Agent.OS'], 'Linux'), eq(variables['Agent.OS'], 'Darwin')), ne(variables['MODULE'], ''))
+    condition: |
+      and(eq( variables['TARGET'], 'desktop'),
+          or(eq(variables['Agent.OS'], 'Linux'),
+          eq(variables['Agent.OS'], 'Darwin')),
+          ne(variables['MODULE'], ''),
+          eq(variables['SUBCOMMAND'], 'install-qt'))
     displayName: Build test with qmake for Linux and macOS with extra module
 
   ##----------------------------------------------------
diff --git a/docs/cli.rst b/docs/cli.rst
index 463a0fc..891772a 100644
--- a/docs/cli.rst
+++ b/docs/cli.rst
@@ -31,7 +31,7 @@ List-* Commands
 
 These commands are used to list the packages available for installation with ``aqt``.
 
-.. _list qt command:
+.. _list-qt command:
 
 list-qt command
 ~~~~~~~~~~~~~~~
@@ -132,7 +132,129 @@ List available versions of Qt, targets, extensions, modules, and architectures.
     May be combined with the ``--extension`` and/or ``--spec`` flags.
 
 
-.. _list tool command:
+.. _list-src command:
+
+list-src command
+~~~~~~~~~~~~~~~~
+
+.. program::  list-src
+
+.. code-block:: bash
+
+    aqt list-src [-h | --help]
+                 <host> (<Qt version> | <spec>)
+
+List source archives available for installation using the `install-src command`_.
+
+.. describe:: host
+
+    linux, windows or mac
+
+.. describe:: Qt version
+
+    This is a Qt version such as 5.9.7, 5.12.1 etc.
+    Use the :ref:`List-Qt Command` to list available versions.
+
+.. describe:: spec
+
+    This is a `SimpleSpec`_ that specifies a range of versions.
+    If you type something in the ``<Qt version>`` positional argument that
+    cannot be interpreted as a version, it will be interpreted as a `SimpleSpec`_,
+    and ``aqt`` will select the highest available version within that `SimpleSpec`_.
+
+    For example, ``aqt list-src mac 5.12`` would print archives for the
+    latest version of Qt 5.12 available (5.12.11 at the time of this writing).
+
+
+.. _list-doc command:
+
+list-doc command
+~~~~~~~~~~~~~~~~
+
+.. program::  list-doc
+
+.. code-block:: bash
+
+    aqt list-doc [-h | --help]
+                 [-m | --modules]
+                 <host> (<Qt version> | <spec>)
+
+List documentation archives and modules available for installation using the
+`install-doc command`_.
+
+By default, ``list-doc`` will print a list of archives available for
+installation using the `install-doc command`_, with the ``--archives`` option.
+
+.. describe:: host
+
+    linux, windows or mac
+
+.. describe:: Qt version
+
+    This is a Qt version such as 5.9.7, 5.12.1 etc.
+    Use the :ref:`List-Qt Command` to list available versions.
+
+.. describe:: spec
+
+    This is a `SimpleSpec`_ that specifies a range of versions.
+    If you type something in the ``<Qt version>`` positional argument that
+    cannot be interpreted as a version, it will be interpreted as a `SimpleSpec`_,
+    and ``aqt`` will select the highest available version within that `SimpleSpec`_.
+
+    For example, ``aqt list-doc mac 5.12`` would print archives for the
+    latest version of Qt 5.12 available (5.12.11 at the time of this writing).
+
+.. option:: --modules
+
+    This flag causes ``list-doc`` to print a list of modules available for
+    installation using the `install-doc command`_, with the ``--modules`` option.
+
+
+.. _list-example command:
+
+list-example command
+~~~~~~~~~~~~~~~~~~~~
+
+.. program::  list-example
+
+.. code-block:: bash
+
+    aqt list-example [-h | --help]
+                     [-m | --modules]
+                     <host> (<Qt version> | <spec>)
+
+List example archives and modules available for installation using the
+`install-example command`_.
+
+By default, ``list-example`` will print a list of archives available for
+installation using the `install-example command`_, with the ``--archives`` option.
+
+.. describe:: host
+
+    linux, windows or mac
+
+.. describe:: Qt version
+
+    This is a Qt version such as 5.9.7, 5.12.1 etc.
+    Use the :ref:`List-Qt Command` to list available versions.
+
+.. describe:: spec
+
+    This is a `SimpleSpec`_ that specifies a range of versions.
+    If you type something in the ``<Qt version>`` positional argument that
+    cannot be interpreted as a version, it will be interpreted as a `SimpleSpec`_,
+    and ``aqt`` will select the highest available version within that `SimpleSpec`_.
+
+    For example, ``aqt list-example mac 5.12`` would print archives for the
+    latest version of Qt 5.12 available (5.12.11 at the time of this writing).
+
+.. option:: --modules
+
+    This flag causes ``list-example`` to print a list of modules available for
+    installation using the `install-example command`_, with the ``--modules`` option.
+
+
+.. _list-tool command:
 
 list-tool command
 ~~~~~~~~~~~~~~~~~
@@ -257,9 +379,20 @@ are described here:
 .. option:: --modules, -m (<list of modules> | all)
 
     Specify extra modules to install as a list.
-    Use the :ref:`List Qt Command` to list available modules.
+    Use the appropriate ``aqt list-*`` command to list available modules:
 
-    This option is applicable to all the ``install-*`` commands except for ``install-tool``.
++------------------+-------------------------+--------------------------------------------------------+
+| Install command  | List command            | Usage of list command                                  |
++==================+=========================+========================================================+
+| install-qt       | `list-qt command`_      | ``list-qt <host> <target> --modules <version> <arch>`` |
++------------------+-------------------------+--------------------------------------------------------+
+| install-example  | `list-example command`_ | ``list-example <host> <version> --modules``            |
++------------------+-------------------------+--------------------------------------------------------+
+| install-doc      | `list-doc command`_     | ``list-doc <host> <version> --modules``                |
++------------------+-------------------------+--------------------------------------------------------+
+
+
+    This option only applicable to ``install-qt``, ``install-example``, and ``install-doc``.
 
     You can install multiple modules like this:
 
@@ -288,7 +421,19 @@ are described here:
     This option is applicable to all the ``install-*`` commands except for ``install-tool``.
 
     You can print a list of all acceptable values to use with this command by
-    using ``aqt list-qt`` with the :ref:`archives flag <list archives flag>`.
+    using the appropriate ``aqt list-*`` command:
+
++------------------+-------------------------+--------------------------------------------------+
+| Install command  | List command            | Usage of list command                            |
++==================+=========================+==================================================+
+| install-qt       | `list-qt command`_      | ``list-qt <host> <target> --archives <version>`` |
++------------------+-------------------------+--------------------------------------------------+
+| install-example  | `list-example command`_ | ``list-example <host> <version>``                |
++------------------+-------------------------+--------------------------------------------------+
+| install-src      | `list-src command`_     | ``list-src <host> <version>``                    |
++------------------+-------------------------+--------------------------------------------------+
+| install-doc      | `list-doc command`_     | ``list-doc <host> <version>``                    |
++------------------+-------------------------+--------------------------------------------------+
 
 
 .. _qt installation command:
@@ -328,7 +473,7 @@ There are various combinations to accept according to Qt version.
 .. describe:: Qt version
 
     This is a Qt version such as 5.9.7, 5.12.1 etc.
-    Use the :ref:`List Qt Command` to list available versions.
+    Use the :ref:`List-Qt Command` to list available versions.
 
 .. describe:: spec
 
@@ -356,7 +501,7 @@ There are various combinations to accept according to Qt version.
 
    * android_armv7, android_arm64_v8a, android_x86, android_x86_64 for android
 
-    Use the :ref:`List Qt Command` to list available architectures.
+    Use the :ref:`List-Qt Command` to list available architectures.
 
 .. option:: --noarchives
 
@@ -367,6 +512,8 @@ There are various combinations to accept according to Qt version.
 See `common options`_.
 
 
+.. _install-src command:
+
 install-src command
 ~~~~~~~~~~~~~~~~~~~
 
@@ -383,10 +530,9 @@ install-src command
         [--internal]
         [-k | --keep]
         [-d | --archive-dest] <path>
-        [-m | --modules (all | <module> [<module>...])]
         [--archives <archive> [<archive>...]]
         [--kde]
-        <host> <target> (<Qt version> | <spec>)
+        <host> [<target>] (<Qt version> | <spec>)
 
 Install Qt source code for the specified version and target.
 
@@ -397,12 +543,13 @@ Install Qt source code for the specified version and target.
 
 .. describe:: target
 
-    desktop, ios or android
+    Deprecated and marked for removal in a future version of aqt.
+    This parameter exists for backwards compatibility reasons, and its value is ignored.
 
 .. describe:: Qt version
 
     This is a Qt version such as 5.9.7, 5.12.1 etc.
-    Use the :ref:`List Qt Command` to list available versions.
+    Use the :ref:`List-Qt Command` to list available versions.
 
 .. describe:: spec
 
@@ -411,9 +558,9 @@ Install Qt source code for the specified version and target.
     cannot be interpreted as a version, it will be interpreted as a `SimpleSpec`_,
     and ``aqt`` will select the highest available version within that `SimpleSpec`_.
 
-    For example, ``aqt install-qt mac desktop 5.12`` would install the newest
-    version of Qt 5.12 available, and ``aqt install-qt mac desktop "*"`` would
-    install the highest version of Qt available.
+    For example, ``aqt install-src mac 5.12`` would install sources for the newest
+    version of Qt 5.12 available, and ``aqt install-src mac "*"`` would
+    install sources for the highest version of Qt available.
 
 .. option:: --kde
 
@@ -425,6 +572,8 @@ Install Qt source code for the specified version and target.
 See `common options`_.
 
 
+.. _install-doc command:
+
 install-doc command
 ~~~~~~~~~~~~~~~~~~~
 
@@ -443,7 +592,7 @@ install-doc command
         [-d | --archive-dest] <path>
         [-m | --modules (all | <module> [<module>...])]
         [--archives <archive> [<archive>...]]
-        <host> <target> (<Qt version> | <spec>)
+        <host> [<target>] (<Qt version> | <spec>)
 
 Install Qt documentation for the specified version and target.
 
@@ -453,12 +602,13 @@ Install Qt documentation for the specified version and target.
 
 .. describe:: target
 
-    desktop, ios or android
+    Deprecated and marked for removal in a future version of aqt.
+    This parameter exists for backwards compatibility reasons, and its value is ignored.
 
 .. describe:: Qt version
 
     This is a Qt version such as 5.9.7, 5.12.1 etc.
-    Use the :ref:`List Qt Command` to list available versions.
+    Use the :ref:`List-Qt Command` to list available versions.
 
 .. describe:: spec
 
@@ -467,13 +617,15 @@ Install Qt documentation for the specified version and target.
     cannot be interpreted as a version, it will be interpreted as a `SimpleSpec`_,
     and ``aqt`` will select the highest available version within that `SimpleSpec`_.
 
-    For example, ``aqt install-qt mac desktop 5.12`` would install the newest
-    version of Qt 5.12 available, and ``aqt install-qt mac desktop "*"`` would
-    install the highest version of Qt available.
+    For example, ``aqt install-doc mac 5.12`` would install documentation for the newest
+    version of Qt 5.12 available, and ``aqt install-doc mac "*"`` would
+    install documentation for the highest version of Qt available.
 
 See `common options`_.
 
 
+.. _install-example command:
+
 install-example command
 ~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -492,7 +644,7 @@ install-example command
         [-d | --archive-dest] <path>
         [-m | --modules (all | <module> [<module>...])]
         [--archives <archive> [<archive>...]]
-        <host> <target> (<Qt version> | <spec>)
+        <host> [<target>] (<Qt version> | <spec>)
 
 Install Qt examples for the specified version and target.
 
@@ -503,12 +655,13 @@ Install Qt examples for the specified version and target.
 
 .. describe:: target
 
-    desktop, ios or android
+    Deprecated and marked for removal in a future version of aqt.
+    This parameter exists for backwards compatibility reasons, and its value is ignored.
 
 .. describe:: Qt version
 
     This is a Qt version such as 5.9.7, 5.12.1 etc.
-    Use the :ref:`List Qt Command` to list available versions.
+    Use the :ref:`List-Qt Command` to list available versions.
 
 .. describe:: spec
 
@@ -517,9 +670,9 @@ Install Qt examples for the specified version and target.
     cannot be interpreted as a version, it will be interpreted as a `SimpleSpec`_,
     and ``aqt`` will select the highest available version within that `SimpleSpec`_.
 
-    For example, ``aqt install-qt mac desktop 5.12`` would install the newest
-    version of Qt 5.12 available, and ``aqt install-qt mac desktop "*"`` would
-    install the highest version of Qt available.
+    For example, ``aqt install-example mac 5.12`` would install examples for the newest
+    version of Qt 5.12 available, and ``aqt install-example mac "*"`` would
+    install examples for the highest version of Qt available.
 
 
 See `common options`_.
@@ -565,7 +718,7 @@ Install tools like QtIFW, mingw, Cmake, Conan, and vcredist.
     Optional field to specify tool variant. It may be required for vcredist and mingw installation.
     tool variant names may be 'qt.tools.win64_mingw810', 'qt.tools.vcredist_msvc2013_x64'.
 
-You should use the :ref:`List Tool command` to display what tools and tool variant names are available.
+You should use the :ref:`List-Tool command` to display what tools and tool variant names are available.
     
 
 See `common options`_.
@@ -612,10 +765,24 @@ Example: Install examples, doc and source:
 
 .. code-block:: console
 
-    aqt install-example windows desktop 5.15.2 -m qtcharts qtnetworkauth
-    aqt install-doc windows desktop 5.15.2 -m qtcharts qtnetworkauth
-    aqt install-src windows desktop 5.15.2 --archives qtbase --kde
+    aqt install-example windows 5.15.2 -m qtcharts qtnetworkauth
+    aqt install-doc windows 5.15.2 -m qtcharts qtnetworkauth
+    aqt install-src windows 5.15.2 --archives qtbase --kde
+
+Example: Print archives available for installation with ``install-example/doc/src``:
+
+.. code-block:: console
+
+    aqt list-example windows 5.15.2
+    aqt list-doc windows 5.15.2
+    aqt list-src windows 5.15.2
+
+Example: Print modules available for installation with ``install-example/doc``:
+
+.. code-block:: console
 
+    aqt list-example windows 5.15.2 --modules
+    aqt list-doc windows 5.15.2 --modules
 
 Example: Install Web Assembly
 
diff --git a/docs/configuration.rst b/docs/configuration.rst
index f9dba17..9657516 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -22,6 +22,7 @@ A file is like as follows:
     print_stacktrace_on_error: False
     always_keep_archives: False
     archive_download_location: .
+    min_archive_size: 41
 
     [requests]
     connection_timeout: 3.5
@@ -85,6 +86,19 @@ archive_download_location:
     will be downloaded, when ``--keep`` is turned on.
     You can override this location with the ``--archives-dest`` option.
 
+min_module_size:
+    This is the minimum decompressed size, in bytes, of the modules that aqt is permitted to list.
+    The authors of aqt have discovered that the Qt repository contains a few mysteriously
+    "empty" modules, including the examples modules for `qtlottie` and `qtquicktimeline`.
+    These modules consist of a single archive that contains empty directories,
+    and they are exactly 40 bytes when uncompressed.
+    The authors feel that it is not useful for ``aqt list-*`` to list these empty modules.
+    If you want to print these modules with ``aqt list-*``, please feel free to change
+    the `min_module_size` value to something less than 40.
+
+    This setting has no effect on your ability to install these modules.
+    ``aqt install-*`` can will still install them without any warnings.
+
 
 The ``[requests]`` section controls the way that ``aqt`` makes network requests.
 
diff --git a/docs/getting_started.rst b/docs/getting_started.rst
index 09a13ce..bdeb61c 100644
--- a/docs/getting_started.rst
+++ b/docs/getting_started.rst
@@ -37,7 +37,7 @@ To use ``aqt`` to install Qt, you will need to tell ``aqt`` four things:
 Keep in mind that Qt for IOS is only available on Mac OS, and Qt for WinRT is
 only available on Windows.
 
-To find out what versions of Qt are available, you can use the :ref:`aqt list-qt command <list qt command>`.
+To find out what versions of Qt are available, you can use the :ref:`aqt list-qt command <list-qt command>`.
 This command will print all versions of Qt available for Windows Desktop:
 
 .. code-block:: console
@@ -56,10 +56,10 @@ This command will print all versions of Qt available for Windows Desktop:
 
 Notice that the version numbers are sorted, grouped by minor version number,
 and separated by a single space-character. The output of all of the 
-:ref:`aqt list-qt <list qt command>` commands is intended to make it easier for you to write programs
-that consume the output of :ref:`aqt list-qt <list qt command>`.
+:ref:`aqt list-qt <list-qt command>` commands is intended to make it easier for you to write programs
+that consume the output of :ref:`aqt list-qt <list-qt command>`.
 
-Because the :ref:`aqt list-qt <list qt command>` command directly queries the Qt downloads repository
+Because the :ref:`aqt list-qt <list-qt command>` command directly queries the Qt downloads repository
 at https://download.qt.io/, the results of this command will always be accurate.
 The `Available Qt versions`_ wiki page was last modified at some point in the past,
 so it may or may not be up to date.
@@ -69,7 +69,7 @@ so it may or may not be up to date.
 Now that we know what versions of Qt are available, let's choose version 6.2.0.
 
 The next thing we need to do is find out what architectures are available for
-Qt 6.2.0 for Windows Desktop. To do this, we can use :ref:`aqt list-qt <list qt command>` with the
+Qt 6.2.0 for Windows Desktop. To do this, we can use :ref:`aqt list-qt <list-qt command>` with the
 ``--arch`` flag:
 
 .. code-block:: console
@@ -81,7 +81,7 @@ Notice that this is a very small subset of the architectures listed in the
 `Available Qt versions`_ wiki page. If we need to use some architecture that
 is not on this list, we can use the `Available Qt versions`_ wiki page to get
 a rough idea of what versions support the architecture we want, and then use
-:ref:`aqt list-qt <list qt command>` to confirm that the architecture is available.
+:ref:`aqt list-qt <list-qt command>` to confirm that the architecture is available.
 
 Let's say that we want to install Qt 6.2.0 with architecture `win64_mingw81`.
 The installation command we need is:
@@ -150,9 +150,9 @@ Installing Modules
 
 Let's say we need to install some modules for Qt 5.15.2 on Windows Desktop.
 First we need to find out what the modules are called, and we can do that 
-with :ref:`aqt list-qt <list qt command>` with the ``--modules`` flag.
+with :ref:`aqt list-qt <list-qt command>` with the ``--modules`` flag.
 Each version of Qt has a different list of modules for each host OS/ target SDK/ architecture
-combination, so we will need to supply :ref:`aqt list-qt <list qt command>` with that information:
+combination, so we will need to supply :ref:`aqt list-qt <list-qt command>` with that information:
 
 .. code-block:: console
 
@@ -174,9 +174,9 @@ If we wish to install all the modules that are available, we can do that with th
 
     $ aqt install-qt windows desktop 5.15.2 win64_mingw81 -m all
 
-Remember that the :ref:`aqt list-qt <list qt command>` command is meant to be scriptable?
+Remember that the :ref:`aqt list-qt <list-qt command>` command is meant to be scriptable?
 One way to install all modules available for Qt 5.15.2 is to send the output of
-:ref:`aqt list-qt <list qt command>` into :ref:`aqt install-qt <qt installation command>`, like this:
+:ref:`aqt list-qt <list-qt command>` into :ref:`aqt install-qt <qt installation command>`, like this:
 
 .. code-block:: console
 
@@ -190,7 +190,7 @@ If you want to install all available modules, you are probably better off using
 the ``all`` keyword, as discussed above. This scripting example is presented to
 give you a sense of how to accomplish something more complicated.
 Perhaps you want to install all modules except `qtnetworkauth`; you could write a script
-that removes `qtnetworkauth` from the output of :ref:`aqt list-qt <list qt command>`,
+that removes `qtnetworkauth` from the output of :ref:`aqt list-qt <list-qt command>`,
 and pipe that into :ref:`aqt install-qt <qt installation command>`.
 This exercise is left to the reader.
 
@@ -231,16 +231,16 @@ Let's see what happens when we try to list architectures and modules for Qt 6:
     Please add your extension using the `--extension` flag.
 
 The Qt 6 for Android repositories are a little different than the Qt 5 repositories,
-and the :ref:`aqt list-qt <list qt command>` tool doesn't know where to look for modules and architectures
+and the :ref:`aqt list-qt <list-qt command>` tool doesn't know where to look for modules and architectures
 if you don't tell it what architecture you need. I know, it sounds a little
 backwards, but that's how the Qt repo was put together.
 
-There are four architectures available, and the error message from :ref:`aqt list-qt <list qt command>`
+There are four architectures available, and the error message from :ref:`aqt list-qt <list-qt command>`
 just told us what they are: `x86_64`, `x86`, `armv7`, and `arm64_v8a`.
 
 We know we want to use `armv7` for the architecture, but we don't know exactly
 what value for 'architecture' we need to pass to :ref:`aqt install-qt <qt installation command>`
-yet, so we will use :ref:`aqt list-qt <list qt command>` again:
+yet, so we will use :ref:`aqt list-qt <list-qt command>` again:
 
 .. code-block:: console
 
@@ -276,7 +276,7 @@ Finally, let's install Qt 6.2.0 for Android armv7 with the ``qtcharts`` and
 Installing Qt for WASM
 ----------------------
 
-To find out how to install Qt for WASM, we need to tell :ref:`aqt list-qt <list qt command>` that we are
+To find out how to install Qt for WASM, we need to tell :ref:`aqt list-qt <list-qt command>` that we are
 using the `wasm` architecture. We can do that by using the ``--extension wasm`` flag.
 
 .. code-block:: console
@@ -312,7 +312,7 @@ Installing Tools
 ----------------
 
 Let's find out what tools are available for Windows Desktop by using the
-:ref:`aqt list-tool <list tool command>` command:
+:ref:`aqt list-tool <list-tool command>` command:
 
 .. code-block:: console
 
@@ -367,9 +367,9 @@ Let's see some more details, using the ``-l`` or ``--long`` flag:
     qt.tools.win64_mingw730   7.3.0-1-202004170606   2020-04-17
     qt.tools.win64_mingw810   8.1.0-1-202004170606   2020-04-17
 
-The ``-l`` flag causes :ref:`aqt list-tool <list tool command>` to print a table
+The ``-l`` flag causes :ref:`aqt list-tool <list-tool command>` to print a table
 that shows plenty of data pertinent to each tool variant available in `tools_mingw`.
-:ref:`aqt list-tool <list tool command>` additionally prints the 'Display Name'
+:ref:`aqt list-tool <list-tool command>` additionally prints the 'Display Name'
 and 'Description' for each tool if your terminal is wider than 95 characters;
 terminals that are narrower than this cannot display this table in a readable way.
 
@@ -380,7 +380,7 @@ This command receives four parameters:
 2. The target SDK (desktop, android, ios, or winrt)
 3. The name of the tool (this is `tools_mingw` in our case)
 4. (Optional) The tool variant name. We saw a list of these when we ran
-   :ref:`aqt list-tool <list tool command>` with the `tool name` argument filled in.
+   :ref:`aqt list-tool <list-tool command>` with the `tool name` argument filled in.
 
 To install `mingw`, you could use this command (please don't):
 
@@ -393,7 +393,7 @@ in this case, you would install 10 different versions of the same tool.
 For some tools, like `qtcreator` or `ifw`, this is an appropriate thing to do,
 since each tool variant is a different program.
 However, for tools like `mingw` and `vcredist`, it would make more sense to use
-:ref:`aqt list-tool <list tool command>` to see what tool variants are available,
+:ref:`aqt list-tool <list-tool command>` to see what tool variants are available,
 and then install just the tool variant you are interested in, like this:
 
 .. code-block:: console


Test patch:
diff --git a/tests/data/windows-5152-src-doc-example-expect.json b/tests/data/windows-5152-src-doc-example-expect.json
index 2010d2b..3f07712 100644
--- a/tests/data/windows-5152-src-doc-example-expect.json
+++ b/tests/data/windows-5152-src-doc-example-expect.json
@@ -24,5 +24,174 @@
     "examples.qtwebengine",
     "src"
   ],
-  "architectures": []
+  "architectures": [],
+  "src": {
+    "modules": [],
+    "archives": [
+      "qtactiveqt",
+      "qtandroidextras",
+      "qtdoc",
+      "qtmacextras",
+      "qtwayland",
+      "qtwinextras",
+      "qtbase",
+      "qtconnectivity",
+      "qtx11extras",
+      "qtwebchannel",
+      "qtmultimedia",
+      "qttranslations",
+      "qtgraphicaleffects",
+      "qtsvg",
+      "qtdeclarative",
+      "qtwebsockets",
+      "qtimageformats",
+      "qttools",
+      "qtxmlpatterns",
+      "qtsensors",
+      "qtserialport",
+      "qtlocation",
+      "qtquickcontrols",
+      "qtquickcontrols2",
+      "qtremoteobjects",
+      "qt3d",
+      "qtwebview",
+      "qtserialbus",
+      "qtscxml",
+      "qtcharts",
+      "qtdatavis3d",
+      "qtpurchasing",
+      "qtvirtualkeyboard",
+      "qtwebengine",
+      "qtgamepad",
+      "qtscript",
+      "qtspeech",
+      "qtnetworkauth",
+      "qtwebglplugin",
+      "qtlottie",
+      "qtquick3d",
+      "qtquicktimeline",
+      "tqtc"
+    ]
+  },
+  "doc": {
+    "modules": [
+      "qtcharts",
+      "qtdatavis3d",
+      "qtlottie",
+      "qtnetworkauth",
+      "qtpurchasing",
+      "qtquick3d",
+      "qtquicktimeline",
+      "qtscript",
+      "qtvirtualkeyboard",
+      "qtwebengine"
+    ],
+    "archives": [
+      "activeqt",
+      "qdoc",
+      "qmake",
+      "qt3d",
+      "qtandroidextras",
+      "qtassistant",
+      "qtbluetooth",
+      "qtconcurrent",
+      "qtcmake",
+      "qtcore",
+      "qtdbus",
+      "qtdesigner",
+      "qtdistancefieldgenerator",
+      "qtdoc",
+      "qtgamepad",
+      "qtgraphicaleffects",
+      "qtgui",
+      "qthelp",
+      "qtimageformats",
+      "qtlabscalendar",
+      "qtlabsplatform",
+      "qtlinguist",
+      "qtlocation",
+      "qtmacextras",
+      "qtmultimedia",
+      "qtnetwork",
+      "qtnfc",
+      "qtopengl",
+      "qtplatformheaders",
+      "qtpositioning",
+      "qtprintsupport",
+      "qtqml",
+      "qtqmlmodels",
+      "qtqmltest",
+      "qtquick",
+      "qtquickcontrols",
+      "qtquickcontrols1",
+      "qtquickdialogs",
+      "qtquickextras",
+      "qtremoteobjects",
+      "qtscxml",
+      "qtsensors",
+      "qtserialbus",
+      "qtserialport",
+      "qtspeech",
+      "qtsql",
+      "qtsvg",
+      "qttestlib",
+      "qtuitools",
+      "qtwaylandcompositor",
+      "qtwebchannel",
+      "qtwebsockets",
+      "qtwebview",
+      "qtwidgets",
+      "qtwinextras",
+      "qtx11extras",
+      "qtxml",
+      "qtxmlpatterns",
+      "tqtc"
+    ]
+  },
+  "examples": {
+    "modules": [
+      "qtcharts",
+      "qtdatavis3d",
+      "qtnetworkauth",
+      "qtpurchasing",
+      "qtquick3d",
+      "qtscript",
+      "qtvirtualkeyboard",
+      "qtwebengine"
+    ],
+    "archives": [
+      "qt3d",
+      "qtactiveqt",
+      "qtandroidextras",
+      "qtbase",
+      "qtconnectivity",
+      "qtdeclarative",
+      "qtdoc",
+      "qtgamepad",
+      "qtgraphicaleffects",
+      "qtimageformats",
+      "qtlocation",
+      "qtmacextras",
+      "qtmultimedia",
+      "qtquickcontrols",
+      "qtquickcontrols2",
+      "qtremoteobjects",
+      "qtscxml",
+      "qtsensors",
+      "qtserialbus",
+      "qtserialport",
+      "qtspeech",
+      "qtsvg",
+      "qttools",
+      "qttranslations",
+      "qtwayland",
+      "qtwebchannel",
+      "qtwebsockets",
+      "qtwebview",
+      "qtwinextras",
+      "qtx11extras",
+      "qtxmlpatterns",
+      "tqtc"
+    ]
+  }
 }
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 260d75b..ba4dbfa 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -14,7 +14,7 @@ def expected_help(actual, prefix=None):
     expected = (
         "usage: aqt [-h] [-c CONFIG]\n"
         "           {install-qt,install-tool,install-doc,install-example,install-src,"
-        "list-qt,list-tool,"
+        "list-qt,list-tool,list-doc,list-example,list-src,"
         "install,tool,doc,examples,src,help,version}\n"
         "           ...\n"
         "\n"
@@ -35,7 +35,7 @@ def expected_help(actual, prefix=None):
         "removal\n"
         "\n"
         "  {install-qt,install-tool,install-doc,install-example,install-src,list-qt,"
-        "list-tool,"
+        "list-tool,list-doc,list-example,list-src,"
         "install,tool,doc,examples,src,help,version}\n"
         "                        Please refer to each help message by using '--help' "
         "with each subcommand\n",
diff --git a/tests/test_install.py b/tests/test_install.py
index e0229ab..6c2ebf7 100644
--- a/tests/test_install.py
+++ b/tests/test_install.py
@@ -334,6 +334,69 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
                 r"Time elapsed: .* second"
             ),
         ),
+        (
+            "install-src windows desktop 5.14.2".split(),
+            "windows",
+            "desktop",
+            "5.14.2",
+            "",
+            "",
+            "windows_x86/desktop/qt5_5142_src_doc_examples/Updates.xml",
+            [
+                MockArchive(
+                    filename_7z="qtbase-everywhere-src-5.14.2.7z",
+                    update_xml_name="qt.qt5.5142.src",
+                    version="5.14.2",
+                    contents=(
+                        PatchedFile(
+                            filename="Src/qtbase/QtBaseSource.cpp",
+                            unpatched_content="int main(){ return 0; }",
+                            patched_content=None,  # not patched
+                        ),
+                    ),
+                ),
+            ],
+            re.compile(
+                r"^aqtinstall\(aqt\) v.* on Python 3.*\n"
+                r"Warning: The parameter 'target' with value 'desktop' is deprecated "
+                r"and marked for removal in a future version of aqt\.\n"
+                r"In the future, please omit this parameter\.\n"
+                r"Downloading qtbase\.\.\.\n"
+                r"Finished installation of qtbase-everywhere-src-5\.14\.2\.7z in .*\n"
+                r"Finished installation\n"
+                r"Time elapsed: .* second"
+            ),
+        ),
+        (
+            "install-src windows 5.14.2".split(),
+            "windows",
+            "desktop",
+            "5.14.2",
+            "",
+            "",
+            "windows_x86/desktop/qt5_5142_src_doc_examples/Updates.xml",
+            [
+                MockArchive(
+                    filename_7z="qtbase-everywhere-src-5.14.2.7z",
+                    update_xml_name="qt.qt5.5142.src",
+                    version="5.14.2",
+                    contents=(
+                        PatchedFile(
+                            filename="Src/qtbase/QtBaseSource.cpp",
+                            unpatched_content="int main(){ return 0; }",
+                            patched_content=None,  # not patched
+                        ),
+                    ),
+                ),
+            ],
+            re.compile(
+                r"^aqtinstall\(aqt\) v.* on Python 3.*\n"
+                r"Downloading qtbase\.\.\.\n"
+                r"Finished installation of qtbase-everywhere-src-5\.14\.2\.7z in .*\n"
+                r"Finished installation\n"
+                r"Time elapsed: .* second"
+            ),
+        ),
         (
             "install 5.9.0 windows desktop win32_mingw53".split(),
             "windows",
@@ -595,12 +658,28 @@ def test_install(
             "* Please use 'aqt list-qt windows desktop --modules 5.15.0 <arch>' to show modules available.\n",
         ),
         (
-            "install-src windows desktop 5.15.0 -m nonexistent foo",
+            "install-doc windows desktop 5.15.0 -m nonexistent foo",
             "windows-5152-src-doc-example-update.xml",
-            "The packages ['foo', 'nonexistent', 'src'] were not found while parsing XML of package information!\n"
+            "Warning: The parameter 'target' with value 'desktop' is deprecated and marked for removal in a future "
+            "version of aqt.\n"
+            "In the future, please omit this parameter.\n"
+            "The packages ['doc', 'foo', 'nonexistent'] were not found while parsing XML of package information!\n"
             "==============================Suggested follow-up:==============================\n"
-            "* Please use 'aqt list-qt windows desktop --arch 5.15.0' to show architectures available.\n"
-            "* Please use 'aqt list-qt windows desktop --modules 5.15.0 <arch>' to show modules available.\n",
+            "* Please use 'aqt list-doc windows 5.15.0 --modules' to show modules available.\n",
+        ),
+        (
+            "install-doc windows 5.15.0 -m nonexistent foo",
+            "windows-5152-src-doc-example-update.xml",
+            "The packages ['doc', 'foo', 'nonexistent'] were not found while parsing XML of package information!\n"
+            "==============================Suggested follow-up:==============================\n"
+            "* Please use 'aqt list-doc windows 5.15.0 --modules' to show modules available.\n",
+        ),
+        (
+            "install-example windows 5.15.0 -m nonexistent foo",
+            "windows-5152-src-doc-example-update.xml",
+            "The packages ['examples', 'foo', 'nonexistent'] were not found while parsing XML of package information!\n"
+            "==============================Suggested follow-up:==============================\n"
+            "* Please use 'aqt list-example windows 5.15.0 --modules' to show modules available.\n",
         ),
         (
             "install-tool windows desktop tools_vcredist nonexistent",
diff --git a/tests/test_list.py b/tests/test_list.py
index 1e1ca3b..bdffee3 100644
--- a/tests/test_list.py
+++ b/tests/test_list.py
@@ -206,6 +206,83 @@ def test_list_architectures_and_modules(monkeypatch, version: str, extension: st
     assert arches == expect["architectures"]
 
 
+@pytest.fixture
+def win_5152_sde_xml_file() -> str:
+    return (Path(__file__).parent / "data" / "windows-5152-src-doc-example-update.xml").read_text("utf-8")
+
+
+def win_5152_sde_expected(cmd_type: str, query_type: str) -> Set[str]:
+    assert cmd_type in ("src", "doc", "examples")
+    assert query_type in ("archives", "modules")
+    _json = json.loads((Path(__file__).parent / "data/windows-5152-src-doc-example-expect.json").read_text("utf-8"))
+    return set(_json[cmd_type][query_type])
+
+
+@pytest.mark.parametrize(
+    "cmd_type, host, version, expected",
+    [
+        (
+            _cmd_type,
+            "windows",
+            "5.15.2",
+            win_5152_sde_expected(_cmd_type, "archives"),
+        )
+        for _cmd_type in ("src", "doc", "examples")
+    ],
+)
+def test_list_src_doc_examples_archives(
+    monkeypatch, win_5152_sde_xml_file, cmd_type: str, host: str, version: str, expected: Set[str]
+):
+    monkeypatch.setattr(MetadataFactory, "fetch_http", lambda self, _: win_5152_sde_xml_file)
+
+    archive_id = ArchiveId("qt", host, "desktop", "src_doc_examples")
+    archives = set(MetadataFactory(archive_id).fetch_archives_sde(cmd_type, Version(version)))
+    assert archives == expected
+
+
+@pytest.mark.parametrize(
+    "cmd_type, host, version, expected",
+    [
+        (
+            _cmd_type,
+            "windows",
+            "5.15.2",
+            win_5152_sde_expected(_cmd_type, "modules"),
+        )
+        for _cmd_type in ("doc", "examples")
+    ],
+)
+def test_list_src_doc_examples_modules(
+    monkeypatch, win_5152_sde_xml_file, cmd_type: str, host: str, version: str, expected: Set[str]
+):
+    monkeypatch.setattr(MetadataFactory, "fetch_http", lambda self, _: win_5152_sde_xml_file)
+
+    archive_id = ArchiveId("qt", host, "desktop", "src_doc_examples")
+    modules = set(MetadataFactory(archive_id).fetch_modules_sde(cmd_type, Version(version)))
+    assert modules == expected
+
+
+@pytest.mark.parametrize(
+    "command, expected",
+    (
+        ("list-src windows 5.15.2", win_5152_sde_expected("src", "archives")),
+        ("list-doc windows 5.15.2", win_5152_sde_expected("doc", "archives")),
+        ("list-example windows 5.15.2", win_5152_sde_expected("examples", "archives")),
+        ("list-doc windows 5.15.2 --modules", win_5152_sde_expected("doc", "modules")),
+        ("list-example windows 5.15.2 --modules", win_5152_sde_expected("examples", "modules")),
+    ),
+)
+def test_list_src_doc_examples_cli(monkeypatch, capsys, win_5152_sde_xml_file, command: str, expected: Set[str]):
+    monkeypatch.setattr(MetadataFactory, "fetch_http", lambda self, _: win_5152_sde_xml_file)
+
+    cli = Cli()
+    assert 0 == cli.run(command.split())
+    out, err = capsys.readouterr()
+    assert not err
+    out_set = set(out.strip().split())
+    assert out_set == expected
+
+
 @pytest.mark.parametrize(
     "version, arch, modules_to_query, modules_failed_query",
     (