Skip to content
This repository was archived by the owner on Jun 16, 2026. It is now read-only.

Commit d34694c

Browse files
committed
fix: formatting errors and failure to detect empty or missing __init__ modules
1 parent 05024a3 commit d34694c

2 files changed

Lines changed: 34 additions & 31 deletions

File tree

src/exportify/pipeline.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,6 @@ def _generate_code(
147147

148148
for manifest in manifests.values():
149149
if not self._should_generate_init(manifest):
150-
skipped_files.append(
151-
SkippedFile(
152-
path=Path(manifest.module_path),
153-
reason="Not a package or has no exports to generate",
154-
)
155-
)
156150
continue
157151

158152
try:
@@ -174,15 +168,18 @@ def _should_generate_init(self, manifest: ExportManifest) -> bool:
174168
# It needs one if:
175169
# 1. It already has one (recorded in self._package_modules)
176170
# 2. It has exports (own or propagated) AND it has children (it's a directory)
177-
# 3. It's the root package being processed (optional, but good for consistency)
171+
# 3. It's a directory (parent) in our source tree
178172
is_existing_package = manifest.module_path in self._package_modules
179173
has_exports = len(manifest.all_exports) > 0
180174

181175
# Use graph to check if it's a parent of other modules
182176
node = self.graph.modules.get(manifest.module_path)
183177
is_parent = bool(node and node.children)
184178

185-
return is_existing_package or (has_exports and is_parent)
179+
# Generate if it exists OR if it is a parent (directory package)
180+
# Even if it has no exports yet, a package usually needs an __init__.py
181+
# but here we focus on those that are parents of our discovered modules.
182+
return is_existing_package or is_parent
186183

187184
def _process_manifest(
188185
self, manifest: ExportManifest, *, dry_run: bool
@@ -333,7 +330,7 @@ def _process_file(self, file_path: Path, source_root: Path) -> None:
333330
parts[-1] = relative.stem
334331
is_package = False
335332

336-
module_path = ".".join(parts) if parts else "root"
333+
module_path = ".".join(parts) if parts else ""
337334

338335
# Track package modules so the generator only writes __init__.py for them.
339336
if is_package:

src/exportify/utils.py

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -196,37 +196,43 @@ def _run_ruff_format(
196196
"""Run ruff format via subprocess and return formatted content if successful."""
197197
import subprocess
198198

199-
ruff_binary = shutil.which("ruff") or f"{shutil.which('uvx')} ruff"
199+
ruff_binary = shutil.which("ruff")
200+
if not ruff_binary and shutil.which("uvx"):
201+
ruff_binary = "uvx ruff"
202+
200203
if not ruff_binary:
201204
return None
205+
206+
# 1. Run ruff format
207+
# Use split() if ruff_binary is "uvx ruff"
208+
cmd = ruff_binary.split() if " " in ruff_binary else [ruff_binary]
202209
result = subprocess.run(
203-
[ruff_binary, "format", "--verbose" if verbose else "--quiet", *stdin_filename_args, "-"],
210+
[*cmd, "format", "--quiet", *stdin_filename_args, "-"],
204211
input=content,
205212
capture_output=True,
206213
text=True,
207214
check=False,
208215
)
216+
if result.returncode != 0:
217+
return None
218+
219+
formatted_content = result.stdout
220+
221+
# 2. Run ruff check --fix on the formatted content
222+
result = subprocess.run(
223+
[*cmd, "check", "--fix", "--quiet", *stdin_filename_args, "-"],
224+
input=formatted_content,
225+
capture_output=True,
226+
text=True,
227+
check=False,
228+
)
229+
209230
if result.returncode == 0:
210-
stdout_message = result.stdout.strip()
211-
result = subprocess.run(
212-
[
213-
ruff_binary,
214-
"check",
215-
"--fix",
216-
"--verbose" if verbose else "--quiet",
217-
*stdin_filename_args,
218-
"-",
219-
],
220-
input=content,
221-
capture_output=True,
222-
text=True,
223-
check=False,
224-
)
225-
if result.returncode == 0:
226-
stdout_message += f"\n\n{result.stdout.strip()}"
227-
stdout_message += "\nAll checks passed after formatting."
228-
return stdout_message
229-
return result.stderr.strip() if result.stderr else None
231+
# Return the final content (from stdout if any, else use formatted_content)
232+
# Note: ruff check --fix - usually outputs the fixed content to stdout
233+
return result.stdout or formatted_content
234+
235+
return None
230236

231237

232238
def format_content(content: str, *, filename: Path | None = None, verbose: bool = False) -> str:

0 commit comments

Comments
 (0)