Repository: buildtesters/buildtest (language: python)

Issue:
add changelog for version 1.6



Discussion / hints:

Fix patch:
diff --git a/.all-contributorsrc b/.all-contributorsrc
deleted file mode 100644
index f269d4c73..000000000
--- a/.all-contributorsrc
+++ /dev/null
@@ -1,49 +0,0 @@
-{
-  "projectName": "buildtest",
-  "projectOwner": "buildtesters",
-  "files": [
-    "ALL-CONTRIBUTORS.md"
-  ],
-  "imageSize": 100,
-  "repoType": "github",
-  "contributorsPerLine": 7,
-  "repoHost": "https://github.com",
-  "commitConvention": "angular",
-  "skipCi": true,
-  "contributors": [
-    {
-      "login": "prathmesh4321",
-      "name": "Prathmesh Sambrekar",
-      "avatar_url": "https://avatars.githubusercontent.com/u/35829130?v=4",
-      "profile": "https://github.com/prathmesh4321",
-      "contributions": [
-        "code",
-        "test",
-        "doc"
-      ]
-    },
-    {
-      "login": "shahzebsiddiqui",
-      "name": "Shahzeb Siddiqui",
-      "avatar_url": "https://avatars.githubusercontent.com/u/12942230?v=4",
-      "profile": "https://www.linkedin.com/in/shahzebmsiddiqui/",
-      "contributions": [
-        "code",
-        "doc",
-        "test"
-      ]
-    },
-    {
-      "login": "Xiang18",
-      "name": "Xiang18",
-      "avatar_url": "https://avatars.githubusercontent.com/u/39176411?v=4",
-      "profile": "https://github.com/xiang18",
-      "contributions": [
-        "code",
-        "test",
-        "doc",
-        "bug"
-      ]
-    }
-  ]
-}
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 7f0f10ac5..d4c952942 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,6 +1,7 @@
 # These are supported funding model platforms
 
-github: shahzebsiddiqui 
+github: shahzebsiddiqui
+open_collective: buildtest
 # patreon: # Replace with a single Patreon username
 # open_collective: # Replace with a single Open Collective username
 # ko_fi: # Replace with a single Ko-fi username
diff --git a/.github/workflows/build_container.yml b/.github/workflows/build_container.yml
index 3eaa124d0..47c8b682d 100644
--- a/.github/workflows/build_container.yml
+++ b/.github/workflows/build_container.yml
@@ -13,7 +13,7 @@ jobs:
       
     steps:
       - name: Check out the repo
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
       
       - name: Set up QEMU
         uses: docker/setup-qemu-action@v2
diff --git a/.github/workflows/installation.yml b/.github/workflows/installation.yml
index 44a5cb619..e50419e1f 100644
--- a/.github/workflows/installation.yml
+++ b/.github/workflows/installation.yml
@@ -17,7 +17,7 @@ jobs:
         python-version: ['3.8', '3.9', '3.10', '3.11']
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
     - name: Setup Python ${{ matrix.python-version }}
       uses: actions/setup-python@v4.7.0
@@ -53,7 +53,7 @@ jobs:
         which buildtest
         buildtest --help
 
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
     - name: Setup tmate session
       if: ${{ failure() }}
       uses: mxschmitt/action-tmate@v3
diff --git a/.github/workflows/jsonschemadocs.yml b/.github/workflows/jsonschemadocs.yml
index ae53ea279..fc294d4e0 100644
--- a/.github/workflows/jsonschemadocs.yml
+++ b/.github/workflows/jsonschemadocs.yml
@@ -11,7 +11,7 @@ jobs:
 
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
     - name: Use Node.js
       uses: actions/setup-node@v3
       with:
@@ -45,9 +45,9 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout 🛎️
-        # If you're using actions/checkout@v3 you must set persist-credentials
+        # If you're using actions/checkout@v4 you must set persist-credentials
         # to false in most cases for the deployment to work correctly.
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           persist-credentials: false
 
@@ -74,7 +74,7 @@ jobs:
           ls -R downloads
 
       - name: Deploy to GitHub Pages 🚀
-        uses: JamesIves/github-pages-deploy-action@v4.4.1
+        uses: JamesIves/github-pages-deploy-action@v4.4.3
         with:
           # ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
           branch: gh-pages
diff --git a/.github/workflows/nightly_regression.yml b/.github/workflows/nightly_regression.yml
index 92670f3d0..f6f7b7bc2 100644
--- a/.github/workflows/nightly_regression.yml
+++ b/.github/workflows/nightly_regression.yml
@@ -17,7 +17,7 @@ jobs:
         python-version: ['3.8', '3.9', '3.10', '3.11']
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
     - name: Setup Python ${{ matrix.python-version }}
       uses: actions/setup-python@v4.7.0
diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml
index b3ccd999d..7fce6fd8f 100644
--- a/.github/workflows/regression.yml
+++ b/.github/workflows/regression.yml
@@ -20,7 +20,7 @@ jobs:
         python-version: ['3.8', '3.9', '3.10', '3.11']
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
     - name: Setup Python ${{ matrix.python-version }}
       uses: actions/setup-python@v4.7.0
diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml
index faa221e4c..8de221087 100644
--- a/.github/workflows/shellcheck.yml
+++ b/.github/workflows/shellcheck.yml
@@ -13,7 +13,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout Repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
       - name: Run Shell Check
         run: |
           sudo apt-get install -y shellcheck
diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml
index 4f2caa631..e0c3e3425 100644
--- a/.github/workflows/style.yml
+++ b/.github/workflows/style.yml
@@ -17,7 +17,7 @@ jobs:
 
       # use isort github action see
       #https://pycqa.github.io/isort/docs/configuration/github_action.html
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: actions/setup-python@v4.7.0
         with:
           python-version: 3.8
diff --git a/.github/workflows/urlchecker.yml b/.github/workflows/urlchecker.yml
index 28ced5639..df2809b34 100644
--- a/.github/workflows/urlchecker.yml
+++ b/.github/workflows/urlchecker.yml
@@ -13,7 +13,7 @@ jobs:
     runs-on: ubuntu-latest
 
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
     - name: URLs-checker
       uses: urlstechie/urlchecker-action@0.0.34
       with:
@@ -35,6 +35,6 @@ jobs:
         retry_count: 5
 
         # Cannot check private GitHub settings
-        exclude_patterns: https://github.com/buildtesters/buildtest/settings,https://hpckp.org/past-edition/hpckp-17/,https://hpckp.org/past-edition/hpckp-18,https://sc19.supercomputing.org/presentation/?id=bof195&sess=sess324,https://sc19.supercomputing.org/,https://trac.mcs.anl.gov/projects/cobalt,https://cache.e4s.io,https://readthedocs.org/accounts/signup/,http://localhost:9000,https://www.hpcwire.com/2019/01/17/pfizer-hpc-engineer-aims-to-automate-software-stack-testing/
+        exclude_patterns: https://github.com/buildtesters/buildtest/settings,https://hpckp.org/past-edition/hpckp-17/,https://hpckp.org/past-edition/hpckp-18,https://sc19.supercomputing.org/presentation/?id=bof195&sess=sess324,https://sc19.supercomputing.org/,https://trac.mcs.anl.gov/projects/cobalt,https://cache.e4s.io,https://readthedocs.org/accounts/signup/,http://localhost:9000,https://www.hpcwire.com/2019/01/17/pfizer-hpc-engineer-aims-to-automate-software-stack-testing/,https://my.cdash.org/
         
         verbose: true
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 54df32051..5afe29f3e 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -10,10 +10,8 @@ repos:
       - id: isort
         args: ["--profile", "black", "--filter-files", "buildtest", "tests", "docs"]
 
-  - repo: https://github.com/psf/black
-    rev: 'refs/tags/22.3.0'
+  - repo: https://github.com/psf/black-pre-commit-mirror
+    rev: '23.9.1'
     hooks:
       - id: black
         language_version: python3
-
-
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 1f9b33d2e..11e325ff6 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -5,7 +5,7 @@ version: 2
 sphinx:
     builder: html
     configuration: docs/conf.py
-    fail_on_warning: true
+    #fail_on_warning: true
 
 build:
   os: "ubuntu-20.04"
diff --git a/ALL-CONTRIBUTORS.md b/ALL-CONTRIBUTORS.md
deleted file mode 100644
index a5e6b3f2b..000000000
--- a/ALL-CONTRIBUTORS.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Buildtest
-## Contributors
-
-<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
-<!-- prettier-ignore-start -->
-<!-- markdownlint-disable -->
-<table>
-  <tbody>
-    <tr>
-      <td align="center" valign="top" width="14.28%"><a href="https://github.com/prathmesh4321"><img src="https://avatars.githubusercontent.com/u/35829130?v=4?s=100" width="100px;" alt="Prathmesh Sambrekar"/><br /><sub><b>Prathmesh Sambrekar</b></sub></a><br /><a href="https://github.com/buildtesters/buildtest/commits?author=prathmesh4321" title="Code">💻</a> <a href="https://github.com/buildtesters/buildtest/commits?author=prathmesh4321" title="Tests">⚠️</a> <a href="https://github.com/buildtesters/buildtest/commits?author=prathmesh4321" title="Documentation">📖</a></td>
-      <td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/shahzebmsiddiqui/"><img src="https://avatars.githubusercontent.com/u/12942230?v=4?s=100" width="100px;" alt="Shahzeb Siddiqui"/><br /><sub><b>Shahzeb Siddiqui</b></sub></a><br /><a href="https://github.com/buildtesters/buildtest/commits?author=shahzebsiddiqui" title="Code">💻</a> <a href="https://github.com/buildtesters/buildtest/commits?author=shahzebsiddiqui" title="Documentation">📖</a> <a href="https://github.com/buildtesters/buildtest/commits?author=shahzebsiddiqui" title="Tests">⚠️</a></td>
-      <td align="center" valign="top" width="14.28%"><a href="https://github.com/xiang18"><img src="https://avatars.githubusercontent.com/u/39176411?v=4?s=100" width="100px;" alt="Xiang18"/><br /><sub><b>Xiang18</b></sub></a><br /><a href="https://github.com/buildtesters/buildtest/commits?author=Xiang18" title="Code">💻</a> <a href="https://github.com/buildtesters/buildtest/commits?author=Xiang18" title="Tests">⚠️</a> <a href="https://github.com/buildtesters/buildtest/commits?author=Xiang18" title="Documentation">📖</a> <a href="https://github.com/buildtesters/buildtest/issues?q=author%3AXiang18" title="Bug reports">🐛</a></td>
-    </tr>
-  </tbody>
-</table>
-
-<!-- markdownlint-restore -->
-<!-- prettier-ignore-end -->
-
-<!-- ALL-CONTRIBUTORS-LIST:END -->
\ No newline at end of file
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 55a30c4d1..2cab85602 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,39 @@
 CHANGELOG
 =========
 
+v1.6 (Sep 28th, 2023)
+----------------------
+
+**Command Line Changes**
+
+- The ``buildtest config profiles remove`` command will remove a given profile from configuration file `#1585 <https://github.com/buildtesters/buildtest/pull/1585>`_
+- The compiler listing is now done via ``buildtest config compilers list`` command, previously it was via ``buildtest config compilers``. `#1588 <https://github.com/buildtesters/buildtest/pull/1588>`_
+- Add short option ``-t`` for ``buildtest inspect query --testpath``. `#1599 <https://github.com/buildtesters/buildtest/pull/1599>`_
+- Change behavior of listing executors from command ``buildtest config executors`` to command name ``buildtest config executors list``. `#1610 <https://github.com/buildtesters/buildtest/pull/1610>`_
+- Add support for building tests by names via ``buildtest build --name``. `#1616 <https://github.com/buildtesters/buildtest/pull/1616>`_
+- Add support for limiting number of jobs that can run concurrently via ``max_jobs`` property in configuration file and option ``buildtest build --max-jobs`` to override configuration on command line. `#1629 <https://github.com/buildtesters/buildtest/pull/1629>`_, `#1630 <https://github.com/buildtesters/buildtest/pull/1630>`_
+
+**Buildspec/Test Changes**
+
+- Add support for deactivating spack environments via ``deactivate`` property. `#1587 <https://github.com/buildtesters/buildtest/pull/1587>`_
+- Add ``set -eo pipefail`` command in generated test script to ensure test are run in strict mode and errors are captured properly. `#1628 <https://github.com/buildtesters/buildtest/pull/1628>`_
+
+**Project Improvements**
+
+- Rewrite logic for building the command line arguments for buildtest. `#1612 <https://github.com/buildtesters/buildtest/pull/1612>`_
+- Update version of **sphinx-autoapi** to fix documentation build error with generating API. `#1632 <https://github.com/buildtesters/buildtest/pull/1632>`_
+- Ensure every buildtest CI run is executed in a unique directory. The environment variable **BUILDTEST_CI_DIR** will be root to where tests will be written in a unique directory. This can be set in shell environment prior to running tests. `#1601 <https://github.com/buildtesters/buildtest/pull/1601/>`_
+- The buildtest commands run as part of documentation builds also performed in unique directory. `#1603 <https://github.com/buildtesters/buildtest/pull/1603>`_
+- Move pytest configuration to pyproject.toml `#1596 <https://github.com/buildtesters/buildtest/pull/1596>`_
+- Upgrade dependencies for **docutils**, **sphinx**, **sphinx-rtd-theme**, **sphinx-design** to be compatible with python 3.8 `#1606 <https://github.com/buildtesters/buildtest/pull/1606>`_
+- Rewrite bash completion script. `#1611 <https://github.com/buildtesters/buildtest/pull/1611>`_
+
+**Bug Fixes**
+
+- Fix time calculation for batch jobs to ensure runtime is calculated correctly from when job runs to when job ends. Previously the test runtime took into account pending time. `#1618 <https://github.com/buildtesters/buildtest/pull/1618>`_
+- Fix issue with ``buildtest report``  only showing latest test records. `#1620 <https://github.com/buildtesters/buildtest/pull/1620>`_
+- Fix issue with CDASH upload (``buildtest cdash upload``) with uniccode characters in test output. `#1627 <https://github.com/buildtesters/buildtest/pull/1627>`_
+
 v1.5 (Aug 4th, 2023)
 ----------------------
 
diff --git a/bash_completion.sh b/bash_completion.sh
index 9e46c281a..022320c06 100644
--- a/bash_completion.sh
+++ b/bash_completion.sh
@@ -28,6 +28,10 @@ _avail_color_themes ()
   python -c "from pygments.styles import STYLE_MAP; print(' '.join(list(STYLE_MAP.keys())))"
 }
 
+_buildtest_commands()
+{
+  buildtest commands --with-aliases
+}
 # get list of available tags
 _avail_tags ()
 {
@@ -49,42 +53,47 @@ _avail_schemas ()
 # list of available executors
 _avail_executors ()
 {
-  buildtest config executors
+  buildtest config executors list
 }
 
 # list of available compilers
 _avail_compilers ()
 {
-  buildtest config compilers
+  buildtest config compilers list
 }
 
 # list of test ids from report
 _test_ids ()
 {
-  buildtest inspect list -t -n | cut -d '|' -f 1
+  buildtest inspect list --terse -n | cut -d '|' -f 1
+}
+# list of available test names from buildspec cache
+_buildspec_test_names()
+{
+  buildtest buildspec find --count=-1  --format name --terse --no-header | sort
 }
 
 # list of test names from report
 _test_name ()
 {
-  buildtest inspect list -t -n | cut -d '|' -f 2 | uniq | sort
+  buildtest inspect list --terse -n | cut -d '|' -f 2 | uniq | sort
 }
 
 _builder_names()
 {
-  buildtest inspect list -b
+  buildtest inspect list --builder
 }
 
 # list of buildspecs from report
 _test_buildspec ()
 {
-  buildtest inspect list -t -n | cut -d '|' -f 3 | uniq | sort
+  buildtest inspect list --terse -n | cut -d '|' -f 3 | uniq | sort
 }
 
 # list of history id
 _history_id ()
 {
-  buildtest history list -t -n | cut -d '|' -f 1 | sort -g
+  buildtest history list --terse -n | cut -d '|' -f 1 | sort -g
 }
 
 _buildspec_cache_test_names()
@@ -124,6 +133,21 @@ _avail_report_formatfields()
 {
   buildtest report --formatfields
 }
+
+_avail_profiles()
+{
+  buildtest config profiles list
+}
+
+_buildtest_show_commands()
+{
+  python -c "from buildtest.cli import BuildTestParser; print(' '.join(BuildTestParser()._buildtest_show_commands))"
+}
+
+_buildtest_options()
+{
+  python -c "from buildtest.cli import BuildTestParser; print(' '.join(BuildTestParser().get_buildtest_options()))"
+}
 #  entry point to buildtest bash completion function
 _buildtest ()
 {
@@ -159,161 +183,220 @@ _buildtest ()
   local next=${COMP_WORDS[1+offset]}
   
   case "$next" in
-  #case "${prev}" in
     build|bd)
-      local shortoption="-b -e -et -f -m -s -t -u -x -xt"
-      local longoption="--buildspec --executor --executor-type --exclude --exclude-tags --filter --helpfilter --limit --maxpendtime --modules --module-purge --nodes --pollinterval --procs --profile --rerun --remove-stagedir --retry --save-profile --stage --tags --timeout --unload-modules"
+      local shortoption="-b -e -et -f -m -n -s -t -u -x -xt"
+      local longoption="--buildspec --executor --executor-type --exclude --exclude-tags --filter --helpfilter --limit --maxpendtime --max-jobs --modules --module-purge --name --nodes --pollinterval --procs --profile --rerun --remove-stagedir --retry --save-profile --stage --tags --timeout --unload-modules"
       local allopts="${longoption} ${shortoption}"
 
-      COMPREPLY=( $( compgen -W "$allopts" -- $cur ) )
-
-      # fill auto-completion for 'buildtest build --executor'
-      if [[ "${prev}" == "-e" ]] || [[ "${prev}" == "--executor"  ]]; then
-        COMPREPLY=( $( compgen -W "$(_avail_executors)" -- $cur ) )
-      fi
-
-      # fill auto-completion for 'buildtest build --stage'
-      if [[ "${prev}" == "-s" ]] || [[ "${prev}" == "--stage"  ]]; then
-        COMPREPLY=( $( compgen -W "stage parse" -- $cur ) )
-      fi
-
-      # fill auto-completion for 'buildtest build --executor-type'
-      if [[ "${prev}" == "-et" ]] || [[ "${prev}" == "--executor-type"  ]]; then
-        COMPREPLY=( $( compgen -W "local batch" -- $cur ) )
-      fi
-
-      # fill auto-completion for 'buildtest build --tag' and 'buildtest build --exclude-tags'
-      if [[ "${prev}" == "-t" ]] || [[ "${prev}" == "--tag"  ]] || [[ "${prev}" == "-xt" ]] || [[ "${prev}" == "--exclude-tags"  ]]; then
-        COMPREPLY=( $( compgen -W "$(_avail_tags)" -- $cur ) )
-      fi
-
-      # fill auto-completion for 'buildtest build --buildspec'
-      if [[ "${prev}" == "-b" ]] || [[ "${prev}" == "--buildspec"  ]] || [[ "${prev}" == "-x" ]] || [[ "${prev}" == "--exclude" ]] ; then
-        COMPREPLY=( $( compgen -W "$(_avail_buildspecs)" -- $cur ) )
-      fi
+      COMPREPLY=( $( compgen -W "$allopts" -- "${cur}" ) )
+
+      case "${prev}" in
+        -e|--executor)
+            COMPREPLY=( $( compgen -W "$(_avail_executors)" -- "${cur}" ) )
+            ;;
+        -s|--stage)
+            COMPREPLY=( $( compgen -W "stage parse" -- "${cur}" ) )
+            ;;
+        -et|--executor-type)
+            COMPREPLY=( $( compgen -W "local batch" -- "${cur}" ) )
+            ;;
+        -t|--tag|-xt|--exclude-tags)
+            COMPREPLY=( $( compgen -W "$(_avail_tags)" -- "${cur}" ) )
+            ;;
+        -b|--buildspec|-x|--exclude)
+            COMPREPLY=( $( compgen -W "$(_avail_buildspecs)" -- "${cur}" ) )
+            ;;
+        -n|--name)
+            COMPREPLY=( $( compgen -W "$(_buildspec_test_names)" -- "${cur}" ) )
+            ;;
+      esac
       ;;
 
     cd)
-      COMPREPLY=( $( compgen  -W "$(_builder_names)" -- $cur ) );;
+      COMPREPLY=( $( compgen  -W "$(_builder_names)" -- "${cur}" ) );;
     clean)
       local opts="-h --help -y --yes"
-      COMPREPLY=( $( compgen -W "$opts" -- $cur ) )
+      COMPREPLY=( $( compgen -W "$opts" -- "${cur}" ) )
       ;;
     path)
       local opts="-b -be -e -h -o -s -t --buildscript --buildenv --errfile --help  --outfile --stagedir --testpath"
-      COMPREPLY=( $( compgen -W "$(_builder_names)" -- $cur ) )
+      COMPREPLY=( $( compgen -W "$(_builder_names)" -- "${cur}" ) )
       if [[ $cur == -* ]] ; then
         COMPREPLY=( $( compgen -W "$opts" -- $cur ) )
       fi
       ;;
     stats)
-      COMPREPLY=( $( compgen  -W "$(_test_name)" -- $cur ) );;
+      COMPREPLY=( $( compgen  -W "$(_test_name)" -- "${cur}" ) );;
     schema)
       local opts="-h -n -e -j --name --example --json"
       COMPREPLY=( $( compgen -W "$opts" -- $cur ) )
 
       # fill auto-completion for 'buildtest schema --name'
       if [[ "${prev}" == "-n" ]] || [[ "${prev}" == "--name"  ]]; then
-        COMPREPLY=( $( compgen -W "$(_avail_schemas)" -- $cur ) )
+        COMPREPLY=( $( compgen -W "$(_avail_schemas)" -- "${cur}" ) )
       fi
       ;;
 
     report|rt)
-      local opts="--detailed --end --fail --filter --filterfields --format --formatfields --help --helpfilter --helpformat --latest --no-header --oldest --pager --pass --row-count --start --terse -d -e -f -h -n -p -s -t c clear l list p path sm summary"
-      COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
-      case "${prev}" in --filter)
-        COMPREPLY=( $( compgen -W "$(_avail_report_filterfields)" -- $cur ) )
-        return
-      esac
-      case "${prev}" in --format)
-        COMPREPLY=( $( compgen -W "$(_avail_report_formatfields)" -- $cur ) )
-        return
-      esac
-      case "$prev" in summary|sm)
-        local opts="-d -h --detailed --help"
-        COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
-        return
+      local opts="--detailed --end --fail --filter --filterfields --format --formatfields --help --helpfilter --helpformat --latest --no-header --oldest --pager --pass --row-count --start --terse -d -e -f -h -n -p -s -t"
+      local cmds="clear list path summary"
+      local aliases="c l p sm"
+      COMPREPLY=( $( compgen -W "${cmds} ${aliases}" -- "${cur}" ) )
+
+      if [[ $cur == -* ]] ; then
+        COMPREPLY=( $( compgen -W "$opts" -- "${cur}" ) )
+      fi
+
+      case "${prev}" in
+        --filter)
+            COMPREPLY=( $( compgen -W "$(_avail_report_filterfields)" -- "${cur}" ) )
+            ;;
+        --format)
+            COMPREPLY=( $( compgen -W "$(_avail_report_formatfields)" -- "${cur}" ) )
+            ;;
+        summary|sm)
+            local opts="-d -h --detailed --help"
+            COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
+            ;;
       esac
     ;;
 
     config|cg)
-      local cmds="-h --help co compilers e edit ex executors p path systems val validate v view"
 
-      COMPREPLY=( $( compgen -W "${cmds}" -- $cur ) )
+      local cmds="co compilers e edit ex executors p path profiles remove systems validate v view"
+      local aliases="co e ex p v val"
+      local opts="-h --help"
+
+      COMPREPLY=( $( compgen -W "${cmds} ${aliases}" -- "${cur}" ) )
+      if [[ $cur == -* ]] ; then
+        COMPREPLY=( $( compgen -W "$opts" -- "${cur}" ) )
+      fi
       # handle completion logic for 'buildtest config <subcommand>' based on subcommands
 
       case "${COMP_WORDS[2+offset]}" in
         compilers|co)
-          local opts="--help --json --yaml -h -j -y find test"
-          COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
-          if [[ "${prev}" == "find" ]]; then
-            local opts="--detailed --file --help --modulepath --update -d -h -m -u"
-            COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
-          fi
-          if [[ "${prev}" == "test" ]]; then
-            COMPREPLY=( $( compgen -W "$(_avail_compilers)" -- $cur ) )
+
+          local opts="--help -h"
+          local cmds="list find remove test"
+          local aliases="rm"
+          COMPREPLY=( $( compgen -W "${cmds} ${aliases}" -- "${cur}" ) )
+          if [[ $cur == -* ]] ; then
+            COMPREPLY=( $( compgen -W "$opts" -- "${cur}" ) )
           fi
+
+          case "${prev}" in
+            list)
+              local opts="--json --yaml -j -y"
+              COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
+              ;;
+            find)
+              local opts="--detailed --file --help --modulepath --update -d -h -m -u"
+              COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
+              ;;
+            remove|rm)
+              COMPREPLY=( $( compgen -W "$(_avail_compilers)" -- "${cur}" ) )
+              ;;
+            test)
+              COMPREPLY=( $( compgen -W "$(_avail_compilers)" -- "${cur}" ) )
+              ;;
+          esac
           ;;
         executors|ex)
           local opts="--help --disabled --invalid --json --yaml -d -h -i -j -y"
-          COMPREPLY=( $( compgen -W "${opts}" -- $cur ) );;
+          local cmds="list"
+
+          case "$prev" in
+              list)
+                  COMPREPLY=( $( compgen -W "$opts" -- "${cur}" ) )
+                  ;;
+              *)
+                  COMPREPLY=( $( compgen -W "${cmds}" -- "${cur}" ) )
+                  ;;
+          esac
+          ;;
         validate|systems)
           local opts="-h --help"
-          COMPREPLY=( $( compgen -W "${opts}" -- $cur ) );;
+          COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) );;
         view|v)
           local opts="--help --pager --theme -h"
-          COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
+          COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
 
           case "${prev}" in --theme)
-            COMPREPLY=( $( compgen -W "$(_avail_color_themes)" -- $cur ) )
-            return
+            COMPREPLY=( $( compgen -W "$(_avail_color_themes)" -- "${cur}" ) )
+            ;;
           esac
         ;;
-      esac
+        profiles)
+          local opts="--help -h"
+          local cmds="list remove"
+          local aliases="rm"
+          COMPREPLY=( $( compgen -W "${cmds} ${aliases}" -- "${cur}" ) )
+          if [[ $cur == -* ]] ; then
+            COMPREPLY=( $( compgen -W "$opts" -- "${cur}" ) )
+          fi
+
+          case "${prev}" in
+            remove|rm)
+              COMPREPLY=( $( compgen -W "$(_avail_profiles)" -- "${cur}" ) )
+              ;;
+            list)
+              local opts="--json --theme --yaml -j -y"
+              COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
+              ;;
+            --theme)
+              COMPREPLY=( $( compgen -W "$(_avail_color_themes)" -- "${cur}" ) )
+              ;;
+          esac
+          ;;
+        esac
       ;;
     inspect|it)
       local cmds="--help -h b buildspec l list n name q query"
-
-      COMPREPLY=( $( compgen -W "${cmds}" -- $cur ) )
+      COMPREPLY=( $( compgen -W "${cmds}" -- "${cur}" ) )
 
       # case statement to handle completion for buildtest inspect [name|id|list] command
       case "${COMP_WORDS[2+offset]}" in
         list|l)
           local opts="--builder --help --no-header --pager --row-count --terse -b -h -n -t"
-          COMPREPLY=( $( compgen -W "${opts}" -- $cur ) );;
+          COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) );;
         name|n)
-          COMPREPLY=( $( compgen -W "$(_test_name)" -- $cur ) )
+          COMPREPLY=( $( compgen -W "$(_test_name)" -- "${cur}" ) )
 
           if [[ $cur == -* ]] ; then
             local opts="--all --help --pager -a -h"
-            COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
+            COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
           fi
           ;;
         buildspec|b)
-          COMPREPLY=( $( compgen -W "$(_test_buildspec)" -- $cur ) )
+          COMPREPLY=( $( compgen -W "$(_test_buildspec)" -- "${cur}" ) )
 
           if [[ $cur == -* ]] ; then
             local opts="--all --help --pager -a -h"
-            COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
+            COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
           fi
           ;;
         query|q)
-          COMPREPLY=( $( compgen -W "$(_builder_names)" -- $cur ) )
+          COMPREPLY=( $( compgen -W "$(_builder_names)" -- "${cur}" ) )
           if [[ $cur == -* ]] ; then
             local opts="--buildscript --buildenv --error --help --output --pager --testpath --theme -b -be -e -o -h -o -t"
-            COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
+            COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
           fi
           case "${prev}" in --theme)
-            COMPREPLY=( $( compgen -W "$(_avail_color_themes)" -- $cur ) )
+            COMPREPLY=( $( compgen -W "$(_avail_color_themes)" -- "${cur}" ) )
             return
           esac
           ;;
       esac
       ;;
-
     buildspec|bc)
-      local cmds="-h --help ef edit-file et edit-test f find m maintainers s show sf show-fail sm summary val validate"
-      COMPREPLY=( $( compgen -W "${cmds}" -- $cur ) )
+      local cmds="edit-file edit-test find maintainers show show-fail summary validate"
+      local aliases="ef et f m s sf sm val"
+      local opts="-h --help"
+      COMPREPLY=( $( compgen -W "${cmds} ${aliases}" -- "${cur}" ) )
+
+      if [[ $cur == -* ]] ; then
+        COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
+      fi
 
       # switch based on 2nd word 'buildtest buildspec <subcommand>'
       case ${COMP_WORDS[2+offset]} in
@@ -322,21 +405,22 @@ _buildtest ()
          # completion for 'buildtest buildspec find invalid'
          invalid)
            local opts="--error --help --row-count -e -h"
-           COMPREPLY=( $( compgen -W "${opts}" -- $cur ) );;
+           COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) );;
          # completion for rest of arguments
          *)
            local longopts="--buildspec --count --executors --filter --filterfields --format --formatfields --group-by-executor --group-by-tags --help --helpfilter --helpformat --no-header --pager --paths --quiet --rebuild --row-count --tags --root --terse"
            local shortopts="-b -e -h -n -p -q -r -t"
-           local subcmds="invalid"
-           local allopts="${longopts} ${shortopts} ${subcmds}"
-           COMPREPLY=( $( compgen -W "${allopts}" -- $cur ) )
-           case "${prev}" in --filter)
-             COMPREPLY=( $( compgen -W "$(_avail_buildspec_filterfields)" -- $cur ) )
-             return
-           esac
-           case "${prev}" in --format)
-             COMPREPLY=( $( compgen -W "$(_avail_buildspec_formatfields)" -- $cur ) )
-             return
+           local cmds="invalid"
+
+           COMPREPLY=( $( compgen -W "${cmds} ${longopts} ${shortopts}" -- "${cur}" ) )
+
+           case "${prev}" in
+           --filter)
+             COMPREPLY=( $( compgen -W "$(_avail_buildspec_filterfields)" -- "${cur}" ) )
+             ;;
+           --format)
+             COMPREPLY=( $( compgen -W "$(_avail_buildspec_formatfields)" -- "${cur}" ) )
+             ;;
            esac
            ;;
          esac
@@ -348,136 +432,146 @@ _buildtest ()
            local longopts="--help --pager"
            local shortopts="-h"
            local allopts="${longopts} ${shortopts}"
-           COMPREPLY=( $( compgen -W "${allopts}" -- $cur ) );;
+           COMPREPLY=( $( compgen -W "${allopts}" -- "${cur}" ) );;
          esac
         ;;
       edit-file|ef)
-        COMPREPLY=( $( compgen -W "$(_avail_buildspecs)" -- $cur ) );;
+        COMPREPLY=( $( compgen -W "$(_avail_buildspecs)" -- "${cur}" ) );;
       edit-test|et)
-        COMPREPLY=( $( compgen -W "$(_buildspec_cache_test_names)" -- $cur ) );;
+        COMPREPLY=( $( compgen -W "$(_buildspec_cache_test_names)" -- "${cur}" ) );;
       show|s)
         local opts="-h --help --theme"
-        COMPREPLY=( $( compgen -W "$(_buildspec_cache_test_names)" -- $cur ) )
+        COMPREPLY=( $( compgen -W "$(_buildspec_cache_test_names)" -- "${cur}" ) )
         if [[ $cur == -* ]] ; then
-          COMPREPLY=( $( compgen -W "$opts" -- $cur ) )
+          COMPREPLY=( $( compgen -W "$opts" -- "${cur}" ) )
         fi
 
         case "${prev}" in --theme)
-          COMPREPLY=( $( compgen -W "$(_avail_color_themes)" -- $cur ) )
+          COMPREPLY=( $( compgen -W "$(_avail_color_themes)" -- "${cur}" ) )
           return
         esac
         ;;
       show-fail|sf)
         local opts="-h --help --theme"
-        COMPREPLY=( $( compgen -W "$(_failed_tests)" -- $cur ) )
+        COMPREPLY=( $( compgen -W "$(_failed_tests)" -- "${cur}" ) )
         if [[ $cur == -* ]] ; then
-          COMPREPLY=( $( compgen -W "$opts" -- $cur ) )
+          COMPREPLY=( $( compgen -W "$opts" -- "${cur}" ) )
         fi
         case "${prev}" in --theme)
-          COMPREPLY=( $( compgen -W "$(_avail_color_themes)" -- $cur ) )
+          COMPREPLY=( $( compgen -W "$(_avail_color_themes)" -- "${cur}" ) )
           return
         esac
         ;;
       maintainers|m)
         local opts="--breakdown --help --row-count --terse --no-header -b -h -n find"
-        COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
+        COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
 
         case ${COMP_WORDS[3+offset]} in
         find)
-          COMPREPLY=( $( compgen -W "$(_avail_maintainers)" -- $cur ) );;
+          COMPREPLY=( $( compgen -W "$(_avail_maintainers)" -- "${cur}" ) );;
         esac
         ;;
       validate|val)
         local opts="--buildspec --exclude --executor --tag -b -e -t -x "
-
-        COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
-        # auto completion for 'buildtest buildspec validate' options
-        if [[ "${prev}" == "-b" ]] || [[ "${prev}" == "--buildspec" ]] || [[ "${prev}" == "-x" ]] || [[ "${prev}" == "--exclude" ]]; then
-          COMPREPLY=( $( compgen -W "$(_avail_buildspecs)" -- $cur ) )
-        elif [[ "${prev}" == "-t" ]] || [[ "${prev}" == "--tags" ]]; then
-          COMPREPLY=( $( compgen -W "$(_avail_tags)" -- $cur ) )
-        elif [[ "${prev}" == "-e" ]] || [[ "${prev}" == "--executor" ]]; then
-          COMPREPLY=( $( compgen -W "$(_avail_executors)" -- $cur ) )
-        fi
-        ;;
+        COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
+
+        case "${prev}" in
+          -b|--buildspec|-x|--exclude)
+              COMPREPLY=( $( compgen -W "$(_avail_buildspecs)" -- "${cur}" ) )
+              ;;
+          -t|--tags)
+              COMPREPLY=( $( compgen -W "$(_avail_tags)" -- "${cur}" ) )
+              ;;
+          -e|--executor)
+              COMPREPLY=( $( compgen -W "$(_avail_executors)" -- "${cur}" ) )
+              ;;
+        esac
+      ;;
       esac
       ;;
-
     history|hy)
-      local cmds="--help --pager -h list query"
-      COMPREPLY=( $( compgen -W "${cmds}" -- $cur ) )
+      local opts="--help -h"
+      local cmds="list query"
+      COMPREPLY=( $( compgen -W "${cmds}" -- "${cur}" ) )
+      if [[ $cur == -* ]] ; then
+        COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
+      fi
 
       case ${COMP_WORDS[2+offset]} in
       list)
-        local opts="--help --no-header --row-count --terse -h -n -t"
-        COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
+        local opts="--help --no-header --pager --row-count --terse -h -n -t"
+        COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
         ;;
       query)
         local opts="--help --log --output -h -l -o"
-        COMPREPLY=( $( compgen -W "$(_history_id)" -- $cur ) )
+        COMPREPLY=( $( compgen -W "$(_history_id)" -- "${cur}" ) )
         if [[ $cur == -* ]]; then
-          COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
+          COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
         fi
         ;;
       esac
       ;;
     cdash)
-      local cmds="--help -h upload view"
+      local cmds="upload view"
+      local opts="--help -h"
 
-      COMPREPLY=( $( compgen -W "${cmds}" -- $cur ) )
+      COMPREPLY=( $( compgen -W "${cmds}" -- "${cur}" ) )
 
-      if [[ "${prev}" == "view" ]]; then
-        local opts="-h --help"
-        COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
-      elif [[ "${prev}" == "upload" ]]; then
-        local opts="--help --open --site -h -o"
-        COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
+      if [[ $cur == -* ]] ; then
+        COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
       fi
+
+      case "${prev}" in
+        view)
+            local opts="-h --help"
+            COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
+            ;;
+        upload)
+            local opts="--help --open --site -h -o"
+            COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
+            ;;
+      esac
       ;;
     stylecheck|style)
       local opts="--help --no-black --no-isort --no-pyflakes --apply -a -h"
-
-      COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
+      COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
       ;;
-    unittests)
+    unittests|test)
       local opts="--coverage --help --pytestopts --sourcefiles -c -h -p -s"
-
-      COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
-      ;;
-    tutorial-examples)
-      local opts="-h --help"
-
-      COMPREPLY=( $( compgen -W "${opts}" -- $cur ) )
+      COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
       ;;
     show|s)
-      local subcommands="build buildspec cdash config history inspect path report schema stylecheck unittests"
-      local alias_cmds="bd bc cg hy it rt style test"
-      local cmds="$subcommands $alias_cmds"
-      COMPREPLY=( $( compgen -W "${cmds}" -- $cur ) )
+      COMPREPLY=( $( compgen -W "$(_buildtest_show_commands)" -- "${cur}" ) )
+      ;;
+    commands|cmds)
+      local opts="--help --with-aliases -a -h"
+      COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
+      ;;
+    # options with only --help
+    debugreport|info|docs|schemadocs|tutorial-examples)
+      local opts="-h --help"
+      COMPREPLY=( $( compgen -W "${opts}" -- "${cur}" ) )
       ;;
     *)
-      local cmds="build buildspec cd cdash clean commands config debugreport docs history info inspect path report schema schemadocs show stats stylecheck tutorial-examples unittests"
-      local alias_cmds="bd bc cg cmd debug hy it rt s style test"
-      local opts="--color --config --debug --editor --help --helpcolor --help-all --loglevel --logpath --no-color --print-log --report --version --view-log -c -d -h -l -p -r -H -V"
-
-
       case "${cur}" in
       # print main options to buildtest
         -*)
-          COMPREPLY=( $( compgen -W "${opts}" -- $cur ) );;
+          COMPREPLY=( $( compgen -W "$(_buildtest_options)" -- "${cur}" ) );;
 
       # print main sub-commands to buildtest
         *)
