Skip to content

feat(init): idempotent + --force/--out#5

Merged
ali90h merged 5 commits into
mainfrom
feat/init-idempotent
Aug 19, 2025
Merged

feat(init): idempotent + --force/--out#5
ali90h merged 5 commits into
mainfrom
feat/init-idempotent

Conversation

@ali90h
Copy link
Copy Markdown
Owner

@ali90h ali90h commented Aug 16, 2025

feat(init): idempotent + --force/--out

What / Why

This PR implements the init command to create default devcontainer configurations with idempotent behavior, force overwrite capability, and custom output path support.

Key Features:

  • Idempotent behavior: Won't overwrite existing files without --force flag (returns exit code 0)
  • Force overwrite: --force flag enables overwriting existing devcontainer files
  • Custom output paths: --out PATH supports writing to custom locations with automatic parent directory creation
  • Atomic file writes: Uses temporary file + rename pattern for safe file operations
  • Proper exit codes: 0=success/exists, 1=I/O errors, 2=misuse errors
  • Default configuration: Python 3.11, Node 20, and Go 1.22 features with venv setup

Architecture:

  • Pure env.py module with exception-based error handling (no prints, no exit codes)
  • CLI layer in cli.py handles exit codes and user messages
  • Comprehensive test coverage with unit, integration, and subprocess tests

Fixes #4

How I Tested

Ran the complete validation suite locally:

pre-commit clean && pre-commit run --all-files  # ✅ All hooks passed
pytest -q                                       # ✅ 52 tests passed
python -m black --check .                      # ✅ Formatting verified

Test Coverage:

  • Default devcontainer configuration validation (Python 3.11, Node 20, Go 1.22)
  • Idempotent behavior without --force flag
  • Force overwrite functionality with --force
  • Custom output paths with --out option
  • Parent directory creation
  • Error handling: invalid paths, permission denied, directory conflicts
  • Exit code validation for all scenarios
  • CLI integration with mocked and subprocess testing
  • Atomic file write operations

Output Snippets

First time creation:

$ autorepro init
Wrote devcontainer to ./devcontainer.json

Idempotent behavior (file already exists):

$ autorepro init
devcontainer.json already exists at ./devcontainer.json.
Use --force to overwrite or --out <path> to write elsewhere.

Force overwrite existing file:

$ autorepro init --force
Wrote devcontainer to /path/to/dev/devcontainer.json

Custom output location:

$ autorepro init --out dev/devcontainer.json
Wrote devcontainer to /path/to/dev/devcontainer.json

Acceptance

  • ✅ Implements exact message wording as specified in Issue # T-002 — init: idempotent + --force / --out #4
  • ✅ Idempotent behavior with proper exit code 0 when file exists
  • ✅ Force overwrite functionality with --force flag
  • ✅ Custom output paths with automatic directory creation
  • ✅ Atomic file writes using temp file + rename pattern
  • ✅ Proper exit codes: 0=success/exists, 1=I/O errors, 2=misuse
  • ✅ Default devcontainer includes Python 3.11, Node 20, Go 1.22
  • ✅ Comprehensive test coverage (23 new tests)
  • ✅ CI: should be green on this PR

@ali90h ali90h merged commit 7ede1dc into main Aug 19, 2025
1 check passed
@ali90h ali90h deleted the feat/init-idempotent branch August 19, 2025 19:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

# T-002 — init: idempotent + --force / --out

1 participant