Repository: miurahr/aqtinstall
Pull request #354 (2021-08-01 06:56:16)

Support new sub command syntax


Patch:
diff --git a/aqt/installer.py b/aqt/installer.py
index 7cabfbe..8a0cb20 100644
--- a/aqt/installer.py
+++ b/aqt/installer.py
@@ -70,7 +70,40 @@ class Cli:
     __slot__ = ["parser", "combinations", "logger"]
 
     def __init__(self):
-        self._create_parser()
+        parser = argparse.ArgumentParser(
+            prog="aqt",
+            description="Another unoffical Qt Installer.\n"
+            "aqt help you install Qt SDK, tools, examples and others\n",
+            formatter_class=argparse.RawTextHelpFormatter,
+            add_help=True,
+        )
+        parser.add_argument(
+            "-c",
+            "--config",
+            type=argparse.FileType("r"),
+            help="Configuration ini file.",
+        )
+        subparsers = parser.add_subparsers(
+            title="subcommands",
+            description="aqt accept several subcommands\n"
+            "install-* subcommands are installer of components\n"
+            "list-* subcommands are show available compoenets\n\n"
+            "commands {install|tool|src|examples|doc} are oblesolete now\n",
+            help="Please refer each help message shown with --help argument for each subcommands",
+        )
+        self._make_install_parsers(subparsers)
+        self._make_list_qt_parser(subparsers)
+        self._make_list_tool_parser(subparsers)
+        self._make_legacy_parsers(subparsers)
+        self._make_common_parsers(subparsers)
+        parser.set_defaults(func=self.show_help)
+        self.parser = parser
+
+    def run(self, arg=None):
+        args = self.parser.parse_args(arg)
+        self._setup_settings(args)
+        result = args.func(args)
+        return result
 
     def _check_tools_arg_combination(self, os_name, tool_name, arch):
         for c in Settings.tools_combinations:
@@ -182,7 +215,7 @@ class Cli:
             return False
         return all([m in available for m in modules])
 
-    def run_install(self, args):
+    def run_install_qt(self, args):
         """Run install subcommand"""
         start_time = time.perf_counter()
         self.show_aqt_version()
@@ -373,7 +406,7 @@ class Cli:
         else:
             exit(1)
 
-    def run_src(self, args):
+    def run_install_src(self, args):
         """Run src subcommand"""
         if args.kde:
             if args.qt_version != "5.15.2":
@@ -393,7 +426,7 @@ class Cli:
             )
         )
 
-    def run_examples(self, args):
+    def run_install_example(self, args):
         """Run example subcommand"""
         start_time = time.perf_counter()
         self._run_src_doc_examples("examples", args)
@@ -403,7 +436,7 @@ class Cli:
             )
         )
 
-    def run_doc(self, args):
+    def run_install_doc(self, args):
         """Run doc subcommand"""
         start_time = time.perf_counter()
         self._run_src_doc_examples("doc", args)
@@ -413,7 +446,7 @@ class Cli:
             )
         )
 
-    def run_tool(self, args):
+    def run_install_tool(self, args):
         """Run tool subcommand"""
         start_time = time.perf_counter()
         self.show_aqt_version()
@@ -546,6 +579,140 @@ class Cli:
         )
         return show_list(meta)
 
