{"id":31813658,"url":"https://github.com/dhodgson615/lintomatic","last_synced_at":"2026-05-18T03:03:52.137Z","repository":{"id":315813280,"uuid":"1060913346","full_name":"dhodgson615/lintomatic","owner":"dhodgson615","description":"A basic linter for Python projects written in Haskell","archived":false,"fork":false,"pushed_at":"2025-09-20T23:23:56.000Z","size":1508,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-20T23:27:12.940Z","etag":null,"topics":["developer-tools","functional-programming","haskell","lint","linter","linters","linting","python","python-3"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dhodgson615.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-20T21:09:34.000Z","updated_at":"2025-09-20T23:20:40.000Z","dependencies_parsed_at":"2025-09-20T23:27:17.775Z","dependency_job_id":"41da409a-7e02-4752-8b4d-f08356ed807b","html_url":"https://github.com/dhodgson615/lintomatic","commit_stats":null,"previous_names":["dhodgson615/lintomatic"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/dhodgson615/lintomatic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhodgson615%2Flintomatic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhodgson615%2Flintomatic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhodgson615%2Flintomatic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhodgson615%2Flintomatic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dhodgson615","download_url":"https://codeload.github.com/dhodgson615/lintomatic/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhodgson615%2Flintomatic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279006769,"owners_count":26084148,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["developer-tools","functional-programming","haskell","lint","linter","linters","linting","python","python-3"],"created_at":"2025-10-11T08:20:29.182Z","updated_at":"2025-10-11T08:20:31.653Z","avatar_url":"https://github.com/dhodgson615.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lintomatic\n\nA specialized Python linter written in Haskell that focuses on docstring line length and indentation consistency.\n\n## Features\n\n- **Docstring Length Checking**: Identifies lines within Python docstrings that exceed 72 characters\n- **Indentation Analysis**: Detects problematic indentation patterns where code dedentation occurs without proper separation\n- **Block Statement Blank Lines**: Ensures Python block statements (if, elif, else, for, while, try, except, finally, with, def, class) have blank lines before them for better readability\n- **Keyword Statement Separation**: Ensures keyword statements (assert, return, if, etc.) have blank lines separating them from non-keyword statements (assignments, expressions) at module level\n- **Recursive Directory Scanning**: Automatically finds and processes all `.py` files in a directory tree\n- **Clear Output**: Provides precise line numbers and categorized issue reporting\n\n## Dependencies\n\n### Haskell Environment\n- **GHC** (Glasgow Haskell Compiler) version 8.10 or later\n- **Cabal** or **Stack** for dependency management (optional, but recommended for development)\n\n### System Requirements\n- Unix-like operating system (Linux, macOS)\n- Windows (with appropriate Haskell installation)\n\n### Installing Haskell Dependencies\n\n#### Option 1: Using GHCup (Recommended)\n```bash\ncurl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh\nghcup install ghc\nghcup install cabal\n```\n\n#### Option 2: System Package Manager\n\n**Ubuntu/Debian:**\n```bash\nsudo apt-get update\nsudo apt-get install ghc cabal-install\n```\n\n**macOS (Homebrew):**\n```bash\nbrew install ghc cabal-install\n```\n\n**Arch Linux:**\n```bash\nsudo pacman -S ghc cabal-install\n```\n\n### Verifying Installation\n```bash\nghc --version      # Should show version 8.10+\ncabal --version    # Should show cabal-install version\n```\n\n## Installation\n\n### Quick Start\n1. Clone the repository:\n   ```bash\n   git clone https://github.com/dhodgson615/lintomatic.git\n   cd lintomatic\n   ```\n\n2. Compile the program:\n   ```bash\n   ghc --make src/lintomatic.hs -o lintomatic\n   ```\n\n3. Run the linter:\n   ```bash\n   ./lintomatic\n   ```\n\n### Alternative Build Methods\n\n#### Using Cabal\n```bash\ncabal build\ncabal run lintomatic\n```\n\n#### Using Make (with provided Makefile)\n```bash\nmake               # Build the executable\nmake test          # Run quick functionality test\nmake check-env     # Verify Haskell environment\nmake clean         # Clean build artifacts\n```\n\n#### Manual Compilation with Optimizations\n```bash\nghc -O2 --make src/lintomatic.hs -o lintomatic\n```\n\n## Usage\n\n### Basic Usage\nRun lintomatic from any directory containing Python files:\n\n```bash\n./lintomatic\n```\n\nThe linter will:\n1. Recursively find all `.py` files in the current directory\n2. Check each file for docstring line length, indentation issues, and block statement formatting\n3. Report findings with specific line numbers\n\n### Example Output\n```\nFile: src/example.py\n        Docstring lines exceeding 72 characters:\n            Line 15\n            Line 23\n        Lines with problematic indentation:\n            Line 45\n        Block statements missing blank lines above:\n            Line 12\n            Line 34\n        Keyword statements missing blank lines from non-keyword statements:\n            Line 18\n            Line 28\n\nFile: tests/test_module.py\n        Docstring lines exceeding 72 characters:\n            Line 8\n```\n\n### Command Line Options\nCurrently, lintomatic runs with default settings:\n- Maximum docstring line length: 72 characters\n- Scans from current directory recursively\n\n## Test Cases\n\n### Manual Testing\n\nCreate test files to verify functionality:\n\n#### Test 1: Docstring Length Issues\nCreate `test_docstring.py`:\n```python\n\"\"\"\nThis is a very long docstring line that definitely exceeds the 72 character limit\n\"\"\"\n\ndef function():\n    \"\"\"Short docstring\"\"\"\n    pass\n\nclass Example:\n    \"\"\"\n    Another long line in a class docstring that should be flagged by the linter tool\n    \"\"\"\n    pass\n```\n\n**Expected Output:**\n```\nFile: test_docstring.py\n        Docstring lines exceeding 72 characters:\n            Line 2\n            Line 10\n```\n\n#### Test 2: Indentation Problems\nCreate `test_indentation.py`:\n```python\ndef example():\n    if True:\n        print(\"indented\")\n    print(\"dedented without blank line above\")  # Should be flagged\n\n    if False:\n        pass\n        \n    print(\"properly separated\")  # Should NOT be flagged\n```\n\n**Expected Output:**\n```\nFile: test_indentation.py\n        Lines with problematic indentation:\n            Line 4\n```\n\n#### Test 3: Block Statement Issues\nCreate `test_blocks.py`:\n```python\nx = 1\nif x \u003e 0:  # Missing blank line before if\n    pass\n\ndef function():\n    pass\nclass TestClass:  # Missing blank line before class\n    pass\n```\n\n**Expected Output:**\n```\nFile: test_blocks.py\n        Block statements missing blank lines above:\n            Line 2\n            Line 6\n```\n\n#### Test 4: Mixed Issues\nCreate `test_mixed.py`:\n```python\n\"\"\"\nThis docstring has a line that is way too long and exceeds the character limit\n\"\"\"\n\ndef problematic_function():\n    \"\"\"Another very long docstring line that should definitely be caught by the linter\"\"\"\n    x = 1\n    if x:\n        y = 2\n    z = 3  # Problematic dedentation\n```\n\n**Expected Output:**\n```\nFile: test_mixed.py\n        Docstring lines exceeding 72 characters:\n            Line 2\n            Line 6\n        Lines with problematic indentation:\n            Line 10\n        Block statements missing blank lines above:\n            Line 8\n```\n\n#### Test 5: Keyword Statement Separation\nCreate `test_keywords.py`:\n```python\na = 10\nb = 9\nc = 8\nassert b == 9  # Missing blank line before assert\nx = 1\nif x \u003e 0:  # Missing blank line before if\n    pass\n```\n\n**Expected Output:**\n```\nFile: test_keywords.py\n        Keyword statements missing blank lines from non-keyword statements:\n            Line 4\n            Line 6\n```\n\n### Automated Testing\n\nLintomatic includes a comprehensive test suite with both unit tests and property-based tests using Haskell's HUnit, QuickCheck, and Tasty frameworks.\n\n#### Running the Test Suite\n\n**Quick validation test:**\n```bash\n./test/validate_lintomatic.sh\n```\n\n**Comprehensive test suite:**\n```bash\ncabal test\n```\n\n**Using Make targets:**\n```bash\nmake test              # Quick functionality test\nmake test-cabal        # Comprehensive test suite with cabal\nmake test-all          # All tests (comprehensive + validation)\nmake test-comprehensive # Complete test suite via script\n```\n\n**Using the test script:**\n```bash\n./run_tests.sh\n```\n\n#### Test Suite Components\n\n**Unit Tests:**\n- **Utility Functions**: Tests for string manipulation functions (`strip`, `lstrip`, `rstrip`)\n- **File Discovery**: Tests for Python file discovery in directory trees\n- **Docstring Length**: Tests for detecting overly long docstring lines\n- **Indentation**: Tests for problematic dedentation detection\n- **Block Statements**: Tests for block statement formatting rules\n- **Keyword Statements**: Tests for keyword/non-keyword transitions\n\n**Property-Based Tests:**\n- **String processing properties**: Idempotency, composition, whitespace handling\n- **Edge case generation**: Automatic testing with randomly generated inputs\n- **Invariant checking**: Ensures functions maintain expected mathematical properties\n\n#### Test Statistics\nThe test suite includes:\n- **31 test cases** covering all major functionality\n- **100 property-based tests** per property (automatically generated)\n- **Unit tests** for specific behavior validation\n- **Integration tests** via the existing validation script\n\n#### Coverage\nTests cover:\n- ✅ Core linting functions\n- ✅ File system operations\n- ✅ String processing utilities\n- ✅ Edge cases and error conditions\n- ✅ Property-based invariants\n- ✅ Backward compatibility\n\n## Haskell Environment Checks\n\n### Pre-compilation Checks\nVerify your Haskell environment before building:\n\n```bash\n# Check GHC installation\nghc --version\n\n# Check if required modules are available\nghc-pkg list | grep -E \"(directory|filepath|base)\"\n\n# Test basic compilation\necho 'main = putStrLn \"Hello\"' \u003e test.hs\nghc test.hs -o test\n./test\nrm test test.hi test.o test.hs\n```\n\n### Common Issues and Solutions\n\n#### Issue: \"Module not found\" errors\n**Solution:** Ensure GHC base libraries are installed:\n```bash\ncabal update\ncabal install --dependencies-only .\n```\n\n#### Issue: Permission denied when running executable\n**Solution:** Make the binary executable:\n```bash\nchmod +x lintomatic\n```\n\n#### Issue: \"ghc: command not found\"\n**Solution:** Add GHC to your PATH or use full paths:\n```bash\nexport PATH=\"$HOME/.ghcup/bin:$PATH\"\n# or\n/usr/local/bin/ghc --make src/lintomatic.hs -o lintomatic\n```\n\n## Use Cases\n\n### 1. Pre-commit Hook\nIntegrate lintomatic into your git workflow:\n```bash\n# In .git/hooks/pre-commit\n#!/bin/bash\ncd \"$(git rev-parse --show-toplevel)\"\nif [ -x \"./lintomatic\" ]; then\n    ./lintomatic\n    if [ $? -ne 0 ]; then\n        echo \"Linting issues found. Commit aborted.\"\n        exit 1\n    fi\nfi\n```\n\n### 2. CI/CD Pipeline\nAdd to your GitHub Actions workflow:\n```yaml\n- name: Install Haskell\n  uses: haskell/actions/setup@v2\n  with:\n    ghc-version: '9.2'\n\n- name: Build lintomatic\n  run: ghc --make src/lintomatic.hs -o lintomatic\n\n- name: Run Python linting\n  run: ./lintomatic\n```\n\n### 3. Development Workflow\n- Run before committing Python code changes\n- Integrate with IDE/editor as an external tool\n- Use in code review processes to maintain consistency\n\n### 4. Documentation Quality Assurance\n- Ensure docstrings remain readable within line limits\n- Maintain consistent Python code style across teams\n- Automated enforcement of documentation standards\n\n### 5. Legacy Code Cleanup\n- Identify areas of existing codebases that need attention\n- Gradual improvement of code quality\n- Generate reports for technical debt assessment\n\n## Future Features\n\n### Planned Enhancements\n- [ ] **Configurable Line Length**: Command-line option to set custom line limits\n- [ ] **Configuration Files**: Support for `.lintomatic.yaml` configuration\n- [ ] **Additional Python Checks**: \n  - Import statement organization\n  - Function argument formatting\n  - Comment line length validation\n- [ ] **Output Formats**: JSON, XML, and CSV output options\n- [ ] **IDE Integration**: LSP (Language Server Protocol) support\n- [ ] **Performance Optimization**: Parallel file processing\n- [ ] **Ignore Patterns**: `.lintomaticignore` file support\n- [ ] **Fix Suggestions**: Automatic fixing capabilities for simple issues\n\n### Possible Extensions\n- [ ] **Multi-language Support**: Extend to other languages beyond Python\n- [ ] **Custom Rule Engine**: Plugin system for user-defined rules\n- [ ] **Git Integration**: Only check changed files in commits\n- [ ] **Team Collaboration**: Shared configuration and team-specific rules\n- [ ] **Metrics Dashboard**: Web interface for project linting statistics\n\n### Contributing to Future Features\nWe welcome contributions! Areas where help is particularly needed:\n- Performance optimization for large codebases\n- Cross-platform testing and compatibility\n- Additional linting rules based on Python PEP standards\n- Integration with popular Python development tools\n\n## Contributing\n\n### Development Setup\n1. Fork the repository\n2. Clone your fork: `git clone https://github.com/yourusername/lintomatic.git`\n3. Create a feature branch: `git checkout -b feature-name`\n4. Make changes and test thoroughly\n5. Submit a pull request\n\n### Code Style\n- Follow Haskell conventions and existing code style\n- Add Haddock documentation for new functions\n- Include test cases for new features\n- Ensure compilation without warnings\n\n### Reporting Issues\n- Use GitHub Issues for bug reports and feature requests\n- Include sample Python files that demonstrate the issue\n- Specify your Haskell/GHC version and operating system\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Acknowledgments\n\n- Built with the Glasgow Haskell Compiler\n- Inspired by Python PEP 8 and documentation best practices\n- Thanks to the Haskell community for excellent tooling and libraries\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdhodgson615%2Flintomatic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdhodgson615%2Flintomatic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdhodgson615%2Flintomatic/lists"}