diff --git a/ptr.py b/ptr.py
index 5ee0624..eae138d 100755
--- a/ptr.py
+++ b/ptr.py
@@ -296,7 +296,10 @@ def _generate_pyre_cmd(
 
 
 def _get_test_modules(
-    base_path: Path, stats: Dict[str, int], run_disabled: bool
+    base_path: Path,
+    stats: Dict[str, int],
+    run_disabled: bool,
+    print_non_configured: bool,
 ) -> Dict[Path, Dict]:
     get_tests_start_time = time()
     all_setup_pys = find_setup_pys(
@@ -307,6 +310,7 @@ def _get_test_modules(
     )
     stats["total.setup_pys"] = len(all_setup_pys)
 
+    non_configured_modules = []  # type: List[Path]
     test_modules = {}  # type: Dict[Path, Dict]
     for setup_py in all_setup_pys:  # pylint: disable=R1702
         disabled_err_msg = "Not running {} as ptr is disabled via config".format(
@@ -345,7 +349,13 @@ def _get_test_modules(
                                     setup_py
                                 )
                             )
+        if setup_py not in test_modules:
+            non_configured_modules.append(setup_py)
+
+    if print_non_configured and non_configured_modules:
+        print_non_configured_modules(non_configured_modules)
 
+    stats["total.non_ptr_setup_pys"] = len(non_configured_modules)
     stats["total.ptr_setup_pys"] = len(test_modules)
     stats["runtime.parse_setup_pys"] = int(time() - get_tests_start_time)
     return test_modules
@@ -743,32 +753,35 @@ def find_py_files(py_files: Set[str], base_dir: Path) -> None:
         find_py_files(py_files, directory)
 
 
-def find_setup_pys(
-    base_path: Path, exclude_patterns: Set[str], follow_symlinks: bool = False
-) -> Set[Path]:
-    def _recursive_find_files(files: Set[Path], base_dir: Path) -> None:
-        dirs = [d for d in base_dir.iterdir() if d.is_dir()]
-        files.update(
-            {x for x in base_dir.iterdir() if x.is_file() and x.name == "setup.py"}
-        )
-        for directory in dirs:
-            if not follow_symlinks and directory.is_symlink():
-                continue
+def _recursive_find_files(
+    files: Set[Path], base_dir: Path, exclude_patterns: Set[str], follow_symlinks: bool
+) -> None:
+    dirs = [d for d in base_dir.iterdir() if d.is_dir()]
+    files.update(
+        {x for x in base_dir.iterdir() if x.is_file() and x.name == "setup.py"}
+    )
+    for directory in dirs:
+        if not follow_symlinks and directory.is_symlink():
+            continue
 
-            skip_dir = False
-            for exclude_pattern in exclude_patterns:
-                if directory.match(exclude_pattern):
-                    skip_dir = True
-                    LOG.debug(
-                        "Skipping {} due to exclude pattern {}".format(
-                            directory, exclude_pattern
-                        )
+        skip_dir = False
+        for exclude_pattern in exclude_patterns:
+            if directory.match(exclude_pattern):
+                skip_dir = True
+                LOG.debug(
+                    "Skipping {} due to exclude pattern {}".format(
+                        directory, exclude_pattern
                     )
-            if not skip_dir:
-                _recursive_find_files(files, directory)
+                )
+        if not skip_dir:
+            _recursive_find_files(files, directory, exclude_patterns, follow_symlinks)
+
 
+def find_setup_pys(
+    base_path: Path, exclude_patterns: Set[str], follow_symlinks: bool = False
+) -> Set[Path]:
     setup_pys = set()  # type: Set[Path]
-    _recursive_find_files(setup_pys, base_path)
+    _recursive_find_files(setup_pys, base_path, exclude_patterns, follow_symlinks)
     return setup_pys
 
 
@@ -803,6 +816,12 @@ def parse_setup_cfg(setup_py: Path) -> Dict[str, Any]:
     return ptr_params
 
 
+def print_non_configured_modules(modules: List[Path]) -> None:
+    print("== {} non ptr configured modules ==".format(len(modules)))
+    for module in sorted(modules):
+        print(" - {}".format(str(module)))
+
+
 def print_test_results(
     test_results: Sequence[test_result], stats: Optional[Dict[str, int]] = None
 ) -> Dict[str, int]:
@@ -935,13 +954,16 @@ async def async_main(
     venv: str,
     venv_keep: bool,
     print_cov: bool,
+    print_non_configured: bool,
     run_disabled: bool,
     force_black: bool,
     stats_file: str,
     venv_timeout: float,
 ) -> int:
     stats = defaultdict(int)  # type: Dict[str, int]
-    tests_to_run = _get_test_modules(base_path, stats, run_disabled)
+    tests_to_run = _get_test_modules(
+        base_path, stats, run_disabled, print_non_configured
+    )
     if not tests_to_run:
         LOG.error(
             "{} has no setup.py files with unit tests defined. Exiting".format(
@@ -950,6 +972,9 @@ async def async_main(
         )
         return 1
 
+    if print_non_configured:
+        return 0
+
     try:
         venv_path = Path(venv)  # type: Optional[Path]
         if venv_path and not venv_path.exists():
@@ -1013,6 +1038,11 @@ def main() -> None:
     parser.add_argument(
         "--print-cov", action="store_true", help="Print modules coverage report"
     )
+    parser.add_argument(
+        "--print-non-configured",
+        action="store_true",
+        help="Print modules not configured to run ptr",
+    )
     parser.add_argument(
         "--progress-interval",
         default=0,
@@ -1053,6 +1083,7 @@ def main() -> None:
                     args.venv,
                     args.keep_venv,
                     args.print_cov,
+                    args.print_non_configured,
                     args.run_disabled,
                     args.force_black,
                     args.stats_file,
diff --git a/setup.py b/setup.py
index 0bb7805..c0c56d0 100644
--- a/setup.py
+++ b/setup.py
@@ -20,7 +20,7 @@ ptr_params = {
     "test_suite": "ptr_tests",
     "test_suite_timeout": 120,
     # Relative path from setup.py to module (e.g. ptr == ptr.py)
-    "required_coverage": {"ptr.py": 84, "TOTAL": 89},
+    "required_coverage": {"ptr.py": 83, "TOTAL": 89},
     # Run black or not
     "run_black": True,
     # Run mypy or not
@@ -47,7 +47,7 @@ def get_long_desc() -> str:
 
 setup(
     name=ptr_params["entry_point_module"],
-    version="19.6.15",
+    version="19.7.16",
     description="Parallel asyncio Python setup.(cfg|py) Test Runner",
     long_description=get_long_desc(),
     long_description_content_type="text/markdown",

Add a mode to show all Projects with no PTR params/config set
## How is `ptr` not doing what you expect?
It would be nice if you could have ptr crawl the file system and list all the projects who don't have PTR set in setup.cfg or setup.py

## What is your suggestion to make this better?
- Add the feature

## How can a developer reproduce this?
You can't - But an example run could be:
```
ptr --find-unactivated-modules
```
diff --git a/ptr_tests.py b/ptr_tests.py
index 39afaeb..fb8e02a 100644
--- a/ptr_tests.py
+++ b/ptr_tests.py
@@ -130,7 +130,20 @@ class TestPtr(unittest.TestCase):
     @patch("ptr.run_tests", async_none)
     @patch("ptr._get_test_modules")
     def test_async_main(self, mock_gtm: Mock) -> None:
-        args = [1, Path("/"), "mirror", 1, "venv", True, True, True, False, "stats", 30]
+        args = [
+            1,
+            Path("/"),
+            "mirror",
+            1,
+            "venv",
+            True,
+            True,
+            False,
+            True,
+            False,
+            "stats",
+            30,
+        ]
         mock_gtm.return_value = False
         self.assertEqual(
             self.loop.run_until_complete(ptr.async_main(*args)), 1  # pyre-ignore
@@ -156,7 +169,7 @@ class TestPtr(unittest.TestCase):
         self.assertEqual(
             sc["ptr"].get("pypi_url", ""), expected_pypi_url  # pyre-ignore
         )
-        self.assertEqual(len(sc["ptr"].get("venv_pkgs", "").split()), 8)  # pyre-ignore
+        self.assertEqual(len(sc["ptr"].get("venv_pkgs", "").split()), 8)
 
     @patch("ptr._gen_check_output", async_none)  # noqa
     @patch("ptr._set_pip_mirror")  # noqa
@@ -280,16 +293,20 @@ class TestPtr(unittest.TestCase):
             lib_path.mkdir()
             self.assertIsNone(ptr._get_site_packages_path(lib_path.parent))
 
-    def test_get_test_modules(self) -> None:
+    @patch("ptr.print")  # noqa
+    def test_get_test_modules(self, mock_print: Mock) -> None:
         base_path = Path(__file__).parent
         stats = defaultdict(int)  # type: Dict[str, int]
-        test_modules = ptr._get_test_modules(base_path, stats, True)
+        test_modules = ptr._get_test_modules(base_path, stats, True, True)
         self.assertEqual(
             test_modules[base_path / "setup.py"],
             ptr_tests_fixtures.EXPECTED_TEST_PARAMS,
         )
-        self.assertEqual(stats["total.setup_pys"], 1)
+        self.assertEqual(stats["total.non_ptr_setup_pys"], 0)
         self.assertEqual(stats["total.ptr_setup_pys"], 1)
+        self.assertEqual(stats["total.setup_pys"], 1)
+        # Make sure we don't run print even tho we set the option to True
+        self.assertFalse(mock_print.called)
 
     def test_gen_output(self) -> None:
         test_cmd = ("echo.exe", "''") if ptr.WINDOWS else ("/bin/echo",)
@@ -335,6 +352,13 @@ class TestPtr(unittest.TestCase):
             ptr.parse_setup_cfg(setup_py), ptr_tests_fixtures.EXPECTED_TEST_PARAMS
         )
 
+    @patch("ptr.print")  # noqa
+    def test_print_non_configured_modules(self, mock_print: Mock) -> None:
+        modules = [Path("/tmp/foo/setup.py"), Path("/tmp/bla/setup.py")]
+        # TODO: Workout why pylint things this function does not exist
+        ptr.print_non_configured_modules(modules)  # pylint: disable=E1101
+        self.assertEqual(3, mock_print.call_count)
+
     @patch("ptr.print")  # noqa
     def test_print_test_results(self, mock_print: Mock) -> None:
         stats = ptr.print_test_results(ptr_tests_fixtures.EXPECTED_COVERAGE_RESULTS)
diff --git a/ptr_tests_fixtures.py b/ptr_tests_fixtures.py
index d278888..cb51eaa 100644
--- a/ptr_tests_fixtures.py
+++ b/ptr_tests_fixtures.py
@@ -29,7 +29,7 @@ EXPECTED_TEST_PARAMS = {
     "entry_point_module": "ptr",
     "test_suite": "ptr_tests",
     "test_suite_timeout": 120,
-    "required_coverage": {"ptr.py": 84, "TOTAL": 89},
+    "required_coverage": {"ptr.py": 83, "TOTAL": 89},
     "run_black": True,
     "run_mypy": True,
     "run_flake8": True,
@@ -196,7 +196,7 @@ disabled = true
 entry_point_module = ptr
 test_suite = ptr_tests
 test_suite_timeout = 120
-required_coverage_ptr.py = 84
+required_coverage_ptr.py = 83
 required_coverage_TOTAL = 89
 run_black = true
 run_mypy = true

pip install -e .
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio pytest
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
astroid==3.3.9
black==25.1.0
click==8.1.8
coverage==7.8.0
dataclasses-json==0.5.7
dill==0.3.9
exceptiongroup==1.2.2
execnet==2.1.1
flake8==7.2.0
iniconfig==2.1.0
isort==6.0.1
libcst==1.7.0
marshmallow==3.26.1
marshmallow-enum==1.5.1
mccabe==0.7.0
mypy==1.15.0
mypy-extensions==1.0.0
packaging==24.2
pathspec==0.12.1
platformdirs==4.3.7
pluggy==1.5.0
psutil==7.0.0
-e git+https://github.com/facebookincubator/ptr.git@15f44235105c0e726d385c1e7d9106146db8f4e9#egg=ptr
pycodestyle==2.13.0
pyflakes==3.3.2
Pygments==2.19.1
pylint==3.3.6
pyre-check==0.9.23
pyre-extensions==0.0.32
pytest==8.3.5
pytest-asyncio==0.26.0
pytest-cov==6.0.0
pytest-mock==3.14.0
pytest-xdist==3.6.1
PyYAML==6.0.2
tabulate==0.9.0
TestSlide==2.7.1
tomli==2.2.1
tomlkit==0.13.2
typeguard==2.13.3
typing-inspect==0.9.0
typing_extensions==4.13.0

name: ptr
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - astroid==3.3.9
      - black==25.1.0
      - click==8.1.8
      - coverage==7.8.0
      - dataclasses-json==0.5.7
      - dill==0.3.9
      - exceptiongroup==1.2.2
      - execnet==2.1.1
      - flake8==7.2.0
      - iniconfig==2.1.0
      - isort==6.0.1
      - libcst==1.7.0
      - marshmallow==3.26.1
      - marshmallow-enum==1.5.1
      - mccabe==0.7.0
      - mypy==1.15.0
      - mypy-extensions==1.0.0
      - packaging==24.2
      - pathspec==0.12.1
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - psutil==7.0.0
      - pycodestyle==2.13.0
      - pyflakes==3.3.2
      - pygments==2.19.1
      - pylint==3.3.6
      - pyre-check==0.9.23
      - pyre-extensions==0.0.32
      - pytest==8.3.5
      - pytest-asyncio==0.26.0
      - pytest-cov==6.0.0
      - pytest-mock==3.14.0
      - pytest-xdist==3.6.1
      - pyyaml==6.0.2
      - tabulate==0.9.0
      - testslide==2.7.1
      - tomli==2.2.1
      - tomlkit==0.13.2
      - typeguard==2.13.3
      - typing-extensions==4.13.0
      - typing-inspect==0.9.0
prefix: /opt/conda/envs/ptr

ptr_tests.py::TestPtr::test_async_main ptr_tests.py::TestPtr::test_get_test_modules ptr_tests.py::TestPtr::test_print_non_configured_modules
ptr_tests.py::TestPtr::test_write_stats_file_raise
ptr_tests.py::TestPtr::test_analyze_coverage ptr_tests.py::TestPtr::test_analyze_coverage_errors ptr_tests.py::TestPtr::test_config ptr_tests.py::TestPtr::test_create_venv ptr_tests.py::TestPtr::test_find_setup_py ptr_tests.py::TestPtr::test_find_setup_py_exclude_default ptr_tests.py::TestPtr::test_gen_output ptr_tests.py::TestPtr::test_generate_black_command ptr_tests.py::TestPtr::test_generate_flake8_command ptr_tests.py::TestPtr::test_generate_install_cmd ptr_tests.py::TestPtr::test_generate_mypy_cmd ptr_tests.py::TestPtr::test_generate_pylint_command ptr_tests.py::TestPtr::test_generate_pyre_cmd ptr_tests.py::TestPtr::test_get_site_packages_path_error ptr_tests.py::TestPtr::test_handle_debug ptr_tests.py::TestPtr::test_main ptr_tests.py::TestPtr::test_parse_setup_cfg ptr_tests.py::TestPtr::test_print_test_results ptr_tests.py::TestPtr::test_process_reporter ptr_tests.py::TestPtr::test_run_black ptr_tests.py::TestPtr::test_set_build_env ptr_tests.py::TestPtr::test_set_pip_mirror ptr_tests.py::TestPtr::test_test_runner ptr_tests.py::TestPtr::test_test_steps_runner ptr_tests.py::TestPtr::test_validate_base_dir ptr_tests.py::TestPtr::test_validate_base_dir_fail ptr_tests.py::TestPtr::test_write_stats_file
setup.py ptr.py
setup.py ptr.py