+    def run_list_tool(self, args: argparse.ArgumentParser) -> int:
+        """Print tools"""
+
+        if not args.target:
+            print(" ".join(ArchiveId.TARGETS_FOR_HOST[args.host]))
+            return 0
+        if args.target not in ArchiveId.TARGETS_FOR_HOST[args.host]:
+            self.logger.error(
+                "'{0.target}' is not a valid target for host '{0.host}'".format(args)
+            )
+            return 1
+
+        meta = MetadataFactory(
+            archive_id=ArchiveId("tools", args.host, args.target),
+            tool_name=args.tool_name,
+            is_long_listing=args.long,
+        )
+        return show_list(meta)
+
+    def show_help(self, args=None):
+        """Display help message"""
+        self.parser.print_help()
+
+    def show_aqt_version(self, args=None):
+        """Display version information"""
+        py_version = platform.python_version()
+        py_impl = platform.python_implementation()
+        py_build = platform.python_compiler()
+        self.logger.info(
+            "aqtinstall(aqt) v{} on Python {} [{} {}]".format(
+                aqt.__version__, py_version, py_impl, py_build
+            )
+        )
+
+    def _set_install_qt_parser(self, install_qt_parser):
+        install_qt_parser.set_defaults(func=self.run_install_qt)
+        self._set_common_argument(install_qt_parser)
+        self._set_common_options(install_qt_parser)
+        install_qt_parser.add_argument(
+            "arch",
+            nargs="?",
+            help="\ntarget linux/desktop: gcc_64, wasm_32"
+            "\ntarget mac/desktop:   clang_64, wasm_32"
+            "\ntarget mac/ios:       ios"
+            "\nwindows/desktop:      win64_msvc2019_64, win32_msvc2019"
+            "\n                      win64_msvc2017_64, win32_msvc2017"
+            "\n                      win64_msvc2015_64, win32_msvc2015"
+            "\n                      win64_mingw81, win32_mingw81"
+            "\n                      win64_mingw73, win32_mingw73"
+            "\n                      win32_mingw53"
+            "\n                      wasm_32"
+            "\nwindows/winrt:        win64_msvc2019_winrt_x64, win64_msvc2019_winrt_x86"
+            "\n                      win64_msvc2017_winrt_x64, win64_msvc2017_winrt_x86"
+            "\n                      win64_msvc2019_winrt_armv7"
+            "\n                      win64_msvc2017_winrt_armv7"
+            "\nandroid:              Qt 5.14:          android (optional)"
+            "\n                      Qt 5.13 or below: android_x86_64, android_arm64_v8a"
+            "\n                                        android_x86, android_armv7",
+        )
+        self._set_module_options(install_qt_parser)
+        install_qt_parser.add_argument(
+            "--noarchives",
+            action="store_true",
+            help="No base packages; allow mod amendment with --modules option.",
+        )
+
+    def _set_install_tool_parser(self, install_tool_parser):
+        install_tool_parser.set_defaults(func=self.run_install_tool)
+        install_tool_parser.add_argument(
+            "host", choices=["linux", "mac", "windows"], help="host os name"
+        )
+        install_tool_parser.add_argument(
+            "target",
+            default=None,
+            choices=["desktop", "winrt", "android", "ios"],
+            help="Target SDK.",
+        )
+        install_tool_parser.add_argument(
+            "tool_name", help="Name of tool such as tools_ifw, tools_mingw"
+        )
+        install_tool_parser.add_argument(
+            "arch",
+            nargs="?",
+            default=None,
+            help="Name of full tool name such as qt.tools.ifw.31. "
+            "Please use 'aqt list-tool' to list acceptable values for this parameter.",
+        )
+        self._set_common_options(install_tool_parser)
+
+    def _make_legacy_parsers(self, subparsers: argparse._SubParsersAction):
+        install_parser = subparsers.add_parser(
+            "install", formatter_class=argparse.RawTextHelpFormatter
+        )
+        self._set_install_qt_parser(install_parser)
+        tool_parser = subparsers.add_parser("tool")
+        self._set_install_tool_parser(tool_parser)
+        #
+        for cmd, f in (
+            ("doc", self.run_install_doc),
+            ("example", self.run_install_example),
+            ("src", self.run_install_src),
+        ):
+            p = subparsers.add_parser(cmd)
+            p.set_defaults(func=f)
+            self._set_common_argument(p)
+            self._set_common_options(p)
+            self._set_module_options(p)
+
+    def _make_install_parsers(self, subparsers: argparse._SubParsersAction):
+        install_qt_parser = subparsers.add_parser(
+            "install-qt", formatter_class=argparse.RawTextHelpFormatter
+        )
+        self._set_install_qt_parser(install_qt_parser)
+        tool_parser = subparsers.add_parser("install-tool")
+        self._set_install_tool_parser(tool_parser)
+        #
+        for cmd, f in (
+            ("install-doc", self.run_install_doc),
+            ("install-example", self.run_install_example),
+        ):
+            p = subparsers.add_parser(cmd)
+            p.set_defaults(func=f)
+            self._set_common_argument(p)
+            self._set_common_options(p)
+            self._set_module_options(p)
+        src_parser = subparsers.add_parser("install-src")
+        src_parser.set_defaults(func=self.run_install_src)
+        self._set_common_argument(src_parser)
+        self._set_common_options(src_parser)
+        self._set_module_options(src_parser)
+        src_parser.add_argument(
+            "--kde", action="store_true", help="patching with KDE patch kit."
+        )
+
     def _make_list_qt_parser(self, subparsers: argparse._SubParsersAction):
         """Creates a subparser that works with the MetadataFactory, and adds it to the `subparsers` parameter"""
         list_parser: argparse.ArgumentParser = subparsers.add_parser(
@@ -618,25 +785,6 @@ class Cli:
         )
         list_parser.set_defaults(func=self.run_list_qt)
 