-          COMPREPLY=( $( compgen -W "${cmds} ${alias_cmds}" -- $cur ) )
-          if [[ "${prev}" == "--color" ]]; then
-            COMPREPLY=( $( compgen -W "$(_supported_colors)" -- $cur ) )
-          fi
-          if [[ "${prev}" == "--loglevel" ]] || [[ "${prev}" == "-l" ]]; then
-            COMPREPLY=( $( compgen -W "DEBUG INFO WARNING ERROR CRITICAL" -- $cur ) )
-          fi
-          if [[ "${prev}" == "--editor" ]]; then
-            COMPREPLY=( $( compgen -W "vi vim emacs nano" -- $cur ) )
-          fi
+          COMPREPLY=( $( compgen -W "$(_buildtest_commands)" -- "${cur}" ) )
+          case "${prev}" in
+            --color)
+                COMPREPLY=( $( compgen -W "$(_supported_colors)" -- "${cur}" ) )
+                ;;
+            --loglevel|-l)
+                COMPREPLY=( $( compgen -W "DEBUG INFO WARNING ERROR CRITICAL" -- "${cur}" ) )
+                ;;
+            --editor)
+                COMPREPLY=( $( compgen -W "vi vim emacs nano" -- "${cur}" ) )
+                ;;
+          esac
           ;;
       esac
   esac
diff --git a/docs/buildspecs/compiler.rst b/docs/buildspecs/compiler.rst
index 299aabf9f..7e5ede78d 100644
--- a/docs/buildspecs/compiler.rst
+++ b/docs/buildspecs/compiler.rst
@@ -48,7 +48,7 @@ Shown below is an example build for this test.
 
 The generated test for test name **hello_f** is the following:
 
-.. dropdown:: ``buildtest inspect query --testpath hello_f``
+.. dropdown:: ``buildtest inspect query -t hello_f``
 
     .. program-output:: cat buildtest_tutorial_examples/compilers/inspect/gnu_hello_fortran.txt
 
@@ -126,7 +126,7 @@ Let's build this test, we will see there is one builder instance for each compil
 If we inspect the following test, we see each test has its own compiler flags. The default cflag
 is ``-O1`` while **gcc_6.5.0** will use ``-O2`` and **gcc_8.3.0** will use ``-O3``.
 
-.. dropdown:: ``buildtest inspect query --testpath hello_c/``
+.. dropdown:: ``buildtest inspect query -t hello_c/``
 
     .. program-output:: cat buildtest_tutorial_examples/compilers/inspect/gnu_hello_c.txt
 
@@ -172,7 +172,7 @@ Now let's build this test.
 We can see the generated test using ``buildtest inspect query`` given the name of test. Take a close
 look at the ``export OMP_NUM_THREADS`` in the generated test.
 
-.. dropdown:: ``buildtest inspect query --testpath openmp_hello_c_example``
+.. dropdown:: ``buildtest inspect query -t openmp_hello_c_example``
 
     .. program-output:: cat buildtest_tutorial_examples/compilers/inspect/openmp_hello.txt
 
@@ -188,10 +188,10 @@ We can build this test by running::
 
     buildtest build -b $BUILDTEST_ROOT/examples/compilers/envvar_override.yml
 
-Next, let's see the generated test by running ``buildtest inspect query --testpath override_environmentvars``. Take a note that we have
+Next, let's see the generated test by running ``buildtest inspect query -t override_environmentvars``. Take a note that we have
 ``export OMP_NUM_THREADS=4`` for `gcc_8.3.0` test and ``export OMP_NUM_THREADS=2`` for system gcc.
 
-.. dropdown:: ``buildtest inspect query --testpath override_environmentvars/``
+.. dropdown:: ``buildtest inspect query -t override_environmentvars/``
 
     .. program-output:: cat buildtest_tutorial_examples/compilers/inspect/envvar_override.txt
 
@@ -253,7 +253,7 @@ You can build this test by running the following::
 Once test is complete let's inspect the generated test. We see that buildtest will insert the line specified
 by ``run`` property after compilation and run the executable.
 
-.. dropdown:: ``buildtest inspect query -b  --testpath custom_run_by_compilers/``
+.. dropdown:: ``buildtest inspect query -b  -t custom_run_by_compilers/``
 
     .. program-output::  cat buildtest_tutorial_examples/compilers/inspect/custom_run.txt
 
@@ -297,7 +297,7 @@ You can run this example by running the following command::
 If we inspect the content of test we see that buildtest will insert the shell commands
 for ``pre_build``, ``post_build``, ``pre_run`` and ``post_run`` in its corresponding section.
 
-.. dropdown:: ``buildtest inspect query --testpath pre_post_build_run``
+.. dropdown:: ``buildtest inspect query -t pre_post_build_run``
 
     .. program-output:: cat buildtest_tutorial_examples/compilers/inspect/pre_post_build_run.txt
 
@@ -335,7 +335,7 @@ If we build this test we see one test is created per compiler instance defined i
 Next, let's see the generated test using ``buildtest inspect query``, we notice buildtest will set variables ``BUILDTEST_*`` for
 each test to map to each compiler.
 
-.. dropdown:: ``buildtest inspect query --testpath stream_openmp_c/``
+.. dropdown:: ``buildtest inspect query -t stream_openmp_c/``
 
     .. program-output:: cat buildtest_tutorial_examples/compilers/inspect/stream_example.txt
 
diff --git a/docs/buildspecs/spack.rst b/docs/buildspecs/spack.rst
index b5e133416..e07979ab9 100644
--- a/docs/buildspecs/spack.rst
+++ b/docs/buildspecs/spack.rst
@@ -44,7 +44,7 @@ Let's build this test by running the following
 Let's inspect the generated script and output file via ``buildtest inspect query`` command. We notice that buildtest
 will source spack setup script and install `zlib` which is automatically installed from the buildcache.
 
-.. dropdown:: ``buildtest inspect query -o --testpath install_specs_example``
+.. dropdown:: ``buildtest inspect query -o -t install_specs_example``
 
     .. program-output:: cat buildtest_tutorial_examples/spack/inspect/install_specs.txt
 
@@ -93,7 +93,7 @@ concretize the environment and install the specs.
 
     .. program-output:: cat buildtest_tutorial_examples/spack/build/env_install.txt
 
-.. dropdown:: ``buildtest inspect query --testpath install_in_spack_env``
+.. dropdown:: ``buildtest inspect query -t install_in_spack_env``
 
     .. program-output:: cat buildtest_tutorial_examples/spack/inspect/env_install.txt
 
@@ -118,7 +118,7 @@ this using the ``option`` field. Shown below is the build and generated script a
 
     .. program-output:: cat buildtest_tutorial_examples/spack/build/env_create_directory.txt
 
-.. dropdown:: ``buildtest inspect query -o --testpath spack_env_directory``
+.. dropdown:: ``buildtest inspect query -o -t spack_env_directory``
 
     .. program-output:: cat buildtest_tutorial_examples/spack/inspect/env_create_directory.txt
 
@@ -147,10 +147,42 @@ will create an environment **manifest_example** using the manifest file that we
 
     .. program-output:: cat buildtest_tutorial_examples/spack/build/env_create_manifest.txt
 
-.. dropdown:: ``buildtest inspect query -o --testpath spack_env_create_from_manifest``
+.. dropdown:: ``buildtest inspect query -o -t spack_env_create_from_manifest``
 
     .. program-output:: cat buildtest_tutorial_examples/spack/inspect/env_create_manifest.txt
 
+Deactivate Spack Environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When you are switching between spack environments, it can be important to deactivate
+your current spack environment which can be used when writing test. This can be achieved
+using the keyword ``deactivate`` which is a boolean type.
+
+If ``deactivate: true`` is set, then we will deactivate the spack environment by
+running ``spack env deactivate``
+
+Shown below is an example buildspec where we create a spack environment, deactivate first and then
+activate the environment. Buildtest will deactivate a spack environment prior to activating an environment
+which is specified via ``activate`` keyword.
+
+.. literalinclude:: ../../examples/spack/spack_env_deactivate.yml
+  :language: yaml
+  :emphasize-lines: 10-14
+
+Let's build this by running the following
+
+.. dropdown:: ``buildtest build -b /home/spack/buildtest/examples/spack/spack_env_deactivate.yml``
+
+    .. program-output:: cat buildtest_tutorial_examples/spack/build/spack_env_deactivate.txt
+
+Let's take a look at the generated test, take note of the ``spack env deactivate`` command and order of commands.
+We run ``spack env create``, followed by ``spack env deactivate`` and finally we activate the environment
+using ``spack env activate``.
+
+.. dropdown:: ``buildtest inspect query --testpath spack_env_deactivate_first``
+
+    .. program-output:: cat buildtest_tutorial_examples/spack/inspect/spack_env_deactivate.txt
+
 Removing Spack Environments
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -177,7 +209,7 @@ Let's build this by running the following
 
 If we build and look at the generated te, we notice that spack will remove environments names: **remove_environment**, **dummy**.
 
-.. dropdown:: ``buildtest inspect query --testpath remove_environment_automatically remove_environment_explicit``
+.. dropdown:: ``buildtest inspect query -t remove_environment_automatically remove_environment_explicit``
 
     .. program-output:: cat buildtest_tutorial_examples/spack/inspect/remove_environment_example.txt
 
@@ -205,7 +237,7 @@ If we build this test and inspect the generated script we should get the followi
 
     .. program-output:: cat buildtest_tutorial_examples/spack/build/pre_post_cmds.txt
 
-.. dropdown:: ``buildtest inspect query -o --testpath run_pre_post_commands``
+.. dropdown:: ``buildtest inspect query -o -t run_pre_post_commands``
 
     .. program-output:: cat buildtest_tutorial_examples/spack/inspect/pre_post_cmds.txt
 
@@ -233,7 +265,7 @@ If we look at the generated script for both tests, we see that mirror is added f
 one can have mirrors defined in their ``spack.yaml`` or one of the `configuration scopes <https://spack.readthedocs.io/en/latest/configuration.html#configuration-scopes>`_
 defined by spack.
 
-.. dropdown:: ``buildtest inspect query -o --testpath add_mirror add_mirror_in_spack_env``
+.. dropdown:: ``buildtest inspect query -o -t add_mirror add_mirror_in_spack_env``
 
     .. program-output:: cat buildtest_tutorial_examples/spack/inspect/mirror_example.txt
 
@@ -270,7 +302,7 @@ The **spack test run --alias** option is used to query results by suitename whic
 
 Take note of the generated test and the suite-name that is generated by buildtest.
 
-.. dropdown:: ``buildtest inspect query -o --testpath spack_test_m4``
+.. dropdown:: ``buildtest inspect query -o -t spack_test_m4``
 
     .. program-output:: cat buildtest_tutorial_examples/spack/inspect/spack_test.txt
 
@@ -302,7 +334,7 @@ in spack environment followed by removing all testsuites using ``spack test remo
 query results in spec format (``spack test results --l --libxml2``) where spack will try to match a result file that matches the
 corresponding spec.
 
-.. dropdown:: ``buildtest inspect query -o --testpath spack_test_results_specs_format``
+.. dropdown:: ``buildtest inspect query -o -t spack_test_results_specs_format``
 
     .. program-output:: cat buildtest_tutorial_examples/spack/inspect/spack_test_specs.txt
 
@@ -329,7 +361,7 @@ files based on name of test. If we build this test, and inspect the generated te
 
     .. program-output:: cat buildtest_tutorial_examples/spack/build/spack_sbatch.txt
 
-.. dropdown:: ``buildtest inspect query --testpath spack_sbatch_example``
+.. dropdown:: ``buildtest inspect query -t spack_sbatch_example``
 
     .. program-output:: cat buildtest_tutorial_examples/spack/inspect/spack_sbatch.txt
 
@@ -366,6 +398,32 @@ Let's check the generated output, take note in the output the full path to where
 clone spack in ``pre_cmds`` in second test in order for buildtest to find the spack binary since you need to specify this the ``root`` property in-order
 for buildtest to install spack in the environment.
 
-.. dropdown:: ``buildtest inspect query --testpath clone_spack_automatically clone_spack_and_specify_root``
+.. dropdown:: ``buildtest inspect query -t clone_spack_automatically clone_spack_and_specify_root``
+
+    .. program-output:: cat buildtest_tutorial_examples/spack/inspect/clone_spack.txt
+
+Loading Specs
+---------------
+
+We can load specs into our user environment via ``spack load`` which can be used for running tests or
+simply loading the package once it is installed. In this next example, we will test ``m4`` package,
+where we load the package first prior to testing it. The ``load`` refers to ``spack load`` and ``options``
+refers to command options passed to ``spack load`` command with a list of specs to load defined
+by ``specs`` property.
+
+In this test, the command would translate to ``spack load --only package m4``
+
+.. literalinclude:: ../../examples/spack/spack_load.yml
+  :language: yaml
+  :emphasize-lines: 9-11
+
+Let's build this by running the following
+
+.. dropdown:: ``buildtest build -b /home/spack/buildtest/examples/spack/spack_load.yml``
+
+    .. program-output:: cat buildtest_tutorial_examples/spack/build/spack_load.txt
+
+Let's take a look at the generated test, take note of the `spack load` command
+.. dropdown:: ``buildtest inspect query -t spack_load_example``
 
-    .. program-output:: cat buildtest_tutorial_examples/spack/inspect/clone_spack.txt
\ No newline at end of file
+    .. program-output:: cat buildtest_tutorial_examples/spack/inspect/spack_load.txt
diff --git a/docs/command.rst b/docs/command.rst
index 38683ad55..975cba787 100644
--- a/docs/command.rst
+++ b/docs/command.rst
@@ -3,4 +3,4 @@ Buildtest Command Reference
 
 .. argparse::
    :ref: buildtest.cli.get_parser
-   :prog: buildtest
\ No newline at end of file
+   :prog: buildtest
diff --git a/docs/command_line_tutorial.rst b/docs/command_line_tutorial.rst
index 125620cfd..ee05f81eb 100644
--- a/docs/command_line_tutorial.rst
+++ b/docs/command_line_tutorial.rst
@@ -137,9 +137,9 @@ error file and support multiple test queries including regular expression!!
 
 Let's try running the following
 
-.. dropdown:: ``buildtest it query -o -e --testpath hello_world``
+.. dropdown:: ``buildtest it query -o -e -t hello_world``
 
-    .. command-output:: buildtest it query -o -e --testpath hello_world
+    .. command-output:: buildtest it query -o -e -t hello_world
 
 You can retrieve paths to given test via ``buildtest path`` that can be useful if you want to navigate to directory or list
 contents. By default ``buildtest path`` will retrieve root directory of test. You can retrieve output and error via
@@ -262,18 +262,18 @@ We also support color themes (``buildtest cg view --theme <theme>``) when showin
 Buildtest configuration file defines one or more :ref:`executors <configuring_executors>` that are used when
 writing test. Every test must be run by an executor. To retrieve all executors in a flat-listing you can run the following
 
-.. dropdown:: ``buildtest cg executors``
+.. dropdown:: ``buildtest cg executors list``
 
-    .. command-output:: buildtest cg executors
+    .. command-output:: buildtest cg executors list
 
 
 Buildtest can show executor details in JSON and YAML format, you can fetch the details by running the following
 
-.. dropdown:: ``buildtest cg executors --json``
+.. dropdown:: ``buildtest cg executors list --json``
 
-    .. command-output:: buildtest cg executors --json
+    .. command-output:: buildtest cg executors list --json
 
 
-.. dropdown:: ``buildtest cg executors --yaml``
+.. dropdown:: ``buildtest cg executors list --yaml``
 
-    .. command-output:: buildtest cg executors --yaml
+    .. command-output:: buildtest cg executors list --yaml
diff --git a/docs/conf.py b/docs/conf.py
index 8d88e5fe1..e5eafdcf4 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -15,13 +15,14 @@
 import os
 import shutil
 import sys
+import tempfile
 
 here = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 sys.path.insert(0, here)
 from buildtest import BUILDTEST_COPYRIGHT, BUILDTEST_VERSION
 from buildtest.cli.buildspec import BuildspecCache
 from buildtest.config import SiteConfiguration
-from buildtest.defaults import BUILDTEST_ROOT, VAR_DIR
+from buildtest.defaults import BUILDTEST_ROOT, DEFAULT_SETTINGS_FILE, VAR_DIR
 from buildtest.utils.file import is_dir
 
 # set BUILDTEST_ROOT environment that is generally set by 'source setup.sh'
@@ -29,6 +30,12 @@
 # add $BUILDTEST_ROOT/bin to $PATH to reference 'buildtest' command in docs
 os.environ["PATH"] += "%s%s" % (os.pathsep, os.path.join(here, "bin"))
 
+os.environ["BUILDTEST_CI_DIR"] = tempfile.mkdtemp()
+print(f"BUILDTEST_CI_DIR: {os.environ['BUILDTEST_CI_DIR']}")
+
+settings_file = os.path.join(os.environ["BUILDTEST_CI_DIR"], "config.yml")
+shutil.copyfile(DEFAULT_SETTINGS_FILE, settings_file)
+
 # remove $BUILDTEST_ROOT/var which writes variable data
 if is_dir(VAR_DIR):
     shutil.rmtree(VAR_DIR)
diff --git a/docs/facility_examples.rst b/docs/facility_examples.rst
index d9306a110..bb3e2ae86 100644
--- a/docs/facility_examples.rst
+++ b/docs/facility_examples.rst
@@ -86,11 +86,11 @@ modules and load `impi/2020` module.
 
 The generated test script is show below, notice that ``mpiicc`` is used to compile the program and run via srun.
 
-.. dropdown:: ``buildtest inspect query --testpath laplace_mpi``
+.. dropdown:: ``buildtest inspect query -t laplace_mpi``
 
     .. code-block:: console
 
-        $ buildtest inspect query --testpath laplace_mpi
+        $ buildtest inspect query -t laplace_mpi
         ─────────────────────────────────────────────── laplace_mpi/1a4c7a6f-0f69-40e7-b451-f9f62843eee5 ────────────────────────────────────────────────
         Executor: cori.slurm.knl_debug
         Description: Laplace MPI code in C
diff --git a/docs/features.rst b/docs/features.rst
index 89d85ee1c..4a6c8a502 100644
--- a/docs/features.rst
+++ b/docs/features.rst
@@ -397,20 +397,32 @@ use the environment **EDITOR** to get the preffered editor; however, one can ove
 
 .. _view_executors:
 
-View Executors (``buildtest config executors``)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+View Executors (``buildtest config executors list``)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-You can use the command ``buildtest config executors`` to view executors from buildtest
+You can use the command ``buildtest config executors list`` to view executors from buildtest
 configuration file.  Shown below is the command usage
 
-.. dropdown:: ``buildtest config executors --help``
+.. dropdown:: ``buildtest config executors list --help``
 
-    .. command-output:: buildtest config executors --help
+    .. command-output:: buildtest config executors list --help
 
-You can run ``buildtest config executors`` without any options and it will report a list of named executors that
-you would reference in buildspec using the ``executor`` property. If you prefer json or yaml format you can use ``--json`` or ``--yaml`` option.
+You can run ``buildtest config executors list`` without any options and it will report a list of named executors that
+you would reference in buildspec using the ``executor`` property.
+
+.. command-output:: buildtest config executors list
+
+If you want to see the executor details, you may want to use ``--json`` or ``--yaml`` option which will show the executor settings in YAML or JSON format.
+Shown below is an example output
+
+.. dropdown:: ``buildtest config executors list --yaml``
+
+    .. command-output:: buildtest config executors list --yaml
+
+.. dropdown:: ``buildtest config executors list --json``
+
+    .. command-output:: buildtest config executors list --json
 
-.. command-output:: buildtest config executors
 
 View Registered Systems (``buildtest config systems``)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/quick_start.rst b/docs/quick_start.rst
index 9e59d4b1b..5d9196880 100644
--- a/docs/quick_start.rst
+++ b/docs/quick_start.rst
@@ -154,4 +154,4 @@ When building tests, you can specify configuration file to use via::
 
 To see a list of available :ref:`executors <configuring_executors>` defined in your configuration file you can run::
 
-  buildtest config executors
+  buildtest config executors list
diff --git a/docs/requirements.txt b/docs/requirements.txt
index ea4978171..9d3190cd0 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,11 +1,11 @@
-# issue with rendering bullet points in sphinx docutils 0.17 or higher see https://stackoverflow.com/questions/67542699/readthedocs-sphinx-not-rendering-bullet-list-from-rst-file
-docutils==0.16
+docutils==0.18.1
 readthedocs-sphinx-search==0.3.1
-sphinx==5.3.0
-sphinx-design==0.4.1
+# don't use sphinx > 7.2.0 because they dropped support for python 3.8. See https://www.sphinx-doc.org/en/master/changes.html for changelog
+sphinx==7.1.2
+sphinx-design==0.5.0
 sphinx-argparse==0.4.0
-sphinx-autoapi==2.1.1
-sphinx-rtd-theme==1.2.2
+sphinx-autoapi==3.0.0
+sphinx-rtd-theme==1.3.0
 sphinxcontrib-programoutput==0.17
 sphinxext-remoteliteralinclude==0.4.0
 sphinx-copybutton==0.5.2
diff --git a/docs/writing_buildspecs/multi_executor.rst b/docs/writing_buildspecs/multi_executor.rst
index 0c0c5338b..b679c9b0c 100644
--- a/docs/writing_buildspecs/multi_executor.rst
+++ b/docs/writing_buildspecs/multi_executor.rst
@@ -7,7 +7,7 @@ The `executor` property can support regular expression to search for compatible
 executors, this can be used if you want to run a test across multiple executors. In buildtest,
 we use `re.fullmatch <https://docs.python.org/3/library/re.html#re.fullmatch>`_ with the input
 pattern defined by **executor** property against a list of available executors defined in configuration file.
-You can retrieve a list of executors by running ``buildtest config executors``.
+You can retrieve a list of executors by running ``buildtest config executors list``.
 
 In example below we will run this test on `generic.local.bash` and `generic.local.sh` executor based
 on the regular expression.
@@ -48,9 +48,9 @@ Now let's look at the generated content of the test as follows. We will see that
 set **X=1**, **Y=3** and **SHELL=bash** for ``generic.local.bash`` and **X=2**, **Y=4** and **SHELL=sh** for
 ``generic.local.sh``
 
-.. dropdown:: ``buildtest inspect query --testpath executors_vars_env_declaration/``
+.. dropdown:: ``buildtest inspect query -t executors_vars_env_declaration/``
 
-   .. command-output:: buildtest inspect query --testpath executors_vars_env_declaration/
+   .. command-output:: buildtest inspect query -t executors_vars_env_declaration/
 
 Scheduler Directives
 ----------------------
@@ -71,9 +71,9 @@ will override the ``sbatch`` property defined in the top-level file otherwise it
 If we inspect this test, we will see each each test have different ``#SBATCH`` directives for each test
 based on the ``sbatch`` property defined in the ``executors`` field.
 
-.. dropdown:: ``buildtest inspect query --testpath executors_sbatch_declaration/``
+.. dropdown:: ``buildtest inspect query -t executors_sbatch_declaration/``
 
-   .. command-output:: buildtest inspect query --testpath executors_sbatch_declaration/
+   .. command-output:: buildtest inspect query -t executors_sbatch_declaration/
 
 Cray Burst Buffer and Data Warp
 ---------------------------------
diff --git a/examples/spack/spack_env_deactivate.yml b/examples/spack/spack_env_deactivate.yml
new file mode 100644
index 000000000..e0e1b7460
--- /dev/null
+++ b/examples/spack/spack_env_deactivate.yml
@@ -0,0 +1,21 @@
+buildspecs:
+  spack_env_deactivate_first:
+    type: spack
+    executor: generic.local.bash
+    description: "deactivate a spack environment first prior to activating it"
+    tags: [spack]
+    spack:
+      root: $HOME/spack
+      env:
+        create:
+          dir: $HOME/spack-envs/m4
+        deactivate: true
+        activate:
+          dir: $HOME/spack-envs/m4
+        specs:
+          - 'm4'
+      install:
+        option: ''
+    post_cmds: |
+      spack find
+      rm -rf $HOME/spack-envs/m4
diff --git a/examples/spack/spack_load.yml b/examples/spack/spack_load.yml
new file mode 100644
index 000000000..5d7577435
--- /dev/null
+++ b/examples/spack/spack_load.yml
@@ -0,0 +1,16 @@
+buildspecs:
+  spack_load_example:
+    type: spack
+    executor: generic.local.bash
+    description: "Run spack load for m4 package and run tests"
+    tags: [spack]
+    spack:
+      root: $HOME/spack
+      load:
+        options: '--only package'
+        specs: [m4]
+      test:
+        run:
+          specs: ['m4']
+        results:
+          option: "-l"
diff --git a/pyproject.toml b/pyproject.toml
index 35e514f80..4ad2ffadc 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -21,7 +21,7 @@ dependencies=[
    'rich',
    'coverage',
    'pytest',
-   'black==23.3.0',
+   'black==23.9.1',
    'pyflakes',
    'urllib3 >=1.26',
 ]
@@ -42,27 +42,26 @@ dev = [
     'docutils==0.16',
     'pre-commit',
     'isort',
-    'black==23.3.0',
+    'black==23.9.1',
     'yamllint'
 ]
 docs = [
-    "docutils==0.16",
+    "docutils==0.18.1",
     "readthedocs-sphinx-search==0.3.1",
-    "sphinx==5.3.0",
-    "sphinx-design==0.4.1",
+    "sphinx==7.1.2",
+    "sphinx-design==0.5.0",
     "sphinx-argparse==0.4.0",
-    "sphinx-autoapi==2.1.1",
-    "sphinx-rtd-theme==1.2.2",
+    "sphinx-autoapi==3.0.0",
+    "sphinx-rtd-theme==1.3.0",
     "sphinxcontrib-programoutput==0.17",
     "sphinxext-remoteliteralinclude==0.4.0",
     "sphinx-copybutton==0.5.2"
 ]
 [tool.black]
-required-version = '23.3.0'
-target-version = ['py38', 'py39', 'py310', 'py311']
+#required-version = '23.3.0'
+#target-version = ['py38', 'py39', 'py310', 'py311']
 skip_magic_trailing_comma = true
 line-length = 88
-verbose = true
 
 [tool.isort]
 profile = 'black'
@@ -75,6 +74,16 @@ use_parentheses = true
 ensure_newline_before_comments = true
 split_on_trailing_comma = true
 
+[tool.pytest.ini_options]
+minversion = "6.0"
+addopts = "-vra -x --durations=20 -vv"
+testpaths = ["tests"]
+markers = [
+    "schema: run schema tests",
+    "utility: run test for utility methods used throughout codebase",
+    "cli: run test for targetting buildtest command line features"
+]
+
 [tool.coverage.run]
 parallel = true
 concurrency = ["multiprocessing"]
diff --git a/requirements.txt b/requirements.txt
index 2fcef208a..06010ee1c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,7 +9,7 @@ rich
 coverage
 pytest
 isort
-black==23.3.0
+black==23.9.1
 pyflakes
 # https://urllib3.readthedocs.io/en/latest/v2-migration-guide.html
 urllib3==1.26.*
\ No newline at end of file


Test patch:
diff --git a/buildtest/__init__.py b/buildtest/__init__.py
index 7a1d13a6b..a5768e572 100644
--- a/buildtest/__init__.py
+++ b/buildtest/__init__.py
@@ -1,3 +1,3 @@
-__version__ = "1.5"
+__version__ = "1.6"
 BUILDTEST_VERSION = __version__
 BUILDTEST_COPYRIGHT = "Copyright (c) 2021-2023, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy), Shahzeb Siddiqui, and Vanessa Sochat. All rights reserved."
diff --git a/buildtest/builders/base.py b/buildtest/builders/base.py
index 2c8175264..dabccec8b 100644
--- a/buildtest/builders/base.py
+++ b/buildtest/builders/base.py
@@ -435,6 +435,11 @@ def runtime(self):
 
         runtime = self._endtime - self._starttime
         self._runtime = runtime.total_seconds()
+
+        # for batch jobs we use the elapsed time for job to calculate the runtime
+        if self.is_batch_job():
+            self._runtime = self.job.elapsedtime
+
         self.metadata["result"]["runtime"] = self._runtime
 
     def get_runtime(self):
@@ -657,14 +662,27 @@ def _emit_command(self):
             Test can be run with shell name, shell options and path to script: ``bash -x /path/to/script.sh``
         """
 
-        if not self.recipe.get("shell") or self.recipe.get("shell") == "python":
+        # if not self.recipe.get("shell") or self.recipe.get("shell") == "python":
+        if self.recipe.get("shell") == "python":
             return [self.testpath]
 
+        if not self.recipe.get("shell"):
+            return [self.shell.name, self.shell.default_opts, self.testpath]
+
         if not self.shell.opts:
             return [self.shell.name, self.testpath]
 
         return [self.shell.name, self.shell.opts, self.testpath]
 
+    def _emit_set_command(self):
+        """This method will emit the set command for strict mode that will exit immediately. In bash, zsh the command is ``set -eo pipefail``. For csh, tcsh and sh there is
+        no such command so we return empty string."""
+
+        if self.shell.name == "bash" or self.shell.name == "zsh":
+            return "set -eo pipefail"
+
+        return ""
+
     def _default_test_variables(self):
         """Return a list of lines inserted in build script that define buildtest specific variables
         that can be referenced when writing tests. The buildtest variables all start with BUILDTEST_*
diff --git a/buildtest/builders/compiler.py b/buildtest/builders/compiler.py
index 7697896cc..03adaadae 100644
--- a/buildtest/builders/compiler.py
+++ b/buildtest/builders/compiler.py
@@ -228,6 +228,9 @@ def generate_script(self):
             lines.append("### END OF DATAWARP DIRECTIVES ###")
 
         lines.append("\n")
+
+        lines.append(self._emit_set_command())
+
         lines.append("# name of executable")
         lines += [self.exec_variable]
 
diff --git a/buildtest/builders/script.py b/buildtest/builders/script.py
index 277887a01..6abaa0992 100644
--- a/buildtest/builders/script.py
+++ b/buildtest/builders/script.py
@@ -132,6 +132,8 @@ def generate_script(self):
             if data_warp_lines:
                 lines += data_warp_lines
 
+        lines.append(self._emit_set_command())
+
         # for python scripts we generate python script and return lines
         if self.shell.name == "python":
             self.logger.debug(f"[{self.name}]: Detected python shell")
diff --git a/buildtest/builders/spack.py b/buildtest/builders/spack.py
index 7561a412f..0505adef2 100644
--- a/buildtest/builders/spack.py
+++ b/buildtest/builders/spack.py
@@ -64,6 +64,8 @@ def generate_script(self):
             if data_warp_lines:
                 lines += data_warp_lines
 
+        lines.append(self._emit_set_command())
+
         var_lines = self._get_variables(self.recipe.get("vars"))
         env_lines = self._get_environment(self.recipe.get("env"))
 
@@ -122,6 +124,15 @@ def generate_script(self):
             else:
                 lines.append(f"spack install {opts}")
 
+        if spack_configuration.get("load"):
+            opts = spack_configuration["load"].get("option") or ""
+
+            if spack_configuration["load"].get("specs"):
+                for spec in spack_configuration["load"]["specs"]:
+                    lines.append(f"spack load {opts} {spec}")
+            else:
+                lines.append(f"spack load{opts}")
+
         if spack_configuration.get("test"):
             lines += self._spack_test(spack_configuration)
 
@@ -196,7 +207,7 @@ def _resolve_spack_root(self, path, verify_spack=True):
 
     def _spack_environment(self, spack_env):
         """This method is responsible for  creating a spack environment, activate an existing
-        spack environment, create a spack environment from a directory and a manifest file (spack.yaml, spack.lock)
+        spack environment, deactivating an existing spack environment, create a spack environment from a directory and a manifest file (spack.yaml, spack.lock)
 
         Args:
             spack_env (dict): Contains property ``env`` from buildspec dictionary
@@ -232,6 +243,10 @@ def _spack_environment(self, spack_env):
             spack_env_create_line = " ".join(cmd)
             lines += [spack_env_create_line]
 
+            # deactivate environment ('spack env deactivate')
+        if spack_env.get("deactivate"):
+            lines += ["spack env deactivate"]
+
         # activate environment ('spack env activate')
         if spack_env.get("activate"):
             opts = spack_env["activate"].get("options") or ""
diff --git a/buildtest/cli/__init__.py b/buildtest/cli/__init__.py
index fb787127d..15eae504c 100644
--- a/buildtest/cli/__init__.py
+++ b/buildtest/cli/__init__.py
@@ -13,9 +13,6 @@
 from buildtest.defaults import console
 from buildtest.schemas.defaults import schema_table
 
-# Variables needed to show all sub commands and their help mesaage
-show_all_help = "-H" in sys.argv or "--help-all" in sys.argv
-
 
 def build_filters_format(val):
     """This method is used as validate argument type for ``buildtest build --filter``.
@@ -192,85 +189,272 @@ def valid_time(value):
 
 
 def get_parser():
-    epilog_str = f"""
-References
+    """This method is used to simply return the parser for sphinx-argparse."""
+    bp = BuildTestParser()
+    return bp.parser
 
-GitHub:                  https://github.com/buildtesters/buildtest
-Documentation:           https://buildtest.readthedocs.io/en/latest/index.html
-Schema Documentation:    https://buildtesters.github.io/buildtest/
-Slack:                   http://hpcbuildtest.slack.com/
 
-Please report issues at https://github.com/buildtesters/buildtest/issues
+class BuildTestParser:
+    """This class implements the buildtest command line interface. This class
+    implements the following methods:
 
-{BUILDTEST_COPYRIGHT}
-"""
+    - :func:`get_parser`: This method builds the command line interface for buildtest
+    - :func:`parse`: This method parses arguments passed to buildtest command line interface
+    """
 
-    parser = argparse.ArgumentParser(
-        prog="buildtest",
-        formatter_class=argparse.RawDescriptionHelpFormatter,
-        description="buildtest is a HPC testing framework for building and running tests.",
-        usage="%(prog)s [options] [COMMANDS]",
-        epilog=epilog_str,
+    _github = "https://github.com/buildtesters/buildtest"
+    _docs = "https://buildtest.readthedocs.io/en/latest/index.html"
+    _schemadocs = "https://buildtesters.github.io/buildtest/"
+    _slack = "http://hpcbuildtest.slack.com/"
+    _issues = "https://github.com/buildtesters/buildtest/issues"
+    _progname = "buildtest"
+    _description = (
+        "buildtest is a HPC testing framework for building and running tests."
     )
+    epilog_str = f"""
+    References
 
-    parser.add_argument(
-        "-V",
-        "--version",
-        action="version",
-        version=f"%(prog)s version {BUILDTEST_VERSION}",
-    )
+    GitHub:                  {_github}
+    Documentation:           {_docs}
+    Schema Documentation:    {_schemadocs}
+    Slack:                   {_slack}
 
-    parser.add_argument(
-        "-c", "--config", dest="configfile", help="Specify Path to Configuration File"
-    )
-    parser.add_argument(
-        "-d", "--debug", action="store_true", help="Stream log messages to stdout"
-    )
-    parser.add_argument(
-        "-l",
-        "--loglevel",
-        help="Filter log messages based on logging level",
-        choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
-        default="DEBUG",
-    )
-    parser.add_argument(
-        "--editor",
-        help="Select your preferred editor when opening files.",
-        choices=["vi", "vim", "emacs", "nano"],
-    )
-    parser.add_argument(
-        "--view-log", action="store_true", help="Show content of last log"
-    )
-    parser.add_argument(
-        "--logpath", action="store_true", help="Print full path to last log file"
-    )
-    parser.add_argument(
-        "--print-log",
-        action="store_true",
-        help="Print content of last log without pagination",
-    )
-    parser.add_argument(
-        "--color",
-        type=supported_color,
-        metavar="COLOR",
-        help="Print output of table with the selected color.",
-    )
-    parser.add_argument(
-        "--no-color", help="Disable colored output", action="store_true"
-    )
-    parser.add_argument(
-        "--helpcolor",
-        action="store_true",
-        help="Print available color options in a table format.",
-    )
-    parser.add_argument("-r", "--report", help="Specify path to test report file")
-    parser.add_argument(
-        "-H", "--help-all", help="List all commands and options", action="help"
-    )
+    Please report issues at {_issues}
+
+    {BUILDTEST_COPYRIGHT}
+    """
+
+    _buildtest_show_commands = [
+        "bd",
+        "build",
+        "bc",
+        "buildspec",
+        "cdash",
+        "cg",
+        "config",
+        "hy",
+        "history",
+        "it",
+        "inspect",
+        "path",
+        "rt",
+        "report",
+        "schema",
+        "style",
+        "stylecheck",
+        "test",
+        "unittests",
+    ]
+
+    def __init__(self):
+        self.parent_parser = self.get_parent_parser()
+
+        self.subcommands = {
+            "build": {"help": "Build and Run test", "aliases": ["bd"]},
+            "buildspec": {"help": "Buildspec Interface", "aliases": ["bc"]},
+            "config": {"help": "Query buildtest configuration", "aliases": ["cg"]},
+            "report": {
+                "help": "Query test report",
+                "aliases": ["rt"],
+                "parents": [
+                    self.parent_parser["pager"],
+                    self.parent_parser["row-count"],
+                    self.parent_parser["terse"],
+                    self.parent_parser["no-header"],
+                    self.parent_parser["count"],
+                ],
+            },
+            "inspect": {"help": "Inspect a test", "aliases": ["it"]},
+            "path": {"help": "Show path attributes for a given test", "aliases": ["p"]},
+            "history": {"help": "Query build history", "aliases": ["hy"]},
+            "schema": {"help": "List schema contents and examples"},
+            "cdash": {"help": "Upload test to CDASH server"},
+            "cd": {"help": "Change directory to root of test given a test name"},
+            "clean": {
+                "help": "Remove all generate files from buildtest including test directory, log files, report file, buildspec cache, history files"
+            },
+            "debugreport": {
+                "help": "Display system information and additional information for debugging purposes.",
+                "aliases": ["debug"],
+            },
+            "stats": {"help": "Show test statistics for given test"},
+            "info": {"help": " Show details regarding current buildtest setup"},
+            "show": {"help": "buildtest command guide"},
+            "commands": {"help": "List all buildtest commands", "aliases": ["cmds"]},
+        }
+
+        self.hidden_subcommands = {
+            "docs": {},
+            "tutorial-examples": {},
+            "schemadocs": {},
+            "unittests": {"aliases": ["test"]},
+            "stylecheck": {"aliases": ["style"]},
+        }
+
+        self.buildtest_subcommands = list(self.subcommands.keys()) + list(
+            self.hidden_subcommands.keys()
+        )
+
+        self.parser = argparse.ArgumentParser(
+            prog=self._progname,
+            formatter_class=argparse.RawDescriptionHelpFormatter,
+            description=self._description,
+            usage="%(prog)s [options] [COMMANDS]",
+            epilog=self.epilog_str,
+        )
 
-    subparsers = parser.add_subparsers(title="COMMANDS", dest="subcommands", metavar="")
+        self.subparsers = self.parser.add_subparsers(
+            title="COMMANDS", dest="subcommands", metavar=""
+        )
+
+        self._build_options()
+        self._build_subparsers()
+
+        # list used to store all main options for buildtest
+        self.main_options = self.get_buildtest_options()
+
+        # Variables needed to show all sub commands and their help message
+        show_all_help = any(arg in ["-H", "--help-all"] for arg in sys.argv)
+        if show_all_help:
+            self.help_all()
+
+        self.build_menu()
+        self.buildspec_menu()
+        self.config_menu()
+        self.report_menu()
+        self.inspect_menu()
+        self.path_menu()
+        self.history_menu()
+        self.schema_menu()
+        self.cdash_menu()
+        self.unittest_menu()
+        self.stylecheck_menu()
+        self.misc_menu()
+
+    def parse(self):
+        """This method parses arguments passed to buildtest command line interface."""
+        return self.parser.parse_args()
+
+    def get_subparsers(self):
+        return self.subparsers
+
+    def _build_subparsers(self):
+        """This method builds subparsers for buildtest command line interface."""
+
+        for name, kwargs in self.subcommands.items():
+            self.subparsers.add_parser(name, **kwargs)
+
+        for name, kwargs in self.hidden_subcommands.items():
+            self.subparsers.add_parser(name, **kwargs)
+
+    def _build_options(self):
+        """This method builds the main options for buildtest command line interface."""
+
+        self.buildtest_options = [
+            (
+                ["-V", "--version"],
+                {
+                    "action": "version",
+                    "version": f"%(prog)s version {BUILDTEST_VERSION}",
+                },
+            ),
+            (["-c", "--configfile"], {"help": "Specify Path to Configuration File"}),
+            (
+                ["-d", "--debug"],
+                {"action": "store_true", "help": "Stream log messages to stdout"},
+            ),
+            (
+                ["-l", "--loglevel"],
+                {
+                    "help": "Filter log messages based on logging level",
+                    "choices": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
+                    "default": "DEBUG",
+                },
+            ),
+            (
+                ["--editor"],
+                {
+                    "help": "Select your preferred editor when opening files.",
+                    "choices": ["vi", "vim", "emacs", "nano"],
+                },
+            ),
+            (
+                ["--view-log"],
+                {"action": "store_true", "help": "Show content of last log"},
+            ),
+            (
+                ["--logpath"],
+                {"action": "store_true", "help": "Print full path to last log file"},
+            ),
+            (
+                ["--print-log"],
+                {
+                    "action": "store_true",
+                    "help": "Print content of last log without pagination",
+                },
+            ),
+            (
+                ["--color"],
+                {
+                    "type": supported_color,
+                    "metavar": "COLOR",
+                    "help": "Print output of table with the selected color.",
+                },
+            ),
+            (
+                ["--no-color"],
+                {"help": "Disable colored output", "action": "store_true"},
+            ),
+            (
+                ["--helpcolor"],
+                {
+                    "action": "store_true",
+                    "help": "Print available color options in a table format.",
+                },
+            ),
+            (["-r", "--report"], {"help": "Specify path to test report file"}),
+            (
+                ["-H", "--help-all"],
+                {"help": "List all commands and options", "action": "help"},
+            ),
+        ]
+
+        for args, kwargs in self.buildtest_options:
+            self.parser.add_argument(*args, **kwargs)
+
+    def get_buildtest_options(self):
+        """This method is used to return all main options for buildtest command line interface. This is useful for bash completion script
+        where we need to return all options for buildtest command line interface for tab completion.
+        """
+        main_options = set()
+        for args, kwargs in self.buildtest_options:
+            for name in args:
+                main_options.add(name)
+
+        # adding -h and --help options
+        main_options.add("-h")
+        main_options.add("--help")
+        return list(sorted(main_options))
+
+    def help_all(self):
+        """This method will add parser for hidden command that can be shown when using ``--help-all/-H``"""
+
+        hidden_parser = {
+            "tutorial-examples": {
+                "help": "Generate documentation examples for Buildtest Tutorial"
+            },
+            "docs": {"help": "Open buildtest docs in browser"},
+            "schemadocs": {"help": "Open buildtest schema docs in browser"},
+            "unittests": {"help": "Run buildtest unit tests", "aliases": ["test"]},
+            "stylecheck": {"help": "Run buildtest style checks", "aliases": ["style"]},
+        }
+
+        for name, subcommand in hidden_parser.items():
+            self.subparsers.add_parser(
+                name, help=subcommand["help"], aliases=subcommand.get("aliases", [])
+            )
 
-    def get_parent_parser():
+    def get_parent_parser(self):
         parent_parser = {}
 
         parent_parser["pager"] = argparse.ArgumentParser(add_help=False)
@@ -291,7 +475,6 @@ def get_parent_parser():
         )
         parent_parser["terse"] = argparse.ArgumentParser(add_help=False)
         parent_parser["terse"].add_argument(
-            "-t",
             "--terse",
             action="store_true",
             help="Print output in machine readable format",
@@ -319,1030 +502,1304 @@ def get_parent_parser():
         )
         return parent_parser
 
