readability-cli 0.8.3__tar.gz → 0.8.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. {readability_cli-0.8.3 → readability_cli-0.8.4}/PKG-INFO +1 -1
  2. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/jsoncstyleguide.md +1 -1
  3. {readability_cli-0.8.3 → readability_cli-0.8.4}/pyproject.toml +1 -1
  4. {readability_cli-0.8.3 → readability_cli-0.8.4}/readability.py +23 -5
  5. {readability_cli-0.8.3 → readability_cli-0.8.4}/test_readability.py +82 -0
  6. {readability_cli-0.8.3 → readability_cli-0.8.4}/uv.lock +1 -1
  7. {readability_cli-0.8.3 → readability_cli-0.8.4}/.github/workflows/ci.yml +0 -0
  8. {readability_cli-0.8.3 → readability_cli-0.8.4}/.github/workflows/publish.yml +0 -0
  9. {readability_cli-0.8.3 → readability_cli-0.8.4}/.github/workflows/update-guides.yml +0 -0
  10. {readability_cli-0.8.3 → readability_cli-0.8.4}/.gitignore +0 -0
  11. {readability_cli-0.8.3 → readability_cli-0.8.4}/.python-version +0 -0
  12. {readability_cli-0.8.3 → readability_cli-0.8.4}/LICENSE +0 -0
  13. {readability_cli-0.8.3 → readability_cli-0.8.4}/README.md +0 -0
  14. {readability_cli-0.8.3 → readability_cli-0.8.4}/configs/biome-default.json +0 -0
  15. {readability_cli-0.8.3 → readability_cli-0.8.4}/configs/pyrefly.toml +0 -0
  16. {readability_cli-0.8.3 → readability_cli-0.8.4}/configs/ruff.toml +0 -0
  17. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/Rguide.md +0 -0
  18. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/cppguide.md +0 -0
  19. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/csharp-style.md +0 -0
  20. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/docguide-style.md +0 -0
  21. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/go-guide.md +0 -0
  22. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/htmlcssguide.md +0 -0
  23. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/javaguide.md +0 -0
  24. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/jsguide.md +0 -0
  25. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/objcguide.md +0 -0
  26. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/pyguide.md +0 -0
  27. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/shellguide.md +0 -0
  28. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/tsguide.md +0 -0
  29. {readability_cli-0.8.3 → readability_cli-0.8.4}/guides/vimscriptguide.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: readability-cli
3
- Version: 0.8.3
3
+ Version: 0.8.4
4
4
  Summary: A CLI to lint, format, and type-check code with Google-style defaults, and pull Google style guides in markdown format.
5
5
  Project-URL: Homepage, https://github.com/owahltinez/readability
6
6
  Project-URL: Repository, https://github.com/owahltinez/readability
@@ -123,7 +123,7 @@ Property names must conform to the following guidelines:
123
123
 
124
124
  * Property names should be meaningful names with defined semantics.
125
125
  * Property names must be camel-cased, ascii strings.
126
- * The first character must be a letter, an underscore (\_) or a dollar sign ($).
126
+ * The first character must be a letter, an underscore (_) or a dollar sign ($).
127
127
  * Subsequent characters can be a letter, a digit, an underscore, or a dollar sign.
128
128
  * Reserved JavaScript keywords should be avoided (A list of reserved JavaScript keywords can be found below).