-    def run_list_tool(self, args: argparse.ArgumentParser) -> int:
-        """Print tools"""
-
-        if not args.target:
-            print(" ".join(ArchiveId.TARGETS_FOR_HOST[args.host]))
-            return 0
-        if args.target not in ArchiveId.TARGETS_FOR_HOST[args.host]:
-            self.logger.error(
-                "'{0.target}' is not a valid target for host '{0.host}'".format(args)
-            )
-            return 1
-
-        meta = MetadataFactory(
-            archive_id=ArchiveId("tools", args.host, args.target),
-            tool_name=args.tool_name,
-            is_long_listing=args.long,
-        )
-        return show_list(meta)
-
     def _make_list_tool_parser(self, subparsers: argparse._SubParsersAction):
         """Creates a subparser that works with the MetadataFactory, and adds it to the `subparsers` parameter"""
         list_parser: argparse.ArgumentParser = subparsers.add_parser(
@@ -677,20 +825,12 @@ class Cli:
         )
         list_parser.set_defaults(func=self.run_list_tool)
 
-    def show_help(self, args=None):
-        """Display help message"""
-        self.parser.print_help()
-
-    def show_aqt_version(self, args=None):
-        """Display version information"""
-        py_version = platform.python_version()
-        py_impl = platform.python_implementation()
-        py_build = platform.python_compiler()
-        self.logger.info(
-            "aqtinstall(aqt) v{} on Python {} [{} {}]".format(
-                aqt.__version__, py_version, py_impl, py_build
-            )
-        )
+    def _make_common_parsers(self, subparsers: argparse._SubParsersAction):
+        help_parser = subparsers.add_parser("help")
+        help_parser.set_defaults(func=self.show_help)
+        #
+        version_parser = subparsers.add_parser("version")
+        version_parser.set_defaults(func=self.show_aqt_version)
 
     def _set_common_options(self, subparser):
         subparser.add_argument(
@@ -744,114 +884,6 @@ class Cli:
             "target", choices=["desktop", "winrt", "android", "ios"], help="target sdk"
         )
 
-    def _create_parser(self):
-        parser = argparse.ArgumentParser(
-            prog="aqt",
-            description="Installer for Qt SDK.",
-            formatter_class=argparse.RawTextHelpFormatter,
-            add_help=True,
-        )
-        parser.add_argument(
-            "-c",
-            "--config",
-            type=argparse.FileType("r"),
-            help="Configuration ini file.",
-        )
-        subparsers = parser.add_subparsers(
-            title="subcommands",
-            description="Valid subcommands",
-            help="subcommand for aqt Qt installer",
-        )
-        install_parser = subparsers.add_parser(
-            "install", formatter_class=argparse.RawTextHelpFormatter
-        )
-        install_parser.set_defaults(func=self.run_install)
-        self._set_common_argument(install_parser)
-        self._set_common_options(install_parser)
-        install_parser.add_argument(
-            "arch",
-            nargs="?",
-            help="\ntarget linux/desktop: gcc_64, wasm_32"
-            "\ntarget mac/desktop:   clang_64, wasm_32"
-            "\ntarget mac/ios:       ios"
-            "\nwindows/desktop:      win64_msvc2019_64, win32_msvc2019"
-            "\n                      win64_msvc2017_64, win32_msvc2017"
-            "\n                      win64_msvc2015_64, win32_msvc2015"
-            "\n                      win64_mingw81, win32_mingw81"
-            "\n                      win64_mingw73, win32_mingw73"
-            "\n                      win32_mingw53"
-            "\n                      wasm_32"
-            "\nwindows/winrt:        win64_msvc2019_winrt_x64, win64_msvc2019_winrt_x86"
-            "\n                      win64_msvc2017_winrt_x64, win64_msvc2017_winrt_x86"
-            "\n                      win64_msvc2019_winrt_armv7"
-            "\n                      win64_msvc2017_winrt_armv7"
-            "\nandroid:              Qt 5.14:          android (optional)"
-            "\n                      Qt 5.13 or below: android_x86_64, android_arm64_v8a"
-            "\n                                        android_x86, android_armv7",
-        )
-        self._set_module_options(install_parser)
-        install_parser.add_argument(
-            "--noarchives",
-            action="store_true",
-            help="No base packages; allow mod amendment with --modules option.",
-        )
-        #
-        doc_parser = subparsers.add_parser("doc")
-        doc_parser.set_defaults(func=self.run_doc)
-        self._set_common_argument(doc_parser)
-        self._set_common_options(doc_parser)
-        self._set_module_options(doc_parser)
-        #
-        examples_parser = subparsers.add_parser("examples")
-        examples_parser.set_defaults(func=self.run_examples)
-        self._set_common_argument(examples_parser)
-        self._set_common_options(examples_parser)
-        self._set_module_options(examples_parser)
-        #
-        src_parser = subparsers.add_parser("src")
-        src_parser.set_defaults(func=self.run_src)
-        self._set_common_argument(src_parser)
-        self._set_common_options(src_parser)
-        self._set_module_options(src_parser)
-        src_parser.add_argument(
-            "--kde", action="store_true", help="patching with KDE patch kit."
-        )
-        #
-        tools_parser = subparsers.add_parser("tool")
-        tools_parser.set_defaults(func=self.run_tool)
-        tools_parser.add_argument(
-            "host", choices=["linux", "mac", "windows"], help="host os name"
-        )
-        tools_parser.add_argument(
-            "target",
-            default=None,
-            choices=["desktop", "winrt", "android", "ios"],
-            help="Target SDK.",
-        )
-
-        tools_parser.add_argument(
-            "tool_name", help="Name of tool such as tools_ifw, tools_mingw"
-        )
-        tools_parser.add_argument(
-            "arch",
-            nargs="?",
-            default=None,
-            help="Name of full tool name such as qt.tools.ifw.31. "
-            "Please use 'aqt list-tool' to list acceptable values for this parameter.",
-        )
-        self._set_common_options(tools_parser)
-
-        self._make_list_qt_parser(subparsers)
-        self._make_list_tool_parser(subparsers)
-        #
-        help_parser = subparsers.add_parser("help")
-        help_parser.set_defaults(func=self.show_help)
-        #
-        version_parser = subparsers.add_parser("version")
-        version_parser.set_defaults(func=self.show_aqt_version)
-        parser.set_defaults(func=self.show_help)
-        self.parser = parser
-
     def _setup_settings(self, args=None):
         # setup logging
         setup_logging()