-    parent_parser = get_parent_parser()
-    build_menu(subparsers)
-    buildspec_menu(subparsers, parent_parser)
-    config_menu(subparsers, parent_parser)
-    report_menu(subparsers, parent_parser)
-    inspect_menu(subparsers, parent_parser)
-    path_menu(subparsers)
-    history_menu(subparsers, parent_parser)
-    schema_menu(subparsers)
-    cdash_menu(subparsers)
-    unittest_menu(subparsers)
-    stylecheck_menu(subparsers)
-    misc_menu(subparsers)
-    tutorial_examples_menu(subparsers)
-
-    # Displays all hidden comands
-    if show_all_help:
-        help_all(subparsers)
-
-    return parser
-
-
-def misc_menu(subparsers):
-    """Build the command line menu for some miscellaneous commands
-
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object to add subparser
-    """
-
-    # Subcommands that do not need to be shown in ``--help``
-    subparsers.add_parser("docs")
-    subparsers.add_parser("schemadocs")
-
-    cd_parser = subparsers.add_parser(
-        "cd", help="change directory to root of test given a test name"
-    )
-    cd_parser.add_argument(
-        "test", help="Change directory to root of test for last run of test."
-    )
-    clean = subparsers.add_parser(
-        "clean",
-        help="Remove all generate files from buildtest including test directory, log files, report file, buildspec cache, history files.",
-    )
-
-    clean.add_argument(
-        "-y", "--yes", action="store_true", help="Confirm yes for all prompts"
-    )
-
-    subparsers.add_parser(
-        "debugreport",
-        help="Display system information and additional information for debugging purposes.",
-        aliases=["debug"],
-    )
-
-    parser_stats = subparsers.add_parser(
-        "stats", help="Show test statistics for given test"
-    )
-    parser_stats.add_argument("name", help="Name of test")
-
-    subparsers.add_parser("info", help="Show details regarding current buildtest setup")
-
-    show_subparser = subparsers.add_parser(
-        "show", aliases=["s"], help="buildtest command guide"
-    )
-    show_subparser.add_argument(
-        "command",
-        choices=[
-            "bd",
-            "build",
-            "bc",
-            "buildspec",
-            "cdash",
-            "cg",
-            "config",
-            "hy",
-            "history",
-            "it",
-            "inspect",
-            "path",
-            "rt",
-            "report",
-            "schema",
-            "style",
-            "stylecheck",
-            "test",
-            "unittests",
-        ],
-        help="Show help message for command",
-    )
-
-    subparsers.add_parser(
-        "commands", help="Display buildtest commands", aliases=["cmd"]
-    )
-
-
-def stylecheck_menu(subparsers):
-    """This method will create command options for ``buildtest stylecheck``
-
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object to add subparser
-    """
-
-    # Subcommands that do not need to be shown in ``--help``
-    stylecheck_parser = subparsers.add_parser("stylecheck", aliases=["style"])
-
-    stylecheck_parser.add_argument(
-        "--no-black", action="store_true", help="Don't run black style check"
-    )
-    stylecheck_parser.add_argument(
-        "--no-isort", action="store_true", help="Don't run isort style check"
-    )
-    stylecheck_parser.add_argument(
-        "--no-pyflakes", action="store_true", help="Dont' run pyflakes check"
-    )
-    stylecheck_parser.add_argument(
-        "-a", "--apply", action="store_true", help="Apply style checks to codebase."
-    )
-
-
-def unittest_menu(subparsers):
-    """This method builds the command line menu for ``buildtest unittests`` command
-
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object to add subparser
-    """
-
-    # Subcommands that do not need to be shown in --help
-    unittests_parser = subparsers.add_parser("unittests", aliases=["test"])
-
-    unittests_parser.add_argument(
-        "-c",
-        "--coverage",
-        action="store_true",
-        help="Enable coverage when running regression test",
-    )
-    unittests_parser.add_argument(
-        "-p", "--pytestopts", type=str, help="Specify option to pytest"
-    )
-    unittests_parser.add_argument(
-        "-s",
-        "--sourcefiles",
-        type=str,
-        help="Specify path to file or directory when running regression test",
-        action="append",
-    )
-
-
-def tutorial_examples_menu(subparsers):
-    """This method builds the command line menu for ``buildtest tutorial-examples`` command
-
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object to add subparser
-    """
-
-    subparsers.add_parser("tutorial-examples")
-
-
-def path_menu(subparsers):
-    """This method builds the command line menu for ``buildtest path`` command
-
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object to add subparser
-    """
-
-    path = subparsers.add_parser("path", help="Show path attributes for a given test")
-    path_group = path.add_mutually_exclusive_group()
-    path_group.add_argument(
-        "-be", "--buildenv", action="store_true", help="Show path to build environment"
-    )
-    path_group.add_argument(
-        "-t", "--testpath", action="store_true", help="Show path to test script"
-    )
-    path_group.add_argument(
-        "-o", "--outfile", action="store_true", help="Show path to output file"
-    )
-    path_group.add_argument(
-        "-e", "--errfile", action="store_true", help="Show path to error file"
-    )
-    path_group.add_argument(
-        "-b", "--buildscript", action="store_true", help="Show path to build script"
-    )
-    path_group.add_argument(
-        "-s", "--stagedir", action="store_true", help="Show path to stage directory"
-    )
-
-    path.add_argument("name", help="Name of test")
-
-
-def history_menu(subparsers, parent_parser):
-    """This method builds the command line menu for ``buildtest history`` command
-
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object to add subparser
-        parent_parser (argparse.ArgumentParser): Parent parser object
-    """
-
-    history_subcmd = subparsers.add_parser(
-        "history", aliases=["hy"], help="Query build history"
-    )
-
-    history_subparser = history_subcmd.add_subparsers(
-        metavar="", description="Query build history file", dest="history"
-    )
-
-    history_subparser.add_parser(
-        "list",
-        help="List a summary of all builds",
-        parents=[
-            parent_parser["pager"],
-            parent_parser["row-count"],
-            parent_parser["terse"],
-            parent_parser["no-header"],
-        ],
-    )
-
-    query = history_subparser.add_parser(
-        "query",
-        help="Query information for a particular build",
-        parents=[parent_parser["pager"]],
-    )
-    query.add_argument("id", type=int, help="Select a build ID")
-    query.add_argument(
-        "-l",
-        "--log",
-        action="store_true",
-        help="Display logfile for corresponding build id",
-    )
-    query.add_argument(
-        "-o",
-        "--output",
-        action="store_true",
-        help="view raw output from buildtest build command",
-    )
-
-
-def build_menu(subparsers):
-    """This method implements command line menu for ``buildtest build`` command.
-
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object to add subparser
-    """
-
-    parser_build = subparsers.add_parser(
-        "build", aliases=["bd"], help="Build and Run test"
-    )
-
-    discover_group = parser_build.add_argument_group(
-        "select", "Select buildspec file to run based on file, tag, executor"
-    )
-    filter_group = parser_build.add_argument_group(
-        "filter", "Filter tests after selection"
-    )
-    module_group = parser_build.add_argument_group("module", "Module Selection option")
-    batch_group = parser_build.add_argument_group("batch", "Batch Submission Options ")
-    extra_group = parser_build.add_argument_group("extra", "All extra options")
-
-    discover_group.add_argument(
-        "-b",
-        "--buildspec",
-        help="Specify a buildspec (file or directory) to build. A buildspec must end in '.yml' extension.",
-        action="append",
-    )
-
-    discover_group.add_argument(
-        "-x",
-        "--exclude",
-        action="append",
-        help="Exclude one or more buildspecs (file or directory) from processing. A buildspec must end in '.yml' extension.",
-    )
-
-    discover_group.add_argument(
-        "-e",
-        "--executor",
-        action="append",
-        type=str,
-        help="Discover buildspecs by executor name found in buildspec cache",
-    )
-    discover_group.add_argument(
-        "-xt",
-        "--exclude-tags",
-        action="append",
-        type=str,
-        help="Exclude tests by one or more tagnames found in buildspec cache",
-    )
-    discover_group.add_argument(
-        "-t",
-        "--tags",
-        action="append",
-        type=str,
-        help="Discover buildspecs by tags found in buildspec cache",
-    )
-
-    discover_group.add_argument(
-        "--rerun",
-        action="store_true",
-        help="Rerun last successful buildtest build command.",
-    )
-
-    filter_group.add_argument(
-        "-f",
-        "--filter",
-        type=build_filters_format,
-        help="Filter buildspec based on tags, type, or maintainers. Usage:  --filter key1=val1,val2;key2=val3;key3=val4,val5",
-    )
-    filter_group.add_argument(
-        "--helpfilter",
-        action="store_true",
-        help="Show available filter fields used with --filter option",
-    )
-    filter_group.add_argument(
-        "-et",
-        "--executor-type",
-        choices=["local", "batch"],
-        help="Filter tests by executor type (local, batch) ",
-    )
-    module_group.add_argument(
-        "--module-purge",
-        action="store_true",
-        help="Run 'module purge' before running any test ",
-    )
-    module_group.add_argument(
-        "-m",
-        "--modules",
-        type=str,
-        help="Specify a list of modules to load during test execution, to specify multiple modules each one must be comma "
-        "separated for instance if you want to load 'gcc' and 'python' module you can do '-m gcc,python' ",
-    )
-    module_group.add_argument(
-        "-u",
-        "--unload-modules",
-        type=str,
-        help="Specify a list of modules to unload during test execution",
-    )
-
-    batch_group.add_argument(
-        "--account",
-        type=str,
-        help="Specify project account used to charge batch jobs (applicable for batch jobs only)",
-    )
-    batch_group.add_argument(
-        "--maxpendtime",
-        type=positive_number,
-        help="Specify Maximum Pending Time (sec) for job before cancelling job. This only applies for batch job submission.",
-    )
-    batch_group.add_argument(
-        "--pollinterval",
-        type=positive_number,
-        help="Specify Poll Interval (sec) for polling batch jobs",
-    )
-    batch_group.add_argument(
-        "--procs",
-        help="Specify number of processes to run tests (only applicable with batch jobs). Multiple values can be specified comma separated.",
-        nargs="+",
-        type=positive_number,
-    )
-    batch_group.add_argument(
-        "--nodes",
-        help="Specify number of nodes to run tests (only applicable with batch jobs). Multiple values can be specified comma separated.",
-        nargs="+",
-        type=positive_number,
-    )
-    extra_group.add_argument(
-        "--limit", type=positive_number, help="Limit number of tests that can be run."
-    )
-    extra_group.add_argument(
-        "--remove-stagedir",
-        action="store_true",
-        help="Remove stage directory after job completion.",
-    )
-    extra_group.add_argument(
-        "--rebuild",
-        type=positive_number,
-        help="Rebuild test X number of times. Must be a positive number between [1-50]",
-    )
-
-    extra_group.add_argument(
-        "--retry", help="Retry failed jobs", type=positive_number, default=1
-    )
-    extra_group.add_argument(
-        "-s",
-        "--stage",
-        help="Control behavior of buildtest build to stop execution after 'parse' or 'build' stage",
-        choices=["parse", "build"],
-    )
-
-    extra_group.add_argument(
-        "--testdir",
-        help="Specify a custom test directory where to write tests. This overrides configuration file and default location.",
-    )
-
-    extra_group.add_argument(
-        "--timeout",
-        help="Specify test timeout in number of seconds",
-        type=positive_number,
-    )
-    extra_group.add_argument(
-        "--save-profile",
-        help="Save buildtest command options into a profile and update configuration file",
-    )
-    extra_group.add_argument(
-        "--profile", help="Specify a profile to load from configuration file"
-    )
-
-
-def buildspec_menu(subparsers, parent_parser):
-    """This method implements ``buildtest buildspec`` command
-
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object
-        parent_parser (argparse.ArgumentParser): Parent parser object
-    """
-
-    parser_buildspec = subparsers.add_parser(
-        "buildspec", aliases=["bc"], help="Buildspec Interface"
-    )
-
-    subparsers_buildspec = parser_buildspec.add_subparsers(
-        description="Buildspec Interface subcommands",
-        dest="buildspecs_subcommand",
-        metavar="",
-    )
-
-    # buildtest buildspec edit-file
-    edit_via_filename = subparsers_buildspec.add_parser(
-        "edit-file", aliases=["ef"], help="Edit buildspec file based on filename"
-    )
-    edit_via_filename.add_argument(
-        "file", help="Edit buildspec file in editor", nargs="*"
-    )
-
-    # buildtest buildspec edit-test
-    edit_via_testname = subparsers_buildspec.add_parser(
-        "edit-test", aliases=["et"], help="Edit buildspec file based on test name"
-    )
-    edit_via_testname.add_argument(
-        "name", help="Show content of buildspec based on test name", nargs="*"
-    )
-
-    # buildtest buildspec find
-
-    buildspec_find = subparsers_buildspec.add_parser(
-        "find",
-        aliases=["f"],
-        help="Query information from buildspecs cache",
-        parents=[
-            parent_parser["pager"],
-            parent_parser["row-count"],
-            parent_parser["no-header"],
-            parent_parser["count"],
-        ],
-    )
-    # buildtest buildspec maintainers
-    buildspec_maintainers = subparsers_buildspec.add_parser(
-        "maintainers",
-        aliases=["m"],
-        help="Query maintainers from buildspecs cache",
-        parents=[
-            parent_parser["row-count"],
-            parent_parser["terse"],
-            parent_parser["no-header"],
-        ],
-    )
-
-    subparsers_maintainers = buildspec_maintainers.add_subparsers()
-    maintainers_find = subparsers_maintainers.add_parser(
-        "find", help="Find buildspecs based on maintainer name"
-    )
-
-    maintainers_find.add_argument(
-        "name", help="Find buildspec based on maintainer name"
-    )
-
-    buildspec_maintainers.add_argument(
-        "-b",
-        "--breakdown",
-        action="store_true",
-        help="Breakdown of buildspecs by maintainers",
-    )
-
-    filter_group = buildspec_find.add_argument_group(
-        "filter and format", "filter and format options"
-    )
-    terse_group = buildspec_find.add_argument_group("terse", "terse options")
-    query_group = buildspec_find.add_argument_group(
-        "query", "query options to retrieve from buildspec cache"
-    )
-
-    # buildtest buildspec find invalid
-    subparsers_invalid = buildspec_find.add_subparsers(
-        metavar="", dest="buildspec_find_subcommand"
-    )
-    invalid_buildspecs = subparsers_invalid.add_parser(
-        "invalid", help="Show invalid buildspecs", parents=[parent_parser["row-count"]]
-    )
-
-    # buildtest buildspec find invalid options
-    invalid_buildspecs.add_argument(
-        "-e", "--error", action="store_true", help="Show error messages"
-    )
-
-    # buildtest buildspec find options
-
-    query_group.add_argument(
-        "-b",
-        "--buildspec",
-        help="Get all buildspec files from cache",
-        action="store_true",
-    )
-    query_group.add_argument(
-        "-e",
-        "--executors",
-        help="get all unique executors from buildspecs",
-        action="store_true",
-    )
-
-    query_group.add_argument(
-        "--group-by-tags", action="store_true", help="Group tests by tag name"
-    )
-    query_group.add_argument(
-        "--group-by-executor", action="store_true", help="Group tests by executor name"
-    )
-    query_group.add_argument(
-        "-p", "--paths", help="print all root buildspec paths", action="store_true"
-    )
-
-    query_group.add_argument(
-        "-t", "--tags", help="List all available tags", action="store_true"
-    )
-
-    filter_group.add_argument(
-        "--filter",
-        type=handle_kv_string,
-        help="Filter buildspec cache with filter fields in format --filter key1=val1,key2=val2",
-    )
-    filter_group.add_argument(
-        "--format",
-        help="Format buildspec cache with format fields in format --format field1,field2,...",
-    )
-    filter_group.add_argument(
-        "--helpfilter",
-        action="store_true",
-        help="Show Filter fields for --filter option for filtering buildspec cache output",
-    )
-    filter_group.add_argument(
-        "--helpformat",
-        action="store_true",
-        help="Show Format fields for --format option for formatting buildspec cache output",
-    )
-    filter_group.add_argument(
-        "--filterfields",
-        action="store_true",
-        help="Print raw Filter fields for --filter option for filtering builspec cache output",
-    )
-    filter_group.add_argument(
-        "--formatfields",
-        action="store_true",
-        help="Print raw Format fields for --format option for formatting builspec cache output",
-    )
-
-    terse_group.add_argument(
-        "--terse", help="Print output in machine readable format", action="store_true"
-    )
-
-    buildspec_find.add_argument(
-        "-r",
-        "--rebuild",
-        help="Rebuild buildspec cache and find all buildspecs again",
-        action="store_true",
-    )
-    buildspec_find.add_argument(
-        "--root",
-        help="Specify root buildspecs (directory) path to load buildspecs into buildspec cache.",
-        type=str,
-        action="append",
-    )
-    buildspec_find.add_argument(
-        "-q",
-        "--quiet",
-        help="Don't print output of buildspec cache when rebuilding cache",
-        action="store_true",
-    )
-
-    # buildtest buildspec show
-    show_buildspecs = subparsers_buildspec.add_parser(
-        "show",
-        aliases=["s"],
-        help="Show content of buildspec file",
-        parents=[parent_parser["theme"]],
-    )
-    show_buildspecs.add_argument(
-        "name", help="Show content of buildspec based on test name", nargs="*"
-    )
-
-    # buildtest buildspec show-fail
-    show_fail_buildspecs = subparsers_buildspec.add_parser(
-        "show-fail",
-        aliases=["sf"],
-        help="Show content of buildspec file for all failed tests",
-        parents=[parent_parser["theme"]],
-    )
-    show_fail_buildspecs.add_argument(
-        "name", help="Show content of buildspec based on failed test name", nargs="*"
-    )
-
-    # buildtest buildspec summary
-    subparsers_buildspec.add_parser(
-        "summary",
-        aliases=["sm"],
-        help="Print summary of buildspec cache",
-        parents=[parent_parser["pager"]],
-    )
-    # buildtest buildspec validate
-    buildspec_validate = subparsers_buildspec.add_parser(
-        "validate", aliases=["val"], help="Validate buildspecs with JSON Schema"
-    )
-    # buildtest buildspec validate options
-    buildspec_validate.add_argument(
-        "-b",
-        "--buildspec",
-        type=str,
-        help="Specify path to buildspec (file, or directory) to validate",
-        action="append",
-    )
-
-    buildspec_validate.add_argument(
-        "-x",
-        "--exclude",
-        type=str,
-        help="Specify path to buildspec to exclude (file or directory) during validation",
-        action="append",
-    )
-
-    buildspec_validate.add_argument(
-        "-e",
-        "--executor",
-        type=str,
-        action="append",
-        help="Specify buildspecs by executor name to validate",
-    )
-    buildspec_validate.add_argument(
-        "-t",
-        "--tag",
-        type=str,
-        action="append",
-        help="Specify buildspecs by tag name to validate",
-    )
-
-
-def config_menu(subparsers, parent_parser):
-    """This method adds argparse argument for ``buildtest config``
-
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object
-        parent_parser (argparse.ArgumentParser): Parent parser object
-    """
-
-    parser_config = subparsers.add_parser(
-        "config", aliases=["cg"], help="Query buildtest configuration"
-    )
-
-    subparsers_config = parser_config.add_subparsers(
-        description="Query information from buildtest configuration file",
-        dest="config",
-        metavar="",
-    )
-
-    compilers = subparsers_config.add_parser(
-        "compilers", aliases=["co"], help="Search compilers"
-    )
-
-    subparsers_config.add_parser(
-        "edit", aliases=["e"], help="Open configuration file in editor"
-    )
-
-    executors = subparsers_config.add_parser(
-        "executors", aliases=["ex"], help="Query executors from buildtest configuration"
-    )
-
-    subparsers_config.add_parser(
-        "path", aliases=["p"], help="Show path to configuration file"
-    )
-
-    subparsers_config.add_parser("systems", help="List all available systems")
-    # buildtest config validate
-    subparsers_config.add_parser(
-        "validate",
-        aliases=["val"],
-        help="Validate buildtest settings file with schema.",
-    )
-    # buildtest config view
-    subparsers_config.add_parser(
-        "view",
-        aliases=["v"],
-        help="View configuration file",
-        parents=[parent_parser["pager"], parent_parser["theme"]],
-    )
-
-    executor_group = executors.add_mutually_exclusive_group()
-
-    # buildtest config executors
-    executor_group.add_argument(
-        "-j", "--json", action="store_true", help="View executor in JSON format"
-    )
-    executor_group.add_argument(
-        "-y", "--yaml", action="store_true", help="View executors in YAML format"
-    )
-    executor_group.add_argument(
-        "-d", "--disabled", action="store_true", help="Show disabled executors"
-    )
-    executor_group.add_argument(
-        "-i", "--invalid", action="store_true", help="Show invalid executors"
-    )
-
-    # buildtest config compilers
-    compilers.add_argument(
-        "-j", "--json", action="store_true", help="List compiler details in JSON format"
-    )
-    compilers.add_argument(
-        "-y", "--yaml", action="store_true", help="List compiler details in YAML format"
-    )
-
-    subparsers_compiler = compilers.add_subparsers(
-        description="Find new compilers and add them to detected compiler section",
-        dest="compilers",
-        metavar="",
-    )
-
-    compiler_find = subparsers_compiler.add_parser(
-        "find", help="Find compilers", parents=[parent_parser["file"]]
-    )
-    compiler_find.add_argument(
-        "-d",
-        "--detailed",
-        help="Display detailed output when finding compilers",
-        action="store_true",
-    )
-    compiler_find.add_argument(
-        "-u",
-        "--update",
-        action="store_true",
-        help="Update configuration file with new compilers",
-    )
-    compiler_find.add_argument(
-        "-m",
-        "--modulepath",
-        type=str,
-        nargs="+",
-        help="Specify a list of directories to search for modules via MODULEPATH to detect compilers",
-    )
-
-    compiler_test = subparsers_compiler.add_parser(
-        "test", help="Test each compiler instance by performing module load test"
-    )
-    compiler_test.add_argument(
-        "compiler_names", nargs="*", help="Specify compiler name to test"
-    )
-
-
-def report_menu(subparsers, parent_parser):
-    """This method implements the ``buildtest report`` command options
-
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object
-        parent_parser (argparse.ArgumentParser): Parent parser object
-    """
-
-    parser_report = subparsers.add_parser(
-        "report",
-        aliases=["rt"],
-        help="Query test report",
-        parents=[
-            parent_parser["pager"],
-            parent_parser["row-count"],
-            parent_parser["terse"],
-            parent_parser["no-header"],
-            parent_parser["count"],
-        ],
-    )
-    subparsers = parser_report.add_subparsers(
-        description="Fetch test results from report file and print them in table format",
-        metavar="",
-        dest="report_subcommand",
-    )
-    subparsers.add_parser("clear", aliases=["c"], help="Remove all report file")
-    subparsers.add_parser("list", aliases=["l"], help="List all report files")
-    subparsers.add_parser(
-        "path", aliases=["p"], help="Print full path to the report file being used"
-    )
-    parser_report_summary = subparsers.add_parser(
-        "summary",
-        aliases=["sm"],
-        help="Summarize test report",
-        parents=[parent_parser["pager"]],
-    )
-    filter_group = parser_report.add_argument_group("filter", "Filter options")
-
-    # buildtest report
-    filter_group.add_argument(
-        "--filter",
-        type=handle_kv_string,
-        help="Filter report by filter fields. The filter fields must be a key=value pair and multiple fields can be comma separated in the following format: --filter key1=val1,key2=val2 . For list of filter fields run: --helpfilter.",
-    )
-
-    filter_group.add_argument(
-        "--helpfilter",
-        action="store_true",
-        help="List available filter fields to be used with --filter option",
-    )
-
-    filter_group.add_argument(
-        "--filterfields",
-        action="store_true",
-        help="Print raw filter fields for --filter option to filter the report",
-    )
-
-    format_group = parser_report.add_argument_group("format", "Format options")
-
-    format_group.add_argument(
-        "--helpformat", action="store_true", help="List of available format fields"
-    )
-
-    format_group.add_argument(
-        "--formatfields",
-        action="store_true",
-        help="Print raw format fields for --format option to format the report",
-    )
-
-    format_detailed_group = parser_report.add_mutually_exclusive_group()
-    format_detailed_group.add_argument(
-        "--format",
-        help="format field for printing purposes. For more details see --helpformat for list of available fields. Fields must be separated by comma (usage: --format <field1>,<field2>,...)",
-    )
+    def misc_menu(self):
+        """Build the command line menu for some miscellaneous commands"""
+
+        subcommands = [
+            {
+                "name": "cd",
+                "help": "Change directory to root of test for last run of test.",
+                "arguments": [
+                    (
+                        ["test"],
+                        {
+                            "help": "Change directory to root of test for last run of test."
+                        },
+                    )
+                ],
+            },
+            {
+                "name": "clean",
+                "help": "Remove all generate files from buildtest including test directory, log files, report file, buildspec cache, history files.",
+                "arguments": [
+                    (
+                        ["-y", "--yes"],
+                        {"action": "store_true", "help": "Confirm yes for all prompts"},
+                    )
+                ],
+            },
+            {
+                "name": "stats",
+                "help": "Display statistics for a specific test.",
+                "arguments": [(["name"], {"help": "Name of test"})],
+            },
+            {
+                "name": "commands",
+                "help": "List all buildtest commands",
+                "arguments": [
+                    (
+                        ["-a", "--with-aliases"],
+                        {
+                            "action": "store_true",
+                            "help": "Return all buildtest commands including command aliases",
+                        },
+                    )
+                ],
+            },
+            {
+                "name": "show",
+                "help": "Show help message for a specific command.",
+                "arguments": [
+                    (
+                        ["command"],
+                        {
+                            "help": "Show help message for command.",
+                            "choices": self._buildtest_show_commands,
+                        },
+                    )
+                ],
+            },
+        ]
+
+        # Create argument parsers for each subcommand
+        parsers = {}
+        for subcommand in subcommands:
+            parser = self.subparsers.choices[subcommand["name"]]
+            for args, kwargs in subcommand.get("arguments", []):
+                parser.add_argument(*args, **kwargs)
+            parsers[subcommand["name"]] = parser
+
+    def stylecheck_menu(self):
+        """This method will create command options for ``buildtest stylecheck``"""
+
+        parser = self.subparsers.choices["stylecheck"]
+
+        stylecheck_args = [
+            (
+                ["--no-black"],
+                {"action": "store_true", "help": "Don't run black style check"},
+            ),
+            (
+                ["--no-isort"],
+                {"action": "store_true", "help": "Don't run isort style check"},
+            ),
+            (
+                ["--no-pyflakes"],
+                {"action": "store_true", "help": "Don't run pyflakes check"},
+            ),
+            (
+                ["-a", "--apply"],
+                {"action": "store_true", "help": "Apply style checks to codebase."},
+            ),
+        ]
+
+        for args, kwargs in stylecheck_args:
+            parser.add_argument(*args, **kwargs)
+
+    def unittest_menu(self):
+        """This method builds the command line menu for ``buildtest unittests`` command"""
+        parser = self.subparsers.choices["unittests"]
+
+        unittests_args = [
+            (
+                ["-c", "--coverage"],
+                {
+                    "action": "store_true",
+                    "help": "Enable coverage when running regression test",
+                },
+            ),
+            (["-p", "--pytestopts"], {"type": str, "help": "Specify option to pytest"}),
+            (
+                ["-s", "--sourcefiles"],
+                {
+                    "type": str,
+                    "help": "Specify path to file or directory when running regression test",
+                    "action": "append",
+                },
+            ),
+        ]
+
+        for args, kwargs in unittests_args:
+            parser.add_argument(*args, **kwargs)
+
+    def path_menu(self):
+        """This method builds the command line menu for ``buildtest path`` command"""
+
+        path = self.subparsers.choices["path"]
+
+        path_options = [
+            (
+                ["-be", "--buildenv"],
+                {"action": "store_true", "help": "Show path to build environment"},
+            ),
+            (
+                ["-t", "--testpath"],
+                {"action": "store_true", "help": "Show path to test script"},
+            ),
+            (
+                ["-o", "--outfile"],
+                {"action": "store_true", "help": "Show path to output file"},
+            ),
+            (
+                ["-e", "--errfile"],
+                {"action": "store_true", "help": "Show path to error file"},
+            ),
+            (
+                ["-b", "--buildscript"],
+                {"action": "store_true", "help": "Show path to build script"},
+            ),
+            (
+                ["-s", "--stagedir"],
+                {"action": "store_true", "help": "Show path to stage directory"},
+            ),
+        ]
+
+        path_group = path.add_mutually_exclusive_group()
+        for args, kwargs in path_options:
+            path_group.add_argument(*args, **kwargs)
+
+        path.add_argument("name", help="Name of test")
+
+    def history_menu(self):
+        """This method builds the command line menu for ``buildtest history`` command"""
+
+        history_subcmd = self.subparsers.choices["history"]
+
+        history_subparser = history_subcmd.add_subparsers(
+            metavar="", description="Query build history file", dest="history"
+        )
 
-    format_detailed_group.add_argument(
-        "-d",
-        "--detailed",
-        help="Print a detailed summary of the test results",
-        action="store_true",
-    )
+        subparser_info = [
+            {
+                "name": "list",
+                "help": "List a summary of all builds",
+                "parents": [
+                    self.parent_parser["pager"],
+                    self.parent_parser["row-count"],
+                    self.parent_parser["terse"],
+                    self.parent_parser["no-header"],
+                ],
+                "arguments": [],
+            },
+            {
+                "name": "query",
+                "help": "Query information for a particular build",
+                "parents": [self.parent_parser["pager"]],
+                "arguments": [
+                    (["id"], {"type": int, "help": "Select a build ID"}),
+                    (
+                        ["-l", "--log"],
+                        {
+                            "action": "store_true",
+                            "help": "Display logfile for corresponding build id",
+                        },
+                    ),
+                    (
+                        ["-o", "--output"],
+                        {
+                            "action": "store_true",
+                            "help": "View raw output from buildtest build command",
+                        },
+                    ),
+                ],
+            },
+        ]
+
+        for subparser_info in subparser_info:
+            subparser = history_subparser.add_parser(
+                subparser_info["name"],
+                help=subparser_info["help"],
+                parents=subparser_info["parents"],
+            )
+            for args, kwargs in subparser_info["arguments"]:
+                subparser.add_argument(*args, **kwargs)
+
+    def build_menu(self):
+        """This method implements command line menu for ``buildtest build`` command."""
+
+        parser_build = self.subparsers.choices["build"]
+
+        groups = [
+            (
+                "discover",
+                "discover",
+                "Select buildspec file to run based on file, tag, executor",
+            ),
+            ("filter", "filter", "Filter tests after selection"),
+            ("module", "module", "Module Selection option"),
+            ("batch", "batch", "Batch Submission options"),
+            ("extra", "extra", "All extra options"),
+        ]
+        arguments = {
+            "discover": [
+                (
+                    ["-b", "--buildspec"],
+                    {
+                        "help": "Specify a buildspec (file or directory) to build. A buildspec must end in '.yml' extension.",
+                        "action": "append",
+                    },
+                ),
+                (
+                    ["-x", "--exclude"],
+                    {
+                        "action": "append",
+                        "help": "Exclude one or more buildspecs (file or directory) from processing. A buildspec must end in '.yml' extension.",
+                    },
+                ),
+                (
+                    ["-n", "--name"],
+                    {
+                        "action": "append",
+                        "help": "Specify a name of test to run",
+                        "type": str,
+                    },
+                ),
+                (
+                    ["-e", "--executor"],
+                    {
+                        "action": "append",
+                        "type": str,
+                        "help": "Discover buildspecs by executor name found in buildspec cache",
+                    },
+                ),
+                (
+                    ["-xt", "--exclude-tags"],
+                    {
+                        "action": "append",
+                        "type": str,
+                        "help": "Exclude tests by one or more tagnames found in buildspec cache",
+                    },
+                ),
+                (
+                    ["-t", "--tags"],
+                    {
+                        "action": "append",
+                        "type": str,
+                        "help": "Discover buildspecs by tags found in buildspec cache",
+                    },
+                ),
+                (
+                    ["--rerun"],
+                    {
+                        "action": "store_true",
+                        "help": "Rerun last successful buildtest build command.",
+                    },
+                ),
+            ],
+            "filter": [
+                (
+                    ["-f", "--filter"],
+                    {
+                        "type": build_filters_format,
+                        "help": "Filter buildspec based on tags, type, or maintainers. Usage:  --filter key1=val1,val2;key2=val3;key3=val4,val5",
+                    },
+                ),
+                (
+                    ["--helpfilter"],
+                    {
+                        "action": "store_true",
+                        "help": "Show available filter fields used with --filter option",
+                    },
+                ),
+                (
+                    ["-et", "--executor-type"],
+                    {
+                        "choices": ["local", "batch"],
+                        "help": "Filter tests by executor type (local, batch)",
+                    },
+                ),
+            ],
+            "module": [
+                (
+                    ["--module-purge"],
+                    {
+                        "action": "store_true",
+                        "help": "Run 'module purge' before running any test",
+                    },
+                ),
+                (
+                    ["-m", "--modules"],
+                    {
+                        "type": str,
+                        "help": "Specify a list of modules to load during test execution, to specify multiple modules each one must be comma separated for instance if you want to load 'gcc' and 'python' module you can do '-m gcc,python'",
+                    },
+                ),
+                (
+                    ["-u", "--unload-modules"],
+                    {
+                        "type": str,
+                        "help": "Specify a list of modules to unload during test execution",
+                    },
+                ),
+            ],
+            "batch": [
+                (
+                    ["--account"],
+                    {
+                        "type": str,
+                        "help": "Specify project account used to charge batch jobs (applicable for batch jobs only)",
+                    },
+                ),
+                (
+                    ["--maxpendtime"],
+                    {
+                        "type": positive_number,
+                        "help": "Specify Maximum Pending Time (sec) for job before cancelling job. This only applies for batch job submission.",
+                    },
+                ),
+                (
+                    ["--pollinterval"],
+                    {
+                        "type": positive_number,
+                        "help": "Specify Poll Interval (sec) for polling batch jobs",
+                    },
+                ),
+                (
+                    ["--procs"],
+                    {
+                        "nargs": "+",
+                        "type": positive_number,
+                        "help": "Specify number of processes to run tests (only applicable with batch jobs). Multiple values can be specified comma separated.",
+                    },
+                ),
+                (
+                    ["--nodes"],
+                    {
+                        "nargs": "+",
+                        "type": positive_number,
+                        "help": "Specify number of nodes to run tests (only applicable with batch jobs). Multiple values can be specified comma separated.",
+                    },
+                ),
+            ],
+            "extra": [
+                (
+                    ["--limit"],
+                    {
+                        "type": positive_number,
+                        "help": "Limit number of tests that can be run.",
+                    },
+                ),
+                (
+                    ["--max-jobs"],
+                    {
+                        "type": positive_number,
+                        "help": "Maximum number of jobs that can be run concurrently.",
+                    },
+                ),
+                (
+                    ["--remove-stagedir"],
+                    {
+                        "action": "store_true",
+                        "help": "Remove stage directory after job completion.",
+                    },
+                ),
+                (
+                    ["--rebuild"],
+                    {
+                        "type": positive_number,
+                        "help": "Rebuild test X number of times. Must be a positive number between [1-50]",
+                    },
+                ),
+                (
+                    ["--retry"],
+                    {
+                        "type": positive_number,
+                        "default": 1,
+                        "help": "Retry failed jobs",
+                    },
+                ),
+                (
+                    ["-s", "--stage"],
+                    {
+                        "choices": ["parse", "build"],
+                        "help": "Control behavior of buildtest build to stop execution after 'parse' or 'build' stage",
+                    },
+                ),
+                (
+                    ["--testdir"],
+                    {
+                        "help": "Specify a custom test directory where to write tests. This overrides configuration file and default location."
+                    },
+                ),
+                (
+                    ["--timeout"],
+                    {
+                        "type": positive_number,
+                        "help": "Specify test timeout in number of seconds",
+                    },
+                ),
+                (
+                    ["--save-profile"],
+                    {
+                        "help": "Save buildtest command options into a profile and update configuration file"
+                    },
+                ),
+                (
+                    ["--profile"],
+                    {"help": "Specify a profile to load from configuration file"},
+                ),
+            ],
+        }
+
+        for group_name, dest_name, desc in groups:
+            group = parser_build.add_argument_group(group_name, description=desc)
+
+            # self.argument_group(arguments=arguments, group=group, dest_name=dest_name)
+
+            for args, kwargs in arguments[dest_name]:
+                group.add_argument(*args, **kwargs)
+
+    def buildspec_menu(self):
+        """This method implements ``buildtest buildspec`` command"""
+
+        parser_buildspec = self.subparsers.choices["buildspec"]
+
+        subparsers_buildspec = parser_buildspec.add_subparsers(
+            description="Buildspec Interface subcommands",
+            dest="buildspecs_subcommand",
+            metavar="",
+        )
 