129
129
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "readability-cli"
3
- version = "0.8.3"
3
+ version = "0.8.4"
4
4
  description = "A CLI to lint, format, and type-check code with Google-style defaults, and pull Google style guides in markdown format."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -1486,6 +1486,12 @@ def _get_tool_definitions(
1486
1486
  pyrefly_config = _default_config_args(
1487
1487
  project_root, ["pyrefly.toml"], "pyrefly"
1488
1488
  )
1489
+ # An explicit path switches Pyrefly to single-file mode, where the
1490
+ # project's includes, excludes, and project-rooted import resolution are
1491
+ # deliberately ignored. A directory backed by project-owned settings is
1492
+ # a project check, so let Pyrefly discover its files from that config.
1493
+ pyrefly_project_mode = path.is_dir() and not pyrefly_config
1494
+ pyrefly_targets = [] if pyrefly_project_mode else [path_str]
1489
1495
  biome_config = []
1490
1496
  if not any(
1491
1497
  (project_root / filename).exists()
@@ -1552,7 +1558,13 @@ def _get_tool_definitions(
1552
1558
  {
1553
1559
  # Type checker only: it reports findings but cannot fix or format
1554
1560
  "name": "pyrefly",
1555
- "check": [*pyrefly, "check", *pyrefly_config, path_str],
1561
+ "check": [
1562
+ *pyrefly,
1563
+ "check",
1564
+ *pyrefly_config,
1565
+ *pyrefly_targets,
1566
+ ],
1567
+ **({"cwd": project_root} if pyrefly_project_mode else {}),
1556
1568
  "trigger": ["pyproject.toml", "pyrefly.toml"],
1557
1569
  "extensions": [".py"],
1558
1570
  },
@@ -1668,6 +1680,7 @@ def _run_tool(
1668
1680
  logger.info("Running %s...", tool_name)
1669
1681
 
1670
1682
  report = CheckReport()
1683
+ cwd = tool_config.get("cwd")
1671
1684
  try:
1672
1685
  if fix:
1673
1686
  # Formatters rewrite files, fixers apply what they can. Both
@@ -1676,11 +1689,11 @@ def _run_tool(
1676
1689
  # and report what they could not deal with.
1677
1690
  for phase in ("format", "fix"):
1678
1691
  if phase in tool_config:
1679
- result = _capture_tool_command(tool_config[phase])
1692
+ result = _capture_tool_command(tool_config[phase], cwd=cwd)
1680
1693
  if _tool_checked_files(tool_name, result):
1681
1694
  report.ran.add(tool_name)
1682
1695
  elif "check_format" in tool_config:
1683
- result = _capture_tool_command(tool_config["check_format"])
1696
+ result = _capture_tool_command(tool_config["check_format"], cwd=cwd)
1684
1697
  if _tool_checked_files(tool_name, result):
1685
1698
  report.ran.add(tool_name)
1686
1699
  # gofmt reports by naming files rather than by exit code
@@ -1694,7 +1707,7 @@ def _run_tool(
1694
1707
  )
1695
1708
 
1696
1709
  if "check" in tool_config:
1697
- result = _capture_tool_command(tool_config["check"])
1710
+ result = _capture_tool_command(tool_config["check"], cwd=cwd)
1698
1711
  if _tool_checked_files(tool_name, result):
1699
1712
  report.ran.add(tool_name)
1700
1713
  if result.returncode != 0:
@@ -1733,11 +1746,15 @@ def _tool_checked_files(
1733
1746
  return not any(summary in output for summary in zero_file_summaries)
1734
1747
 
1735
1748
 
1736
- def _capture_tool_command(cmd: list[str]) -> subprocess.CompletedProcess:
1749
+ def _capture_tool_command(
1750
+ cmd: list[str], cwd: Path | None = None
1751
+ ) -> subprocess.CompletedProcess:
1737
1752
  """Run a tool and capture what it said, whatever its exit code.
1738
1753
 
1739
1754
  Args:
1740
1755
  cmd: The command list to execute.
1756
+ cwd: Directory in which the tool should run. Defaults to the caller's
1757
+ current working directory.
1741
1758
 
1742
1759
  Returns:
1743
1760
  The completed process, including captured output and its exit code.
@@ -1753,6 +1770,7 @@ def _capture_tool_command(cmd: list[str]) -> subprocess.CompletedProcess:
1753
1770
  text=True,
1754
1771
  check=False,
1755
1772
  timeout=DEFAULT_TIMEOUT,
1773
+ cwd=cwd,
1756
1774
  )
1757
1775
 
1758
1776
 
@@ -459,6 +459,36 @@ def test_check_command_pyrefly(
459
459
  assert ["pyrefly", "check", "--config", cfg, "script.py"] in called_cmds
460
460
 
461
461
 
462
+ @patch("shutil.which")
463
+ @patch("subprocess.run")
464
+ def test_check_command_runs_configured_directory_as_pyrefly_project(
465
+ mock_run: MagicMock, mock_which: MagicMock, tmp_path: Path
466
+ ) -> None:
467
+ """The CLI lets project-owned includes and excludes select Python files."""
468
+ mock_which.side_effect = lambda name: name if name == "pyrefly" else None
469
+ mock_run.return_value = MagicMock(returncode=0, stdout="", stderr="")
470
+
471
+ runner = CliRunner()
472
+ with runner.isolated_filesystem(temp_dir=tmp_path):
473
+ Path("pyrefly.toml").write_text(
474
+ 'project-excludes = ["**/excluded.py"]\n'
475
+ )
476
+ Path("main.py").touch()
477
+ project_root = Path.cwd()
478
+
479
+ result = runner.invoke(cli, ["check", "."])
480
+
481
+ assert result.exit_code == 0
482
+ pyrefly_calls = [
483
+ invocation
484
+ for invocation in mock_run.call_args_list
485
+ if invocation.args[0][0] == "pyrefly"
486
+ ]
487
+ assert len(pyrefly_calls) == 1
488
+ assert pyrefly_calls[0].args[0] == ["pyrefly", "check"]
489
+ assert pyrefly_calls[0].kwargs["cwd"] == project_root
490
+
491
+
462
492
  def test_has_project_config(tmp_path: Path) -> None:
463
493
  """Tests project config detection via dedicated files and pyproject.
464
494
 
@@ -514,6 +544,58 @@ def test_default_configs_omitted_when_project_configured(
514
544
  assert "--config-path" not in tools["biome"][command]
515
545
 
516
546
 
547
+ def test_pyrefly_uses_project_mode_only_for_configured_directories(
548
+ tmp_path: Path,
549
+ ) -> None:
550
+ """Directories use config discovery while explicit files stay explicit."""
551
+ (tmp_path / "pyrefly.toml").write_text(
552
+ 'project-excludes = ["**/excluded.py"]\n'
553
+ )
554
+ py_file = tmp_path / "main.py"
555
+ py_file.touch()
556
+
557
+ with patch("shutil.which", side_effect=lambda name: name):
558
+ directory_tools = {
559
+ tool["name"]: tool
560
+ for tool in _get_tool_definitions(tmp_path, tmp_path)
561
+ }
562
+ file_tools = {
563
+ tool["name"]: tool
564
+ for tool in _get_tool_definitions(py_file, tmp_path)
565
+ }
566
+
567
+ assert directory_tools["pyrefly"]["check"] == ["pyrefly", "check"]
568
+ assert directory_tools["pyrefly"]["cwd"] == tmp_path
569
+ assert file_tools["pyrefly"]["check"] == [
570
+ "pyrefly",
571
+ "check",
572
+ str(py_file),
573
+ ]
574
+ assert "cwd" not in file_tools["pyrefly"]
575
+
576
+
577
+ def test_pyrefly_bundled_config_keeps_an_explicit_directory(
578
+ tmp_path: Path,
579
+ ) -> None:
580
+ """Project mode cannot use a config rooted in the installed package."""
581
+ (tmp_path / "main.py").touch()
582
+
583
+ with patch("shutil.which", side_effect=lambda name: name):
584
+ tools = {
585
+ tool["name"]: tool
586
+ for tool in _get_tool_definitions(tmp_path, tmp_path)
587
+ }
588
+
589
+ assert tools["pyrefly"]["check"] == [
590
+ "pyrefly",
591
+ "check",
592
+ "--config",
593
+ str(_bundled_config("pyrefly")),
594
+ str(tmp_path),
595
+ ]
596
+ assert "cwd" not in tools["pyrefly"]
597
+
598
+
517
599
  def test_biome_bundled_config_is_injected_into_every_command(
518
600
  tmp_path: Path,
519
601
  ) -> None:
@@ -194,7 +194,7 @@ wheels = [
194
194
 
195
195
  [[package]]
196
196
  name = "readability-cli"
197
- version = "0.8.3"
197
+ version = "0.8.4"
198
198
  source = { editable = "." }
199
199
  dependencies = [
200
200
  { name = "beautifulsoup4" },
File without changes