@@ -867,12 +899,6 @@ class Cli:
             else:
                 Settings.load_settings()
 
-    def run(self, arg=None):
-        args = self.parser.parse_args(arg)
-        self._setup_settings(args)
-        result = args.func(args)
-        return result
-
     @staticmethod
     def _is_valid_version_str(
         version_str: str, *, allow_latest: bool = False, allow_empty: bool = False
diff --git a/ci/generate_azure_pipelines_matrices.py b/ci/generate_azure_pipelines_matrices.py
index 34a3ad3..03e64aa 100644
--- a/ci/generate_azure_pipelines_matrices.py
+++ b/ci/generate_azure_pipelines_matrices.py
@@ -70,20 +70,20 @@ all_platform_build_jobs = [
 # Linux Desktop
 for qt_version in qt_versions:
     linux_build_jobs.append(
-        BuildJob("install", qt_version, "linux", "desktop", "gcc_64", "gcc_64")
+        BuildJob("install-qt", qt_version, "linux", "desktop", "gcc_64", "gcc_64")
     )
 
 # Mac Desktop
 for qt_version in qt_versions:
     mac_build_jobs.append(
-        BuildJob("install", qt_version, "mac", "desktop", "clang_64", "clang_64")
+        BuildJob("install-qt", qt_version, "mac", "desktop", "clang_64", "clang_64")
     )
 
 # Windows Desktop
 windows_build_jobs.extend(
     [
         BuildJob(
-            "install",
+            "install-qt",
             "5.14.2",
             "windows",
             "desktop",
@@ -92,7 +92,7 @@ windows_build_jobs.extend(
             mirror=random.choice(MIRRORS),
         ),
         BuildJob(
-            "install",
+            "install-qt",
             "5.14.2",
             "windows",
             "desktop",
@@ -101,7 +101,7 @@ windows_build_jobs.extend(
             mirror=random.choice(MIRRORS),
         ),
         BuildJob(
-            "install",
+            "install-qt",
             "5.13.2",
             "windows",
             "desktop",
@@ -110,7 +110,7 @@ windows_build_jobs.extend(
             mirror=random.choice(MIRRORS),
         ),
         BuildJob(
-            "install",
+            "install-qt",
             "5.15.2",
             "windows",
             "desktop",
@@ -121,7 +121,7 @@ windows_build_jobs.extend(
         # Known issue with Azure-Pipelines environment: it has a pre-installed mingw81 which cause link error.
         # BuildJob('install', '5.15.0', 'windows', 'desktop', 'win32_mingw81', 'mingw81_32', mirror=MIRROR),
         BuildJob(
-            "install",
+            "install-qt",
             "5.15.2",
             "windows",
             "desktop",
@@ -137,7 +137,7 @@ windows_build_jobs.extend(
 linux_build_jobs.extend(
     [
         BuildJob(
-            "install",
+            "install-qt",
             "5.15.2",
             "linux",
             "desktop",
@@ -146,10 +146,10 @@ linux_build_jobs.extend(
             module="qtcharts qtnetworkauth",
         ),
         BuildJob(
-            "install", "5.14.2", "linux", "desktop", "gcc_64", "gcc_64", module="all"
+            "install-qt", "5.14.2", "linux", "desktop", "gcc_64", "gcc_64", module="all"
         ),
         BuildJob(
-            "install",
+            "install-qt",
             "5.15.2",
             "linux",
             "desktop",
@@ -158,28 +158,28 @@ linux_build_jobs.extend(
             subarchives="qtbase qttools qt icu",
         ),
         BuildJob(
-            "src", "6.1.0", "linux", "desktop", "gcc_64", "gcc_64", subarchives="qt"
+            "install-src", "6.1.0", "linux", "desktop", "gcc_64", "gcc_64", subarchives="qt"
         ),
         BuildJob(
-            "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"
         ),
         # test for list commands
-        BuildJob('list', '5.15.2', 'linux', 'desktop', '', '', spec="<6", list_options={
+        BuildJob('list-qt', '5.15.2', 'linux', 'desktop', '', '', spec="<6", list_options={
             'HAS_EXTENSIONS': "True",
         }),
-        BuildJob('list', '6.1.0', 'linux', 'android', '', '', spec=">6.0,<6.1.1", list_options={
+        BuildJob('list-qt', '6.1.0', 'linux', 'android', '', '', spec=">6.0,<6.1.1", list_options={
             'HAS_EXTENSIONS': "True",
             'USE_EXTENSION': "armv7",
         }),
         # tests run on linux but query data about other platforms
-        BuildJob('list', '5.14.1', 'mac', 'ios', '', '', spec="<=5.14.1", list_options={}),
-        BuildJob('list', '5.13.1', 'windows', 'winrt', '', '', spec=">5.13.0,<5.13.2", list_options={}),
+        BuildJob('list-qt', '5.14.1', 'mac', 'ios', '', '', spec="<=5.14.1", list_options={}),
+        BuildJob('list-qt', '5.13.1', 'windows', 'winrt', '', '', spec=">5.13.0,<5.13.2", list_options={}),
     ]
 )
 mac_build_jobs.extend(
     [
         BuildJob(
-            "install",
+            "install-qt",
             "6.2.0",
             "mac",
             "desktop",
@@ -188,7 +188,7 @@ mac_build_jobs.extend(
             module="addons.qtcharts addons.qtnetworkauth",
         ),
         BuildJob(
-            "install",
+            "install-qt",
             "5.14.2",
             "mac",
             "desktop",
@@ -201,23 +201,23 @@ mac_build_jobs.extend(
 
 # WASM
 linux_build_jobs.append(
-    BuildJob("install", "5.14.2", "linux", "desktop", "wasm_32", "wasm_32")
+    BuildJob("install-qt", "5.14.2", "linux", "desktop", "wasm_32", "wasm_32")
 )
 mac_build_jobs.append(
-    BuildJob("install", "5.14.2", "mac", "desktop", "wasm_32", "wasm_32")
+    BuildJob("install-qt", "5.14.2", "mac", "desktop", "wasm_32", "wasm_32")
 )
 
 # mobile SDK
 mac_build_jobs.extend(
     [
-        BuildJob("install", "5.15.2", "mac", "ios", "ios", "ios"),
+        BuildJob("install-qt", "5.15.2", "mac", "ios", "ios", "ios"),
         BuildJob(
-            "install", "6.1.0", "mac", "android", "android_armv7", "android_armv7"
+            "install-qt", "6.1.0", "mac", "android", "android_armv7", "android_armv7"
         ),
     ]
 )
 linux_build_jobs.extend(
-    [BuildJob("install", "6.1.0", "linux", "android", "android_armv7", "android_armv7")]
+    [BuildJob("install-qt", "6.1.0", "linux", "android", "android_armv7", "android_armv7")]
 )
 
 # Test binary patch of qmake
@@ -226,7 +226,7 @@ linux_build_jobs.extend(
         # New output dir is shorter than the default value; qmake could fail to
         # locate prefix dir if the value is patched wrong
         BuildJob(
-            "install",
+            "install-qt",
             "5.12.11",
             "linux",
             "desktop",
@@ -237,7 +237,7 @@ linux_build_jobs.extend(
         # New output dir is longer than the default value.
         # This case is meant to work without any bugfix; if this fails, the test is setup wrong
         BuildJob(
-            "install",
+            "install-qt",
             "5.12.11",
             "linux",
             "desktop",
diff --git a/ci/steps.yml b/ci/steps.yml
index 028cf89..bb22a7e 100644
--- a/ci/steps.yml
+++ b/ci/steps.yml
@@ -19,7 +19,7 @@ steps:
       sleep $number
       mkdir Qt
       cd Qt
-      if [[ "$(SUBCOMMAND)" == "install" ]]; then
+      if [[ "$(SUBCOMMAND)" == "install-qt" ]]; then
         opt=""
         if [[ "$(QT_BASE_MIRROR)" != "" ]]; then
           opt+=" -b $(QT_BASE_MIRROR)"
@@ -35,12 +35,12 @@ steps:
         if [[ "$(SUBARCHIVES)" != "" ]]; then
           opt+=" --archives $(SUBARCHIVES)"
         fi
-        python -m aqt install $(QT_VERSION) $(HOST) $(TARGET) $(ARCH) $opt
+        python -m aqt install-qt $(QT_VERSION) $(HOST) $(TARGET) $(ARCH) $opt
         if [[ "$(TARGET)" == "android" || "$(TARGET)" == "ios" ]]; then
           if [[ "$(HOST)" == "windows" ]]; then
-            python -m aqt install $(QT_VERSION) $(HOST) desktop mingw81_64 --archives qtbase
+            python -m aqt install-qt $(QT_VERSION) $(HOST) desktop mingw81_64 --archives qtbase
           else
-            python -m aqt install $(QT_VERSION) $(HOST) desktop --archives qtbase
+            python -m aqt install-qt $(QT_VERSION) $(HOST) desktop --archives qtbase
           fi
         fi
         if [[ "$(OUTPUT_DIR)" != "" ]]; then
@@ -98,10 +98,10 @@ steps:
         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
       fi
-      if [[ "$(SUBCOMMAND)" == "src" ]]; then
+      if [[ "$(SUBCOMMAND)" == "install-src" ]]; then
         python -m aqt $(SUBCOMMAND) $(QT_VERSION) $(HOST) $(TARGET) --archives $(SUBARCHIVES)
       fi
-      if [[ "$(SUBCOMMAND)" == "doc" ]]; then
+      if [[ "$(SUBCOMMAND)" == "install-doc" ]]; then
         python -m aqt $(SUBCOMMAND) $(QT_VERSION) $(HOST) $(TARGET) --archives $(SUBARCHIVES)
       fi
     workingDirectory: $(Build.BinariesDirectory)
@@ -128,13 +128,13 @@ steps:
       export PATH=$(QT_BINDIR):$PATH
       qmake $(Build.BinariesDirectory)/tests/accelbubble
       make
-    condition: and(eq(variables['TARGET'], 'android'), or(eq(variables['Agent.OS'], 'Linux'), eq(variables['Agent.OS'], 'Darwin')), ne(variables['SUBCOMMAND'], 'list'))
+    condition: and(eq(variables['TARGET'], 'android'), or(eq(variables['Agent.OS'], 'Linux'), eq(variables['Agent.OS'], 'Darwin')), ne(variables['SUBCOMMAND'], 'list-qt'))
     displayName: Build accelbubble example application to test for android
 
   - script: |
       sudo apt-get update
       sudo apt-get install -y libgl1-mesa-dev
-    condition: and(eq(variables['TARGET'], 'desktop'), eq(variables['Agent.OS'], 'Linux'), eq(variables['SUBCOMMAND'], 'install'))
+    condition: and(eq(variables['TARGET'], 'desktop'), eq(variables['Agent.OS'], 'Linux'), eq(variables['SUBCOMMAND'], 'install-qt'))
     displayName: install test dependency for Linux
 
   ##----------------------------------------------------
@@ -176,7 +176,7 @@ steps:
       export PATH=$(QT_BINDIR):$PATH
       qmake $(Build.BinariesDirectory)/tests/helloworld
       make
-    condition: and(eq( variables['TARGET'], 'desktop' ), ne( variables['ARCH'], 'wasm_32' ), or(eq(variables['Agent.OS'], 'Linux'), eq(variables['Agent.OS'], 'Darwin')), eq(variables['MODULE'], ''), eq(variables['SUBCOMMAND'], 'install'))
+    condition: and(eq( variables['TARGET'], 'desktop' ), ne( variables['ARCH'], 'wasm_32' ), or(eq(variables['Agent.OS'], 'Linux'), eq(variables['Agent.OS'], 'Darwin')), eq(variables['MODULE'], ''), eq(variables['SUBCOMMAND'], 'install-qt'))
     displayName: Build test with qmake for Linux and macOS w/o extra module
   - powershell: |
       if ( $env:TOOLCHAIN -eq 'MSVC' ) {
@@ -190,10 +190,10 @@ steps:
         jom
       } elseif ( $env:TOOLCHAIN -eq 'MINGW' ) {
         if ( $env:ARCH -eq 'win64_mingw81' ) {
-          python -m aqt tool --outputdir $(Build.BinariesDirectory)/Qt $(HOST) desktop tools_mingw qt.tools.win64_mingw810
+          python -m aqt install-tool --outputdir $(Build.BinariesDirectory)/Qt $(HOST) desktop tools_mingw qt.tools.win64_mingw810
           [Environment]::SetEnvironmentVariable("Path", ";$(Build.BinariesDirectory)\Qt\Tools\mingw810_64\bin" + $env:Path, "Machine")
         } else {
-          python -m aqt tool --outputdir $(Build.BinariesDirectory)/Qt $(HOST) desktop tools_mingw qt.tools.win32_mingw810
+          python -m aqt install-tool --outputdir $(Build.BinariesDirectory)/Qt $(HOST) desktop tools_mingw qt.tools.win32_mingw810
           [Environment]::SetEnvironmentVariable("Path", ";$(Build.BinariesDirectory)\Qt\Tools\mingw810_32\bin" + $env:Path, "Machine")
         }
         $env:Path = "$(Build.BinariesDirectory)\Qt\Tools\$(ARCHDIR)\bin;$(WIN_QT_BINDIR);" + $env:Path
diff --git a/docs/cli.rst b/docs/cli.rst
index 888dfc6..39b18bc 100644
--- a/docs/cli.rst
+++ b/docs/cli.rst
@@ -289,11 +289,11 @@ install Qt documents specified version and target.
 Example installation command
 ----------------------------
 
-.. program:: install-examples
+.. program:: install-example
 
 .. code-block:: bash
 
-    aqt install-examples <Qt version> <target OS> <target variant>
+    aqt install-example <Qt version> <target OS> <target variant>
 
 install Qt examples specified version and target.
 
@@ -353,30 +353,30 @@ Example: Installing Qt SDK 5.12.0 for Linux with QtCharts and QtNetworkAuth:
 .. code-block:: console
 
     pip install aqtinstall
-    sudo aqt install --outputdir /opt 5.12.0 linux desktop -m qtcharts qtnetworkauth
+    sudo aqt install-qt --outputdir /opt 5.12.0 linux desktop -m qtcharts qtnetworkauth
 
 
 Example: Installing Android (armv7) Qt 5.10.2:
 
 .. code-block:: console
 
-    aqt install 5.10.2 linux android android_armv7
+    aqt install-qt 5.10.2 linux android android_armv7
 
 
 Example: Install examples, doc and source:
 
 .. code-block:: console
 
-    aqt examples 5.15.2 windows desktop -m qtcharts qtnetworkauth
-    aqt doc 5.15.2 windows desktop -m qtcharts qtnetworkauth
-    aqt src 5.15.2 windows desktop --archives qtbase --kde
+    aqt install-example 5.15.2 windows desktop -m qtcharts qtnetworkauth
+    aqt install-doc 5.15.2 windows desktop -m qtcharts qtnetworkauth
+    aqt install-src 5.15.2 windows desktop --archives qtbase --kde
 
 
 Example: Install Web Assembly
 
 .. code-block:: console
 
-    aqt install 5.15.0 linux desktop wasm_32
+    aqt install-qt 5.15.0 linux desktop wasm_32
 
 
 Example: List available versions of Qt on Linux
@@ -432,7 +432,7 @@ Example: Install an Install FrameWork (IFW):
 
 .. code-block:: console
 
-    aqt tool linux desktop tools_ifw
+    aqt install-tool linux desktop tools_ifw
 
 
 Example: Install vcredist on Windows:
@@ -440,7 +440,7 @@ Example: Install vcredist on Windows:
 .. code-block:: doscon
 
 
-    aqt tool windows tools_vcredist
+    aqt install-tool windows tools_vcredist
     .\Qt\Tools\vcredist\vcredist_msvc2019_x64.exe /norestart /q
 
 
@@ -448,7 +448,7 @@ Example: Install MinGW on Windows
 
 .. code-block:: doscon
 
-    aqt tool -O c:\Qt windows tools_mingw qt.tools.win64_mingw810
+    aqt install-tool -O c:\Qt windows tools_mingw qt.tools.win64_mingw810
     set PATH=C:\Qt\Tools\mingw810_64\bin
 
 
diff --git a/docs/installation.rst b/docs/installation.rst
index 2493441..21d984e 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -24,6 +24,38 @@ Same as usual, it can be installed with `pip`
     $ pip install aqtinstall
 
 
+
+Command changes
+===============
+
+From version 2.0.0, sub commands are changed. There has also been legacy commands for backward compatibility
+but are not recommended now.
+
++----------------- -+---------------------+------------------------+
+| New sub commands  | Legacy sub commands |  Note                  |
++===================+=====================+========================+
+| install-qt        | install             |                        |
++----------------- -+---------------------+------------------------+
+| install-tool      | tool                | Arguments are changed  |
+|                   |                     | new syntax doesn't take|
+|                   |                     | version                |
++----------------- -+---------------------+------------------------+
+| install-example   | examples            | caution with last (s)  |
++----------------- -+---------------------+------------------------+
+| install-src       | src                 | New command only can   |
+|                   |                     | take --kde option      |
++----------------- -+---------------------+------------------------+
+| install-doc       | doc                 |                        |
++----------------- -+---------------------+------------------------+
+|                   | list                | legacy list command are|
+|                   |                     | deprecated.            |
++----------------- -+---------------------+------------------------+
+| list-qt           |                     |                        |
++----------------- -+---------------------+------------------------+
+| list-tool         |                     |                        |
++----------------- -+---------------------+------------------------+
+
+
 Usage
 =====
 
@@ -32,7 +64,7 @@ General usage looks like this:
 .. code-block:: bash
 
     aqt [-h][--help][-O | --outputdir <directory>][-b | --base <mirror url>][-E | --external <7zip command>] \
-        install <qt-version> <host> <target> [<arch>] [-m all | -m [extra module] [extra module]...] [--internal]
+        install-qt <qt-version> <host> <target> [<arch>] [-m all | -m [extra module] [extra module]...] [--internal]
         [--archives <archive>[ <archive>...]] [--timeout <timeout(sec)>]
 
 You can also call with ``python -m aqt`` syntax as well as command script ``aqt``.
@@ -64,7 +96,7 @@ You can install tools and utilities using following syntax;
 .. code-block:: bash
 
     python -m aqt [-h][--help][-O | --outputdir <directory>][-b | --base <mirror url>][-E | --external <7zip command>] \
-        tool <host> <tool_name> <tool-version> <arch> [--timeout <timeout>]
+        install-tool <host> <tool_name> <tool-version> <arch> [--timeout <timeout>]
 
 * tool_name is one of `tools_ifw`, `tools_vcredist`, and `tools_openssl`.
 * arch is full qualified tool name such as `qt.tools.ifw.31` which values can be seen on Qt `archive_site`_


Test patch:
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 4f02626..98e40d7 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -11,9 +11,12 @@ def test_cli_help(capsys):
     expected = "".join(
         [
             "usage: aqt [-h] [-c CONFIG]\n",
-            "           {install,doc,examples,src,tool,list-qt,list-tool,help,version} ...\n",
+            "           {install-qt,install-tool,install-doc,install-example,install-src,list-qt,list-tool,",
+            "install,tool,doc,example,src,help,version}\n",
+            "           ...\n",
             "\n",
-            "Installer for Qt SDK.\n",
+            "Another unoffical Qt Installer.\n",
+            "aqt help you install Qt SDK, tools, examples and others\n",
             "\n",
             "optional arguments:\n",
             "  -h, --help            show this help message and exit\n",
@@ -21,10 +24,15 @@ def test_cli_help(capsys):
             "                        Configuration ini file.\n",
             "\n",
             "subcommands:\n",
-            "  Valid subcommands\n",
+            "  aqt accept several subcommands\n",
+            "  install-* subcommands are installer of components\n",
+            "  list-* subcommands are show available compoenets\n",
+            "  \n",
+            "  commands {install|tool|src|examples|doc} are oblesolete now\n",
             "\n",
-            "  {install,doc,examples,src,tool,list-qt,list-tool,help,version}\n",
-            "                        subcommand for aqt Qt installer\n",
+            "  {install-qt,install-tool,install-doc,install-example,install-src,list-qt,list-tool,",
+            "install,tool,doc,example,src,help,version}\n",
+            "                        Please refer each help message shown with --help argument for each subcommands\n",
         ]
     )
     cli = Cli()
@@ -79,8 +87,8 @@ def test_cli_invalid_version(capsys, invalid_version):
     )
 
     for cmd in (
-        ("install", invalid_version, "mac", "desktop"),
-        ("doc", invalid_version, "mac", "desktop"),
+        ("install-qt", invalid_version, "mac", "desktop"),
+        ("install-doc", invalid_version, "mac", "desktop"),
         ("list-qt", "mac", "desktop", "--modules", invalid_version),
     ):
         with pytest.raises(SystemExit) as pytest_wrapped_e:
@@ -102,29 +110,3 @@ def test_cli_check_mirror():
     args = cli.parser.parse_args(arg)
     assert args.base == "https://download.qt.io/"
     assert cli._check_mirror(args.base)
-
-
-def test_cli_launch_with_no_argument(capsys):
-    expected = "".join(
-        [
-            "usage: aqt [-h] [-c CONFIG]\n",
-            "           {install,doc,examples,src,tool,list-qt,list-tool,help,version} ...\n",
-            "\n",
-            "Installer for Qt SDK.\n",
-            "\n",
-            "optional arguments:\n",
-            "  -h, --help            show this help message and exit\n",
-            "  -c CONFIG, --config CONFIG\n",
-            "                        Configuration ini file.\n",
-            "\n",
-            "subcommands:\n",
-            "  Valid subcommands\n",
-            "\n",
-            "  {install,doc,examples,src,tool,list-qt,list-tool,help,version}\n",
-            "                        subcommand for aqt Qt installer\n",
-        ]
-    )
-    cli = Cli()
-    cli.run([])
-    out, err = capsys.readouterr()
-    assert out == expected