-    pass_fail = parser_report.add_mutually_exclusive_group()
+        buildspec_subcommands = [
+            {
+                "name": "edit-file",
+                "help": "Edit buildspec file based on filename",
+                "parents": [],
+                "aliases": ["ef"],
+                "args": [
+                    (["file"], {"help": "Edit buildspec file in editor", "nargs": "*"})
+                ],
+            },
+            {
+                "name": "edit-test",
+                "help": "Edit buildspec file based on test name",
+                "parents": [],
+                "aliases": ["et"],
+                "args": [
+                    (
+                        ["name"],
+                        {
+                            "help": "Show content of buildspec based on test name",
+                            "nargs": "*",
+                        },
+                    )
+                ],
+            },
+            {
+                "name": "find",
+                "help": "Query information from buildspecs cache",
+                "aliases": ["f"],
+                "parents": [
+                    self.parent_parser["pager"],
+                    self.parent_parser["row-count"],
+                    self.parent_parser["terse"],
+                    self.parent_parser["no-header"],
+                    self.parent_parser["count"],
+                ],
+                " args": [],
+            },
+            {
+                "name": "maintainers",
+                "help": "Query maintainers from buildspecs cache",
+                "aliases": ["m"],
+                "parents": [
+                    self.parent_parser["row-count"],
+                    self.parent_parser["terse"],
+                    self.parent_parser["no-header"],
+                ],
+                "arguments": [
+                    (
+                        ["-b", "--breakdown"],
+                        {
+                            "action": "store_true",
+                            "help": "Breakdown of buildspecs by maintainers",
+                        },
+                    )
+                ],
+            },
+            {
+                "name": "show",
+                "help": "Show content of buildspec file",
+                "parents": [self.parent_parser["theme"]],
+                "aliases": ["s"],
+                "arguments": [
+                    (
+                        ["name"],
+                        {
+                            "help": "Show content of buildspec based on test name",
+                            "nargs": "*",
+                        },
+                    )
+                ],
+            },
+            {
+                "name": "show-fail",
+                "help": "Show content of buildspec file for all failed tests",
+                "parents": [self.parent_parser["theme"]],
+                "aliases": ["sf"],
+                "arguments": [
+                    (
+                        ["name"],
+                        {
+                            "help": "Show content of buildspec based on failed test name",
+                            "nargs": "*",
+                        },
+                    )
+                ],
+            },
+            {
+                "name": "summary",
+                "help": "Print summary of buildspec cache",
+                "parents": [self.parent_parser["theme"], self.parent_parser["pager"]],
+                "arguments": [],
+                "aliases": ["sm"],
+            },
+            {
+                "name": "validate",
+                "help": "Validate buildspecs with JSON Schema",
+                "parents": [],
+                "aliases": ["val"],
+                "arguments": [
+                    (
+                        ["-b", "--buildspec"],
+                        {
+                            "type": str,
+                            "action": "append",
+                            "help": "Specify path to buildspec (file, or directory) to validate",
+                        },
+                    ),
+                    (
+                        ["-x", "--exclude"],
+                        {
+                            "type": str,
+                            "action": "append",
+                            "help": "Specify path to buildspec to exclude (file or directory) during validation",
+                        },
+                    ),
+                    (
+                        ["-e", "--executor"],
+                        {
+                            "type": str,
+                            "action": "append",
+                            "help": "Specify buildspecs by executor name to validate",
+                        },
+                    ),
+                    (
+                        ["-t", "--tag"],
+                        {
+                            "type": str,
+                            "action": "append",
+                            "help": "Specify buildspecs by tag name to validate",
+                        },
+                    ),
+                ],
+            },
+        ]
+
+        subcommand = {}
+        # Loop through the list of dictionaries and create subcommands with their parent parsers and arguments
+        for cmd_info in buildspec_subcommands:
+            name = cmd_info["name"]
+            subcommand[name] = subparsers_buildspec.add_parser(
+                cmd_info["name"],
+                help=cmd_info["help"],
+                parents=cmd_info["parents"],
+                aliases=cmd_info.get("aliases", []),
+            )
+            for arg_info in cmd_info.get("arguments", []):
+                subcommand[name].add_argument(*arg_info[0], **arg_info[1])
 
-    pass_fail.add_argument(
-        "-f", "--fail", help="Retrieve all FAIL tests", action="store_true"
-    )
-    pass_fail.add_argument(
-        "-p",
-        "--pass",
-        dest="passed",
-        help="Retrieve all PASS tests",
-        action="store_true",
-    )
+        # build menu for 'buildtest buildspec maintainers' command
 
-    parser_report.add_argument(
-        "-s", "--start", type=valid_time, help="Retrieve tests by starttime"
-    )
-    parser_report.add_argument(
-        "-e", "--end", type=valid_time, help="Retrieve tests by endtime"
-    )
-    parser_report.add_argument(
-        "--latest",
-        help="Retrieve latest record of particular test",
-        action="store_true",
-    )
-    parser_report.add_argument(
-        "--oldest",
-        help="Retrieve oldest record of particular test",
-        action="store_true",
-    )
-    parser_report_summary.add_argument(
-        "--detailed", "-d", action="store_true", help="Enable a more detailed report"
-    )
+        subparsers_maintainers = subcommand["maintainers"].add_subparsers()
+        maintainers_find = subparsers_maintainers.add_parser(
+            "find", help="Find buildspecs based on maintainer name"
+        )
+        maintainers_find.add_argument(
+            "name", help="Find buildspec based on maintainer name"
+        )
 
+        # build menu for 'buildtest buildspec find' command
+        self.buildspec_find_menu(subcommand["find"])
+
+    def buildspec_find_menu(self, buildspec_find_parser):
+        groups = [
+            ("query", "query", "query options to retrieve from buildspec cache"),
+            ("filter", "filter", "filter and format options"),
+            ("extra", "extra", "All extra options"),
+        ]
+        arguments = {
+            "query": [
+                (
+                    ["-b", "--buildspec"],
+                    {
+                        "help": "Get all buildspec files from cache",
+                        "action": "store_true",
+                    },
+                ),
+                (
+                    ["-e", "--executors"],
+                    {
+                        "help": "Get all unique executors from buildspecs",
+                        "action": "store_true",
+                    },
+                ),
+                (
+                    ["--group-by-tags"],
+                    {"action": "store_true", "help": "Group tests by tag name"},
+                ),
+                (
+                    ["--group-by-executor"],
+                    {"action": "store_true", "help": "Group tests by executor name"},
+                ),
+                (
+                    ["-p", "--paths"],
+                    {"action": "store_true", "help": "Print all root buildspec paths"},
+                ),
+                (
+                    ["-t", "--tags"],
+                    {"action": "store_true", "help": "List all available tags"},
+                ),
+            ],
+            "filter": [
+                (
+                    ["--filter"],
+                    {
+                        "type": handle_kv_string,
+                        "help": "Filter buildspec cache with filter fields in format --filter key1=val1,key2=val2",
+                    },
+                ),
+                (
+                    ["--format"],
+                    {
+                        "help": "Format buildspec cache with format fields in format --format field1,field2,..."
+                    },
+                ),
+                (
+                    ["--helpfilter"],
+                    {
+                        "action": "store_true",
+                        "help": "Show Filter fields for --filter option for filtering buildspec cache output",
+                    },
+                ),
+                (
+                    ["--helpformat"],
+                    {
+                        "action": "store_true",
+                        "help": "Show Format fields for --format option for formatting buildspec cache output",
+                    },
+                ),
+                (
+                    ["--filterfields"],
+                    {
+                        "action": "store_true",
+                        "help": "Print raw Filter fields for --filter option for filtering buildspec cache output",
+                    },
+                ),
+                (
+                    ["--formatfields"],
+                    {
+                        "action": "store_true",
+                        "help": "Print raw Format fields for --format option for formatting buildspec cache output",
+                    },
+                ),
+            ],
+            "extra": [
+                (
+                    ["-r", "--rebuild"],
+                    {
+                        "action": "store_true",
+                        "help": "Rebuild buildspec cache and find all buildspecs again",
+                    },
+                ),
+                (
+                    ["--root"],
+                    {
+                        "type": str,
+                        "action": "append",
+                        "help": "Specify root buildspecs (directory) path to load buildspecs into buildspec cache.",
+                    },
+                ),
+                (
+                    ["-q", "--quiet"],
+                    {
+                        "action": "store_true",
+                        "help": "Don't print output of buildspec cache when rebuilding cache",
+                    },
+                ),
+            ],
+        }
+
+        for group_name, dest_name, desc in groups:
+            group = buildspec_find_parser.add_argument_group(
+                group_name, description=desc
+            )
 
-def inspect_menu(subparsers, parent_parser):
-    """This method builds argument for ``buildtest inspect`` command
+            for args, kwargs in arguments[dest_name]:
+                group.add_argument(*args, **kwargs)
+
+        buildtest_find_commands = [
+            {
+                "name": "invalid",
+                "help": "Show invalid buildspecs",
+                "parents": [self.parent_parser["row-count"]],
+                "arguments": [
+                    (
+                        ["-e", "--error"],
+                        {"action": "store_true", "help": "Show error messages"},
+                    )
+                ],
+            }
+        ]
+        subcommand = {}
+        subparsers_invalid = buildspec_find_parser.add_subparsers(
+            metavar="", dest="buildspec_find_subcommand"
+        )
+        for cmd_info in buildtest_find_commands:
+            name = cmd_info["name"]
+            subcommand[name] = subparsers_invalid.add_parser(
+                cmd_info["name"],
+                help=cmd_info["help"],
+                parents=cmd_info["parents"],
+                aliases=cmd_info.get("aliases", []),
+            )
+            for arg_info in cmd_info.get("arguments", []):
+                subcommand[name].add_argument(*arg_info[0], **arg_info[1])
 
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object
-        parent_parser (argparse.ArgumentParser): Parent parser object
-    """
+    def config_menu(self):
+        """This method adds argparse argument for ``buildtest config``"""
 
-    parser_inspect = subparsers.add_parser(
-        "inspect", aliases=["it"], help="Inspect a test based on NAME or ID "
-    )
+        parser_config = self.subparsers.choices["config"]
 
-    subparser = parser_inspect.add_subparsers(
-        description="Inspect Test result based on Test ID or Test Name",
-        dest="inspect",
-        metavar="",
-    )
-    inspect_buildspec = subparser.add_parser(
-        "buildspec",
-        aliases=["b"],
-        help="Inspect a test based on buildspec",
-        parents=[parent_parser["pager"]],
-    )
-    name = subparser.add_parser(
-        "name",
-        aliases=["n"],
-        help="Specify name of test",
-        parents=[parent_parser["pager"]],
-    )
-    query_list = subparser.add_parser(
-        "query",
-        aliases=["q"],
-        help="Query fields from record",
-        parents=[parent_parser["pager"], parent_parser["theme"]],
-    )
-    # buildtest inspect buildspec
-    inspect_buildspec.add_argument(
-        "buildspec", nargs="*", help="List of buildspecs to query"
-    )
-    inspect_buildspec.add_argument(
-        "-a", "--all", action="store_true", help="Fetch all records for a given test"
-    )
-
-    name.add_argument("name", nargs="*", help="Name of test")
-
-    # buildtest inspect list
-    inspect_list = subparser.add_parser(
-        "list",
-        aliases=["l"],
-        help="List all test names, ids, and corresponding buildspecs",
-        parents=[
-            parent_parser["pager"],
-            parent_parser["row-count"],
-            parent_parser["terse"],
-            parent_parser["no-header"],
-        ],
-    )
+        subparsers_config = parser_config.add_subparsers(
+            description="Query information from buildtest configuration file",
+            dest="config",
+            metavar="",
+        )
 
-    inspect_list.add_argument(
-        "-b", "--builder", action="store_true", help="List test in builder format"
-    )
+        # Define the top-level commands and their subcommands in a list
+        command_menu = [
+            {
+                "name": "edit",
+                "aliases": ["e"],
+                "help": "Open configuration file in editor",
+            },
+            {
+                "name": "path",
+                "aliases": ["p"],
+                "help": "Show path to configuration file",
+            },
+            {"name": "systems", "help": "List all available systems"},
+            {
+                "name": "validate",
+                "aliases": ["val"],
+                "help": "Validate buildtest settings file with schema.",
+            },
+            {
+                "name": "view",
+                "aliases": ["v"],
+                "help": "View configuration file",
+                "parents": [self.parent_parser["pager"], self.parent_parser["theme"]],
+            },
+            {
+                "name": "profiles",
+                "help": "Query profile from buildtest configuration",
+                "subcommands": [
+                    {
+                        "name": "list",
+                        "help": "List all profiles",
+                        "parents": [self.parent_parser["theme"]],
+                        "arguments": [
+                            (
+                                ("-y", "--yaml"),
+                                {
+                                    "action": "store_true",
+                                    "help": "List Profile details in YAML Format",
+                                },
+                            )
+                        ],
+                    },
+                    {
+                        "name": "remove",
+                        "aliases": ["rm"],
+                        "help": "Remove a profile from configuration",
+                        "arguments": [
+                            (
+                                ("profile_name",),
+                                {
+                                    "nargs": "*",
+                                    "help": "Specify profile name to remove",
+                                },
+                            )
+                        ],
+                    },
+                ],
+            },
+            {
+                "name": "executors",
+                "aliases": ["ex"],
+                "help": "Query executors from buildtest configuration",
+                "subcommands": [
+                    {
+                        "name": "list",
+                        "help": "List all executors",
+                        "mutually_exclusive_group": True,
+                        "arguments": [
+                            (
+                                ("-j", "--json"),
+                                {
+                                    "action": "store_true",
+                                    "help": "View executor in JSON format",
+                                },
+                            ),
+                            (
+                                ("-y", "--yaml"),
+                                {
+                                    "action": "store_true",
+                                    "help": "View executors in YAML format",
+                                },
+                            ),
+                            (
+                                ("-d", "--disabled"),
+                                {
+                                    "action": "store_true",
+                                    "help": "Show disabled executors",
+                                },
+                            ),
+                            (
+                                ("-i", "--invalid"),
+                                {
+                                    "action": "store_true",
+                                    "help": "Show invalid executors",
+                                },
+                            ),
+                        ],
+                    }
+                ],
+            },
+            {
+                "name": "compilers",
+                "aliases": ["co"],
+                "help": "Search compilers",
+                "subcommands": [
+                    {
+                        "name": "list",
+                        "help": "List compilers",
+                        "mutually_exclusive_group": True,
+                        "arguments": [
+                            (
+                                ("-j", "--json"),
+                                {
+                                    "action": "store_true",
+                                    "help": "List compiler details in JSON format",
+                                },
+                            ),
+                            (
+                                ("-y", "--yaml"),
+                                {
+                                    "action": "store_true",
+                                    "help": "List compiler details in YAML format",
+                                },
+                            ),
+                        ],
+                    },
+                    {
+                        "name": "test",
+                        "help": "Test each compiler instance by performing module load test",
+                        "arguments": [
+                            (
+                                ("compiler_names",),
+                                {"nargs": "*", "help": "Specify compiler name to test"},
+                            )
+                        ],
+                    },
+                    {
+                        "name": "find",
+                        "help": "Find compilers",
+                        "parents": [self.parent_parser["file"]],
+                        "arguments": [
+                            (
+                                ("-d", "--detailed"),
+                                {
+                                    "help": "Display detailed output when finding compilers",
+                                    "action": "store_true",
+                                },
+                            ),
+                            (
+                                ("-u", "--update"),
+                                {
+                                    "action": "store_true",
+                                    "help": "Update configuration file with new compilers",
+                                },
+                            ),
+                            (
+                                ("-m", "--modulepath"),
+                                {
+                                    "type": str,
+                                    "nargs": "+",
+                                    "help": "Specify a list of directories to search for modules via MODULEPATH to detect compilers",
+                                },
+                            ),
+                        ],
+                    },
+                    {
+                        "name": "remove",
+                        "aliases": ["rm"],
+                        "help": "Remove compilers",
+                        "arguments": [
+                            (
+                                ("compiler_names",),
+                                {
+                                    "nargs": "*",
+                                    "help": "Specify compiler name to remove",
+                                },
+                            )
+                        ],
+                    },
+                ],
+            },
+        ]
+
+        # Iterate through the command menu and create subparsers and arguments
+        for command_data in command_menu:
+            # if command_data["name"] == "compilers":
+            #    continue
+
+            subparser_command = subparsers_config.add_parser(
+                command_data["name"],
+                aliases=command_data.get("aliases", []),
+                help=command_data["help"],
+                parents=command_data.get("parents", []),
+            )
 
-    # buildtest inspect query
-    query_list.add_argument(
-        "-b", "--buildscript", action="store_true", help="Print build script"
-    )
-    query_list.add_argument(
-        "-be", "--buildenv", action="store_true", help="Print content of build env"
-    )
-    query_list.add_argument(
-        "-e", "--error", action="store_true", help="Print error file"
-    )
-    query_list.add_argument(
-        "-o", "--output", action="store_true", help="Print output file"
-    )
-    query_list.add_argument(
-        "--testpath", action="store_true", help="Print content of testpath"
-    )
+            subcommands = command_data.get("subcommands", [])
+            subparsers_subcommand = subparser_command.add_subparsers(
+                description=f"Query information about {command_data['name']}",
+                dest=command_data["name"],
+                metavar="",
+            )
 
-    query_list.add_argument(
-        "name", nargs="*", help="Name of builder to query in report file"
-    )
+            for subcommand_data in subcommands:
+                subparser_subcommand = subparsers_subcommand.add_parser(
+                    subcommand_data["name"],
+                    aliases=subcommand_data.get("aliases", []),
+                    help=subcommand_data["help"],
+                    parents=subcommand_data.get("parents", []),
+                )
+
+                arguments = subcommand_data.get("arguments", [])
+                mutually_exclusive_group = None
+                if (
+                    "mutually_exclusive_group" in subcommand_data
+                    and subcommand_data["mutually_exclusive_group"]
+                ):
+                    # Add the options to a mutually exclusive group
+                    mutually_exclusive_group = (
+                        subparser_subcommand.add_mutually_exclusive_group()
+                    )
+
+                for args, kwargs in arguments:
+                    if not mutually_exclusive_group:
+                        subparser_subcommand.add_argument(*args, **kwargs)
+                        continue
+
+                    mutually_exclusive_group.add_argument(*args, **kwargs)
+
+    def report_menu(self):
+        """This method implements the ``buildtest report`` command options"""
+
+        report_arguments = [
+            (
+                ["--latest"],
+                {
+                    "help": "Retrieve latest record of a particular test",
+                    "action": "store_true",
+                },
+            ),
+            (
+                ["--oldest"],
+                {
+                    "help": "Retrieve oldest record of a particular test",
+                    "action": "store_true",
+                },
+            ),
+            (
+                ["-s", "--start"],
+                {"type": valid_time, "help": "Filter test by starttime"},
+            ),
+            (["-e", "--end"], {"type": valid_time, "help": "Filter test by endtime"}),
+        ]
+
+        filter_arguments = [
+            (
+                ["--filter"],
+                {
+                    "type": handle_kv_string,
+                    "help": "Filter report by filter fields. The filter fields must be in key=value format and multiple fields can be comma separated (e.g., --filter key1=val1,key2=val2). For a list of filter fields, run --helpfilter.",
+                },
+            ),
+            (
+                ["--helpfilter"],
+                {
+                    "action": "store_true",
+                    "help": "List available filter fields to be used with --filter option",
+                },
+            ),
+            (
+                ["--filterfields"],
+                {
+                    "action": "store_true",
+                    "help": "Print raw filter fields for --filter option to filter the report",
+                },
+            ),
+        ]
+
+        format_arguments = [
+            (
+                ["--helpformat"],
+                {
+                    "action": "store_true",
+                    "help": "List available format fields to be used with --format option",
+                },
+            ),
+            (
+                ["--formatfields"],
+                {
+                    "action": "store_true",
+                    "help": "Print raw format fields for --format option to format the report",
+                },
+            ),
+        ]
+
+        groups = {
+            "filter": filter_arguments,
+            "format": format_arguments,
+            "extra": report_arguments,
+        }
+
+        parser_report = self.subparsers.choices["report"]
+
+        subparsers = parser_report.add_subparsers(
+            description="Fetch test results from the report file and print them in table format",
+            metavar="",
+            dest="report_subcommand",
+        )
 
+        subcommands = [
+            ("clear", ["c"], "Remove all report files"),
+            ("list", ["l"], "List all report files"),
+            ("path", ["p"], "Print full path to the report file being used"),
+            ("summary", ["sm"], "Summarize test report"),
+        ]
+
+        report_subparsers = {}
+
+        for cmd, aliases, help_text in subcommands:
+            if cmd == "summary":
+                report_subparsers[cmd] = subparsers.add_parser(
+                    cmd,
+                    aliases=aliases,
+                    help=help_text,
+                    parents=[self.parent_parser["pager"]],
+                )
+                continue
+
+            report_subparsers[cmd] = subparsers.add_parser(
+                cmd, aliases=aliases, help=help_text
+            )
 
-def schema_menu(subparsers):
-    """This method builds menu for ``buildtest schema``
+        for group_name, group_arguments in groups.items():
+            group = parser_report.add_argument_group(group_name)
 
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object
-    """
-
-    parser_schema = subparsers.add_parser(
-        "schema", help="List schema contents and examples"
-    )
-    parser_schema.add_argument(
-        "-e", "--example", action="store_true", help="Show schema examples"
-    )
-    parser_schema.add_argument(
-        "-j", "--json", action="store_true", help="Display json schema file"
-    )
-    parser_schema.add_argument(
-        "-n",
-        "--name",
-        help="show schema by name (e.g., script)",
-        metavar="Schema Name",
-        choices=schema_table["names"],
-    )
+            for args, args_info in group_arguments:
+                group.add_argument(*args, **args_info)
 
+        # Define mutually exclusive groups
+        pass_fail_group = parser_report.add_mutually_exclusive_group()
+        pass_fail_group.add_argument(
+            "-f", "--fail", help="Retrieve all FAIL tests", action="store_true"
+        )
+        pass_fail_group.add_argument(
+            "-p",
+            "--pass",
+            dest="passed",
+            help="Retrieve all PASS tests",
+            action="store_true",
+        )
 
-def cdash_menu(subparsers):
-    """This method builds arguments for ``buildtest cdash`` command.
+        format_group = parser_report.add_mutually_exclusive_group()
+        format_group.add_argument(
+            "--format",
+            help="Format field for printing purposes. Fields must be separated by commas (e.g., --format field1,field2,...).",
+        )
+        format_group.add_argument(
+            "-d",
+            "--detailed",
+            action="store_true",
+            help="Print a detailed summary of the test results",
+        )
 
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object
-    """
+        report_subparsers["summary"].add_argument(
+            "--detailed",
+            "-d",
+            action="store_true",
+            help="Enable a more detailed report",
+        )
 
-    parser_cdash = subparsers.add_parser("cdash", help="Upload test to CDASH server")
+    def inspect_menu(self):
+        """This method builds argument for ``buildtest inspect`` command"""
 
-    subparser = parser_cdash.add_subparsers(
-        description="buildtest CDASH integeration", dest="cdash", metavar=""
-    )
-    subparser.add_parser("view", help="Open CDASH project in webbrowser")
+        parser_inspect = self.subparsers.choices["inspect"]
 
-    upload = subparser.add_parser("upload", help="Upload Test to CDASH server")
+        subparser = parser_inspect.add_subparsers(
+            description="Inspect Test result based on Test ID or Test Name",
+            dest="inspect",
+            metavar="",
+        )
 
-    upload.add_argument("--site", help="Specify site name reported in CDASH")
-    upload.add_argument("buildname", help="Specify Build Name reported in CDASH")
-    upload.add_argument(
-        "-o", "--open", action="store_true", help="Open CDASH report in browser"
-    )
+        menu = {
+            "buildspec": {
+                "aliases": ["b"],
+                "help": "Inspect a test based on buildspec",
+                "parents": [self.parent_parser["pager"]],
+                "arguments": [
+                    (
+                        ["buildspec"],
+                        {"nargs": "*", "help": "List of buildspecs to query"},
+                    ),
+                    (
+                        ["-a", "--all"],
+                        {
+                            "action": "store_true",
+                            "help": "Fetch all records for a given test",
+                        },
+                    ),
+                ],
+            },
+            "name": {
+                "aliases": ["n"],
+                "help": "Specify name of test",
+                "parents": [self.parent_parser["pager"]],
+                "arguments": [(["name"], {"nargs": "*", "help": "Name of test"})],
+            },
+            "query": {
+                "aliases": ["q"],
+                "help": "Query fields from record",
+                "parents": [self.parent_parser["pager"], self.parent_parser["theme"]],
+                "arguments": [
+                    (
+                        ["-b", "--buildscript"],
+                        {"action": "store_true", "help": "Print build script"},
+                    ),
+                    (
+                        ["-be", "--buildenv"],
+                        {"action": "store_true", "help": "Print content of build env"},
+                    ),
+                    (
+                        ["-e", "--error"],
+                        {"action": "store_true", "help": "Print error file"},
+                    ),
+                    (
+                        ["-o", "--output"],
+                        {"action": "store_true", "help": "Print output file"},
+                    ),
+                    (
+                        ["-t", "--testpath"],
+                        {"action": "store_true", "help": "Print content of testpath"},
+                    ),
+                    (
+                        ["name"],
+                        {
+                            "nargs": "*",
+                            "help": "Name of builder to query in report file",
+                        },
+                    ),
+                ],
+            },
+            "list": {
+                "aliases": ["l"],
+                "help": "List all test names, ids, and corresponding buildspecs",
+                "parents": [
+                    self.parent_parser["pager"],
+                    self.parent_parser["row-count"],
+                    self.parent_parser["terse"],
+                    self.parent_parser["no-header"],
+                ],
+                "arguments": [
+                    (
+                        ["-b", "--builder"],
+                        {"action": "store_true", "help": "List test in builder format"},
+                    )
+                ],
+            },
+        }
+
+        # Create parsers and arguments using the menu dictionary
+        for command, options in menu.items():
+            parser = subparser.add_parser(
+                command,
+                aliases=options["aliases"],
+                help=options["help"],
+                parents=options["parents"],
+            )
+            for arg_info in options["arguments"]:
+                parser.add_argument(*arg_info[0], **arg_info[1])
 
+        return
 
-def help_all(subparsers):
-    """This method will add parser for hidden command that can be shown when using ``--help-all/-H``
+    def schema_menu(self):
+        """This method builds menu for ``buildtest schema``"""
+
+        parser_schema = self.subparsers.choices["schema"]
+
+        schema_args = [
+            (
+                ["-e", "--example"],
+                {"action": "store_true", "help": "Show schema examples"},
+            ),
+            (
+                ["-j", "--json"],
+                {"action": "store_true", "help": "Display json schema file"},
+            ),
+            (
+                ["-n", "--name"],
+                {
+                    "help": "show schema by name (e.g., script)",
+                    "metavar": "Schema Name",
+                    "choices": schema_table["names"],
+                },
+            ),
+        ]
+
+        for arg_info in schema_args:
+            parser_schema.add_argument(*arg_info[0], **arg_info[1])
+
+    def cdash_menu(self):
+        """This method builds arguments for ``buildtest cdash`` command."""
+
+        cdash_commands = {
+            "view": {"help": "Open CDASH project in web browser"},
+            "upload": {"help": "Upload test results to CDASH server"},
+        }
+
+        cdash_arguments = {
+            "view": [],
+            "upload": [
+                (["--site"], {"help": "Specify site name reported in CDASH"}),
+                (["buildname"], {"help": "Specify Build Name reported in CDASH"}),
+                (
+                    ["-o", "--open"],
+                    {"action": "store_true", "help": "Open CDASH report in browser"},
+                ),
+            ],
+        }
+
+        parser_cdash = self.subparsers.choices["cdash"]
+        subparser = parser_cdash.add_subparsers(
+            description="buildtest CDASH integration", dest="cdash", metavar=""
+        )
 
-    Args:
-        subparsers (argparse._SubParsersAction): Subparser object
-    """
-    hidden_parser = {
-        "tutorial-examples": "Generate documentation examples for Buildtest Tutorial",
-        "docs": "Open buildtest docs in browser",
-        "schemadocs": "Open buildtest schema docs in browser",
-        "unittests": {"help": "Run buildtest unit tests", "aliases": ["test"]},
-        "stylecheck": {"help": "Run buildtest style checks", "aliases": ["style"]},
-    }
-
-    for command, val in hidden_parser.items():
-        if type(val) is dict:
-            subparsers.add_parser(
-                command, help=val.get("help"), aliases=val.get("aliases")
-            )
-        else:
-            subparsers.add_parser(command, help=val)
+        for command, command_info in cdash_commands.items():
+            cdash_parser = subparser.add_parser(command, **command_info)
+            for args, args_info in cdash_arguments[command]:
+                cdash_parser.add_argument(*args, **args_info)
diff --git a/buildtest/cli/build.py b/buildtest/cli/build.py
index e5a0e6139..c1bbd4421 100644
--- a/buildtest/cli/build.py
+++ b/buildtest/cli/build.py
@@ -116,6 +116,7 @@ def resolve_testdirectory(configuration: SiteConfiguration, testdir: str = None)
 def discover_buildspecs(
     buildspecs: Optional[List[str]] = None,
     exclude_buildspecs: Optional[List[str]] = None,
+    name: Optional[List[str]] = None,
     executors: Optional[List[str]] = None,
     tags: Optional[List[str]] = None,
 ) -> Dict[str, List[str]]:
@@ -125,6 +126,7 @@ def discover_buildspecs(
     Args:
         buildspecs (list, optional): List of input buildspecs passed by argument ``buildtest build --buildspec``
         exclude_buildspecs (list, optional): List of excluded buildspecs by argument ``buildtest build --exclude``
+        name (list, optional): List of test names to discover buildspecs that are specified by ``buildtest build --name``
         tags (list, optional): List of input tags for discovering buildspecs by argument ``buildtest build --tags``
         executors (list, optional): List of input executors for discovering buildspecs by argument ``buildtest build --executor``
 
@@ -138,6 +140,7 @@ def discover_buildspecs(
     buildspec_dict["excluded"] = []
     buildspec_dict["detected"] = []
     buildspec_dict["tags"] = {}
+    buildspec_dict["name"] = {}
     buildspec_dict["executors"] = {}
 
     logger.debug(
@@ -167,6 +170,15 @@ def discover_buildspecs(
         logger.debug(f"Discovered buildspecs based on executors: {executors}")
         logger.debug(found_buildspecs)
 
+    if name:
+        found_buildspecs, buildspec_dict["name"] = discover_buildspecs_by_name(
+            buildspec_cache=cache, names=name
+        )
+
+        buildspec_dict["included"] += found_buildspecs
+        logger.debug(f"Discovered buildspecs based on names: {name}")
+        logger.debug(found_buildspecs)
+
     # discover buildspecs based on --buildspec
     if buildspecs:
         # Discover list of one or more Buildspec files based on path provided. Since --buildspec can be provided multiple
@@ -240,7 +252,7 @@ def print_discovered_buildspecs(buildspec_dict):
     table = Table(
         title="Discovered buildspecs", box=box.DOUBLE_EDGE, header_style="blue"
     )
-    table.add_column("buildspec", style="green")
+    table.add_column("buildspec", style="green", overflow="fold")
 
     for i in buildspec_dict["included"]:
         table.add_row(i)
@@ -251,7 +263,7 @@ def print_discovered_buildspecs(buildspec_dict):
         table = Table(
             title="Excluded buildspecs", box=box.DOUBLE_EDGE, header_style="blue"
         )
-        table.add_column("buildspec", style="red")
+        table.add_column("buildspec", style="red", overflow="fold")
 
         for i in buildspec_dict["excluded"]:
             table.add_row(i)
@@ -265,7 +277,7 @@ def print_discovered_buildspecs(buildspec_dict):
                 box=box.DOUBLE_EDGE,
                 header_style="blue",
             )
-            table.add_column("buildspec", style="turquoise2")
+            table.add_column("buildspec", style="turquoise2", overflow="fold")
             for row in buildspec_dict["tags"][tagname]:
                 table.add_row(row)
             console.print(table)
@@ -278,11 +290,24 @@ def print_discovered_buildspecs(buildspec_dict):
                 box=box.DOUBLE_EDGE,
                 header_style="blue",
             )
-            table.add_column("buildspecs", style="magenta1")
+            table.add_column("buildspecs", style="magenta1", overflow="fold")
             for row in buildspec_dict["executors"][executorname]:
                 table.add_row(f"{row}")
             console.print(table)
 
+    # print breakdown of buildspecs by executors
+    if buildspec_dict.get("name"):
+        for name in buildspec_dict["name"].keys():
+            table = Table(
+                title=f"Buildspecs by Name={name}",
+                box=box.DOUBLE_EDGE,
+                header_style="blue",
+            )
+            table.add_column("buildspecs", style="yellow2", overflow="fold")
+            for row in buildspec_dict["name"][name]:
+                table.add_row(f"{row}")
+            console.print(table)
+
     print("\n")
     console.print(
         "[green bold]Total Discovered Buildspecs: ", len(buildspec_dict["included"])
@@ -348,6 +373,33 @@ def discover_buildspecs_by_tags(buildspec_cache, tagnames):
     return buildspecs, buildspecs_by_tags
 
 
+def discover_buildspecs_by_name(buildspec_cache, names):
+    """This method will discover buildspecs given a list of test names.
+
+     Args:
+        buildspec_cache (dict): Loaded buildspec cache as a dictionary
+        names (list): List of test names to search for buildspecs from cache
+
+
+    Returns:
+         list, dict: first argument is a list of buildspecs discovered for all test names. The second argument is
+         dictionary breakdown of buildspecs by each name
+    """
+
+    buildspec_by_names = {}
+    found_buildspecs = []
+    for name in names:
+        for buildspecfile in buildspec_cache["buildspecs"].keys():
+            # if there is a match, add buildspecs and proceed to next test name
+            if name in buildspec_cache["buildspecs"][buildspecfile].keys():
+                buildspec_by_names[name] = [buildspecfile]
+                found_buildspecs.append(buildspecfile)
+                break
+
+    found_buildspecs = list(set(found_buildspecs))
+    return found_buildspecs, buildspec_by_names
+
+
 def discover_buildspecs_by_executor(buildspec_cache, executors):
     """This method discovers buildspecs by executor name, using ``buildtest build --executor``
     command. This method will read BUILDSPEC_CACHE_FILE and search for ``executor`` property
@@ -468,8 +520,8 @@ def print_filters():
     """
 
     table = Table(title="Buildtest Filters", header_style="blue")
-    table.add_column("Field", style="green")
-    table.add_column("Description", style="red")
+    table.add_column("Field", style="green", overflow="fold")
+    table.add_column("Description", style="red", overflow="fold")
 
     table.add_row("tags", "Filter tests by [italic]'tag'[/italic] field")
     table.add_row("type", "Filter test by [italic]'type'[/italic] field")
@@ -486,6 +538,7 @@ def __init__(
         buildspecs=None,
         exclude_buildspecs=None,
         tags=None,
+        name=None,
         exclude_tags=None,
         executors=None,
         testdir=None,
@@ -511,6 +564,7 @@ def __init__(
         limit=None,
         save_profile=None,
         profile=None,
+        max_jobs=None,
     ):
         """The initializer method is responsible for checking input arguments for type
         check, if any argument fails type check we raise an error. If all arguments pass
@@ -521,6 +575,7 @@ def __init__(
             buildspecs (list, optional): list of buildspecs from command line ``buildtest build --buildspec``
             exclude_buildspecs (list, optional): list of excluded buildspecs from command line ``buildtest build --exclude``
             tags (list, optional): list if tags to discover tests specified via command line ``buildtest build --tags``
+            name (list, optional): list of test names to run specified via command line ``buildtest build --name``
             exclude_tags (list, optional): list if tags to exclude specified via command line ``buildtest build --exclude-tags``
             executors (list, optional): list of executors passed from command line ``buildtest build --executors``
             testdir (str): Path to test directory where tests are written. This argument can be passed from command line ``buildtest build --testdir``
@@ -546,10 +601,18 @@ def __init__(
             limit (int, optional): Limit number of tests that can be run. This option is specified by ``buildtest build --limit``
             save_profile (str, optional): Save profile to buildtest configuration specified by ``buildtest build --save-profile``
             profile (str, optional): Profile to load from buildtest configuration specified by ``buildtest build --profile``
+            max_jobs (int, optional): Maximum number of jobs to run concurrently. This option is specified by ``buildtest build --max-jobs``
         """
 
         # check for input arguments that are expected to be a list
-        for arg_name in [buildspecs, exclude_buildspecs, tags, exclude_tags, executors]:
+        for arg_name in [
+            buildspecs,
+            exclude_buildspecs,
+            tags,
+            exclude_tags,
+            executors,
+            name,
+        ]:
             if arg_name and not isinstance(arg_name, list):
                 raise BuildTestError(f"{arg_name} is not of type list")
 
@@ -568,7 +631,7 @@ def __init__(
                     f"--rebuild {rebuild} exceeds maximum rebuild limit of 50"
                 )
 
-        for field in [timeout, limit, retry]:
+        for field in [timeout, limit, retry, max_jobs]:
             if field is not None:
                 if not isinstance(field, int):
                     raise BuildTestError(f"{field} is not of type int")
@@ -580,6 +643,7 @@ def __init__(
         self.buildspecs = buildspecs
         self.exclude_buildspecs = exclude_buildspecs
         self.tags = tags
+        self.name = name
         self.exclude_tags = exclude_tags
         self.executors = executors
         self.maxpendtime = maxpendtime
@@ -601,6 +665,7 @@ def __init__(
         self.limit = limit
         self.save_profile = save_profile
         self.profile = profile
+        self.max_jobs = max_jobs
 
         # this variable contains the detected buildspecs that will be processed by buildtest.
         self.detected_buildspecs = None
@@ -678,6 +743,7 @@ def __init__(
             account=self.account,
             pollinterval=self.pollinterval,
             timeout=self.timeout,
+            max_jobs=self.max_jobs,
         )
 
         self.system = buildtest_system
@@ -728,6 +794,7 @@ def load_rerun_file(self):
         self.buildspecs = content["buildspecs"]
         self.tags = content["tags"]
         self.exclude_tags = content["exclude_tags"]
+        self.name = content["name"]
         self.filter = content["filter"]
         self.exclude_buildspecs = content["exclude_buildspecs"]
         self.executors = content["executors"]
@@ -748,6 +815,7 @@ def load_rerun_file(self):
         self.executor_type = content["executor_type"]
         self.timeout = content["timeout"]
         self.limit = content["limit"]
+        self.max_jobs = content["max_jobs"]
 
     def save_rerun_file(self):
         """Record buildtest command options and save them into rerun file which is read when invoking ``buildtest build --rerun``."""
@@ -756,6 +824,7 @@ def save_rerun_file(self):
             "buildspecs": self.buildspecs,
             "tags": self.tags,
             "exclude_tags": self.exclude_tags,
+            "name": self.name,
             "filter": self.filter_buildspecs,
             "exclude_buildspecs": self.exclude_buildspecs,
             "executors": self.executors,
@@ -776,6 +845,7 @@ def save_rerun_file(self):
             "executor_type": self.executor_type,
             "timeout": self.timeout,
             "limit": self.limit,
+            "max_jobs": self.max_jobs,
         }
 
         with open(BUILDTEST_RERUN_FILE, "w") as fd:
@@ -797,6 +867,7 @@ def save_profile_to_configuration(self):
             "exclude-buildspecs": self.exclude_buildspecs,
             "tags": self.tags,
             "exclude-tags": self.exclude_tags,
+            "name": self.name,
             "executors": self.executors,
             "module": self.modules,
             "unload-modules": self.unload_modules,
@@ -810,6 +881,8 @@ def save_profile_to_configuration(self):
             "timeout": self.timeout,
             "filter": self.filter_buildspecs,
             "executor-type": self.executor_type,
+            "max_jobs": self.max_jobs,
+            "remove-stagedir": self.remove_stagedir,
         }
         # we need to set module-purge to None if it is False. We delete all keys  that are 'None' before writing to configuration file
         profile_configuration["module-purge"] = (
@@ -863,6 +936,7 @@ def load_profile(self):
         self.exclude_buildspecs = profile_configuration.get("exclude-buildspecs")
         self.tags = profile_configuration.get("tags")
         self.exclude_tags = profile_configuration.get("exclude-tags")
+        self.name = profile_configuration.get("name")
         self.executors = profile_configuration.get("executors")
         self.limit = profile_configuration.get("limit")
         self.account = profile_configuration.get("account")
@@ -876,6 +950,8 @@ def load_profile(self):
         self.rebuild = profile_configuration.get("rebuild")
         self.filter_buildspecs = profile_configuration.get("filter")
         self.executor_type = profile_configuration.get("executor-type")
+        self.max_jobs = profile_configuration.get("max_jobs")
+        self.remove_stagedir = profile_configuration.get("remove-stagedir")
 
     def _validate_filters(self):
         """Check filter fields provided by ``buildtest build --filter`` are valid types and supported. Currently
@@ -919,6 +995,7 @@ def build(self):
         self.discovered_bp = discover_buildspecs(
             buildspecs=self.buildspecs,
             exclude_buildspecs=self.exclude_buildspecs,
+            name=self.name,
             tags=self.tags,
             executors=self.executors,
         )
@@ -1170,11 +1247,11 @@ def _print_test_summary(self, builders):
 
         table = Table(title="Test Summary", show_lines=True, header_style="blue")
         table.add_column("builder", overflow="fold")
-        table.add_column("executor")
-        table.add_column("status")
+        table.add_column("executor", overflow="fold")
+        table.add_column("status", overflow="fold")
         table.add_column("checks (ReturnCode, Regex, Runtime)", overflow="fold")
-        table.add_column("returncode")
-        table.add_column("runtime")
+        table.add_column("returncode", overflow="fold")
+        table.add_column("runtime", overflow="fold")
 
         passed_tests = 0
         failed_tests = 0
@@ -1330,14 +1407,14 @@ def print_builders_by_type(self, builders, builder_type):
             builder_type (str): The builder type corresponding to the list of ``builders``. This type corresponds to the ``type`` field in the test
         """
         table = Table(
-            Column(header="builder", style="blue"),
-            Column(header="type", style="cyan1"),
-            Column(header="executor", style="green"),
-            Column(header="compiler", style="red"),
-            Column(header="nodes", style="orange3"),
-            Column(header="procs", style="orange3"),
-            Column(header="description", style="magenta"),
-            Column(header="buildspecs", style="yellow"),
+            Column(header="builder", style="blue", overflow="fold"),
+            Column(header="type", style="cyan1", overflow="fold"),
+            Column(header="executor", style="green", overflow="fold"),
+            Column(header="compiler", style="red", overflow="fold"),
+            Column(header="nodes", style="orange3", overflow="fold"),
+            Column(header="procs", style="orange3", overflow="fold"),
+            Column(header="description", style="magenta", overflow="fold"),
+            Column(header="buildspecs", style="yellow", overflow="fold"),
             title=f"Builders by type={builder_type}",
             show_lines=True,
             header_style="blue",
diff --git a/buildtest/cli/buildspec.py b/buildtest/cli/buildspec.py
index 30d164efd..f31a126e5 100644
--- a/buildtest/cli/buildspec.py
+++ b/buildtest/cli/buildspec.py
@@ -968,8 +968,8 @@ def print_invalid_buildspecs(
         # if --error is not specified print list of invalid buildspecs in rich table
         if not error:
             table = Table(
-                "Buildspec",
-                "Exception",
+                Column("Buildspec", overflow="fold"),
+                Column("Exception", overflow="fold"),
                 title="Invalid Buildspecs",
                 header_style="blue",
                 style="cyan",
diff --git a/buildtest/cli/cdash.py b/buildtest/cli/cdash.py
index 93ddd29b6..47a7a37d8 100644
--- a/buildtest/cli/cdash.py
+++ b/buildtest/cli/cdash.py
@@ -250,6 +250,10 @@ def upload_test_cdash(
                     ansi_escape.sub("", test["output"])
                     ansi_escape.sub("", test["error"])
 
+                    # need to encode in ASCII characters for example any uniccoded characters will cause CDASH upload to fail
+                    test["output"] = test["output"].encode("ascii", "ignore").decode()
+                    test["error"] = test["error"].encode("ascii", "ignore").decode()
+
     console.print(f"Uploading {len(tests)} tests")
 
     build_stamp = build_starttime.strftime(output_datetime_format)
@@ -426,7 +430,7 @@ def upload_test_cdash(
             match = buildid_regexp.search(resp_value)
             if match:
                 buildid = match.group(1)
-                url_view = f"{cdash_url}/viewTest.php?buildid={buildid}"
+                url_view = urljoin(cdash_url, f"viewTest.php?buildid={buildid}")
                 console.print(f"You can view the results at: {url_view}")
                 if open_browser:
                     webbrowser.open(url_view)
diff --git a/buildtest/cli/commands.py b/buildtest/cli/commands.py
index 268df2336..040181453 100644
--- a/buildtest/cli/commands.py
+++ b/buildtest/cli/commands.py
@@ -1,28 +1,20 @@
-def list_buildtest_commands():
-    """This method implements command ``buildtest commands`` which shows a list of buildtest commands"""
+from buildtest.cli import BuildTestParser
 
-    cmds_list = [
-        "build",
-        "buildspec",
-        "cd",
-        "cdash",
-        "clean",
-        "config",
-        "debugreport",
-        "docs",
-        "history",
-        "info",
-        "inspect",
-        "path",
-        "report",
-        "schema",
-        "schemadocs",
-        "show",
-        "stats",
-        "stylecheck",
-        "tutorial-examples",
-        "unittests",
-    ]
 
-    for field in cmds_list:
+def list_buildtest_commands(with_aliases=None):
+    """This method implements command ``buildtest commands`` which shows a list of buildtest commands
+
+    Args:
+        with_aliases (bool): Return a list of buildtest commands with aliases
+    """
+
+    cmds = BuildTestParser()
+    subcmds = sorted(cmds.buildtest_subcommands)
+
+    # if --with-aliases we will show all available choices for subcommands including aliases
+    if with_aliases:
+        subparser = cmds.get_subparsers()
+        subcmds = sorted(list(subparser.choices.keys()))
+
+    for field in sorted(subcmds):
         print(field)
diff --git a/buildtest/cli/compilers.py b/buildtest/cli/compilers.py
index 643ccb425..58fa043f9 100644
--- a/buildtest/cli/compilers.py
+++ b/buildtest/cli/compilers.py
@@ -27,19 +27,75 @@ def compiler_cmd(args, configuration):
             update=args.update,
             filepath=args.file,
         )
-        return
 
     if args.compilers == "test":
         compiler_test(configuration, args.compiler_names)
-        return
 
+    if args.compilers == "list":
+        list_compilers(
+            configuration=configuration, print_yaml=args.yaml, print_json=args.json
+        )
+    if args.compilers in ["remove", "rm"]:
+        remove_compilers(configuration=configuration, names=args.compiler_names)
+
+
+def remove_compilers(configuration, names):
+    """This method will remove compilers from buildtest configuration file and update the configuration file. A list
+    of compiler names are specified, if compiler is found it will be removed.
+
+    Args:
+        configuration (buildtest.config.SiteConfiguration): An instance of SiteConfiguration class
+        names (list): A list of compiler names to remove from configuration file
+
+    """
+    compilers = configuration.target_config["compilers"]["compiler"]
+    updated_compilers = compilers.copy()
+
+    # iterate over the compiler configuration with list of input compiler names to remove. If compiler is found, then delete the key.
+    for compiler_type, compiler_section in compilers.items():
+        for name in names:
+            if name in compiler_section:
+                console.rule(f"Removing compiler name: {name}")
+                console.print(yaml.safe_dump(compiler_section[name]))
+                del compiler_section[name]
+        updated_compilers[compiler_type] = compiler_section
+        # if no compilers are present for a key
+        if len(updated_compilers[compiler_type].keys()) == 0:
+            del updated_compilers[compiler_type]
+
+    configuration.target_config["compilers"]["compiler"] = updated_compilers
+
+    if len(configuration.target_config["compilers"]["compiler"]) == 0:
+        del configuration.target_config["compilers"]["compiler"]
+
+    custom_validator(
+        configuration.config, schema_table["settings.schema.json"]["recipe"]
+    )
+
+    console.print(f"Updating configuration file: {configuration.file}")
+
+    with open(configuration.file, "w") as fd:
+        yaml.safe_dump(
+            configuration.config, fd, default_flow_style=False, sort_keys=False
+        )
+
+
+def list_compilers(configuration, print_yaml=None, print_json=None):
+    """This method will print available compilers found in configuration file which
+        can be retrieved by running ``buildtest config compilers list``
+
+    Args:
+        configuration (buildtest.config.SiteConfiguration): An instance of SiteConfiguration class
+        print_yaml (bool, optional): Print output in YAML format
+        print_json (bool, optional): Print output in JSON format
+    """
     bc = BuildtestCompilers(configuration)
 
-    if args.json:
+    if print_json:
         bc.print_json()
         return
 
-    if args.yaml:
+    if print_yaml:
         bc.print_yaml()
         return
 
@@ -98,13 +154,13 @@ def compiler_test(configuration, compiler_names=None):
     compiler_pass = Table(title="Compilers Test Pass")
     compiler_fail = Table(title="Compilers Test Fail")
 
-    compiler_pass.add_column("No.", style="cyan", no_wrap=True)
-    compiler_pass.add_column("Compiler Name", style="green")
-    compiler_pass.add_column("Status", justify="right")
+    compiler_pass.add_column("No.", style="cyan", no_wrap=True, overflow="fold")
+    compiler_pass.add_column("Compiler Name", style="green", overflow="fold")
+    compiler_pass.add_column("Status", justify="right", overflow="fold")
 
-    compiler_fail.add_column("No.", style="cyan", no_wrap=True)
-    compiler_fail.add_column("Compiler Name", style="red")
-    compiler_fail.add_column("Status", justify="right")
+    compiler_fail.add_column("No.", style="cyan", no_wrap=True, overflow="fold")
+    compiler_fail.add_column("Compiler Name", style="red", overflow="fold")
+    compiler_fail.add_column("Status", justify="right", overflow="fold")
 
     for idx, pass_compiler in enumerate(pass_compilers):
         compiler_pass.add_row(str(idx + 1), pass_compiler, "✅")
@@ -243,8 +299,9 @@ def __init__(
         self.modulepath = self.modulepath or os.getenv("MODULEPATH")
 
         if not deep_get(self.configuration.target_config, "compilers", "compiler"):
-            raise BuildTestError("compiler section not defined")
-
+            raise BuildTestError(
+                "Unable to find any compilers in configuration file. Please define a compiler or detect compilers by running 'buildtest config compilers find'"
+            )
         self.compilers = self.configuration.target_config["compilers"]["compiler"]
 
         self._names = []
@@ -354,7 +411,7 @@ def _validate_modules(self, module_dict):
             table = Table(
                 title="Discovered Modules", show_lines=True, header_style="blue"
             )
-            table.add_column("Name")
+            table.add_column("Name", overflow="fold")
             for modules in module_dict.values():
                 for name in modules:
                     table.add_row(name)
diff --git a/buildtest/cli/config.py b/buildtest/cli/config.py
index 7d6c1c44d..fcc7568c6 100644
--- a/buildtest/cli/config.py
+++ b/buildtest/cli/config.py
@@ -10,6 +10,7 @@
 from buildtest.defaults import console
 from buildtest.exceptions import ConfigurationError
 from buildtest.executors.setup import BuildExecutor
+from buildtest.schemas.defaults import custom_validator, schema_table
 
 
 def config_cmd(args, configuration, editor, system):
@@ -20,19 +21,28 @@ def config_cmd(args, configuration, editor, system):
         configuration (buildtest.config.SiteConfiguration): An instance of SiteConfiguration class
         system (buildtest.system.BuildTestSystem): An instance of BuildTestSystem class
     """
+
     if args.config in ["view", "v"]:
         view_configuration(configuration, theme=args.theme, pager=args.pager)
 
+    elif args.config in ["profiles"]:
+        if args.profiles == "list":
+            list_profiles(configuration, theme=args.theme, print_yaml=args.yaml)
+
+        if args.profiles in ["remove", "rm"]:
+            remove_profiles(configuration, profile_name=args.profile_name)
+
     elif args.config in ["executors", "ex"]:
         buildexecutor = BuildExecutor(configuration)
-        view_executors(
-            configuration,
-            buildexecutor,
-            args.json,
-            args.yaml,
-            args.disabled,
-            args.invalid,
-        )
+        if args.executors == "list":
+            view_executors(
+                configuration,
+                buildexecutor,
+                args.json,
+                args.yaml,
+                args.disabled,
+                args.invalid,
+            )
 
     elif args.config in ["validate", "val"]:
         validate_config(configuration, system.system["moduletool"])
@@ -72,9 +82,9 @@ def view_system(configuration):
 
     # table = {"system": [], "description": [], "hostnames": [], "moduletool": []}
     table = Table(
-        "system",
-        "description",
-        "moduletool",
+        Column("system", overflow="fold"),
+        Column("description", overflow="fold"),
+        Column("moduletool", overflow="fold"),
         Column("hostnames", overflow="fold"),
         title=f"System Summary (Configuration={configuration.file})",
         header_style="blue",
@@ -154,6 +164,78 @@ def view_configuration(configuration, theme=None, pager=None):
     console.print(syntax)
 
 
+def remove_profiles(configuration, profile_name):
+    """This method will remove profile names from configuration file given a list of profile names. This method
+    will be invoked when user runs ``buildtest config profiles remove`` command.
+
+    Args:
+        configuration (buildtest.config.SiteConfiguration): An instance of SiteConfiguration class
+        profile_name (list): List of name of profile to remove
+    """
+
+    if not configuration.target_config.get("profiles"):
+        console.print(
+            f"Unable to remove any profiles because no profiles found in configuration file: {configuration.file}. Please create a profile using [red]buildtest build --save-profile[/red]"
+        )
+        return
+
+    # variable to determine if file needs to be written back to disk
+    write_back = False
+
+    for name in profile_name:
+        if name not in configuration.target_config["profiles"]:
+            console.print(f"Unable to remove profile: {name} because it does not exist")
+            continue
+
+        del configuration.target_config["profiles"][name]
+        console.print(f"Removing profile: {name}")
+        write_back = True
+
+    # if no profiles exist then delete top-level key 'profiles'
+    if len(configuration.target_config["profiles"].keys()) == 0:
+        del configuration.target_config["profiles"]
+
+    custom_validator(
+        configuration.config, schema_table["settings.schema.json"]["recipe"]
+    )
+
+    # only update the configuration file if we removed a profile
+    if write_back:
+        console.print(f"Updating configuration file: {configuration.file}")
+
+        with open(configuration.file, "w") as fd:
+            yaml.safe_dump(
+                configuration.config, fd, default_flow_style=False, sort_keys=False
+            )
+
+
+def list_profiles(configuration, theme=None, print_yaml=None):
+    """Display the list of profile for buildtest configuration file. This implements command ``buildtest config profiles list``
+
+    Args:
+        configuration (buildtest.config.SiteConfiguration): An instance of SiteConfiguration class
+        theme (str, optional): Color theme to choose. This is the Pygments style (https://pygments.org/docs/styles/#getting-a-list-of-available-styles) which is specified by ``--theme`` option
+        print_yaml (bool, optional): Display profiles in yaml format. This is specified by ``--yaml`` option
+    """
+
+    if not configuration.target_config.get("profiles"):
+        console.print(
+            f"Unable to list any profiles because no profiles found in configuration file: {configuration.file}. Please create a profile using `buildtest build --save-profile`"
+        )
+        return
+    if print_yaml:
+        profile_configuration = yaml.dump(
+            configuration.target_config["profiles"], indent=2
+        )
+        syntax = Syntax(profile_configuration, "yaml", theme=theme or "monokai")
+        console.print(syntax)
+        return
+
+    # print profiles as raw text
+    for profile_name in configuration.target_config["profiles"].keys():
+        print(profile_name)
+
+
 def view_executors(
     configuration,
     buildexecutor,
diff --git a/buildtest/cli/helpcolor.py b/buildtest/cli/helpcolor.py
index fb65679b0..49ecd382e 100644
--- a/buildtest/cli/helpcolor.py
+++ b/buildtest/cli/helpcolor.py
@@ -1,12 +1,17 @@
 from rich.color import ANSI_COLOR_NAMES
-from rich.table import Table
+from rich.table import Column, Table
 
 from buildtest.defaults import console
 
 
 def print_available_colors(color_names=ANSI_COLOR_NAMES):
     """Print the available color options in a table format on background of the color option."""
-    table = Table("Number", "Color", header_style="bold", title="Available Colors")
+    table = Table(
+        Column("Number", overflow="fold"),
+        Column("Color", overflow="fold"),
+        header_style="bold",
+        title="Available Colors",
+    )
     for color, number in color_names.items():
         table.add_row(f"[black]{number}", f"[black]{color}", style="on " + color)
     console.print(table)
diff --git a/buildtest/cli/history.py b/buildtest/cli/history.py
index 9e2d8ba2a..6bdece335 100644
--- a/buildtest/cli/history.py
+++ b/buildtest/cli/history.py
@@ -145,15 +145,18 @@ def list_build_history(
     history_table = Table(
         header_style="blue", show_lines=True, row_styles=[consoleColor]
     )
-    history_table.add_column("id")
-    history_table.add_column("hostname")
-    history_table.add_column("user")
-    history_table.add_column("system")
-    history_table.add_column("date")
-    history_table.add_column("pass tests")
-    history_table.add_column("fail tests")
-    history_table.add_column("total tests")
-    history_table.add_column("command", overflow="fold")
+    for field in [
+        "id",
+        "hostname",
+        "user",
+        "system",
+        "date",
+        "pass tests",
+        "fail tests",
+        "total tests",
+        "command",
+    ]:
+        history_table.add_column(field, overflow="fold")
 
     for (
         build_id,
diff --git a/buildtest/cli/inspect.py b/buildtest/cli/inspect.py
index 99c01a24a..dffdc5526 100644
--- a/buildtest/cli/inspect.py
+++ b/buildtest/cli/inspect.py
@@ -5,7 +5,7 @@
 
 from rich.pretty import pprint
 from rich.syntax import Syntax
-from rich.table import Table
+from rich.table import Column, Table
 
 from buildtest.defaults import console
 from buildtest.utils.file import read_file, resolve_path
@@ -150,7 +150,7 @@ def inspect_list(
         row_styles=[consoleColor],
     )
     for column in table.keys():
-        inspect_table.add_column(column)
+        inspect_table.add_column(column, overflow="fold")
 
     for identifier, name, buildspec in zip(
         table["id"], table["name"], table["buildspec"]
@@ -221,7 +221,11 @@ def print_by_query(
                 console.print(f"[red]Log File: {test['logpath']}")
 
                 if test["metrics"]:
-                    table = Table("[blue]Name", "[blue]Value", title="Metrics")
+                    table = Table(
+                        Column("Name", overflow="fold", header_style="blue"),
+                        Column("Value", overflow="fold", header_style="blue"),
+                        title="Metrics",
+                    )
                     for name, values in test["metrics"].items():
                         table.add_row(name, values)
 
diff --git a/buildtest/cli/report.py b/buildtest/cli/report.py
index 2c3f7d61d..1a4099ce3 100644
--- a/buildtest/cli/report.py
+++ b/buildtest/cli/report.py
@@ -4,7 +4,7 @@
 import random
 import sys
 
-from rich.table import Table
+from rich.table import Column, Table
 
 from buildtest.defaults import BUILD_REPORT, BUILDTEST_REPORTS, console
 from buildtest.exceptions import BuildTestError
@@ -27,6 +27,7 @@ def is_int(val):
 
 
 class Report:
+    default_row_count = 50
     # list of format fields
     format_field_description = {
         "buildspec": "Buildspec File",
@@ -130,6 +131,7 @@ def __init__(
         )
         self.pager = pager
         self.color = color
+        self.count = count
         self.input_report = report_file
 
         # if detailed option is specified
@@ -497,7 +499,11 @@ def process_report(self):
 
     def print_format_fields(self):
         """Displays list of format field which implements command ``buildtest report --helpformat``"""
-        table = Table("[blue]Field", "[blue]Description", title="Format Fields")
+        table = Table(
+            Column("Field", overflow="fold", header_style="blue"),
+            Column("Description", overflow="fold", header_style="blue"),
+            title="Format Fields",
+        )
         for field, description in self.format_field_description.items():
             table.add_row(f"[red]{field}", f"[green]{description}")
 
@@ -507,9 +513,9 @@ def print_filter_fields(self):
         """Displays list of help filters which implements command ``buildtest report --helpfilter``"""
 
         table = Table(
-            "[blue]Field",
-            "[blue]Description",
-            "[blue]Expected Value",
+            Column("Field", overflow="fold", header_style="blue"),
+            Column("Description", overflow="fold", header_style="blue"),
+            Column("Expected Value", overflow="fold", header_style="blue"),
             title="Filter Fields",
         )
 
@@ -587,12 +593,16 @@ def print_report(
             root_disk_usage|PASS|0
             root_disk_usage|PASS|0
         """
+        if not self.count:
+            self.count = (
+                self.configuration.target_config["report"].get("count")
+                or self.default_row_count
+            )
+
+        # print_report method can specify count argument instead of calling the Report class which is useful for regression test. Therefore if its specified
+        # in method then use the value
+        self.count = count or self.count
 
-        count = (
-            self.configuration.target_config["report"].get("count")
-            if count is None
-            else count
-        )
         terse = (
             self.configuration.target_config["report"].get("terse")
             if terse is None
@@ -608,11 +618,13 @@ def print_report(
 
             transpose_list = [list(i) for i in zip(*row_entry)]
 
-            if count == 0:
+            if self.count == 0:
                 return
 
             # limited number of rows to be printed in terse mode. If count is negative we print all rows
-            transpose_list = transpose_list[:count] if count > 0 else transpose_list
+            transpose_list = (
+                transpose_list[: self.count] if self.count > 0 else transpose_list
+            )
 
             for row in transpose_list:
                 line = "|".join(row)
@@ -627,11 +639,13 @@ def print_report(
 
             transpose_list = [list(i) for i in zip(*row_entry)]
 
-            if count == 0:
+            if self.count == 0:
                 console.print(table)
                 return
 
-            transpose_list = transpose_list[:count] if count > 0 else transpose_list
+            transpose_list = (
+                transpose_list[: self.count] if self.count > 0 else transpose_list
+            )
             for row in transpose_list:
                 table.add_row(*row)
 
@@ -889,17 +903,13 @@ def report_cmd(args, configuration, report_file=None):
     if pager:
         with console.pager():
             results.print_report(
-                terse=args.terse,
-                noheader=args.no_header,
-                count=args.count,
-                color=consoleColor,
+                terse=args.terse, noheader=args.no_header, color=consoleColor
             )
         return
     results.print_report(
         terse=args.terse,
         row_count=args.row_count,
         noheader=args.no_header,
-        count=args.count,
         color=consoleColor,
     )
 
@@ -915,10 +925,10 @@ def report_summary(report, configuration, detailed=None, color=None):
     test_breakdown = report.breakdown_by_test_names()
 
     table = Table(title="Breakdown by test", header_style=consoleColor)
-    table.add_column("Name", style=consoleColor)
-    table.add_column("Total Pass", style=consoleColor)
-    table.add_column("Total Fail", style=consoleColor)
-    table.add_column("Total Runs", style=consoleColor)
+    table.add_column("Name", overflow="fold", style=consoleColor)
+    table.add_column("Total Pass", overflow="fold", style=consoleColor)
+    table.add_column("Total Fail", overflow="fold", style=consoleColor)
+    table.add_column("Total Runs", overflow="fold", style=consoleColor)
 
     for k in test_breakdown.keys():
         table.add_row(
diff --git a/buildtest/cli/show.py b/buildtest/cli/show.py
index 0712179b3..80a0802bb 100644
--- a/buildtest/cli/show.py
+++ b/buildtest/cli/show.py
@@ -7,8 +7,8 @@ def print_build_show():
     """This method will print help message for command ``buildtest show build``"""
 
     table = Table(title="Building buildspecs", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row("buildtest build -b <file>", "Build a single buildspec file")
     table.add_row(
@@ -38,6 +38,10 @@ def print_build_show():
         "buildtest build -b <file> -xt pass,fail",
         "Build buildspecs by file and exclude tests with tagname 'pass' and 'fail'. Tag names can be specified as comma separated list",
     )
+    table.add_row(
+        "buildtest build --name hello_world --name add_numbers",
+        "Discover buildspecs by test name 'hello_world' and 'add_numbers'",
+    )
     table.add_row(
         "buildtest build -e <executor1> -e <executor2>",
         "Building buildspecs by executor",
@@ -114,8 +118,8 @@ def print_buildspec_show():
     """This method will print help message for command ``buildtest show buildspec``"""
 
     table = Table(title="Finding Buildspecs", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row(
         "buildtest buildspec find",
@@ -182,8 +186,8 @@ def print_buildspec_show():
     console.print(table)
 
     table = Table(title="Validating Buildspecs", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row(
         "buildtest buildspec validate -b <file>",
@@ -205,8 +209,8 @@ def print_buildspec_show():
     console.print(table)
 
     table = Table(title="Additional Features of Buildspecs", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row("buildtest buildspec summary", "Show summary of buildspec cache file")
     table.add_row(
@@ -262,8 +266,8 @@ def print_config_show():
     """This method will print help message for command ``buildtest show config``"""
 
     table = Table(title="Configuring Buildtest", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row("buildtest config view", "View content of configuration file")
     table.add_row(
@@ -276,21 +280,23 @@ def print_config_show():
         "buildtest config edit", "Edit configuration file in your preferred editor"
     )
     table.add_row(
-        "buildtest config executors",
+        "buildtest config executors list",
         "List all executors in flat listing from configuration file",
     )
     table.add_row(
-        "buildtest config executors --yaml",
+        "buildtest config executors list --yaml",
         "Show executor configuration in YAML format",
     )
     table.add_row(
-        "buildtest config executors --json",
+        "buildtest config executors list --json",
         "Show executor configuration in JSON format",
     )
     table.add_row(
-        "buildtest config executors --disabled", "List all disabled executors"
+        "buildtest config executors list --disabled", "List all disabled executors"
+    )
+    table.add_row(
+        "buildtest config executors list --json", "List all invalid executors"
     )
-    table.add_row("buildtest config executors --json", "List all invalid executors")
     table.add_row("buildtest config path", "Show path to configuration file")
     table.add_row(
         "buildtest config systems",
@@ -301,7 +307,7 @@ def print_config_show():
         "Validate configuration file /tmp/config.yml",
     )
     table.add_row(
-        "buildtest config compilers",
+        "buildtest config compilers list",
         "List all compilers from configuration file in flat listing",
     )
     table.add_row(
@@ -316,6 +322,17 @@ def print_config_show():
         "buildtest config compilers test",
         "Test each compiler instance by performing module load test",
     )
+    table.add_row(
+        "buildtest config compilers remove gcc/7.5.0",
+        "Remove compiler instance gcc/7.5.0",
+    )
+    table.add_row(
+        "buildtest config profiles list", "Listing all profiles from configuration file"
+    )
+    table.add_row(
+        "buildtest config profiles remove python",
+        "Remove a profile 'python' from configuration file",
+    )
     console.print(table)
 
 
@@ -323,8 +340,8 @@ def print_inspect_show():
     """This method will print help message for command ``buildtest show inspect``"""
 
     table = Table(title="Inspecting a test", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row(
         "buildtest inspect list",
@@ -369,8 +386,8 @@ def print_report_show():
     """This method will print help message for command ``buildtest show report``"""
 
     table = Table(title="Viewing Test Report", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row("buildtest report", "Display all test results")
     table.add_row("buildtest report --pager", "Paginate output of test results")
@@ -426,8 +443,8 @@ def print_history_show():
     """This method will print help message for command ``buildtest show history``"""
 
     table = Table(title="Editing buildspec", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row("buildtest history list", "List all build history files")
     table.add_row("buildtest history list --terse", "Print output in terse format")
@@ -456,8 +473,8 @@ def print_cdash_show():
     """This method will print help message for command ``buildtest show cdash``"""
 
     table = Table(title="Editing buildspec", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row(
         "buildtest cdash upload DEMO",
@@ -485,8 +502,8 @@ def print_schema_show():
     """This method will print help message for command ``buildtest show schema``"""
 
     table = Table(title="Buildtest Schemas", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row("buildtest schema", "Report all buildtest schema files")
     table.add_row(
@@ -504,8 +521,8 @@ def print_stylecheck_show():
     """This method will print help message for command ``buildtest show stylecheck``"""
 
     table = Table(title="Buildtest stylecheck", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row(
         "buildtest stylecheck",
@@ -525,8 +542,8 @@ def print_unittests_show():
     """This method will print help message for command ``buildtest show unittests``"""
 
     table = Table(title="Buildtest unittests", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row(
         "buildtest unittests", "Run all unittests, tests are executed via pytest"
@@ -552,11 +569,11 @@ def print_unittests_show():
 
 
 def print_path_show():
-    """This method will print help message for command ``buildtest show schema``"""
+    """This method will print help message for command ``buildtest show path``"""
 
     table = Table(title="Get Path to Test", show_lines=False)
-    table.add_column("Command", justify="left", style="cyan")
-    table.add_column("Description", justify="left", style="magenta")
+    table.add_column("Command", justify="left", style="cyan", overflow="fold")
+    table.add_column("Description", justify="left", style="magenta", overflow="fold")
 
     table.add_row(
         "buildtest path circle_area", "Get test root for test name 'circle_area'"
diff --git a/buildtest/defaults.py b/buildtest/defaults.py
index 439856e91..3551e5f77 100644
--- a/buildtest/defaults.py
+++ b/buildtest/defaults.py
@@ -24,8 +24,19 @@
 # dictionary used for storing status of builds
 USER_SETTINGS_FILE = os.path.join(BUILDTEST_USER_HOME, "config.yml")
 
+# default configuration file
+DEFAULT_SETTINGS_FILE = os.path.join(
+    BUILDTEST_ROOT, "buildtest", "settings", "config.yml"
+)
 
 VAR_DIR = os.path.join(BUILDTEST_ROOT, "var")
+ci_dir = os.getenv("BUILDTEST_CI_DIR")
+
+if ci_dir:
+    VAR_DIR = os.path.join(ci_dir, "var")
+    settings_file = os.path.join(ci_dir, "config.yml")
+    DEFAULT_SETTINGS_FILE = settings_file
+
 
 BUILDTEST_LOGFILE = os.path.join(VAR_DIR, "buildtest.log")
 DEFAULT_LOGDIR = os.path.join(VAR_DIR, "logs")
@@ -51,9 +62,6 @@
     os.path.join(BUILDTEST_ROOT, "general_tests"),
 ]
 
-DEFAULT_SETTINGS_FILE = os.path.join(
-    BUILDTEST_ROOT, "buildtest", "settings", "config.yml"
-)
 TUTORIALS_SETTINGS_FILE = os.path.join(
     BUILDTEST_ROOT, "buildtest", "settings", "spack_container.yaml"
 )
diff --git a/buildtest/executors/base.py b/buildtest/executors/base.py
index 602271a6a..2c44a39de 100644
--- a/buildtest/executors/base.py
+++ b/buildtest/executors/base.py
@@ -3,8 +3,11 @@
 """
 
 import logging
+import os
+import time
 
 from buildtest.builders.base import BuilderBase
+from buildtest.defaults import console
 from buildtest.utils.tools import deep_get
 
 
@@ -12,8 +15,11 @@ class BaseExecutor:
     """The BaseExecutor is an abstract base class for all executors."""
 
     type = "base"
+    default_maxpendtime = 86400
 
-    def __init__(self, name, settings, site_configs, timeout=None):
+    def __init__(
+        self, name, settings, site_configs, timeout=None, account=None, maxpendtime=None
+    ):
         """Initiate a base executor, meaning we provide a name (also held
         by the BuildExecutor base that holds it) and the loaded dictionary
         of config opts to parse.
@@ -23,11 +29,14 @@ def __init__(self, name, settings, site_configs, timeout=None):
             setting (dict): setting for a given executor defined in configuration file
             site_configs (buildtest.config.SiteConfiguration): Instance of SiteConfiguration class
             timeout (str, optional): Test timeout in number of seconds
+            maxpendtime (int, optional): Maximum Pending Time until job is cancelled. The default is 1 day (86400s)
+            account (str, optional): Account to use for job submission
+            maxpendtime (int, optional): Maximum Pending Time until job is cancelled. The default is 1 day (86400s)
         """
 
         self._bashopts = "--norc --noprofile -eo pipefail"
         self._shopts = "--norc --noprofile -eo pipefail"
-        self._cshopts = "-e"
+        self._cshopts = "-ef"
         self._zshopts = "-f"
         self.cmd = None
         self.shell = "bash"
@@ -36,9 +45,11 @@ def __init__(self, name, settings, site_configs, timeout=None):
         self._settings = settings
         self._buildtestsettings = site_configs
         self.timeout = timeout
-        self.load()
         self.builders = []
+        self.account = account
+        self.maxpendtime = maxpendtime
 
+        self.load()
         # the shell type for executors will be bash by default
         # self.shell = "bash"
 
@@ -78,6 +89,7 @@ def load(self):
                 "defaults",
                 "maxpendtime",
             )
+            or self.default_maxpendtime
         )
 
     def run(self):
@@ -85,6 +97,79 @@ def run(self):
         so we are sure that the builder is defined. This is also where
         we set the result to return.
         """
+        raise NotImplementedError
+
+    def poll(self, builder):
+        builder.job.poll()
+
+        # if job is complete gather job data
+        if builder.job.is_complete():
+            self.gather(builder)
+            return
+
+        builder.stop()
+
+        if builder.job.is_running():
+            builder.job.elapsedtime = time.time() - builder.job.starttime
+            builder.job.elapsedtime = round(builder.job.elapsedtime, 2)
+            if self._cancel_job_if_elapsedtime_exceeds_timeout(builder):
+                return
+
+        if builder.job.is_suspended() or builder.job.is_pending():
+            if self._cancel_job_if_pendtime_exceeds_maxpendtime(builder):
+                return
+
+        builder.start()
+
+    def gather(self, builder):
+        """Gather Job detail after completion of job by invoking the builder method ``builder.job.gather()``.
+        We retrieve exit code, output file, error file and update builder metadata.
+
+        Args:
+            builder (buildtest.buildsystem.base.BuilderBase): An instance object of BuilderBase type
+        """
+
+        builder.record_endtime()
+
+        builder.metadata["job"] = builder.job.gather()
+        builder.metadata["result"]["returncode"] = builder.job.exitcode()
+
+        self.logger.debug(
+            f"[{builder.name}] returncode: {builder.metadata['result']['returncode']}"
+        )
+
+        builder.metadata["outfile"] = os.path.join(
+            builder.stage_dir, builder.job.output_file()
+        )
+        builder.metadata["errfile"] = os.path.join(
+            builder.stage_dir, builder.job.error_file()
+        )
+        console.print(f"[blue]{builder}[/]: Job {builder.job.get()} is complete! ")
+        builder.post_run_steps()
+
+    def _cancel_job_if_elapsedtime_exceeds_timeout(self, builder):
+        if not self.timeout:
+            return
+
+        # cancel job when elapsed time exceeds the timeout value.
+        if builder.job.elapsedtime > self.timeout:
+            builder.job.cancel()
+            builder.failed()
+            console.print(
+                f"[blue]{builder}[/]: [red]Cancelling Job {builder.job.get()} because job exceeds timeout of {self.timeout} sec with current elapsed time of {builder.job.elapsedtime} sec[/red] "
+            )
+
+    def _cancel_job_if_pendtime_exceeds_maxpendtime(self, builder):
+        builder.job.pendtime = time.time() - builder.job.submittime
+        builder.job.pendtime = round(builder.job.pendtime, 2)
+
+        if builder.job.pendtime > self.maxpendtime:
+            builder.job.cancel()
+            builder.failed()
+            console.print(
+                f"[blue]{builder}[/]: [red]Cancelling Job {builder.job.get()} because job exceeds max pend time of {self.maxpendtime} sec with current pend time of {builder.job.pendtime} sec[/red] "
+            )
+            return
 
     def __str__(self):
         return self.name
diff --git a/buildtest/executors/cobalt.py b/buildtest/executors/cobalt.py
index 20806e817..150d12d66 100644
--- a/buildtest/executors/cobalt.py
+++ b/buildtest/executors/cobalt.py
@@ -33,6 +33,7 @@ def __init__(
         self.account = account
         self.maxpendtime = maxpendtime
         super().__init__(name, settings, site_configs, timeout=timeout)
+
         self.queue = self._settings.get("queue")
 
     def launcher_command(self, numprocs, numnodes):
diff --git a/buildtest/executors/lsf.py b/buildtest/executors/lsf.py
index c33d91d43..e6ca2bc0f 100644
--- a/buildtest/executors/lsf.py
+++ b/buildtest/executors/lsf.py
@@ -29,9 +29,14 @@ class LSFExecutor(BaseExecutor):
     def __init__(
         self, name, settings, site_configs, account=None, maxpendtime=None, timeout=None
     ):
-        self.account = account
-        self.maxpendtime = maxpendtime
-        super().__init__(name, settings, site_configs, timeout=None)
+        super().__init__(
+            name,
+            settings,
+            site_configs,
+            timeout=timeout,
+            account=account,
+            maxpendtime=maxpendtime,
+        )
 
         self.queue = self._settings.get("queue")
 
@@ -75,8 +80,10 @@ def run(self, builder):
 
         cmd = f"bash {self._bashopts} {os.path.basename(builder.build_script)}"
 
-        timeout = self.timeout or self._buildtestsettings.target_config.get("timeout")
-        command = builder.run(cmd, timeout)
+        self.timeout = self.timeout or self._buildtestsettings.target_config.get(
+            "timeout"
+        )
+        command = builder.run(cmd, self.timeout)
 
         if command.returncode() != 0:
             builder.failed()
@@ -113,61 +120,3 @@ def run(self, builder):
         console.print(msg)
 
         return builder
-
-    def poll(self, builder):
-        """Given a builder object we poll the job by invoking builder method ``builder.job.poll()`` return state of job. If
-        job is suspended or pending we stop timer and check if timer exceeds maxpendtime value which could be defined in configuration
-        file or passed via command line ``--max-pend-time``
-
-        Args:
-            builder (buildtest.buildsystem.base.BuilderBase): An instance object of BuilderBase type
-        """
-
-        builder.job.poll()
-
-        # if job is complete gather job data
-        if builder.job.is_complete():
-            self.gather(builder)
-            return
-
-        builder.stop()
-        if builder.job.is_suspended() or builder.job.is_pending():
-            self.logger.debug(f"Time Duration: {builder.duration}")
-            self.logger.debug(f"Max Pend Time: {self.maxpendtime}")
-
-            # if timer time is more than requested pend time then cancel job
-            if int(builder.timer.duration()) > self.maxpendtime:
-                builder.job.cancel()
-                builder.failed()
-                console.print(
-                    f"[blue]{builder}[/]: [red]Cancelling Job {builder.job.get()} because job exceeds max pend time of {self.maxpendtime} sec with current pend time of {builder.timer.duration()} sec[/red] "
-                )
-                return
-
-        builder.start()
-
-    def gather(self, builder):
-        """Gather Job detail after completion of job by invoking the builder method ``builder.job.gather()``.
-        We retrieve exit code, output file, error file and update builder metadata.
-
-        Args:
-            builder (buildtest.buildsystem.base.BuilderBase): An instance object of BuilderBase type
-        """
-
-        builder.record_endtime()
-
-        builder.metadata["job"] = builder.job.gather()
-        builder.metadata["result"]["returncode"] = builder.job.exitcode()
-
-        self.logger.debug(
-            f"[{builder.name}] returncode: {builder.metadata['result']['returncode']}"
-        )
-
-        builder.metadata["outfile"] = os.path.join(
-            builder.stage_dir, builder.job.output_file()
-        )
-        builder.metadata["errfile"] = os.path.join(
-            builder.stage_dir, builder.job.error_file()
-        )
-        console.print(f"[blue]{builder}[/]: Job {builder.job.get()} is complete! ")
-        builder.post_run_steps()
diff --git a/buildtest/executors/pbs.py b/buildtest/executors/pbs.py
index 08f18ff09..d2f60a90f 100644
--- a/buildtest/executors/pbs.py
+++ b/buildtest/executors/pbs.py
@@ -26,9 +26,15 @@ class PBSExecutor(BaseExecutor):
     def __init__(
         self, name, settings, site_configs, account=None, maxpendtime=None, timeout=None
     ):
-        self.maxpendtime = maxpendtime
-        self.account = account
-        super().__init__(name, settings, site_configs, timeout=timeout)
+        super().__init__(
+            name,
+            settings,
+            site_configs,
+            timeout=timeout,
+            account=account,
+            maxpendtime=maxpendtime,
+        )
+
         self.queue = self._settings.get("queue")
 
     def launcher_command(self, numprocs=None, numnodes=None):
@@ -62,15 +68,15 @@ def run(self, builder):
             builder (buildtest.buildsystem.base.BuilderBase): An instance object of BuilderBase type
         """
 
-        self.load()
-
         os.chdir(builder.stage_dir)
 
         cmd = f"bash {self._bashopts} {os.path.basename(builder.build_script)}"
 
-        timeout = self.timeout or self._buildtestsettings.target_config.get("timeout")
+        self.timeout = self.timeout or self._buildtestsettings.target_config.get(
+            "timeout"
+        )
 
-        command = builder.run(cmd, timeout=timeout)
+        command = builder.run(cmd, timeout=self.timeout)
 
         if command.returncode() != 0:
             builder.failed()
@@ -91,60 +97,3 @@ def run(self, builder):
         self.logger.debug(msg)
 
         return builder
-
-    def poll(self, builder):
-        """This method is responsible for polling PBS job which will update the job state. If job is complete we will
-        gather job result. If job is pending we will stop timer and check if pend time exceeds max pend time for executor.
-        If so we will cancel the job.
-
-        Args:
-            builder (buildtest.buildsystem.base.BuilderBase): An instance object of BuilderBase type
-        """
-
-        builder.job.poll()
-
-        # if job is complete gather job data
-        if builder.job.is_complete():
-            self.gather(builder)
-            return
-
-        builder.stop()
-
-        # if job in pending or suspended, check if it exceeds maxpendtime if so cancel job
-        if builder.job.is_pending() or builder.job.is_suspended():
-            self.logger.debug(f"Time Duration: {builder.timer.duration()}")
-            self.logger.debug(f"Max Pend Time: {self.maxpendtime}")
-
-            # if timer time is more than requested pend time then cancel job
-            if int(builder.timer.duration()) > self.maxpendtime:
-                builder.job.cancel()
-                builder.failed()
-                console.print(
-                    f"[blue]{builder}[/]: [red]Cancelling Job {builder.job.get()} because job exceeds max pend time of {self.maxpendtime} sec with current pend time of {builder.timer.duration()} sec[/red] "
-                )
-                console.print(
-                    f"{builder} in job state: {builder.job.state()} and {builder._state}"
-                )
-                return
-
-        builder.start()
-
-    def gather(self, builder):
-        """This method is responsible for gather job results including output and error file and complete metadata
-        for job which is stored in the builder object. We will retrieve job exitcode which corresponds to test
-        returncode.
-
-        Args:
-            builder (buildtest.buildsystem.base.BuilderBase): An instance object of BuilderBase type
-        """
-
-        builder.record_endtime()
-        builder.metadata["job"] = builder.job.gather()
-        builder.metadata["result"]["returncode"] = builder.job.exitcode()
-
-        builder.metadata["outfile"] = builder.job.output_file()
-        builder.metadata["errfile"] = builder.job.error_file()
-
-        console.print(f"[blue]{builder}[/]: Job {builder.job.get()} is complete! ")
-
-        builder.post_run_steps()
diff --git a/buildtest/executors/setup.py b/buildtest/executors/setup.py
index 7d74ec44a..18371becd 100644
--- a/buildtest/executors/setup.py
+++ b/buildtest/executors/setup.py
@@ -10,7 +10,7 @@
 import os
 import time
 
-from rich.table import Table
+from rich.table import Column, Table
 
 from buildtest.builders.base import BuilderBase
 from buildtest.defaults import BUILDTEST_EXECUTOR_DIR, console
@@ -45,6 +45,7 @@ def __init__(
         maxpendtime=None,
         pollinterval=None,
         timeout=None,
+        max_jobs=None,
     ):
         """Initialize executors, meaning that we provide the buildtest
         configuration that are validated, and can instantiate
@@ -55,6 +56,7 @@ def __init__(
             account (str, optional): pass account name to charge batch jobs.
             maxpendtime (int, optional): maximum pend time in second until job is cancelled.
             pollinterval (int, optional): Number of seconds to wait until polling batch jobs
+            max_jobs (int, optional): Maximum number of jobs to run at a time.
         """
 
         # stores a list of builders objects
@@ -83,64 +85,26 @@ def __init__(
         self.executors = {}
         logger.debug("Getting Executors from buildtest settings")
 
-        if site_config.valid_executors["local"]:
-            for name in self.configuration.valid_executors["local"].keys():
-                self.executors[name] = LocalExecutor(
-                    name=name,
-                    settings=self.configuration.valid_executors["local"][name][
-                        "setting"
-                    ],
-                    site_configs=self.configuration,
-                    timeout=timeout,
-                )
-
-        if site_config.valid_executors["slurm"]:
-            for name in self.configuration.valid_executors["slurm"]:
-                self.executors[name] = SlurmExecutor(
-                    name=name,
-                    account=account,
-                    settings=self.configuration.valid_executors["slurm"][name][
-                        "setting"
-                    ],
-                    site_configs=self.configuration,
-                    maxpendtime=maxpendtime,
-                    timeout=timeout,
-                )
-
-        if self.configuration.valid_executors["lsf"]:
-            for name in self.configuration.valid_executors["lsf"]:
-                self.executors[name] = LSFExecutor(
-                    name=name,
-                    account=account,
-                    settings=self.configuration.valid_executors["lsf"][name]["setting"],
-                    site_configs=self.configuration,
-                    maxpendtime=maxpendtime,
-                    timeout=timeout,
-                )
-
-        if self.configuration.valid_executors["pbs"]:
-            for name in self.configuration.valid_executors["pbs"]:
-                self.executors[name] = PBSExecutor(
-                    name=name,
-                    account=account,
-                    settings=self.configuration.valid_executors["pbs"][name]["setting"],
-                    site_configs=self.configuration,
-                    maxpendtime=maxpendtime,
-                    timeout=timeout,
-                )
-
-        if self.configuration.valid_executors["cobalt"]:
-            for name in self.configuration.valid_executors["cobalt"]:
-                self.executors[name] = CobaltExecutor(
+        executor_types = {
+            "local": LocalExecutor,
+            "slurm": SlurmExecutor,
+            "lsf": LSFExecutor,
+            "pbs": PBSExecutor,
+            "cobalt": CobaltExecutor,
+        }
+
+        for executor_type, executor_cls in executor_types.items():
+            valid_executors = self.configuration.valid_executors.get(executor_type, {})
+            for name, executor_settings in valid_executors.items():
+                self.executors[name] = executor_cls(
                     name=name,
                     account=account,
-                    settings=self.configuration.valid_executors["cobalt"][name][
-                        "setting"
-                    ],
+                    settings=executor_settings.get("setting"),
                     site_configs=self.configuration,
                     maxpendtime=maxpendtime,
                     timeout=timeout,
                 )
+        self.max_jobs = max_jobs or self.configuration.target_config.get("max_jobs")
         self.setup()
 
     def __str__(self):
@@ -193,20 +157,23 @@ class **__init__** method.
 
         for executor_name in self.names():
             create_dir(os.path.join(BUILDTEST_EXECUTOR_DIR, executor_name))
-            executor_settings = self.executors[executor_name]._settings
 
             # if before_script field defined in executor section write content to var/executors/<executor>/before_script.sh
             file = os.path.join(
                 BUILDTEST_EXECUTOR_DIR, executor_name, "before_script.sh"
             )
-            module_cmds = get_module_commands(executor_settings.get("module"))
-
-            content = "#!/bin/bash" + "\n"
+            module_cmds = get_module_commands(
+                self.executors[executor_name]._settings.get("module")
+            )
+            content = ["#!/bin/bash"]
 
             if module_cmds:
-                content += "\n".join(module_cmds) + "\n"
+                content += module_cmds
 
-            content += executor_settings.get("before_script") or ""
+            content.append(
+                self.executors[executor_name]._settings.get("before_script") or ""
+            )
+            content = "\n".join(content)
             write_file(file, content)
 
     def select_builders_to_run(self, builders):
@@ -350,12 +317,22 @@ def run(self, builders):
 
             run_builders = self.select_builders_to_run(active_builders)
 
+            # if max_jobs property is set then reduce the number of jobs to run to max_jobs
+            if self.max_jobs:
+                run_builders = run_builders[: self.max_jobs]
+
             if not run_builders:
                 raise BuildTestError("Unable to run tests ")
 
-            print(
-                f"In this iteration we are going to run the following tests: {run_builders}"
+            run_table = Table(
+                Column("Builder", overflow="fold", style="red"),
+                title="Builders Eligible to Run",
+                header_style="blue",
             )
+            for builder in run_builders:
+                run_table.add_row(f"{str(builder)}")
+            console.print(run_table)
+
             results = []
 
             for builder in run_builders:
@@ -436,7 +413,15 @@ def print_job_details(self, active_jobs):
             active_jobs (list): List of builders whose jobs are pending, suspended or running
             completed_jobs (list): List of builders whose jobs are completed
         """
-        table_columns = ["builder", "executor", "jobid", "jobstate", "runtime"]
+        table_columns = [
+            "builder",
+            "executor",
+            "jobid",
+            "jobstate",
+            "runtime",
+            "elapsedtime",
+            "pendtime",
+        ]
         pending_jobs_table = Table(
             title="Pending and Suspended Jobs", header_style="blue"
         )
@@ -444,9 +429,9 @@ def print_job_details(self, active_jobs):
         completed_jobs_table = Table(title="Completed Jobs", header_style="blue")
 
         for column in table_columns:
-            pending_jobs_table.add_column(column)
-            running_jobs_table.add_column(column)
-            completed_jobs_table.add_column(column)
+            pending_jobs_table.add_column(column, overflow="fold")
+            running_jobs_table.add_column(column, overflow="fold")
+            completed_jobs_table.add_column(column, overflow="fold")
 
         for builder in active_jobs:
             if builder.job.is_pending() or builder.job.is_suspended():
@@ -456,6 +441,8 @@ def print_job_details(self, active_jobs):
                     f"[red]{builder.job.get()}",
                     f"[cyan]{builder.job.state()}",
                     f"[magenta]{str(builder.timer.duration())}",
+                    f"[yellow]{str(builder.job.elapsedtime)}",
+                    f"[yellow]{str(builder.job.pendtime)}",
                 )
 
             if builder.job.is_running():
@@ -465,6 +452,8 @@ def print_job_details(self, active_jobs):
                     f"[red]{builder.job.get()}",
                     f"[cyan]{builder.job.state()}",
                     f"[magenta]{str(builder.timer.duration())}",
+                    f"[yellow]{str(builder.job.elapsedtime)}",
+                    f"[yellow]{str(builder.job.pendtime)}",
                 )
 
             if builder.job.is_complete():
@@ -474,6 +463,8 @@ def print_job_details(self, active_jobs):
                     f"[red]{builder.job.get()}",
                     f"[cyan]{builder.job.state()}",
                     f"[magenta]{str(builder.metadata['result']['runtime'])}",
+                    f"[yellow]{str(builder.job.elapsedtime)}",
+                    f"[yellow]{str(builder.job.pendtime)}",
                 )
 
         # only print table if there are rows in table
diff --git a/buildtest/executors/slurm.py b/buildtest/executors/slurm.py
index 3c4d5220a..0c26b4d0e 100644
--- a/buildtest/executors/slurm.py
+++ b/buildtest/executors/slurm.py
@@ -29,9 +29,14 @@ class SlurmExecutor(BaseExecutor):
     def __init__(
         self, name, settings, site_configs, account=None, maxpendtime=None, timeout=None
     ):
-        self.maxpendtime = maxpendtime
-        self.account = account
-        super().__init__(name, settings, site_configs, timeout=timeout)
+        super().__init__(
+            name,
+            settings,
+            site_configs,
+            timeout=timeout,
+            account=account,
+            maxpendtime=maxpendtime,
+        )
 
         self.cluster = self._settings.get("cluster")
         self.partition = self._settings.get("partition")
@@ -72,15 +77,15 @@ def run(self, builder):
             builder (buildtest.buildsystem.base.BuilderBase): An instance object of BuilderBase type
         """
 
-        self.result = {}
-
         os.chdir(builder.stage_dir)
         self.logger.debug(f"Changing to directory {builder.stage_dir}")
 
         cmd = f"bash {self._bashopts} {os.path.basename(builder.build_script)}"
 
-        timeout = self.timeout or self._buildtestsettings.target_config.get("timeout")
-        command = builder.run(cmd, timeout)
+        self.timeout = self.timeout or self._buildtestsettings.target_config.get(
+            "timeout"
+        )
+        command = builder.run(cmd, self.timeout)
 
         if command.returncode() != 0:
             builder.failed()
@@ -105,40 +110,6 @@ def run(self, builder):
 
         return builder
 
-    def poll(self, builder):
-        """This method is called during poll stage where we invoke ``builder.job.poll()`` to get updated
-        job state. If job is pending or suspended we stop timer and check if job needs to be cancelled if
-        time exceeds ``maxpendtime`` value.
-
-        Args:
-            builder (buildtest.buildsystem.base.BuilderBase): An instance object of BuilderBase type
-        """
-
-        builder.job.poll()
-
-        # if job is complete gather job data
-        if builder.job.complete():
-            self.gather(builder)
-            return
-
-        builder.stop()
-
-        # if job state in PENDING check if we need to cancel job by checking internal timer
-        if builder.job.is_pending() or builder.job.is_suspended():
-            self.logger.debug(f"Time Duration: {builder.duration}")
-            self.logger.debug(f"Max Pend Time: {self.maxpendtime}")
-
-            # if timer exceeds 'maxpendtime' then cancel job
-            if int(builder.timer.duration()) > self.maxpendtime:
-                builder.job.cancel()
-                builder.failed()
-                console.print(
-                    f"[blue]{builder}[/]: [red]Cancelling Job {builder.job.get()} because job exceeds max pend time of {self.maxpendtime} sec with current pend time of {builder.timer.duration()} sec[/red] "
-                )
-                return
-
-        builder.start()
-
     def gather(self, builder):
         """Gather Slurm job data after job completion. In this step we call ``builder.job.gather()``,
         and update builder metadata such as returncode, output and error file.
diff --git a/buildtest/main.py b/buildtest/main.py
index a58bbeafa..472550a2a 100644
--- a/buildtest/main.py
+++ b/buildtest/main.py
@@ -2,11 +2,12 @@
 
 import os
 import shutil
+import tempfile
 import webbrowser
 
 from rich.traceback import install
 
-from buildtest.cli import get_parser
+from buildtest.cli import BuildTestParser
 from buildtest.cli.build import BuildTest, Tee
 from buildtest.cli.buildspec import (
     BuildspecCache,
@@ -47,7 +48,6 @@
     BUILDTEST_EXECUTOR_DIR,
     BUILDTEST_LOGFILE,
     BUILDTEST_USER_HOME,
-    VAR_DIR,
     console,
 )
 from buildtest.exceptions import BuildTestError
@@ -70,9 +70,8 @@
 def main():
     """Entry point to buildtest."""
 
-    parser = get_parser()
-    args = parser.parse_args()
-
+    parser = BuildTestParser()
+    args = parser.parse()
     install(show_locals=True)
     no_color = False
 
@@ -144,15 +143,15 @@ def main():
 
     # buildtest build command
     if args.subcommands in ["build", "bd"]:
-        fname = os.path.join(VAR_DIR, "output.txt")
-
-        with Tee(fname):
+        stdout_file = tempfile.NamedTemporaryFile(delete=True, suffix=".txt")
+        with Tee(stdout_file.name):
             cmd = BuildTest(
                 configuration=configuration,
                 buildspecs=args.buildspec,
                 exclude_buildspecs=args.exclude,
                 executors=args.executor,
                 tags=args.tags,
+                name=args.name,
                 exclude_tags=args.exclude_tags,
                 filter_buildspecs=args.filter,
                 rebuild=args.rebuild,
@@ -177,13 +176,18 @@ def main():
                 limit=args.limit,
                 save_profile=args.save_profile,
                 profile=args.profile,
+                max_jobs=args.max_jobs,
             )
             cmd.build()
 
         if cmd.build_success():
             build_history_dir = cmd.get_build_history_dir()
 
-            shutil.move(fname, os.path.join(build_history_dir, "output.txt"))
+            shutil.copyfile(
+                stdout_file.name, os.path.join(build_history_dir, "output.txt")
+            )
+
+        stdout_file.close()
 
     # buildtest build history
     if args.subcommands in ["history", "hy"]:
@@ -373,8 +377,8 @@ def main():
             apply_stylechecks=args.apply,
         )
 
-    elif args.subcommands in ["commands", "cmd"]:
-        list_buildtest_commands()
+    elif args.subcommands in ["commands", "cmds"]:
+        list_buildtest_commands(with_aliases=args.with_aliases)
 
 
 if __name__ == "__main__":
diff --git a/buildtest/scheduler/job.py b/buildtest/scheduler/job.py
index d58cc9631..fd0295904 100644
--- a/buildtest/scheduler/job.py
+++ b/buildtest/scheduler/job.py
@@ -1,3 +1,6 @@
+import time
+
+
 class Job:
     """This is a base class for holding job level data and common methods for used
     for batch job submission."""
@@ -5,6 +8,17 @@ class Job:
     def __init__(self, jobID):
         self.jobid = jobID
         self._state = None
+        # used to store the job elapsed time
+        self.elapsedtime = 0
+
+        # used for job pending time
+        self.pendtime = 0
+
+        # time when job was submitted
+        self.submittime = time.time()
+
+        # time when job was started
+        self.starttime = None
 
     def state(self):
         """Return job state"""
diff --git a/buildtest/scheduler/lsf.py b/buildtest/scheduler/lsf.py
index d4f954b99..54ece37b7 100644
--- a/buildtest/scheduler/lsf.py
+++ b/buildtest/scheduler/lsf.py
@@ -1,5 +1,6 @@
 import json
 import logging
+import time
 
 from buildtest.scheduler.job import Job
 from buildtest.utils.command import BuildTestCommand
@@ -89,6 +90,10 @@ def poll(self):
 
         logger.debug(f"Exit Code: {self._exitcode}")
 
+        # if job is running and the start time is not recorded then we record the start time
+        if self.is_running() and not self.starttime:
+            self.starttime = time.time()
+
     def gather(self):
         """This method will retrieve the output and error file for a given jobID using the following commands.
 
diff --git a/buildtest/scheduler/pbs.py b/buildtest/scheduler/pbs.py
index fd6d51ce5..87d527d73 100644
--- a/buildtest/scheduler/pbs.py
+++ b/buildtest/scheduler/pbs.py
@@ -1,5 +1,6 @@
 import json
 import logging
+import time
 
 from buildtest.scheduler.job import Job
 from buildtest.utils.command import BuildTestCommand
@@ -130,6 +131,10 @@ def poll(self):
         # The Exit_status property will be available when job is finished
         self._exitcode = job_data["Jobs"][self.jobid].get("Exit_status")
 
+        # if job is running and the start time is not recorded then we record the start time
+        if self.is_running() and not self.starttime:
+            self.starttime = time.time()
+
     def gather(self):
         """This method is called once job is complete. We will gather record of job by running
         ``qstat -x -f -F json <jobid>`` and return the json object as a dict.  This method is responsible
diff --git a/buildtest/scheduler/slurm.py b/buildtest/scheduler/slurm.py
index fdf9927a3..273aa714b 100644
--- a/buildtest/scheduler/slurm.py
+++ b/buildtest/scheduler/slurm.py
@@ -1,4 +1,5 @@
 import logging
+import time
 
 from buildtest.scheduler.job import Job
 from buildtest.utils.command import BuildTestCommand
@@ -126,13 +127,26 @@ def poll(self):
         if self.cluster:
             query += f" --clusters={self.cluster}"
 
-        cmd = BuildTestCommand(query)
-        cmd.execute()
+        # there is a delay when test is run until slurm can query job via 'sacct'. This is relevant when using
+        # 1 sec pollinterval. The sacct query will not return the job state so we sleep and try until we get value
+        while True:
+            cmd = BuildTestCommand(query)
+            cmd.execute()
+
+            logger.debug(f"Querying JobID: '{self.jobid}' by running: '{query}'")
+            output = cmd.get_output()
+            self._state = "".join(output).rstrip()
+
+            if self._state:
+                logger.debug(f"JobID: '{self.jobid}' Job State: {self._state}")
+                break
+            logger.debug(
+                f"Unable to get job state for JobID: '{self.jobid}' so trying again"
+            )
+            time.sleep(0.1)
 
-        logger.debug(f"Querying JobID: '{self.jobid}'  Job State by running: '{query}'")
-        job_state = cmd.get_output()
-        self._state = "".join(job_state).rstrip()
-        logger.debug(f"JobID: '{self.jobid}' job state:{self._state}")
+        if self.is_running() and not self.starttime:
+            self.starttime = time.time()
 
     def gather(self):
         """Gather job record which is called after job completion. We use `sacct` to gather
@@ -146,6 +160,7 @@ def gather(self):
             - "ConsumedEnergyRaw"
             - "CPUTimeRaw"
             - "Elapsed"
+            - "ElapsedRaw"
             - "End"
             - "ExitCode"
             - "JobID"
@@ -186,6 +201,7 @@ def gather(self):
             "ConsumedEnergyRaw",
             "CPUTimeRaw",
             "Elapsed",
+            "ElapsedRaw",
             "End",
             "ExitCode",
             "JobID",
diff --git a/buildtest/schemas/examples/settings.schema.json/valid/local-executor.yml b/buildtest/schemas/examples/settings.schema.json/valid/local-executor.yml
index a6a808988..584c17dd6 100644
--- a/buildtest/schemas/examples/settings.schema.json/valid/local-executor.yml
+++ b/buildtest/schemas/examples/settings.schema.json/valid/local-executor.yml
@@ -5,6 +5,8 @@ system:
     #testdir: $BUILDTEST_ROOT/tests
     moduletool: N/A
     poolsize: 1
+    max_jobs: 1
+    pager: False
     cdash:
       url: https://my.cdash.org
       project: buildtest
diff --git a/buildtest/schemas/examples/spack.schema.json/invalid/spack_env_deactivate.yml b/buildtest/schemas/examples/spack.schema.json/invalid/spack_env_deactivate.yml
new file mode 100644
index 000000000..ce0547478
--- /dev/null
+++ b/buildtest/schemas/examples/spack.schema.json/invalid/spack_env_deactivate.yml
@@ -0,0 +1,21 @@
+buildspecs:
+  spack_env_deactivate_first:
+    type: spack
+    executor: generic.local.bash
+    description: "deactivate a spack environment first prior to activating it"
+    tags: [spack]
+    spack:
+      root: $HOME/spack
+      env:
+        create:
+          dir: $HOME/spack-envs/m4
+        deactivate: 2.0
+        activate:
+          dir: $HOME/spack-envs/m4
+        specs:
+          - 'm4'
+      install:
+        option: ''
+    post_cmds: |
+      spack find
+      rm -rf $HOME/spack-envs/m4
diff --git a/buildtest/schemas/examples/spack.schema.json/invalid/spack_load_invalid_example.yml b/buildtest/schemas/examples/spack.schema.json/invalid/spack_load_invalid_example.yml
new file mode 100644
index 000000000..fb2d9a215
--- /dev/null
+++ b/buildtest/schemas/examples/spack.schema.json/invalid/spack_load_invalid_example.yml
@@ -0,0 +1,16 @@
+buildspecs:
+  spack_load_invalid_example:
+    type: spack
+    executor: generic.local.bash
+    description: "Run spack load for m4 package and run tests"
+    tags: [spack]
+    spack:
+      root: $HOME/spack
+      load:
+        options: '--only package'
+        specs: [1.5]
+      test:
+        run:
+          specs: ['m4']
+        results:
+          option: "-l"
diff --git a/buildtest/schemas/examples/spack.schema.json/valid/spack_env_deactivate.yml b/buildtest/schemas/examples/spack.schema.json/valid/spack_env_deactivate.yml
new file mode 100644
index 000000000..e0e1b7460
--- /dev/null
+++ b/buildtest/schemas/examples/spack.schema.json/valid/spack_env_deactivate.yml
@@ -0,0 +1,21 @@
+buildspecs:
+  spack_env_deactivate_first:
+    type: spack
+    executor: generic.local.bash
+    description: "deactivate a spack environment first prior to activating it"
+    tags: [spack]
+    spack:
+      root: $HOME/spack
+      env:
+        create:
+          dir: $HOME/spack-envs/m4
+        deactivate: true
+        activate:
+          dir: $HOME/spack-envs/m4
+        specs:
+          - 'm4'
+      install:
+        option: ''
+    post_cmds: |
+      spack find
+      rm -rf $HOME/spack-envs/m4
diff --git a/buildtest/schemas/examples/spack.schema.json/valid/spack_load_valid_example.yml b/buildtest/schemas/examples/spack.schema.json/valid/spack_load_valid_example.yml
new file mode 100644
index 000000000..b25a39fb6
--- /dev/null
+++ b/buildtest/schemas/examples/spack.schema.json/valid/spack_load_valid_example.yml
@@ -0,0 +1,16 @@
+buildspecs:
+  spack_load_valid_example:
+    type: spack
+    executor: generic.local.bash
+    description: "Run spack load for m4 package and run tests"
+    tags: [spack]
+    spack:
+      root: $HOME/spack
+      load:
+        options: '--only package'
+        specs: [m4]
+      test:
+        run:
+          specs: ['m4']
+        results:
+          option: "-l"
diff --git a/buildtest/schemas/settings.schema.json b/buildtest/schemas/settings.schema.json
index 0815bf2ee..2f0915751 100644
--- a/buildtest/schemas/settings.schema.json
+++ b/buildtest/schemas/settings.schema.json
@@ -61,6 +61,11 @@
           "minimum": 1,
           "description": "Specify size of Process Pool for parallel processing using ``multiprocessing.Pool``"
         },
+        "max_jobs": {
+            "type": "integer",
+            "minimum": 1,
+            "description": "Maximum number of jobs that can be run at a given time for a particular executor"
+        },
         "testdir": {
           "type": "string",
           "description": "Specify full path to test directory where buildtest will write tests."
@@ -294,8 +299,7 @@
                   },
                   "account": {
                     "$ref": "#/definitions/account"
-                  },
-                  "max_jobs": {"$ref":  "#/definitions/max_jobs"}
+                  }
                 }
               },
               "local": {
@@ -393,11 +397,6 @@
       "type": "string",
       "description": "Specify path to Fortran compiler wrapper. You may specify a compiler wrapper such as ``gfortran`` assuming its in $PATH or you can use ``modules`` property to resolve path to compiler wrapper."
     },
-    "max_jobs": {
-      "description": "Maximum number of jobs that can be run at a given time for a particular executor",
-      "type": "integer",
-      "minimum": 1
-    },
     "compiler_section": {
       "description": "A compiler section is composed of ``cc``, ``cxx`` and ``fc`` wrapper these are required when you need to specify compiler wrapper.",
       "type": "object",
@@ -474,7 +473,6 @@
           "description": "Specify the shell launcher you want to use when running tests locally"
         },
         "before_script": { "#ref": "#/definitions/script" },
-        "max_jobs": {"$ref":  "#/definitions/max_jobs"},
         "disable": {"$ref":  "#/definitions/disable"},
         "module": { "$ref": "#/definitions/module" }
       }
@@ -522,7 +520,6 @@
           "description": "overrides default ``account`` value",
           "$ref": "#/definitions/account"
         },
-        "max_jobs": {"$ref":  "#/definitions/max_jobs"},
         "disable": {"$ref":  "#/definitions/disable"},
         "module": { "$ref": "#/definitions/module" }
       }
@@ -563,7 +560,6 @@
           "description": "overrides default ``account`` value",
           "$ref": "#/definitions/account"
         },
-        "max_jobs": {"$ref":  "#/definitions/max_jobs"},
         "disable": {"$ref":  "#/definitions/disable"},
         "module": { "$ref": "#/definitions/module" }
       }
@@ -604,7 +600,6 @@
           "description": "overrides default ``account`` value",
           "$ref": "#/definitions/account"
         },
-        "max_jobs": {"$ref":  "#/definitions/max_jobs"},
         "disable": {"$ref":  "#/definitions/disable"},
         "module": { "$ref": "#/definitions/module" }
       }
@@ -645,7 +640,6 @@
           "description": "overrides default ``account`` value",
           "$ref": "#/definitions/account"
         },
-        "max_jobs": {"$ref":  "#/definitions/max_jobs"},
         "disable": {"$ref":  "#/definitions/disable"},
         "module": { "$ref": "#/definitions/module" }
       }
@@ -686,20 +680,22 @@
         "module": {"type": "string"},
         "unload-modules": {"type": "string"},
         "module-purge": {"type": "boolean"},
-        "rebuild": {"type": "integer", "minimum": 1, "maximum": 50},
-        "limit": {"type": "integer", "minimum": 1},
+        "rebuild": {"type": "integer", "minimum": 1, "maximum": 50, "description": "Specify number of tests to rebuild"},
+        "limit": {"type": "integer", "minimum": 1, "description": "Limit number of tests to build"},
         "account": {"type": "string"},
-        "maxpendtime": {"type": "integer", "minimum": 1},
-        "pollinterval": {"type": "integer", "minimum": 1},
+        "maxpendtime": {"type": "integer", "minimum": 1, "description": "Specify maximum pending time in seconds"},
+        "pollinterval": {"type": "integer", "minimum": 1, "description": "Specify poll interval in seconds"},
         "procs": {"$ref": "definitions.schema.json#/definitions/list_of_positive_integers"},
         "nodes": {"$ref": "definitions.schema.json#/definitions/list_of_positive_integers"},
-        "testdir": {"type": "string"},
+        "testdir": {"type": "string", "description": "Specify test directory where buildtest will write tests."},
         "timeout": {"type": "integer", "minimum": 1},
         "executor-type": {
           "type": "string",
           "description": "Specify the `executor-type` field used by ``--executor-type`` option which determines if test will run by local or batch executor",
           "enum": ["local", "batch"]
-        }
+        },
+        "remove-stagedir": {"type": "boolean", "description": "Remove stage directory after test completes"},
+        "max-jobs": {"type": "integer", "minimum": 1, "description": "Maximum number of jobs that can be run at a given time for a particular executor"}
       }
     }
   }
diff --git a/buildtest/schemas/spack.schema.json b/buildtest/schemas/spack.schema.json
index 2ab7b1fab..c141cf711 100644
--- a/buildtest/schemas/spack.schema.json
+++ b/buildtest/schemas/spack.schema.json
@@ -68,6 +68,10 @@
           "$ref": "#definitions/install",
           "description": "Install spack packages by running ``spack install``. "
         },
+        "load": {
+          "$ref": "#definitions/load",
+          "description": "load spack packages by running ``spack load`` "
+        },
         "verify_spack": {
           "type": "boolean",
           "description": "This boolean will determine if we need to check for file existence where spack is cloned via ``root`` property and file **$SPACK_ROOT/share/spack/setup-env.sh** exists. These checks can be disabled by setting this to ``False`` which can be useful if you dont want buildtest to raise exception during test generation process and test is skipped.",
@@ -114,6 +118,10 @@
             }
           }
         },
+        "deactivate": {
+          "type": "boolean",
+          "description": "Deactivate a spack environment prior to activating it via ``spack env deactivate``"
+        },
         "activate": {
           "additionalProperties": false,
           "type": "object",
@@ -176,6 +184,21 @@
         }
       }
     },
+    "load": {
+      "description": "load spack packages using ``spack load`` command",
+
+      "type": "object",
+      "properties": {
+        "options": {
+          "type": "string",
+          "description": "Pass options to ``spack load`` command"
+        },
+        "specs": {
+          "$ref": "definitions.schema.json#/definitions/list_of_strings",
+          "description": "List of specs to install using ``spack load`` command"
+        }
+      }
+    },
     "test": {
       "type": "object",
       "additionalProperties": false,
diff --git a/buildtest/settings/config.yml b/buildtest/settings/config.yml
index f56549b7b..cb24679c6 100644
--- a/buildtest/settings/config.yml
+++ b/buildtest/settings/config.yml
@@ -1,45 +1,50 @@
 system:
   generic:
-    # specify list of hostnames where buildtest can run for given system record
-    hostnames: [".*"]
-
+    # specify a list of hostnames that is a regular expression where buildtest can run.
+    hostnames: ['.*']
     # system description
     description: Generic System
-    # specify module system used at your site (environment-modules, lmod)
+    # specify module system to use. Supported module systems are lmod, environment-modules or set to N/A if not available
     moduletool: N/A
 
-    # specify test timeout duration in number of seconds
-    # timeout: 60
-
-    # pool size for parallel processing using multiprocessing.Pool. Pool Size must be 1 or higher. The pool size is calculated as follows: poolsize = min(poolsize, os.cpu_count())
+    # specify size of job pool (https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.Pool). This will configure the number of processes that can run in parallel.
+    # If not specified then buildtest will use all available cores on the system.
     poolsize: 1
 
-    # determine whether to enable pagination
-    pager: False
+    # maximum number of jobs that can run in parallel. If not specified, buildtest will run all jobs in parallel.
+    #max_jobs: 1
+
+    # test timeout in number of seconds
+    # timeout: 3600
 
+    # enable pagination for buildtest
+    pager: false
+
+    # options for buildtest buildspec find command
     buildspecs:
-      # whether to rebuild cache file automatically when running `buildtest buildspec find`
-      rebuild: False
-      # limit number of records to display when running `buildtest buildspec find`
+      # determine whether to rebuild buildspec cache
+      rebuild: false
+      # determine number of records to display
       count: 15
-      # format fields to display when running `buildtest buildspec find`, By default we will show name,description
-      format: "name,description"
-      # enable terse mode
-      terse: False
-      # specify list of directories to search for buildspecs when building cache
-      #root: [ $BUILDTEST_ROOT/examples, /tmp/buildspecs ]
+      # specify format fields
+      format: name,description
+      # display output in terse mode
+      terse: false
+
+    # options for buildtest report command
     report:
+      # number of records to display
       count: 25
-      #enable terse mode for report
-      terse: False
-      format: "name,id,state,runtime,returncode"
-      # show the latest for every test
-      latest: True
-      # show the oldest for every test
-      oldest: False
+      # display output in terse mode
+      terse: false
+      # specify format fields
+      format: name,id,state,runtime,returncode
+      # show latest test run
+      latest: false
+      # show oldest test run
+      oldest: false
 
     executors:
-      # define local executors for running jobs locally
       local:
         bash:
           description: submit jobs on local machine using bash shell
@@ -53,39 +58,20 @@ system:
         zsh:
           description: submit jobs on local machine using zsh shell
           shell: zsh
-    # compiler block
     compilers:
-      # a list of directories to search for modules
-      # modulepath: ['/tmp', '/var/']
-
-      # regular expression to search for compilers based on module pattern. Used with 'buildtest config compilers find' to generate compiler instance
-      # find:
-      #  gcc: "^(gcc)"
-      #  intel: "^(intel)"
-      #  cray: "^(craype)"
-      #  pgi: "^(pgi)"
-      #  cuda: ^(cuda)"
-      #  clang: "^(clang)"
-
-      # declare compiler instance which can be site-specific. You can let 'buildtest config compilers find' generate compiler section
       compiler:
         gcc:
           builtin_gcc:
             cc: gcc
             fc: gfortran
             cxx: g++
-
-    # location of log directory
-    # logdir: /tmp/
-
-    # specify location where buildtest will write tests
-    # testdir: /tmp
-
-    # specify one or more directory where buildtest should load buildspecs
-    # buildspec_roots: []
-
+    # specify CDASH configuration when using 'buildtest cdash upload'
     cdash:
+      # CDASH server
       url: https://my.cdash.org/
+      # name of CDASH project where to push test reports
       project: buildtest
+      # specify the site name which should generally by name of your HPC system. This is used by CDASH to group test results by site
       site: generic
+      # specify the build name which is used to group test results by build name
       buildname: tutorials
diff --git a/buildtest/tools/docs.py b/buildtest/tools/docs.py
index 9f60d1ecf..ad7b6b007 100644
--- a/buildtest/tools/docs.py
+++ b/buildtest/tools/docs.py
@@ -72,25 +72,29 @@ def build_spack_examples(autogen_dir):
         f"{build_dir}/env_create_directory.txt": f"buildtest build -b {SPACK_EXAMPLE_DIR}/env_create_directory.yml",
         f"{build_dir}/env_create_manifest.txt": f"buildtest build -b {SPACK_EXAMPLE_DIR}/env_create_manifest.yml",
         f"{build_dir}/remove_environment_example.txt": f"buildtest build -b {SPACK_EXAMPLE_DIR}/remove_environment_example.yml",
+        f"{build_dir}/spack_env_deactivate.txt": f"buildtest build -b {SPACK_EXAMPLE_DIR}/spack_env_deactivate.yml",
         f"{build_dir}/pre_post_cmds.txt": f"buildtest build -b {SPACK_EXAMPLE_DIR}/pre_post_cmds.yml",
         f"{build_dir}/mirror_example.txt": f"buildtest build -b {SPACK_EXAMPLE_DIR}/mirror_example.yml",
+        f"{build_dir}/spack_load.txt": f"buildtest build -b {SPACK_EXAMPLE_DIR}/spack_load.yml",
         f"{build_dir}/spack_test.txt": f"buildtest build -b {SPACK_EXAMPLE_DIR}/spack_test.yml",
         f"{build_dir}/spack_test_specs.txt": f"buildtest build -b {SPACK_EXAMPLE_DIR}/spack_test_specs.yml",
         f"{build_dir}/spack_sbatch.txt": f"buildtest build -b {SPACK_EXAMPLE_DIR}/spack_sbatch.yml",
         f"{build_dir}/e4s_testsuite_mpich.txt": f"buildtest build -b {SPACK_EXAMPLE_DIR}/e4s_testsuite_mpich.yml",
         f"{build_dir}/clone_spack.txt": f"buildtest build -b {SPACK_EXAMPLE_DIR}/clone_spack.yml",
-        f"{inspect_dir}/install_specs.txt": "buildtest inspect query -o --testpath install_specs_example",
-        f"{inspect_dir}/env_install.txt": "buildtest inspect query --testpath install_in_spack_env",
-        f"{inspect_dir}/env_create_directory.txt": "buildtest inspect query -o --testpath spack_env_directory",
-        f"{inspect_dir}/env_create_manifest.txt": "buildtest inspect query -o --testpath spack_env_create_from_manifest",
-        f"{inspect_dir}/remove_environment_example.txt": "buildtest inspect query --testpath remove_environment_automatically remove_environment_explicit",
-        f"{inspect_dir}/pre_post_cmds.txt": "buildtest inspect query -o --testpath run_pre_post_commands",
-        f"{inspect_dir}/mirror_example.txt": "buildtest inspect query -o  --testpath add_mirror add_mirror_in_spack_env",
-        f"{inspect_dir}/spack_test.txt": "buildtest inspect query -o --testpath spack_test_m4",
-        f"{inspect_dir}/spack_test_specs.txt": "buildtest inspect query -o --testpath spack_test_results_specs_format",
-        f"{inspect_dir}/spack_sbatch.txt": "buildtest inspect query --testpath spack_sbatch_example",
-        f"{inspect_dir}/clone_spack.txt": "buildtest inspect query -o --testpath clone_spack_automatically clone_spack_and_specify_root",
-        f"{inspect_dir}/e4s_testsuite_mpich.txt": "buildtest inspect query -o -e --testpath mpich_e4s_testsuite",
+        f"{inspect_dir}/install_specs.txt": "buildtest inspect query -o -t install_specs_example",
+        f"{inspect_dir}/env_install.txt": "buildtest inspect query -t install_in_spack_env",
+        f"{inspect_dir}/env_create_directory.txt": "buildtest inspect query -o -t spack_env_directory",
+        f"{inspect_dir}/env_create_manifest.txt": "buildtest inspect query -o -t spack_env_create_from_manifest",
+        f"{inspect_dir}/spack_env_deactivate.txt": "buildtest inspect query -t spack_env_deactivate_first",
+        f"{inspect_dir}/remove_environment_example.txt": "buildtest inspect query -t remove_environment_automatically remove_environment_explicit",
+        f"{inspect_dir}/pre_post_cmds.txt": "buildtest inspect query -o -t run_pre_post_commands",
+        f"{inspect_dir}/mirror_example.txt": "buildtest inspect query -o  -t add_mirror add_mirror_in_spack_env",
+        f"{inspect_dir}/spack_load.txt": "buildtest inspect query -t spack_load_example",
+        f"{inspect_dir}/spack_test.txt": "buildtest inspect query -o -t spack_test_m4",
+        f"{inspect_dir}/spack_test_specs.txt": "buildtest inspect query -o -t spack_test_results_specs_format",
+        f"{inspect_dir}/spack_sbatch.txt": "buildtest inspect query -t spack_sbatch_example",
+        f"{inspect_dir}/clone_spack.txt": "buildtest inspect query -o -t clone_spack_automatically clone_spack_and_specify_root",
+        f"{inspect_dir}/e4s_testsuite_mpich.txt": "buildtest inspect query -o -e -t mpich_e4s_testsuite",
     }
 
     for fname, command in commands_to_run.items():
@@ -114,24 +118,24 @@ def build_compiler_examples(autogen_dir):
     COMPILER_EXAMPLE_DIR = os.path.join(BUILDTEST_ROOT, "examples", "compilers")
     commands_to_run = {
         f"{build_dir}/gnu_hello_fortran.txt": f"buildtest build -b {COMPILER_EXAMPLE_DIR}/gnu_hello_fortran.yml",
-        f"{inspect_dir}/gnu_hello_fortran.txt": "buildtest inspect query --testpath hello_f",
+        f"{inspect_dir}/gnu_hello_fortran.txt": "buildtest inspect query -t hello_f",
         f"{compiler_dir}/compilers_list.txt": "buildtest config compilers -y",
         f"{build_dir}/vecadd.txt": f"buildtest build -b {COMPILER_EXAMPLE_DIR}/vecadd.yml",
         f"{build_dir}/gnu_hello_c.txt": f"buildtest build -b {COMPILER_EXAMPLE_DIR}/gnu_hello_c.yml",
-        f"{inspect_dir}/gnu_hello_c.txt": "buildtest inspect query --testpath hello_c/",
+        f"{inspect_dir}/gnu_hello_c.txt": "buildtest inspect query -t hello_c/",
         f"{build_dir}/compiler_exclude.txt": f"buildtest build -b {COMPILER_EXAMPLE_DIR}/compiler_exclude.yml",
         f"{build_dir}/openmp_hello.txt": f"buildtest build -b {COMPILER_EXAMPLE_DIR}/openmp_hello.yml",
-        f"{inspect_dir}/openmp_hello.txt": "buildtest inspect query --testpath openmp_hello_c_example",
+        f"{inspect_dir}/openmp_hello.txt": "buildtest inspect query -t openmp_hello_c_example",
         f"{build_dir}/envvar_override.txt": f"buildtest build -b {COMPILER_EXAMPLE_DIR}/envvar_override.yml",
-        f"{inspect_dir}/envvar_override.txt": "buildtest inspect query --testpath override_environmentvars/",
+        f"{inspect_dir}/envvar_override.txt": "buildtest inspect query -t override_environmentvars/",
         f"{build_dir}/compiler_status_regex.txt": f"buildtest build -b {COMPILER_EXAMPLE_DIR}/compiler_status_regex.yml",
         f"{inspect_dir}/compiler_status_regex.txt": "buildtest inspect query -o override_status_regex/",
         f"{build_dir}/custom_run.txt": f"buildtest build -b {COMPILER_EXAMPLE_DIR}/custom_run.yml",
-        f"{inspect_dir}/custom_run.txt": "buildtest inspect query -b  --testpath custom_run_by_compilers/",
+        f"{inspect_dir}/custom_run.txt": "buildtest inspect query -b  -t custom_run_by_compilers/",
         f"{build_dir}/pre_post_build_run.txt": f"buildtest build -b {COMPILER_EXAMPLE_DIR}/pre_post_build_run.yml",
-        f"{inspect_dir}/pre_post_build_run.txt": "buildtest inspect query --testpath pre_post_build_run",
+        f"{inspect_dir}/pre_post_build_run.txt": "buildtest inspect query -t pre_post_build_run",
         f"{build_dir}/stream_example.txt": f"buildtest build -b {COMPILER_EXAMPLE_DIR}/stream_example.yml",
-        f"{inspect_dir}/stream_example.txt": "buildtest inspect query --testpath stream_openmp_c/",
+        f"{inspect_dir}/stream_example.txt": "buildtest inspect query -t stream_openmp_c/",
         f"{build_dir}/stream_example_metrics.txt": f"buildtest build -b {COMPILER_EXAMPLE_DIR}/stream_example_metrics.yml",
         f"{inspect_dir}/stream_openmp_metrics.txt": "buildtest inspect query -o stream_openmp_metrics/",
     }
diff --git a/buildtest/tools/unittests.py b/buildtest/tools/unittests.py
index 524ff062e..56a26ed3d 100644
--- a/buildtest/tools/unittests.py
+++ b/buildtest/tools/unittests.py
@@ -7,6 +7,8 @@
 if here not in sys.path:
     sys.path.insert(0, here)
 
+import tempfile
+
 import coverage
 import pytest
 
@@ -14,6 +16,7 @@
     BUILDTEST_ROOT,
     BUILDTEST_UNITTEST_ROOT,
     BUILDTEST_USER_HOME,
+    DEFAULT_SETTINGS_FILE,
     VAR_DIR,
     console,
 )
@@ -36,6 +39,13 @@ def run_unit_tests(pytestopts=None, sourcefiles=None, enable_coverage=False):
             "Please check your buildtest installation by running 'source setup.sh'"
         )
 
+    os.environ["BUILDTEST_CI_DIR"] = tempfile.mkdtemp()
+    settings_file = os.path.join(os.environ["BUILDTEST_CI_DIR"], "config.yml")
+    shutil.copyfile(DEFAULT_SETTINGS_FILE, settings_file)
+
+    console.rule("Running buildtest unit tests")
+    console.print("BUILDTEST_CI_DIR", os.getenv("BUILDTEST_CI_DIR"))
+
     pytestopts = pytestopts.split() if pytestopts else []
     sources = []
 
diff --git a/buildtest/utils/shell.py b/buildtest/utils/shell.py
index 768550bfe..7d2d4ebbf 100755
--- a/buildtest/utils/shell.py
+++ b/buildtest/utils/shell.py
@@ -151,6 +151,16 @@ def __init__(self, shell="bash"):
 
         self._opts = " ".join(shell.split()[1:])
         self.path = self.name
+        self.default_opts = None
+
+        if self.name == "bash":
+            self.default_opts = "--norc --noprofile -eo pipefail"
+        elif self.name == "csh":
+            self.default_opts = "-ef"
+        elif self.name == "zsh":
+            self.default_opts = "-f"
+        else:
+            self.default_opts = ""
 
     @property
     def opts(self):
diff --git a/docs/buildtest_tutorial_examples/compilers/inspect/custom_run.txt b/docs/buildtest_tutorial_examples/compilers/inspect/custom_run.txt
index ee8a3ffa0..4052dfeff 100644
--- a/docs/buildtest_tutorial_examples/compilers/inspect/custom_run.txt
+++ b/docs/buildtest_tutorial_examples/compilers/inspect/custom_run.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query -b  --testpath custom_run_by_compilers/ 
+$ buildtest inspect query -b  -t custom_run_by_compilers/
 ────────────────────────────────────────────────────────────────────────────────── custom_run_by_compilers/569258a7-97a4-4beb-b4bc-1859d643bf14 ───────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: Customize binary launch based on compiler
diff --git a/docs/buildtest_tutorial_examples/compilers/inspect/envvar_override.txt b/docs/buildtest_tutorial_examples/compilers/inspect/envvar_override.txt
index 296e87822..f33a4917f 100644
--- a/docs/buildtest_tutorial_examples/compilers/inspect/envvar_override.txt
+++ b/docs/buildtest_tutorial_examples/compilers/inspect/envvar_override.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query --testpath override_environmentvars/ 
+$ buildtest inspect query -t override_environmentvars/
 ────────────────────────────────────────────────────────────────────────────────── override_environmentvars/8a3cd42a-89cf-4dd4-ac71-769482ead72c ──────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: override default environment variables
diff --git a/docs/buildtest_tutorial_examples/compilers/inspect/gnu_hello_c.txt b/docs/buildtest_tutorial_examples/compilers/inspect/gnu_hello_c.txt
index 58db30b8b..6543364c5 100644
--- a/docs/buildtest_tutorial_examples/compilers/inspect/gnu_hello_c.txt
+++ b/docs/buildtest_tutorial_examples/compilers/inspect/gnu_hello_c.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query --testpath hello_c/ 
+$ buildtest inspect query -t hello_c/
 ────────────────────────────────────────────────────────────────────────────────────────── hello_c/a40def68-aca7-4fde-8ac7-1559bc1f81e6 ───────────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: Hello World C Compilation
diff --git a/docs/buildtest_tutorial_examples/compilers/inspect/gnu_hello_fortran.txt b/docs/buildtest_tutorial_examples/compilers/inspect/gnu_hello_fortran.txt
index e23d0254a..89e61695c 100644
--- a/docs/buildtest_tutorial_examples/compilers/inspect/gnu_hello_fortran.txt
+++ b/docs/buildtest_tutorial_examples/compilers/inspect/gnu_hello_fortran.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query --testpath hello_f 
+$ buildtest inspect query -t hello_f
 ────────────────────────────────────────────────────────────────────────────────────────── hello_f/600c36b4-feda-4b60-9c77-ff409d864136 ───────────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: Hello World Fortran Compilation
diff --git a/docs/buildtest_tutorial_examples/compilers/inspect/openmp_hello.txt b/docs/buildtest_tutorial_examples/compilers/inspect/openmp_hello.txt
index 0f2a995f7..0f57bf77d 100644
--- a/docs/buildtest_tutorial_examples/compilers/inspect/openmp_hello.txt
+++ b/docs/buildtest_tutorial_examples/compilers/inspect/openmp_hello.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query --testpath openmp_hello_c_example 
+$ buildtest inspect query -t openmp_hello_c_example
 ─────────────────────────────────────────────────────────────────────────────────── openmp_hello_c_example/acf167ec-751d-45c4-999d-93c7643c117b ───────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: OpenMP Hello World C example
diff --git a/docs/buildtest_tutorial_examples/compilers/inspect/pre_post_build_run.txt b/docs/buildtest_tutorial_examples/compilers/inspect/pre_post_build_run.txt
index ed3fa3bc2..d553b4285 100644
--- a/docs/buildtest_tutorial_examples/compilers/inspect/pre_post_build_run.txt
+++ b/docs/buildtest_tutorial_examples/compilers/inspect/pre_post_build_run.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query --testpath pre_post_build_run 
+$ buildtest inspect query -t pre_post_build_run
 ───────────────────────────────────────────────────────────────────────────────────── pre_post_build_run/52b3e3cd-9764-400b-922d-a4b087cca93b ─────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: example using pre_build, post_build, pre_run, post_run example
diff --git a/docs/buildtest_tutorial_examples/compilers/inspect/stream_example.txt b/docs/buildtest_tutorial_examples/compilers/inspect/stream_example.txt
index a6e467518..f6b3f9767 100644
--- a/docs/buildtest_tutorial_examples/compilers/inspect/stream_example.txt
+++ b/docs/buildtest_tutorial_examples/compilers/inspect/stream_example.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query --testpath stream_openmp_c/ 
+$ buildtest inspect query -t stream_openmp_c/
 ────────────────────────────────────────────────────────────────────────────────────── stream_openmp_c/91a2d4f4-63a0-4a5f-8b09-e092b904972c ───────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: STREAM Microbenchmark C Test with OpenMP
diff --git a/docs/buildtest_tutorial_examples/spack/build/spack_env_deactivate.txt b/docs/buildtest_tutorial_examples/spack/build/spack_env_deactivate.txt
new file mode 100644
index 000000000..9341fc8f1
--- /dev/null
+++ b/docs/buildtest_tutorial_examples/spack/build/spack_env_deactivate.txt
@@ -0,0 +1,71 @@
+$ buildtest build -b /home/spack/buildtest/examples/spack/spack_env_deactivate.yml 
+╭────────────────────────────────────────────────────── buildtest summary ───────────────────────────────────────────────────────╮                                     
+│                                                                                                                                │                                     
+│ User:               spack                                                                                                      │                                     
+│ Hostname:           189b8c776423                                                                                               │                                     
+│ Platform:           Linux                                                                                                      │                                     
+│ Current Time:       2023/08/11 16:03:30                                                                                        │                                     
+│ buildtest path:     /home/spack/buildtest/bin/buildtest                                                                        │                                     
+│ buildtest version:  1.5                                                                                                        │                                     
+│ python path:        /home/spack/.pyenv/buildtest/bin/python3                                                                   │                                     
+│ python version:     3.8.6                                                                                                      │                                     
+│ Configuration File: /home/spack/buildtest/buildtest/settings/spack_container.yml                                               │                                     
+│ Test Directory:     /home/spack/runs                                                                                           │                                     
+│ Report File:        /home/spack/buildtest/var/report.json                                                                      │                                     
+│ Command:            /home/spack/buildtest/bin/buildtest build -b /home/spack/buildtest/examples/spack/spack_env_deactivate.yml │                                     
+│                                                                                                                                │                                     
+╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯                                     
+───────────────────────────────────────────────────────────────────────  Discovering Buildspecs ───────────────────────────────────────────────────────────────────────
+                      Discovered buildspecs                      
+╔═══════════════════════════════════════════════════════════════╗
+║ buildspec                                                     ║
+╟───────────────────────────────────────────────────────────────╢
+║ /home/spack/buildtest/examples/spack/spack_env_deactivate.yml ║
+╚═══════════════════════════════════════════════════════════════╝
+
+
+Total Discovered Buildspecs:  1
+Total Excluded Buildspecs:  0
+Detected Buildspecs after exclusion:  1
+───────────────────────────────────────────────────────────────────────── Parsing Buildspecs ──────────────────────────────────────────────────────────────────────────
+Valid Buildspecs: 1
+Invalid Buildspecs: 0
+/home/spack/buildtest/examples/spack/spack_env_deactivate.yml: VALID
+Total builder objects created: 1
+                                                                        Builders by type=spack                                                                         
+┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
+┃ builder                            ┃ type  ┃ executor           ┃ compiler ┃ nodes ┃ procs ┃ description                       ┃ buildspecs                         ┃
+┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
+│ spack_env_deactivate_first/bb6f82… │ spack │ generic.local.bash │ None     │ None  │ None  │ deactivate a spack environment    │ /home/spack/buildtest/examples/sp… │
+│                                    │       │                    │          │       │       │ first prior to activating it      │                                    │
+└────────────────────────────────────┴───────┴────────────────────┴──────────┴───────┴───────┴───────────────────────────────────┴────────────────────────────────────┘
+──────────────────────────────────────────────────────────────────────────── Building Test ────────────────────────────────────────────────────────────────────────────
+spack_env_deactivate_first/bb6f8295: Creating test directory: /home/spack/runs/generic.local.bash/spack_env_deactivate/spack_env_deactivate_first/bb6f8295
+spack_env_deactivate_first/bb6f8295: Creating the stage directory: /home/spack/runs/generic.local.bash/spack_env_deactivate/spack_env_deactivate_first/bb6f8295/stage
+spack_env_deactivate_first/bb6f8295: Writing build script: /home/spack/runs/generic.local.bash/spack_env_deactivate/spack_env_deactivate_first/bb6f8295/spack_env_deactivate_first_build.sh
+──────────────────────────────────────────────────────────────────────────── Running Tests ────────────────────────────────────────────────────────────────────────────
+Spawning 2 processes for processing builders
+───────────────────────────────────────────────────────────────────────────── Iteration 1 ─────────────────────────────────────────────────────────────────────────────
+spack_env_deactivate_first/bb6f8295 does not have any dependencies adding test to queue
+spack_env_deactivate_first/bb6f8295: Current Working Directory : /home/spack/runs/generic.local.bash/spack_env_deactivate/spack_env_deactivate_first/bb6f8295/stage
+spack_env_deactivate_first/bb6f8295: Running Test via command: bash --norc --noprofile -eo pipefail spack_env_deactivate_first_build.sh
+spack_env_deactivate_first/bb6f8295: Test completed in 3.870062 seconds
+spack_env_deactivate_first/bb6f8295: Test completed with returncode: 0
+spack_env_deactivate_first/bb6f8295: Writing output file -  /home/spack/runs/generic.local.bash/spack_env_deactivate/spack_env_deactivate_first/bb6f8295/spack_env_deactivate_first.out
+spack_env_deactivate_first/bb6f8295: Writing error file - /home/spack/runs/generic.local.bash/spack_env_deactivate/spack_env_deactivate_first/bb6f8295/spack_env_deactivate_first.err
+In this iteration we are going to run the following tests: [spack_env_deactivate_first/bb6f8295]
+                                                           Test Summary                                                            
+┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┓
+┃ builder                             ┃ executor           ┃ status ┃ checks (ReturnCode, Regex, Runtime) ┃ returncode ┃ runtime  ┃
+┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━┩
+│ spack_env_deactivate_first/bb6f8295 │ generic.local.bash │ PASS   │ None None None                      │ 0          │ 3.870062 │
+└─────────────────────────────────────┴────────────────────┴────────┴─────────────────────────────────────┴────────────┴──────────┘
+
+
+
+Passed Tests: 1/1 Percentage: 100.000%
+Failed Tests: 0/1 Percentage: 0.000%
+
+
+Adding 1 test results to /home/spack/buildtest/var/report.json
+Writing Logfile to: /home/spack/buildtest/var/logs/buildtest_s9w5kx1s.log
diff --git a/docs/buildtest_tutorial_examples/spack/build/spack_load.txt b/docs/buildtest_tutorial_examples/spack/build/spack_load.txt
new file mode 100644
index 000000000..56329bdb4
--- /dev/null
+++ b/docs/buildtest_tutorial_examples/spack/build/spack_load.txt
@@ -0,0 +1,71 @@
+$ buildtest build -b /home/spack/buildtest/examples/spack/spack_load.yml 
+╭───────────────────────────────────────────────── buildtest summary ──────────────────────────────────────────────────╮                                                    
+│                                                                                                                      │                                                    
+│ User:               spack                                                                                            │                                                    
+│ Hostname:           b6f30f1b3d3f                                                                                     │                                                    
+│ Platform:           Linux                                                                                            │                                                    
+│ Current Time:       2023/08/08 18:10:42                                                                              │                                                    
+│ buildtest path:     /home/spack/buildtest/bin/buildtest                                                              │                                                    
+│ buildtest version:  1.5                                                                                              │                                                    
+│ python path:        /home/spack/.pyenv/buildtest/bin/python3                                                         │                                                    
+│ python version:     3.8.6                                                                                            │                                                    
+│ Configuration File: /home/spack/buildtest/buildtest/settings/spack_container.yml                                     │                                                    
+│ Test Directory:     /home/spack/runs                                                                                 │                                                    
+│ Report File:        /home/spack/buildtest/var/report.json                                                            │                                                    
+│ Command:            /home/spack/buildtest/bin/buildtest build -b /home/spack/buildtest/examples/spack/spack_load.yml │                                                    
+│                                                                                                                      │                                                    
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯                                                    
+─────────────────────────────────────────────────────────────────────────  Discovering Buildspecs ──────────────────────────────────────────────────────────────────────────
+                 Discovered buildspecs                 
+╔═════════════════════════════════════════════════════╗
+║ buildspec                                           ║
+╟─────────────────────────────────────────────────────╢
+║ /home/spack/buildtest/examples/spack/spack_load.yml ║
+╚═════════════════════════════════════════════════════╝
+
+
+Total Discovered Buildspecs:  1
+Total Excluded Buildspecs:  0
+Detected Buildspecs after exclusion:  1
+──────────────────────────────────────────────────────────────────────────── Parsing Buildspecs ────────────────────────────────────────────────────────────────────────────
+Valid Buildspecs: 1
+Invalid Buildspecs: 0
+/home/spack/buildtest/examples/spack/spack_load.yml: VALID
+Total builder objects created: 1
+                                                                           Builders by type=spack                                                                           
+┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
+┃ builder                     ┃ type  ┃ executor           ┃ compiler ┃ nodes ┃ procs ┃ description                             ┃ buildspecs                               ┃
+┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
+│ spack_load_example/60d45649 │ spack │ generic.local.bash │ None     │ None  │ None  │ Run spack load for m4 package and run   │ /home/spack/buildtest/examples/spack/sp… │
+│                             │       │                    │          │       │       │ tests                                   │                                          │
+└─────────────────────────────┴───────┴────────────────────┴──────────┴───────┴───────┴─────────────────────────────────────────┴──────────────────────────────────────────┘
+────────────────────────────────────────────────────────────────────────────── Building Test ───────────────────────────────────────────────────────────────────────────────
+spack_load_example/60d45649: Creating test directory: /home/spack/runs/generic.local.bash/spack_load/spack_load_example/60d45649
+spack_load_example/60d45649: Creating the stage directory: /home/spack/runs/generic.local.bash/spack_load/spack_load_example/60d45649/stage
+spack_load_example/60d45649: Writing build script: /home/spack/runs/generic.local.bash/spack_load/spack_load_example/60d45649/spack_load_example_build.sh
+────────────────────────────────────────────────────────────────────────────── Running Tests ───────────────────────────────────────────────────────────────────────────────
+Spawning 2 processes for processing builders
+─────────────────────────────────────────────────────────────────────────────── Iteration 1 ────────────────────────────────────────────────────────────────────────────────
+spack_load_example/60d45649 does not have any dependencies adding test to queue
+spack_load_example/60d45649: Current Working Directory : /home/spack/runs/generic.local.bash/spack_load/spack_load_example/60d45649/stage
+spack_load_example/60d45649: Running Test via command: bash --norc --noprofile -eo pipefail spack_load_example_build.sh
+spack_load_example/60d45649: Test completed in 2.911326 seconds
+spack_load_example/60d45649: Test completed with returncode: 0
+spack_load_example/60d45649: Writing output file -  /home/spack/runs/generic.local.bash/spack_load/spack_load_example/60d45649/spack_load_example.out
+spack_load_example/60d45649: Writing error file - /home/spack/runs/generic.local.bash/spack_load/spack_load_example/60d45649/spack_load_example.err
+In this iteration we are going to run the following tests: [spack_load_example/60d45649]
+                                                       Test Summary                                                        
+┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┓
+┃ builder                     ┃ executor           ┃ status ┃ checks (ReturnCode, Regex, Runtime) ┃ returncode ┃ runtime  ┃
+┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━┩
+│ spack_load_example/60d45649 │ generic.local.bash │ PASS   │ None None None                      │ 0          │ 2.911326 │
+└─────────────────────────────┴────────────────────┴────────┴─────────────────────────────────────┴────────────┴──────────┘
+
+
+
+Passed Tests: 1/1 Percentage: 100.000%
+Failed Tests: 0/1 Percentage: 0.000%
+
+
+Adding 1 test results to /home/spack/buildtest/var/report.json
+Writing Logfile to: /home/spack/buildtest/var/logs/buildtest_hhrqf19o.log
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/clone_spack.txt b/docs/buildtest_tutorial_examples/spack/inspect/clone_spack.txt
index 7522b966e..44e733158 100644
--- a/docs/buildtest_tutorial_examples/spack/inspect/clone_spack.txt
+++ b/docs/buildtest_tutorial_examples/spack/inspect/clone_spack.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query -o --testpath clone_spack_automatically clone_spack_and_specify_root 
+$ buildtest inspect query -o -t clone_spack_automatically clone_spack_and_specify_root
 ──────────────────────────────────────────────────────────────────────────────────── clone_spack_automatically/32829f81-0acc-4d11-bb99-e77bb01e37c7 ────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: Clone spack automatically
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/e4s_testsuite_mpich.txt b/docs/buildtest_tutorial_examples/spack/inspect/e4s_testsuite_mpich.txt
index 9c44dc867..b25bb484d 100644
--- a/docs/buildtest_tutorial_examples/spack/inspect/e4s_testsuite_mpich.txt
+++ b/docs/buildtest_tutorial_examples/spack/inspect/e4s_testsuite_mpich.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query -o -e --testpath mpich_e4s_testsuite 
+$ buildtest inspect query -o -e -t mpich_e4s_testsuite
 ──────────────────────────────────────────────────────────────────────────────────── mpich_e4s_testsuite/0c47b479-3a67-45c4-aef5-4dfdfe61232d ─────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: Run E4S Testsuite mpich test
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/env_create_directory.txt b/docs/buildtest_tutorial_examples/spack/inspect/env_create_directory.txt
index 0c11a030e..5e797a427 100644
--- a/docs/buildtest_tutorial_examples/spack/inspect/env_create_directory.txt
+++ b/docs/buildtest_tutorial_examples/spack/inspect/env_create_directory.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query -o --testpath spack_env_directory 
+$ buildtest inspect query -o -t spack_env_directory
 ──────────────────────────────────────────────────────────────────────────────────── spack_env_directory/490db0c3-43d9-4660-8b5b-1523d2fff912 ─────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: create spack environment in directory
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/env_create_manifest.txt b/docs/buildtest_tutorial_examples/spack/inspect/env_create_manifest.txt
index 9e9d9720d..8b049de15 100644
--- a/docs/buildtest_tutorial_examples/spack/inspect/env_create_manifest.txt
+++ b/docs/buildtest_tutorial_examples/spack/inspect/env_create_manifest.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query -o --testpath spack_env_create_from_manifest 
+$ buildtest inspect query -o -t spack_env_create_from_manifest
 ─────────────────────────────────────────────────────────────────────────────── spack_env_create_from_manifest/7e04b3e5-3626-490c-b107-a84b1fbae3e7 ───────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: Create spack environment from spack.yaml
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/env_install.txt b/docs/buildtest_tutorial_examples/spack/inspect/env_install.txt
index 976ac3b32..6c03d69a4 100644
--- a/docs/buildtest_tutorial_examples/spack/inspect/env_install.txt
+++ b/docs/buildtest_tutorial_examples/spack/inspect/env_install.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query --testpath install_in_spack_env 
+$ buildtest inspect query -t install_in_spack_env
 ──────────────────────────────────────────────────────────────────────────────────── install_in_spack_env/0f16f091-372b-44e4-8726-b1c1e39a68c3 ────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: Install m4 and zlib in a spack environment named m4_zlib
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/install_specs.txt b/docs/buildtest_tutorial_examples/spack/inspect/install_specs.txt
index 76b411370..12653876b 100644
--- a/docs/buildtest_tutorial_examples/spack/inspect/install_specs.txt
+++ b/docs/buildtest_tutorial_examples/spack/inspect/install_specs.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query -o --testpath install_specs_example clone_spack_and_install_zlib 
+$ buildtest inspect query -o -t install_specs_example clone_spack_and_install_zlib
 ─────────────────────────────────────────────────────────────────────────────────── install_specs_example/40031985-7bf5-41c1-a58e-dbf8edfbda49 ────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: Install zlib from an existing spack instance
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/mirror_example.txt b/docs/buildtest_tutorial_examples/spack/inspect/mirror_example.txt
index 91f754f13..6961e40a0 100644
--- a/docs/buildtest_tutorial_examples/spack/inspect/mirror_example.txt
+++ b/docs/buildtest_tutorial_examples/spack/inspect/mirror_example.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query -o  --testpath add_mirror add_mirror_in_spack_env 
+$ buildtest inspect query -o  -t add_mirror add_mirror_in_spack_env
 ───────────────────────────────────────────────────────────────────────────────────────── add_mirror/5d67c243-2eaa-49d5-8ec9-c2c65c023bcc ─────────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: Declare spack mirror
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/pre_post_cmds.txt b/docs/buildtest_tutorial_examples/spack/inspect/pre_post_cmds.txt
index 33ca23590..ff75a9365 100644
--- a/docs/buildtest_tutorial_examples/spack/inspect/pre_post_cmds.txt
+++ b/docs/buildtest_tutorial_examples/spack/inspect/pre_post_cmds.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query -o --testpath run_pre_post_commands 
+$ buildtest inspect query -o -t run_pre_post_commands
 ─────────────────────────────────────────────────────────────────────────────────── run_pre_post_commands/63b3f722-8c27-4fb3-bb70-64030167d3c0 ────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: Install zlib
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/remove_environment_example.txt b/docs/buildtest_tutorial_examples/spack/inspect/remove_environment_example.txt
index 98011ca65..6dfbe501b 100644
--- a/docs/buildtest_tutorial_examples/spack/inspect/remove_environment_example.txt
+++ b/docs/buildtest_tutorial_examples/spack/inspect/remove_environment_example.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query --testpath remove_environment_automatically remove_environment_explicit 
+$ buildtest inspect query -t remove_environment_automatically remove_environment_explicit
 ────────────────────────────────────────────────────────────────────────────── remove_environment_automatically/7258748c-312f-4092-9773-0e48a17aed4a ──────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: remove spack environment automatically before creating a new environment
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/spack_env_deactivate.txt b/docs/buildtest_tutorial_examples/spack/inspect/spack_env_deactivate.txt
new file mode 100644
index 000000000..0e1e51d91
--- /dev/null
+++ b/docs/buildtest_tutorial_examples/spack/inspect/spack_env_deactivate.txt
@@ -0,0 +1,32 @@
+$ buildtest inspect query --testpath spack_env_deactivate_first 
+─────────────────────────────────────────────────── spack_env_deactivate_first/bb6f8295-ee09-4f6d-b164-5e6bf6bd4ae0 ───────────────────────────────────────────────────
+Executor: generic.local.bash
+Description: deactivate a spack environment first prior to activating it
+State: PASS
+Returncode: 0
+Runtime: 3.870062 sec
+Starttime: 2023/08/11 16:03:30
+Endtime: 2023/08/11 16:03:34
+Command: bash --norc --noprofile -eo pipefail spack_env_deactivate_first_build.sh
+Test Script: /home/spack/runs/generic.local.bash/spack_env_deactivate/spack_env_deactivate_first/bb6f8295/spack_env_deactivate_first.sh
+Build Script: /home/spack/runs/generic.local.bash/spack_env_deactivate/spack_env_deactivate_first/bb6f8295/spack_env_deactivate_first_build.sh
+Output File: /home/spack/runs/generic.local.bash/spack_env_deactivate/spack_env_deactivate_first/bb6f8295/spack_env_deactivate_first.out
+Error File: /home/spack/runs/generic.local.bash/spack_env_deactivate/spack_env_deactivate_first/bb6f8295/spack_env_deactivate_first.err
+Log File: /home/spack/buildtest/var/logs/buildtest_s9w5kx1s.log
+──────────────── Test File: /home/spack/runs/generic.local.bash/spack_env_deactivate/spack_env_deactivate_first/bb6f8295/spack_env_deactivate_first.sh ────────────────
+#!/bin/bash                                                                                                                                                            
+source /home/spack/spack/share/spack/setup-env.sh                                                                                                                      
+spack env create  -d /home/spack/spack-envs/m4                                                                                                                         
+spack env deactivate                                                                                                                                                   
+spack env activate  -d /home/spack/spack-envs/m4                                                                                                                       
+spack add m4                                                                                                                                                           
+spack install                                                                                                                                                          
+                                                                                                                                                                       
+                                                                                                                                                                       
+######## START OF POST COMMANDS ########                                                                                                                               
+spack find                                                                                                                                                             
+rm -rf $HOME/spack-envs/m4                                                                                                                                             
+                                                                                                                                                                       
+######## END OF POST COMMANDS   ########                                                                                                                               
+                                                                                                                                                                       
+                                                                                                                                                                       
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/spack_load.txt b/docs/buildtest_tutorial_examples/spack/inspect/spack_load.txt
new file mode 100644
index 000000000..7fd2f7d6a
--- /dev/null
+++ b/docs/buildtest_tutorial_examples/spack/inspect/spack_load.txt
@@ -0,0 +1,21 @@
+$ buildtest inspect query -t spack_load_example
+───────────────────────────────────────────────────────── spack_load_example/60d45649-5ee2-4efd-978b-58b7bafbc10d ──────────────────────────────────────────────────────────
+Executor: generic.local.bash
+Description: Run spack load for m4 package and run tests
+State: PASS
+Returncode: 0
+Runtime: 2.911326 sec
+Starttime: 2023/08/08 18:10:42
+Endtime: 2023/08/08 18:10:45
+Command: bash --norc --noprofile -eo pipefail spack_load_example_build.sh
+Test Script: /home/spack/runs/generic.local.bash/spack_load/spack_load_example/60d45649/spack_load_example.sh
+Build Script: /home/spack/runs/generic.local.bash/spack_load/spack_load_example/60d45649/spack_load_example_build.sh
+Output File: /home/spack/runs/generic.local.bash/spack_load/spack_load_example/60d45649/spack_load_example.out
+Error File: /home/spack/runs/generic.local.bash/spack_load/spack_load_example/60d45649/spack_load_example.err
+Log File: /home/spack/buildtest/var/logs/buildtest_hhrqf19o.log
+─────────────────────────────── Test File: /home/spack/runs/generic.local.bash/spack_load/spack_load_example/60d45649/spack_load_example.sh ────────────────────────────────
+#!/bin/bash                                                                                                                                                                 
+source /home/spack/spack/share/spack/setup-env.sh                                                                                                                           
+spack load  m4                                                                                                                                                              
+spack test run --alias 47fcdc7a-1994-4013-98c2-eba6d48e7103 m4                                                                                                              
+spack test results -l 47fcdc7a-1994-4013-98c2-eba6d48e7103                                                                                                                  
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/spack_sbatch.txt b/docs/buildtest_tutorial_examples/spack/inspect/spack_sbatch.txt
index c91fd5536..fb495bdb7 100644
--- a/docs/buildtest_tutorial_examples/spack/inspect/spack_sbatch.txt
+++ b/docs/buildtest_tutorial_examples/spack/inspect/spack_sbatch.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query --testpath spack_sbatch_example 
+$ buildtest inspect query -t spack_sbatch_example
 ──────────────────────────────────────────────────────────────────────────────────── spack_sbatch_example/f86aa2f5-b3fa-40e9-94d1-d7b1faf58c25 ────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: sbatch directives can be defined in spack schema
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/spack_test.txt b/docs/buildtest_tutorial_examples/spack/inspect/spack_test.txt
index 61f591b14..832ebbf18 100644
--- a/docs/buildtest_tutorial_examples/spack/inspect/spack_test.txt
+++ b/docs/buildtest_tutorial_examples/spack/inspect/spack_test.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query -o --testpath spack_test_m4 
+$ buildtest inspect query -o -t spack_test_m4
 ─────────────────────────────────────────────────────────────────────────────────────── spack_test_m4/10440e33-ad42-4430-9573-c284a4a539bc ────────────────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: Run spack test for m4 package and report results
diff --git a/docs/buildtest_tutorial_examples/spack/inspect/spack_test_specs.txt b/docs/buildtest_tutorial_examples/spack/inspect/spack_test_specs.txt
index 56059f64c..2676f21dc 100644
--- a/docs/buildtest_tutorial_examples/spack/inspect/spack_test_specs.txt
+++ b/docs/buildtest_tutorial_examples/spack/inspect/spack_test_specs.txt
@@ -1,4 +1,4 @@
-$ buildtest inspect query -o --testpath spack_test_results_specs_format 
+$ buildtest inspect query -o -t spack_test_results_specs_format
 ────────────────────────────────────────────────────────────────────────────── spack_test_results_specs_format/14270fab-4e5f-4e84-ad46-64ac869eeb80 ───────────────────────────────────────────────────────────────────────────────
 Executor: generic.local.bash
 Description: Run spack test results with spec format
diff --git a/docs/configuring_buildtest/compilers.rst b/docs/configuring_buildtest/compilers.rst
index 14761026e..023857297 100644
--- a/docs/configuring_buildtest/compilers.rst
+++ b/docs/configuring_buildtest/compilers.rst
@@ -32,27 +32,27 @@ which includes the name of the compiler in this example we call ``builtin_gcc``
 system compiler that defines C, C++ and Fortran compilers using ``cc``, ``cxx`` and
 ``fc``.
 
-One can retrieve all compilers using ``buildtest config compilers``, there are few
+One can retrieve all compilers using ``buildtest config compilers list``, there are few
 options for this command.
 
-.. dropdown:: ``buildtest config compilers --help``
+.. dropdown:: ``buildtest config compilers list --help``
 
-    .. command-output:: buildtest config compilers --help
+    .. command-output:: buildtest config compilers list --help
 
 buildtest can represent compiler output in JSON, YAML using the ``--json`` and ``--yaml``.
 Shown below is an example output with these options
 
-.. dropdown:: ``buildtest config compilers --json``
+.. dropdown:: ``buildtest config compilers list --json``
 
-    .. command-output:: buildtest config compilers --json
+    .. command-output:: buildtest config compilers list --json
 
-.. dropdown:: ``buildtest config compilers --yaml``
+.. dropdown:: ``buildtest config compilers list --yaml``
 
-    .. command-output:: buildtest config compilers --yaml
+    .. command-output:: buildtest config compilers list --yaml
 
-If you want to see a flat listing of the compilers as names you can simply run ``buildtest config compilers`` as shown below
+If you want to see a flat listing of the compilers as names you can simply run ``buildtest config compilers list`` as shown below
 
-.. command-output:: buildtest config compilers
+.. command-output:: buildtest config compilers list
 
 .. _detect_compilers:
 
@@ -70,7 +70,7 @@ Detect Compilers (Experimental Feature)
 .. Note::
 
     ``buildtest config compilers find`` will not update the buildtest configuration with new compilers, you will need to use ``--update`` option
-    to override the configuration file.
+    to write changes back to configuration file.
 
 
 buildtest can detect compilers based on modulefiles and generate compiler section
@@ -86,6 +86,7 @@ In example, below we define a pattern for gcc modules as ``^(gcc)`` which will
 find all modules that start with name `gcc`.
 
 .. code-block:: yaml
+   :emphasize-lines: 2-3
 
     compilers:
       find:
@@ -98,8 +99,8 @@ find all modules that start with name `gcc`.
             fc: /usr/bin/gfortran
 
 
-In this system, we have two gcc modules installed via `spack <https://spack.readthedocs.io/en/latest/>`_
-package manager, we will attempt to add both modules as compiler instance in buildtest.
+In this system, we have two gcc modules and we will add both modules as compiler
+declaration in buildtest.
 
 .. code-block:: console
 
@@ -108,7 +109,7 @@ package manager, we will attempt to add both modules as compiler instance in bui
     gcc/9.3.0-n7p74fd
     gcc/10.2.0-37fmsw7
 
-Next we run ``buildtest config compilers find`` which will search all modules based on
+We will run ``buildtest config compilers find`` which will search all modules based on
 regular expression and add compilers in their respective group. In this example, buildtest
 automatically add ``gcc/9.2.0-n7p74fd`` and ``gcc/10.2.0-37fmsw7`` modules as compiler
 instance. Depending on the compiler group, buildtest will update the properties
@@ -117,7 +118,7 @@ the module configuration to be used to access the compiler, the ``load`` propert
 The ``purge`` property is a boolean that determines whether to run **module purge** prior to loading modules when using the compiler.
 If ``purge: true`` is set then we will do **module purge**.
 
-.. dropdown:: ``buildtest config compilers``
+.. dropdown:: ``buildtest config compilers find``
 
     .. code-block:: console
        :emphasize-lines: 9-24
@@ -154,7 +155,7 @@ by searching the modules in MODULEPATH and testing each one with a regular expre
 We can see in the output buildtest is applying a regular expression with each modulefile and if there is a match, we
 add the compiler instance into the appropriate compiler group.
 
-.. dropdown:: ``buildtest config compilers --detailed``
+.. dropdown:: ``buildtest config compilers find --detailed``
 
     .. code-block:: console
        :linenos:
@@ -279,7 +280,7 @@ Now take a look at generated compilers upon running ``buildtest config compiler
    :linenos:
    :emphasize-lines: 16,24
 
-       (buildtest)  ~/Documents/github/ buildtest config compilers find
+         buildtest config compilers find
        MODULEPATH: /Users/siddiq90/projects/spack/share/spack/lmod/darwin-catalina-x86_64/Core:/usr/local/Cellar/lmod/8.6.14/modulefiles/Darwin:/usr/local/Cellar/lmod/8.6.14/modulefiles/Core
        ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Detect Compilers ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
        gcc:
@@ -318,7 +319,7 @@ is the programming environment modulefile that will load the GNU compiler on Cra
 
 .. literalinclude:: ../tests/settings/nersc.yml
     :language: yaml
-    :emphasize-lines: 6-10
+    :emphasize-lines: 18-22
 
 Now let's run **buildtest config compilers find --detailed** and take note of the generated compilers, you will see that ``PrgEnv-*`` modules will be found in each
 compiler instance under the ``module``, ``load`` section. Furthermore, you will see the cray wrappers **cc**, **CC**, and **ftn** are used
@@ -328,7 +329,7 @@ instead of the compiler wrappers when defining a compiler instance that uses a P
 
     .. code-block:: console
 
-        (buildtest)  ~/gitrepos/buildtest/tests/settings/ [prgenv_support] buildtest config compilers find --detailed
+         buildtest config compilers find --detailed
         MODULEPATH: /opt/cray/pe/perftools/21.12.0/modulefiles:/opt/cray/pe/craype-targets/default/modulefiles:/opt/cray/ari/modulefiles:/opt/cray/pe/modulefiles:/opt/cray/modulefiles:/opt/modulefiles:/global/common/software/nersc/cle7up03/modulefiles:/global/common/software/nersc/cle7up03/extra_modulefiles:/global/common/cori_cle7up03/ftg/modulefiles
         Searching modules by parsing content of command: module av -t
           Discovered Modules
@@ -659,4 +660,99 @@ compiler ``gcc/9.1.01``
         ┃ No. ┃ Compiler Name ┃ Status ┃
         ┡━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━┩
         │ 1   │ gcc/9.1.0     │     ✅ │
-        └─────┴───────────────┴────────┘
\ No newline at end of file
+        └─────┴───────────────┴────────┘
+
+Removing Compilers
+-------------------
+
+The ``buildtest config compilers remove`` command allows you to remove a compiler from the configuration file.
+This command takes a positional argument that includes the name of compiler you want to remove. buildtest will
+search for compiler name in configuration file and attempt to remove it if it's found.
+
+This command can be used when you find compilers are out of date, for instance you can run ``buildtest config compilers test``
+to test all compilers and show which compilers failed during test. In output below we have
+one failed compiler name ``nvhpc-mixed/23.7``.
+
+.. code-block:: console
+
+    $ buildtest config compilers test
+    Compiler 'builtin_gcc' has no 'modules' defined therefore skipping test
+            Compilers Test Pass
+    ┏━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┓
+    ┃ No. ┃ Compiler Name     ┃ Status ┃
+    ┡━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━┩
+    │ 1   │ builtin_gcc       │     ✅ │
+    │ 2   │ gcc/11.2.0        │     ✅ │
+    │ 3   │ gcc/10.3.0        │     ✅ │
+    │ 4   │ gcc/12.2.0        │     ✅ │
+    │ 5   │ gcc/12.1.0        │     ✅ │
+    │ 6   │ cce/15.0.1        │     ✅ │
+    │ 7   │ cce/15.0.0        │     ✅ │
+    │ 8   │ nvhpc/21.11       │     ✅ │
+    │ 9   │ nvhpc/21.9        │     ✅ │
+    │ 10  │ nvhpc/22.7        │     ✅ │
+    │ 11  │ nvhpc-mixed/21.11 │     ✅ │
+    │ 12  │ nvhpc-mixed/21.9  │     ✅ │
+    │ 13  │ nvhpc-mixed/22.7  │     ✅ │
+    │ 14  │ nvhpc/23.1        │     ✅ │
+    │ 15  │ nvhpc-mixed/23.1  │     ✅ │
+    └─────┴───────────────────┴────────┘
+            Compilers Test Fail
+    ┏━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━┓
+    ┃ No. ┃ Compiler Name    ┃ Status ┃
+    ┡━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━┩
+    │ 1   │ nvhpc-mixed/23.7 │     ❌ │
+    └─────┴──────────────────┴────────┘
+
+Note we have tab completion for compilers names that can be removed which can help select the compiler you want
+to remove.
+
+.. code-block::
+
+    $ buildtest config compilers remove
+    builtin_gcc        cce/15.0.1         gcc/11.2.0         gcc/12.2.0         nvhpc/21.9         nvhpc/23.1         nvhpc-mixed/21.9   nvhpc-mixed/23.1
+    cce/15.0.0         gcc/10.3.0         gcc/12.1.0         nvhpc/21.11        nvhpc/22.7         nvhpc-mixed/21.11  nvhpc-mixed/22.7   nvhpc-mixed/23.7
+
+Let's remove the compiler `nvhpc-mixed/23.7` by running the following, take note buildtest will update the configuration file
+
+.. code-block::
+
+    $ buildtest config compilers remove nvhpc-mixed/23.7
+    ──────────────────────────────────────────────────────────────────────────────── Removing compiler name: nvhpc-mixed/23.7 ────────────────────────────────────────────────────────────────────────────────
+    cc: cc
+    cxx: CC
+    fc: ftn
+    module:
+      load:
+      - PrgEnv-nvidia
+      - nvhpc-mixed/23.7
+      purge: false
+
+    Updating configuration file: /global/u1/s/siddiq90/gitrepos/buildtest-nersc/config.yml
+
+Now if we rerun the compiler tests, we see all compilers have passed checks
+
+.. code-block:: console
+
+    $ buildtest config compilers test
+    Compiler 'builtin_gcc' has no 'modules' defined therefore skipping test
+            Compilers Test Pass
+    ┏━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┓
+    ┃ No. ┃ Compiler Name     ┃ Status ┃
+    ┡━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━┩
+    │ 1   │ builtin_gcc       │     ✅ │
+    │ 2   │ gcc/11.2.0        │     ✅ │
+    │ 3   │ gcc/10.3.0        │     ✅ │
+    │ 4   │ gcc/12.2.0        │     ✅ │
+    │ 5   │ gcc/12.1.0        │     ✅ │
+    │ 6   │ cce/15.0.1        │     ✅ │
+    │ 7   │ cce/15.0.0        │     ✅ │
+    │ 8   │ nvhpc/21.11       │     ✅ │
+    │ 9   │ nvhpc/21.9        │     ✅ │
+    │ 10  │ nvhpc/22.7        │     ✅ │
+    │ 11  │ nvhpc-mixed/21.11 │     ✅ │
+    │ 12  │ nvhpc-mixed/21.9  │     ✅ │
+    │ 13  │ nvhpc-mixed/22.7  │     ✅ │
+    │ 14  │ nvhpc/23.1        │     ✅ │
+    │ 15  │ nvhpc-mixed/23.1  │     ✅ │
+    └─────┴───────────────────┴────────┘
\ No newline at end of file
diff --git a/docs/configuring_buildtest/overview.rst b/docs/configuring_buildtest/overview.rst
index f368d774f..fa4794b20 100644
--- a/docs/configuring_buildtest/overview.rst
+++ b/docs/configuring_buildtest/overview.rst
@@ -191,7 +191,7 @@ For instance if you want all bash scripts to run in login shell you can specify
 Then you can reference this executor as ``executor: generic.local.login_bash`` and your
 tests will be submitted via ``bash --login /path/to/test.sh``.
 
-Once you define your executors, you can :ref:`query the executors <view_executors>` via ``buildtest config executors``
+Once you define your executors, you can :ref:`query the executors <view_executors>` via ``buildtest config executors list``
 command.
 
 Disable an executor
@@ -656,6 +656,21 @@ Shown below we set ``poolsize`` to 1.
 
         poolsize: 1
 
+.. _configuring_max_jobs:
+
+Configuring Max Jobs
+---------------------
+
+The ``max_jobs`` property is used to limit number of jobs that can run concurrently. This is useful if you want to limit,
+the workload on your system. Buildtest will run all jobs in parallel by default, if ``max_jobs`` is not specified.
+If you want to run all tests in serial, you can set ``max_jobs: 1`` as shown below.
+
+.. code-block:: yaml
+
+    max_jobs: 1
+
+This value can be overridden via ``buildtest build --max-jobs`` option. For more details see :ref:`limit_max_jobs`
+
 Managing Profiles
 ------------------
 
@@ -725,4 +740,65 @@ is an object and attributes ``tags``, ``maintainers``, ``type`` correspond to th
           - script
 
 We have added additional checks in the JSON schema for valid values for each type, for instance if you specify an invalid value for ``type`` field
-which is used to filter buildspecs by the ``type`` field, then you will get an invalid configuration file.
\ No newline at end of file
+which is used to filter buildspecs by the ``type`` field, then you will get an invalid configuration file.
+
+
+Listing Profiles
+~~~~~~~~~~~~~~~~~
+
+This section in the profile permits you to enumerate the profiles available for encapsulating buildtest build options.
+
+Lets create a profile by running the following buildtest command.
+
+.. command-output:: buildtest build -t python --save-profile=python
+
+The `--save-profile` is used to specify name of profile that will be written in configuration file.
+
+In order to see all profiles you can run ``buildtest config profiles list`` as shown below
+
+.. command-output:: buildtest config profiles list
+
+.. command-output:: buildtest config profiles list --yaml
+
+Removing Profiles
+~~~~~~~~~~~~~~~~~~
+
+You can remove a profile by running ``buildtest config profiles remove <profile>``, where <profile> is the name of profile.
+
+This command will update your configuration file and remove the profile name from configuration. You can
+remove multiple profiles at once, buildtest will check if profile name exist and attempt to remove it. If its not
+found, it will simply skip it.
+
+First, lets create two profile using ``buildtest build --save-profile``
+
+.. dropdown:: Creating profiles
+
+    .. command-output:: buildtest build -t python --save-profile=prof1
+
+    .. command-output:: buildtest build -b tutorials/shell_examples.yml  --save-profile=prof2
+
+Now we will list the profiles to confirm they are created and remove them. Next we will rerun ``buildtest config profiles list`` to confirm
+profiles are removed
+
+.. dropdown:: Example on how to create, list and remove profiles
+
+    .. code-block:: console
+
+        $ buildtest config profiles list
+        python-tests
+        python
+        prof1
+        prof2
+
+    .. code-block:: console
+
+        $ buildtest config profiles remove prof1 prof2
+        Removing profile: prof1
+        Removing profile: prof2
+        Updating configuration file: /Users/siddiq90/Documents/github/buildtest/buildtest/settings/config.yml
+
+    .. code-block:: console
+
+        $ buildtest config profiles list
+        python-tests
+        python
\ No newline at end of file
diff --git a/docs/contributing/regression_testing.rst b/docs/contributing/regression_testing.rst
index ed33a14cb..11d0b85c8 100644
--- a/docs/contributing/regression_testing.rst
+++ b/docs/contributing/regression_testing.rst
@@ -122,10 +122,9 @@ the script via python
        :shell:
 
 
-The `pytest.ini <https://github.com/buildtesters/buildtest/blob/devel/pytest.ini>`_
-found in top-level folder defines pytest configuration for running the unit tests. Some of the unit tests are
-assigned a `marker <https://docs.pytest.org/en/6.2.x/example/markers.html>`_ which allows one to run a group of test together. You
-can find all markers by running ``pytest --markers``.
+The pytest configuration is defined in `pyproject.toml <https://github.com/buildtesters/buildtest/blob/devel/pyproject.toml>`_
+found in top-level folder. Some of the unit tests are assigned a `marker <https://docs.pytest.org/en/6.2.x/example/markers.html>`_
+which allows one to run a group of test together. You can find all markers by running ``pytest --markers``.
 
 If you want to run all tests with ``schema`` marker you can do the following::
 
diff --git a/docs/gettingstarted/buildingtest.rst b/docs/gettingstarted/buildingtest.rst
index 6180eb4a3..165ddc2ca 100644
--- a/docs/gettingstarted/buildingtest.rst
+++ b/docs/gettingstarted/buildingtest.rst
@@ -192,6 +192,48 @@ where no test are eligible to run after exclusion has been applied.
     .. command-output:: buildtest build -b tutorials/test_status/pass_returncode.yml -xt pass,fail
         :returncode: 1
 
+Building by Test Names
+-----------------------
+
+You can discover buildspecs by test names using the ``--name`` option or short option ``-n``. This feature can be used if
+you want to run a particular test and not worrying about the buildspec file that is belongs to. Note we have tab
+completion builtin to this feature to show list of tests that are found in the buildspec cache. Shown below
+is an example output of the tab completion listing all available tests
+
+.. code-block:: console
+
+      buildtest build --name _bin_bash_shell
+    _bin_bash_shell                   current_user_queue                lsf_version                       runtime_test_pass                 status_regex_stderr_pass
+    _bin_sh_shell                     dead_nodes                        metric_file_regex                 sh_shell                          status_regex_stdout_fail
+    add_numbers                       display_hosts_format              metric_file_regex_invalid_file    shell_options                     status_regex_stdout_pass
+    always_fail                       display_lsf_hosts                 metric_regex_example              show_accounts                     status_returncode_by_executors
+    always_pass                       executors_sbatch_declaration      multiple_executors                show_all_jobs                     stream_test
+    assert_contains_fail              executors_vars_env_declaration    node_down_fail_list_reason        show_host_groups                  string_tag
+    assert_eq_example                 exit1_fail                        nodes_state_allocated             show_jobs                         summary_example
+    assert_eq_invalid_metric          exit1_pass                        nodes_state_completing            show_lsf_configuration            symlink_test
+    assert_eq_mismatch                fail_test                         nodes_state_down                  show_lsf_models                   systemd_default_target
+    assert_gt_example                 file_and_dir_checks               nodes_state_idle                  show_lsf_queues                   tcsh_env_declaration
+    assert_le_example                 file_count_by_expression          nodes_state_reboot                show_lsf_queues_current_user      test1
+    assert_lt_example                 file_count_by_extension           pass_and_fail_test                show_lsf_queues_formatted         test2
+
+
+Let's try building an example test by name ``hello_world``. Take note in output, buildtest will show a breakdown of buildspecs
+discovered by the test name.
+
+.. dropdown:: ``buildtest build --name hello_world``
+
+    .. command-output:: buildtest build --name hello_world
+
+You can specify multiple test names just specify the option multiple times. In example below we will demonstrate this example
+
+.. dropdown:: ``buildtest build --name add_numbers --name summary_example``
+
+    .. command-output:: buildtest build --name add_numbers --name summary_example
+
+Please note, buildtest will discover buildspecs given the test name (``--name``) option and then run all tests defined in the buildspec file.
+A buildspec file may include several tests and by default all of them are run. This option is
+**not meant to filter buildspecs by the selected test**, but only a means for discovering buildspecs by test name.
+
 .. _build_by_executor:
 
 Building by Executors
@@ -517,11 +559,27 @@ with a profile called **python-tests**
 
 .. dropdown:: buildtest configuration with profile
 
-    .. command-output:: cat $BUILDTEST_ROOT/buildtest/settings/config.yml
-        :shell:
+    .. command-output:: buildtest config view
+
 
 Next, let's build the tests via newly created profile and take note that it will run all tests with tag `python`
 
 .. dropdown:: ``buildtest build --profile=python-tests``
 
     .. command-output:: buildtest build --profile=python-tests
+
+.. _limit_max_jobs:
+
+Limit Maximum Jobs that can run concurrently
+---------------------------------------------
+
+Buildtest can cap a limit on number of tests that can run concurrently. This can be set in configuration file via :ref:`max_jobs <configuring_max_jobs>`
+field or overridden on command line option via ``--max-jobs``. By default, buildtest will run all jobs concurrently, however with
+``--max-jobs``, buildtest will limit number of concurrent jobs specified by ``--max-jobs``.
+
+Let's limit the number of concurrent jobs to 2 tests, take note that buildtest will run 2 tests per iteration, and wait until test is completed and
+then proceed to next test.
+
+.. dropdown:: ``buildtest build -b tutorials/hello_world.yml --rebuild=5 --max-jobs=2``
+
+    .. command-output:: buildtest build -b tutorials/hello_world.yml --rebuild=5 --max-jobs=2
diff --git a/docs/gettingstarted/query_test_report.rst b/docs/gettingstarted/query_test_report.rst
index fcea7685f..9f40f134b 100644
--- a/docs/gettingstarted/query_test_report.rst
+++ b/docs/gettingstarted/query_test_report.rst
@@ -381,9 +381,9 @@ is delimited by PIPE symbol (``|``). The ``--terse`` option works with ``--forma
 next example, we report all FAIL tests in terse output. The first line is the header of tables followed by
 output, if you want to disable output of header you can use ``--no-header`` option.
 
-.. dropdown:: ``buildtest report --filter state=FAIL --format=name,id,state -t``
+.. dropdown:: ``buildtest report --filter state=FAIL --format=name,id,state --terse``
 
-    .. command-output:: buildtest report --filter state=FAIL --format=name,id,state -t
+    .. command-output:: buildtest report --filter state=FAIL --format=name,id,state --terse
 
 Report Summary (``buildtest report summary``)
 ----------------------------------------------
@@ -443,9 +443,9 @@ querying test records via :ref:`buildtest inspect name <inspect_by_name>` or :re
 If you are interested in parsing output of ``buildtest inspect list``, you can may find the ``--terse`` option useful. The output will show
 headers followed by entries, the headers can be omitted by specifying ``--no-header`` option.
 
-.. dropdown:: ``buildtest inspect list -t``
+.. dropdown:: ``buildtest inspect list --terse``
 
-    .. command-output:: buildtest inspect list -t
+    .. command-output:: buildtest inspect list --terse
        :ellipsis: 5
 
 .. _inspect_by_name:
@@ -539,12 +539,12 @@ print content of output file
     .. command-output:: buildtest inspect query -o circle_area
 
 If you want to see content of error file use the ``-e`` or ``--error`` flag. It would be useful to inspect
-content of build script and generated test, which can be retrieved using ``--testpath`` and ``--buildscript``. Let's
+content of build script and generated test, which can be retrieved using ``-t`` and ``--buildscript``. Let's
 query test ``circle_area`` and report all of the content fields
 
-.. dropdown:: ``buildtest inspect query -o -e --testpath -b circle_area``
+.. dropdown:: ``buildtest inspect query -o -e -t -b circle_area``
 
-    .. command-output:: buildtest inspect query -o -e --testpath -b circle_area
+    .. command-output:: buildtest inspect query -o -e -t -b circle_area
 
 We can query multiple tests using ``buildtest inspect query`` since each test is a positional argument. Any
 options specified to `buildtest inspect query` will be applied to all test. For instance, let's fetch the output the
diff --git a/pytest.ini b/pytest.ini
deleted file mode 100644
index 2c0355ef6..000000000
--- a/pytest.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[pytest]
-addopts = -vra -x --durations=20
-testpaths = tests
-markers =
-    schema: run schema tests
-    utility: run test for utility methods used throughout codebase
-    cli: run test for targetting buildtest command line features
diff --git a/tests/cli/test_argparse.py b/tests/cli/test_argparse.py
index 0968fa2e0..32f114e94 100644
--- a/tests/cli/test_argparse.py
+++ b/tests/cli/test_argparse.py
@@ -4,7 +4,6 @@
 
 from buildtest.cli import (
     build_filters_format,
-    get_parser,
     handle_kv_string,
     positive_number,
     supported_color,
@@ -82,11 +81,3 @@ def test_valid_time():
     # raises exception when its unable to convert time
     with pytest.raises(ValueError):
         valid_time("2022-01-01 abcdef")
-
-
-def test_arg_parse():
-    parser = get_parser()
-    print(parser)
-
-    assert parser.prog == "buildtest"
-    assert parser.usage == "%(prog)s [options] [COMMANDS]"
diff --git a/tests/cli/test_build.py b/tests/cli/test_build.py
index 7b2b7e3df..aac79d032 100644
--- a/tests/cli/test_build.py
+++ b/tests/cli/test_build.py
@@ -287,6 +287,24 @@ def test_exclude_tags(self):
         with pytest.raises(SystemExit):
             cmd.build()
 
+    @pytest.mark.cli
+    def test_buildspecs_by_name(self):
+        # testing buildtest build --name
+        cmd = BuildTest(
+            configuration=configuration,
+            name=["hello_world", "add_numbers"],
+            buildtest_system=self.system,
+        )
+        cmd.build()
+
+        # should raise exception if `name` is not a list
+        with pytest.raises(BuildTestError):
+            BuildTest(
+                configuration=configuration,
+                name="pass_test",
+                buildtest_system=self.system,
+            )
+
     @pytest.mark.cli
     def test_build_csh_executor(self):
         if not shutil.which("csh"):
@@ -394,6 +412,16 @@ def test_build_limit(self):
                 limit=1.5,
             )
 
+    def test_max_jobs(self):
+        # testing buildtest build -b tutorials/hello_world.yml --max-jobs=2 --rebuild=4
+        cmd = BuildTest(
+            configuration=configuration,
+            buildspecs=["tutorials/hello_world.yml"],
+            rebuild=4,
+            max_jobs=2,
+        )
+        cmd.build()
+
     @pytest.mark.cli
     def test_invalid_buildspes(self):
         buildspec_file = [
@@ -488,6 +516,8 @@ def test_save_profile(self):
             rebuild=2,
             timeout=60,
             executor_type="local",
+            remove_stagedir=True,
+            max_jobs=2,
             buildtest_system=self.system,
             save_profile="demo",
         )
@@ -615,6 +645,14 @@ def test_invalid_timeout_type(self):
         with pytest.raises(BuildTestError):
             BuildTest(configuration=configuration, tags=["pass"], timeout=-1)
 
+    def test_invalid_max_jobs(self):
+        with pytest.raises(BuildTestError):
+            BuildTest(configuration=configuration, tags=["pass"], max_jobs=0)
+
+        # must be an integer
+        with pytest.raises(BuildTestError):
+            BuildTest(configuration=configuration, tags=["pass"], max_jobs=0.1)
+
     def test_invalid_exclude_tags_type(self):
         # exclude_tags must be a list
         with pytest.raises(BuildTestError):
diff --git a/tests/cli/test_commands.py b/tests/cli/test_commands.py
index 286eadba6..7b9489d17 100644
--- a/tests/cli/test_commands.py
+++ b/tests/cli/test_commands.py
@@ -3,3 +3,5 @@
 
 def test_buildtest_commands():
     list_buildtest_commands()
+
+    list_buildtest_commands(with_aliases=True)
diff --git a/tests/cli/test_config.py b/tests/cli/test_config.py
index b1c6874dd..1530e333b 100644
--- a/tests/cli/test_config.py
+++ b/tests/cli/test_config.py
@@ -1,8 +1,13 @@
 import os
+import shutil
+import tempfile
 
 import pytest
 
+from buildtest.cli.build import BuildTest
 from buildtest.cli.config import (
+    list_profiles,
+    remove_profiles,
     validate_config,
     view_configuration,
     view_executors,
@@ -66,11 +71,50 @@ def test_config_path():
     view_path(configuration)
 
 
+@pytest.mark.cli
+class TestProfiles:
+    tf = tempfile.NamedTemporaryFile(suffix=".yml")
+    shutil.copy2(configuration.file, tf.name)
+
+    buildtest_config = SiteConfiguration(settings_file=tf.name)
+    buildtest_config.detect_system()
+    buildtest_config.validate(moduletool=system.system["moduletool"])
+
+    cmd = BuildTest(
+        configuration=buildtest_config,
+        buildtest_system=system,
+        tags=["python"],
+        save_profile="python",
+    )
+    cmd.build()
+
+    def test_list_profiles(self):
+        # buildtest config profiles list
+        list_profiles(self.buildtest_config)
+
+        # buildtest config profiles list --theme emacs --yaml
+        list_profiles(self.buildtest_config, theme="emacs", print_yaml=True)
+
+        # buildtest config profiles list --yaml
+        list_profiles(self.buildtest_config, print_yaml=True)
+
+    @pytest.mark.cli
+    def test_profiles_remove(self):
+        # get all profile names from configuration file
+        profiles = list(self.buildtest_config.target_config["profiles"].keys())
+
+        # This will remove all profiles since 'profiles' is list of all profile names
+        remove_profiles(self.buildtest_config, profiles)
+
+        # testing removing profiles when no profiles exist
+        remove_profiles(self.buildtest_config, profiles[0])
+
+
 @pytest.mark.cli
 def test_config_executors():
     buildexecutor = BuildExecutor(configuration)
 
-    # buildtest config executors --json
+    # buildtest config executors list --json
     view_executors(
         configuration=configuration,
         buildexecutor=buildexecutor,
@@ -80,7 +124,7 @@ def test_config_executors():
         invalid=False,
     )
 
-    # buildtest config executors --yaml
+    # buildtest config executors list --yaml
     view_executors(
         configuration=configuration,
         buildexecutor=buildexecutor,
@@ -90,7 +134,7 @@ def test_config_executors():
         invalid=False,
     )
 
-    # buildtest config executors -d
+    # buildtest config executors list --disabled
     view_executors(
         configuration=configuration,
         buildexecutor=buildexecutor,
@@ -100,7 +144,7 @@ def test_config_executors():
         invalid=False,
     )
 
-    # buildtest config executors -i
+    # buildtest config executors list --invalid
     view_executors(
         configuration=configuration,
         buildexecutor=buildexecutor,
@@ -110,7 +154,7 @@ def test_config_executors():
         invalid=True,
     )
 
-    # buildtest config executors
+    # buildtest config executors list
     view_executors(
         configuration=configuration,
         buildexecutor=buildexecutor,
@@ -131,7 +175,7 @@ def test_disabled_invalid_executors():
 
     print("reading config file:", configfile)
     be = BuildExecutor(configuration)
-    # buildtest config executors -d
+    # buildtest config executors list --disabled
     view_executors(
         configuration=configuration,
         buildexecutor=be,
@@ -141,7 +185,7 @@ def test_disabled_invalid_executors():
         invalid=False,
     )
 
-    # buildtest config executors -i
+    # buildtest config executors list --invalid
     view_executors(
         configuration=configuration,
         buildexecutor=be,
diff --git a/tests/settings/ascent.yml b/tests/settings/ascent.yml
index ee550c895..21e2dab49 100644
--- a/tests/settings/ascent.yml
+++ b/tests/settings/ascent.yml
@@ -4,6 +4,8 @@ system:
     - login1.ascent.olcf.ornl.gov
     moduletool: lmod
     poolsize: 8
+    max_jobs: 10
+    pager: False
     buildspecs:
       rebuild: False
       count: 15
@@ -13,7 +15,7 @@ system:
       count: 25
       terse: False
       format: "name,id,state,runtime,returncode"
-      latest: True
+      latest: False
       oldest: False
     executors:
       defaults:
diff --git a/tests/settings/jlse.yml b/tests/settings/jlse.yml
index 9c5724c5f..582140b02 100644
--- a/tests/settings/jlse.yml
+++ b/tests/settings/jlse.yml
@@ -4,6 +4,8 @@ system:
     - jlselogin*
     moduletool: environment-modules
     poolsize: 8
+    max_jobs: 10
+    pager: False
     buildspecs:
       rebuild: False
       count: 15
@@ -13,7 +15,7 @@ system:
       count: 25
       terse: False
       format: "name,id,state,runtime,returncode"
-      latest: True
+      latest: False
       oldest: False
     executors:
       defaults:
diff --git a/tests/settings/nersc.yml b/tests/settings/nersc.yml
index 1d851ec4c..654eb9f8c 100644
--- a/tests/settings/nersc.yml
+++ b/tests/settings/nersc.yml
@@ -3,6 +3,8 @@ system:
     hostnames: ["login*"]
     moduletool: lmod
     poolsize: 8
+    max_jobs: 10
+    pager: False
     buildspecs:
       rebuild: False
       count: 15
@@ -12,7 +14,7 @@ system:
       count: 25
       terse: False
       format: "name,id,state,runtime,returncode"
-      latest: True
+      latest: False
       oldest: False
     compilers:
       enable_prgenv: true
diff --git a/tests/settings/pbs.yml b/tests/settings/pbs.yml
index 9732e7a06..1777d6bb4 100644
--- a/tests/settings/pbs.yml
+++ b/tests/settings/pbs.yml
@@ -2,6 +2,9 @@ system:
   generic:
     hostnames: ['.*']
     moduletool: N/A
+    poolsize: 1
+    max_jobs: 1
+    pager: False
     buildspecs:
       rebuild: False
       count: 15
@@ -11,7 +14,7 @@ system:
       count: 25
       terse: False
       format: "name,id,state,runtime,returncode"
-      latest: True
+      latest: False
       oldest: False
     executors:
       defaults:
diff --git a/tests/test_nersc.py b/tests/test_nersc.py
index 3998e51ec..496d11d3f 100644
--- a/tests/test_nersc.py
+++ b/tests/test_nersc.py
@@ -1,27 +1,27 @@
 import os
-import socket
 import tempfile
 
 import pytest
 
 from buildtest.cli.build import BuildTest
 from buildtest.cli.buildspec import BuildspecCache
-from buildtest.cli.compilers import BuildtestCompilers, compiler_find, compiler_test
+from buildtest.cli.compilers import (
+    BuildtestCompilers,
+    compiler_find,
+    compiler_test,
+    remove_compilers,
+)
 from buildtest.config import SiteConfiguration
 from buildtest.defaults import BUILDTEST_ROOT
 from buildtest.system import BuildTestSystem
 
 
 class TestNersc:
-    hostname = socket.getfqdn()
     here = os.path.dirname(os.path.abspath(__file__))
-
-    if not hostname.startswith("login"):
+    if not os.getenv("NERSC_HOST") == "perlmutter":
         pytest.skip(
-            "This test runs on Perlmutter Login nodes ('login*')",
-            allow_module_level=True,
+            "This test can only run on Perlmutter Login nodes", allow_module_level=True
         )
-
     settings_file = os.path.join(here, "settings", "nersc.yml")
 
     system = BuildTestSystem()
@@ -32,6 +32,12 @@ class TestNersc:
     BuildspecCache(rebuild=True, configuration=bc)
 
     def test_slurm_hostname(self):
+        if not os.getenv("NERSC_HOST") == "perlmutter":
+            pytest.skip(
+                "This test can only run on Perlmutter Login nodes",
+                allow_module_level=True,
+            )
+
         cmd = BuildTest(
             configuration=self.bc,
             buildspecs=[
@@ -47,6 +53,11 @@ def test_slurm_hostname(self):
         cmd.build()
 
     def test_slurm_max_pend(self):
+        if not os.getenv("NERSC_HOST") == "perlmutter":
+            pytest.skip(
+                "This test can only run on Perlmutter Login nodes",
+                allow_module_level=True,
+            )
         cmd = BuildTest(
             configuration=self.bc,
             buildspecs=[
@@ -66,6 +77,11 @@ def test_slurm_max_pend(self):
             cmd.build()
 
     def test_compiler_find(self):
+        if not os.getenv("NERSC_HOST") == "perlmutter":
+            pytest.skip(
+                "This test can only run on Perlmutter Login nodes",
+                allow_module_level=True,
+            )
         # testing buildtest config compilers find
         compilers = BuildtestCompilers(configuration=self.bc)
         compilers.find_compilers()
@@ -74,10 +90,20 @@ def test_compiler_find(self):
         compiler_find(configuration=self.bc, detailed=True)
 
     def test_compiler_test(self):
+        if not os.getenv("NERSC_HOST") == "perlmutter":
+            pytest.skip(
+                "This test can only run on Perlmutter Login nodes",
+                allow_module_level=True,
+            )
         # testing buildtest config compilers test
         compiler_test(configuration=self.bc)
 
     def test_compiler_find_alternative_filepath(self):
+        if not os.getenv("NERSC_HOST") == "perlmutter":
+            pytest.skip(
+                "This test can only run on Perlmutter Login nodes",
+                allow_module_level=True,
+            )
         # testing buildtest config compilers find
         compilers = BuildtestCompilers(configuration=self.bc)
         compilers.find_compilers()
@@ -86,3 +112,7 @@ def test_compiler_find_alternative_filepath(self):
         temp_path = tempfile.NamedTemporaryFile(dir=os.path.expanduser("~"))
         compiler_find(configuration=self.bc, filepath=temp_path.name)
         temp_path.close()
+
+    def test_compiler_remove(self):
+        compilers = BuildtestCompilers(configuration=self.bc)
+        remove_compilers(configuration=self.bc, names=compilers.names())
diff --git a/tutorials/test_status/status_regex.yml b/tutorials/test_status/status_regex.yml
index c334d1eee..2447bbe07 100644
--- a/tutorials/test_status/status_regex.yml
+++ b/tutorials/test_status/status_regex.yml
@@ -26,18 +26,18 @@ buildspecs:
     type: script
     tags: [system]
     description: Pass test based on regular expression
-    run: echo "PASS"
+    run: echo "PASS" 1>&2
     status:
       regex:
         stream: stderr
-        exp: "^(PASS)$"
+        exp: '^(PASS)$'
 
   status_regex_stderr_fail:
     executor: generic.local.bash
     type: script
     tags: [system]
     description: Pass test based on regular expression
-    run: echo "FAIL"
+    run: echo "FAIL" 1>&2
     status:
       regex:
         stream: stderr