codesorter 0.1.0__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 (60) hide show
  1. codesorter-0.1.0/.github/dependabot.yml +14 -0
  2. codesorter-0.1.0/.github/workflows/ci.yml +17 -0
  3. codesorter-0.1.0/.github/workflows/pre-commit_autoupdate.yml +14 -0
  4. codesorter-0.1.0/.github/workflows/prepare_release.yml +20 -0
  5. codesorter-0.1.0/.github/workflows/pypi.yml +29 -0
  6. codesorter-0.1.0/.github/workflows/scorecard.yml +40 -0
  7. codesorter-0.1.0/.github/workflows/stale_action.yml +12 -0
  8. codesorter-0.1.0/.github/workflows/tag_release.yml +10 -0
  9. codesorter-0.1.0/.gitignore +39 -0
  10. codesorter-0.1.0/.libcst.codemod.yaml +36 -0
  11. codesorter-0.1.0/.pre-commit-config.yaml +53 -0
  12. codesorter-0.1.0/.pre-commit-hooks.yaml +15 -0
  13. codesorter-0.1.0/.python-version +1 -0
  14. codesorter-0.1.0/.readthedocs.yaml +14 -0
  15. codesorter-0.1.0/CHANGES.rst +19 -0
  16. codesorter-0.1.0/LICENSE.txt +22 -0
  17. codesorter-0.1.0/PKG-INFO +323 -0
  18. codesorter-0.1.0/README.rst +268 -0
  19. codesorter-0.1.0/codesorter/__init__.py +5 -0
  20. codesorter-0.1.0/codesorter/cli.py +227 -0
  21. codesorter-0.1.0/codesorter/const.py +25 -0
  22. codesorter-0.1.0/codesorter/py.typed +0 -0
  23. codesorter-0.1.0/codesorter/sort_code.py +334 -0
  24. codesorter-0.1.0/docs/Makefile +19 -0
  25. codesorter-0.1.0/docs/code_overview/sort_code.rst +20 -0
  26. codesorter-0.1.0/docs/conf.py +30 -0
  27. codesorter-0.1.0/docs/docutils.conf +2 -0
  28. codesorter-0.1.0/docs/genindex.rst +3 -0
  29. codesorter-0.1.0/docs/index.rst +18 -0
  30. codesorter-0.1.0/docs/make.bat +35 -0
  31. codesorter-0.1.0/docs/package_info/change_log.rst +1 -0
  32. codesorter-0.1.0/examples/after_example.py +150 -0
  33. codesorter-0.1.0/examples/before_example.py +150 -0
  34. codesorter-0.1.0/pyproject.toml +195 -0
  35. codesorter-0.1.0/tests/__init__.py +1 -0
  36. codesorter-0.1.0/tests/conftest.py +31 -0
  37. codesorter-0.1.0/tests/test_files/basic_function_input.py +10 -0
  38. codesorter-0.1.0/tests/test_files/basic_function_output.py +10 -0
  39. codesorter-0.1.0/tests/test_files/class_global_dependency_input.py +77 -0
  40. codesorter-0.1.0/tests/test_files/class_global_dependency_output.py +77 -0
  41. codesorter-0.1.0/tests/test_files/class_inheritance_input.py +74 -0
  42. codesorter-0.1.0/tests/test_files/class_inheritance_output.py +74 -0
  43. codesorter-0.1.0/tests/test_files/class_method_input.py +9 -0
  44. codesorter-0.1.0/tests/test_files/class_method_output.py +9 -0
  45. codesorter-0.1.0/tests/test_files/classmethod_input.py +12 -0
  46. codesorter-0.1.0/tests/test_files/classmethod_output.py +12 -0
  47. codesorter-0.1.0/tests/test_files/comprehensive_input.py +187 -0
  48. codesorter-0.1.0/tests/test_files/comprehensive_output.py +187 -0
  49. codesorter-0.1.0/tests/test_files/custom_decorators_input.py +76 -0
  50. codesorter-0.1.0/tests/test_files/custom_decorators_output.py +76 -0
  51. codesorter-0.1.0/tests/test_files/mixed_decorators_input.py +15 -0
  52. codesorter-0.1.0/tests/test_files/mixed_decorators_output.py +15 -0
  53. codesorter-0.1.0/tests/test_files/property_input.py +32 -0
  54. codesorter-0.1.0/tests/test_files/property_output.py +32 -0
  55. codesorter-0.1.0/tests/test_files/pytest_fixtures_input.py +46 -0
  56. codesorter-0.1.0/tests/test_files/pytest_fixtures_output.py +46 -0
  57. codesorter-0.1.0/tests/test_files/staticmethod_input.py +12 -0
  58. codesorter-0.1.0/tests/test_files/staticmethod_output.py +12 -0
  59. codesorter-0.1.0/tests/test_sort_code.py +169 -0
  60. codesorter-0.1.0/uv.lock +1331 -0
@@ -0,0 +1,14 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: github-actions
4
+ directory: /
5
+ schedule:
6
+ interval: monthly
7
+ labels:
8
+ - "Dependencies"
9
+ - package-ecosystem: uv
10
+ directory: /
11
+ schedule:
12
+ interval: monthly
13
+ labels:
14
+ - "Dependencies"
@@ -0,0 +1,17 @@
1
+ concurrency:
2
+ group: check-${{ github.ref }}
3
+ cancel-in-progress: true
4
+ jobs:
5
+ ci:
6
+ name: CI
7
+ uses: praw-dev/.github/.github/workflows/ci.yml@9ff8957d0cab4cf8c9d7cb5592aedb3d456cc058 # v1.4.0
8
+ with:
9
+ min_python: "3.10"
10
+ python_versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]'
11
+ name: CI
12
+ on:
13
+ workflow_dispatch:
14
+ push:
15
+ branches: ["main"]
16
+ pull_request:
17
+ permissions: read-all
@@ -0,0 +1,14 @@
1
+ jobs:
2
+ pre-commit_autoupdate:
3
+ name: Update pre-commit hooks
4
+ secrets:
5
+ APP_ID: ${{ secrets.APP_ID }}
6
+ APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
7
+ uses: praw-dev/.github/.github/workflows/pre-commit_autoupdate.yml@9ff8957d0cab4cf8c9d7cb5592aedb3d456cc058 # v1.4.0
8
+ name: Update pre-commit hooks
9
+ on:
10
+ schedule:
11
+ - cron: 0 15 * * 1
12
+ workflow_dispatch:
13
+ permissions:
14
+ contents: read
@@ -0,0 +1,20 @@
1
+ name: Prepare Release
2
+ on:
3
+ workflow_dispatch:
4
+ inputs:
5
+ version:
6
+ description: The version to prepare for release
7
+ required: true
8
+ permissions:
9
+ contents: read
10
+ jobs:
11
+ prepare_release:
12
+ name: Prepare Release
13
+ secrets:
14
+ APP_ID: ${{ secrets.APP_ID }}
15
+ APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
16
+ uses: praw-dev/.github/.github/workflows/prepare_release.yml@9ff8957d0cab4cf8c9d7cb5592aedb3d456cc058 # v1.4.0
17
+ with:
18
+ package: codesorter
19
+ version: ${{ inputs.version }}
20
+ version_file: const.py
@@ -0,0 +1,29 @@
1
+ jobs:
2
+ pypi-publish:
3
+ environment: release
4
+ name: Upload release to PyPI
5
+ permissions:
6
+ id-token: write
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
10
+ with:
11
+ persist-credentials: false
12
+ - name: Set up Python
13
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
14
+ with:
15
+ python-version: 3.x
16
+ - name: Install dependencies
17
+ run: |
18
+ python -m pip install --upgrade pip
19
+ pip install build
20
+ - name: Build package
21
+ run: python -m build
22
+ - name: Publish package distributions to PyPI
23
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
24
+ name: Upload Python Package
25
+ on:
26
+ release:
27
+ types: [published]
28
+ permissions:
29
+ contents: read
@@ -0,0 +1,40 @@
1
+ # This workflow uses actions that are not certified by GitHub. They are provided
2
+ # by a third-party and are governed by separate terms of service, privacy
3
+ # policy, and support documentation.
4
+
5
+ name: Scorecard supply-chain security
6
+ on:
7
+ branch_protection_rule:
8
+ schedule:
9
+ - cron: '36 1 * * 3'
10
+ push:
11
+ branches: ["main"]
12
+ permissions: read-all
13
+ jobs:
14
+ analysis:
15
+ name: Scorecard analysis
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ security-events: write
19
+ id-token: write
20
+ steps:
21
+ - name: "Checkout code"
22
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
23
+ with:
24
+ persist-credentials: false
25
+ - name: "Run analysis"
26
+ uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
27
+ with:
28
+ results_file: results.sarif
29
+ results_format: sarif
30
+ publish_results: true
31
+ - name: "Upload artifact"
32
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
33
+ with:
34
+ name: SARIF file
35
+ path: results.sarif
36
+ retention-days: 5
37
+ - name: "Upload to code-scanning"
38
+ uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
39
+ with:
40
+ sarif_file: results.sarif
@@ -0,0 +1,12 @@
1
+ jobs:
2
+ stale_action:
3
+ name: Close stale issues and PRs
4
+ uses: praw-dev/.github/.github/workflows/stale_action.yml@9ff8957d0cab4cf8c9d7cb5592aedb3d456cc058 # v1.4.0
5
+ name: Close stale issues and PRs
6
+ on:
7
+ schedule:
8
+ - cron: 0 */6 * * *
9
+ workflow_dispatch:
10
+ permissions:
11
+ issues: write
12
+ pull-requests: write
@@ -0,0 +1,10 @@
1
+ name: Tag Release
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ permissions:
6
+ contents: write
7
+ jobs:
8
+ tag_release:
9
+ name: Tag Release
10
+ uses: praw-dev/.github/.github/workflows/tag_release.yml@9ff8957d0cab4cf8c9d7cb5592aedb3d456cc058 # v1.4.0
@@ -0,0 +1,39 @@
1
+ # Byte-compiled / cached
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ build/
8
+ dist/
9
+ *.egg-info/
10
+ *.egg
11
+
12
+ # Virtual envs
13
+ .venv/
14
+ venv/
15
+ env/
16
+
17
+ # Test / coverage
18
+ .coverage
19
+ .coverage.*
20
+ coverage.xml
21
+ htmlcov/
22
+ .pytest_cache/
23
+ .tox/
24
+
25
+ # Docs
26
+ docs/_build/
27
+
28
+ # Type / lint caches
29
+ .ruff_cache/
30
+ .mypy_cache/
31
+ .pyright/
32
+
33
+ # Editors / OS
34
+ .DS_Store
35
+ .idea/
36
+ .vscode/
37
+
38
+ # Project-local runtime artifacts
39
+ sorted.json
@@ -0,0 +1,36 @@
1
+ # String that LibCST should look for in code which indicates that the
2
+ # module is generated code.
3
+ generated_code_marker: '@generated'
4
+ # Command line and arguments for invoking a code formatter. Anything
5
+ # specified here must be capable of taking code via stdin and returning
6
+ # formatted code via stdout.
7
+ formatter: ['ruff', 'format', '-']
8
+ # List of regex patterns which LibCST will evaluate against filenames to
9
+ # determine if the module should be touched.
10
+ blacklist_patterns:
11
+ - '.*/\.bzr/.*'
12
+ - '.*/\.direnv/.*'
13
+ - '.*/\.eggs/.*'
14
+ - '.*/\.git/.*'
15
+ - '.*/\.hg/.*'
16
+ - '.*/\.mypy_cache/.*'
17
+ - '.*/\.nox/.*'
18
+ - '.*/\.pytest_cache/.*'
19
+ - '.*/\.ruff_cache/.*'
20
+ - '.*/\.svn/.*'
21
+ - '.*/\.tox/.*'
22
+ - '.*/\.venv/.*'
23
+ - '.*/__pycache__/.*'
24
+ - '.*/__pypackages__/.*'
25
+ - '.*/build/.*'
26
+ - '.*/dist/.*'
27
+ - '.*/env/.*'
28
+ - '.*/node_modules/.*'
29
+ - '.*/venv/.*'
30
+ # List of modules that contain codemods inside of them.
31
+ modules:
32
+ - 'codesorter'
33
+ # Absolute or relative path of the repository root, used for providing
34
+ # full-repo metadata. Relative paths should be specified with this file
35
+ # location as the base.
36
+ repo_root: '.'
@@ -0,0 +1,53 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - always_run: true
5
+ entry: codesorter --exclude examples --exclude test_files
6
+ id: codesorter
7
+ language: system
8
+ name: codesorter
9
+ pass_filenames: false
10
+ types: [ python ]
11
+
12
+ - hooks:
13
+ - id: docstrfmt
14
+ require_serial: true
15
+ repo: https://github.com/LilSpazJoekp/docstrfmt
16
+ rev: 8688ba6420d7b5ca95a8ba0edf8a9953babdc3da # frozen: v2.1.1
17
+
18
+ - hooks:
19
+ - id: auto-walrus
20
+ repo: https://github.com/MarcoGorelli/auto-walrus
21
+ rev: 1743edbed52f3d61886b59d98a27164a8af29c0d # frozen: 0.4.1
22
+
23
+ - hooks:
24
+ - args: [ --exit-non-zero-on-fix, --fix ]
25
+ id: ruff
26
+ - id: ruff-format
27
+ repo: https://github.com/astral-sh/ruff-pre-commit
28
+ rev: 3b3f7c3f57fe9925356faf5fe6230835138be230 # frozen: v0.15.17
29
+
30
+ - hooks:
31
+ - files: ^(.*\.toml)$
32
+ id: toml-sort-fix
33
+ repo: https://github.com/pappasam/toml-sort
34
+ rev: 2970ae9bb7124fe5117a27e10c10d2da051ce05a # frozen: v0.24.4
35
+
36
+ - hooks:
37
+ - id: check-added-large-files
38
+ - id: check-executables-have-shebangs
39
+ - id: check-shebang-scripts-are-executable
40
+ - id: check-toml
41
+ - id: check-yaml
42
+ - id: end-of-file-fixer
43
+ - args: [ --fix=lf ]
44
+ id: mixed-line-ending
45
+ - args: [ --pytest-test-first ]
46
+ files: ^tests/(integration|unit)/.*\.py$
47
+ id: name-tests-test
48
+ - id: no-commit-to-branch
49
+ - files: ^(\.github/workflows/.*\.ya?ml|\.readthedocs.ya?ml)$
50
+ id: sort-simple-yaml
51
+ - id: trailing-whitespace
52
+ repo: https://github.com/pre-commit/pre-commit-hooks
53
+ rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0
@@ -0,0 +1,15 @@
1
+ - id: codesorter
2
+ name: codesorter
3
+ description: Sort Python code with codesorter.
4
+ entry: codesorter
5
+ language: python
6
+ types: [python]
7
+ require_serial: true
8
+
9
+ - id: codesorter-check
10
+ name: codesorter (check)
11
+ description: Check that Python code is sorted by codesorter.
12
+ entry: codesorter --check
13
+ language: python
14
+ types: [python]
15
+ require_serial: true
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,14 @@
1
+ build:
2
+ os: ubuntu-lts-latest
3
+ tools:
4
+ python: "3.14"
5
+ jobs:
6
+ install:
7
+ - pip install uv
8
+ - UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" uv sync --frozen --no-dev --group docs --link-mode=copy
9
+ formats:
10
+ - htmlzip
11
+ sphinx:
12
+ configuration: docs/conf.py
13
+ fail_on_warning: true
14
+ version: 2
@@ -0,0 +1,19 @@
1
+ ############
2
+ Change Log
3
+ ############
4
+
5
+ codesorter follows `semantic versioning <https://semver.org/>`_.
6
+
7
+ ********************
8
+ 0.1.0 (2026/06/14)
9
+ ********************
10
+
11
+ **Added**
12
+
13
+ - Initial release of CodeSorter.
14
+ - CLI interface with directory walking, sensible default excludes, ``.gitignore``
15
+ honoring, and ``-e/--exclude`` / ``--no-default-excludes`` / ``--no-gitignore`` flags.
16
+ - Pre-commit hooks (``codesorter`` and ``codesorter-check``) for downstream consumers.
17
+ - Comprehensive test suite covering function, method, property, fixture, decorator, and
18
+ inheritance sort behaviors.
19
+ - Example before/after files in ``examples/``.
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2022, Joel Payne
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
17
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,323 @@
1
+ Metadata-Version: 2.4
2
+ Name: codesorter
3
+ Version: 0.1.0
4
+ Summary: A Python codemod that sorts and organizes code in your files.
5
+ Project-URL: Change Log, https://codesorter.readthedocs.io/en/latest/package_info/change_log.html
6
+ Project-URL: Documentation, https://codesorter.readthedocs.io/
7
+ Project-URL: Issue Tracker, https://github.com/praw-dev/CodeSorter/issues
8
+ Project-URL: Source Code, https://github.com/praw-dev/CodeSorter
9
+ Author-email: Joel Payne <lilspazjoekp@gmail.com>
10
+ Maintainer-email: Joel Payne <lilspazjoekp@gmail.com>, Bryce Boe <bbzbryce@gmail.com>
11
+ License: Copyright (c) 2022, Joel Payne
12
+ All rights reserved.
13
+
14
+ Redistribution and use in source and binary forms, with or without
15
+ modification, are permitted provided that the following conditions are met:
16
+
17
+ 1. Redistributions of source code must retain the above copyright notice, this
18
+ list of conditions and the following disclaimer.
19
+ 2. Redistributions in binary form must reproduce the above copyright notice,
20
+ this list of conditions and the following disclaimer in the documentation
21
+ and/or other materials provided with the distribution.
22
+
23
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
27
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
+ License-File: LICENSE.txt
34
+ Keywords: codemod,codesorter,libcst,sort
35
+ Classifier: Development Status :: 4 - Beta
36
+ Classifier: Environment :: Console
37
+ Classifier: Intended Audience :: Developers
38
+ Classifier: License :: OSI Approved :: MIT License
39
+ Classifier: Operating System :: OS Independent
40
+ Classifier: Programming Language :: Python
41
+ Classifier: Programming Language :: Python :: 3
42
+ Classifier: Programming Language :: Python :: 3.10
43
+ Classifier: Programming Language :: Python :: 3.11
44
+ Classifier: Programming Language :: Python :: 3.12
45
+ Classifier: Programming Language :: Python :: 3.13
46
+ Classifier: Programming Language :: Python :: 3.14
47
+ Classifier: Topic :: Software Development :: Code Generators
48
+ Classifier: Topic :: Software Development :: Quality Assurance
49
+ Classifier: Topic :: Utilities
50
+ Classifier: Typing :: Typed
51
+ Requires-Python: >=3.10
52
+ Requires-Dist: libcst<2.0.0,>=1.8.6
53
+ Requires-Dist: pathspec>=1.1.1
54
+ Description-Content-Type: text/x-rst
55
+
56
+ ############
57
+ CodeSorter
58
+ ############
59
+
60
+ CodeSorter is a LibCST codemod that automatically sorts and organizes Python code.
61
+
62
+ **********
63
+ Features
64
+ **********
65
+
66
+ - **Smart Sorting**: Automatically sorts functions, classes, and methods alphabetically
67
+ - **Decorator Awareness**: Properly handles ``@property``, ``@staticmethod``,
68
+ ``@classmethod``, and ``@pytest.fixture`` decorators
69
+ - **Hierarchical Organization**: Maintains logical grouping within classes and modules
70
+ - **Pytest Integration**: Special handling for pytest fixtures with proper scope
71
+ ordering
72
+ - **CLI Interface**: Simple command-line interface for easy integration
73
+ - **Pre-commit Hook**: Ready-to-use pre-commit hook for automated code organization
74
+
75
+ **************
76
+ Installation
77
+ **************
78
+
79
+ From PyPI:
80
+
81
+ .. code-block:: bash
82
+
83
+ # using uv and add to the lint dependency group
84
+ uv add --group lint codesorter
85
+ # or using pip
86
+ pip install codesorter
87
+
88
+ From Source:
89
+
90
+ .. code-block:: bash
91
+
92
+ git clone https://github.com/praw-dev/CodeSorter.git
93
+ cd CodeSorter
94
+ uv pip install -e .
95
+
96
+ Development Installation:
97
+
98
+ .. code-block:: bash
99
+
100
+ git clone https://github.com/praw-dev/CodeSorter.git
101
+ cd CodeSorter
102
+ uv sync
103
+
104
+ *******
105
+ Usage
106
+ *******
107
+
108
+ Command Line Interface
109
+ ======================
110
+
111
+ The simplest way to use CodeSorter is through the command-line interface:
112
+
113
+ .. code-block:: bash
114
+
115
+ # Sort a single file
116
+ codesorter my_file.py
117
+
118
+ # Sort all Python files in a directory
119
+ codesorter my_project/
120
+
121
+ # Sort with additional options
122
+ codesorter --help
123
+
124
+ Pre-commit Hook
125
+ ===============
126
+
127
+ Add CodeSorter to your pre-commit configuration to automatically sort code on every
128
+ commit:
129
+
130
+ .. code-block:: yaml
131
+
132
+ # .pre-commit-config.yaml
133
+ repos:
134
+ - repo: https://github.com/praw-dev/CodeSorter
135
+ rev: v0.0.3
136
+ hooks:
137
+ - id: codesorter
138
+
139
+ Or use the check-only variant, which fails the hook without modifying files:
140
+
141
+ .. code-block:: yaml
142
+
143
+ repos:
144
+ - repo: https://github.com/praw-dev/CodeSorter
145
+ rev: v0.0.3
146
+ hooks:
147
+ - id: codesorter-check
148
+
149
+ Programmatic Usage
150
+ ==================
151
+
152
+ You can also use CodeSorter programmatically:
153
+
154
+ .. code-block:: python
155
+
156
+ import libcst as cst
157
+ from codesorter.sort_code import SortCodeCommand
158
+ from libcst.codemod import CodemodContext
159
+
160
+ # Parse your code
161
+ code = """
162
+ def z_function():
163
+ pass
164
+
165
+ def a_function():
166
+ pass
167
+ """
168
+
169
+ # Create context and command
170
+ context = CodemodContext()
171
+ command = SortCodeCommand(context)
172
+
173
+ # Transform the code
174
+ result = command.transform_module(cst.parse_module(code))
175
+ print(result.code)
176
+
177
+ **************
178
+ How It Works
179
+ **************
180
+
181
+ CodeSorter uses LibCST (Concrete Syntax Tree) to parse and transform Python code. It
182
+ applies sophisticated sorting rules:
183
+
184
+ Function Sorting
185
+ ================
186
+
187
+ - Functions are sorted alphabetically by name
188
+ - Global functions are sorted separately from class methods
189
+
190
+ Class Method Sorting
191
+ ====================
192
+
193
+ - Methods are sorted with special consideration for decorators: - ``@property`` methods
194
+ (getters, setters, deleters) - ``@staticmethod`` methods - ``@classmethod`` methods -
195
+ Regular instance methods
196
+ - Methods within classes maintain their logical grouping
197
+
198
+ Pytest Fixture Sorting
199
+ ======================
200
+
201
+ - Fixtures are sorted by scope (session, package, module, class, function)
202
+ - Within each scope, fixtures are sorted alphabetically
203
+ - ``autouse`` fixtures are handled specially
204
+
205
+ Example Transformation
206
+ ======================
207
+
208
+ **Before:**
209
+
210
+ .. code-block:: python
211
+
212
+ class MyClass:
213
+ def z_method(self):
214
+ pass
215
+
216
+ @property
217
+ def a_property(self):
218
+ pass
219
+
220
+ @staticmethod
221
+ def b_static():
222
+ pass
223
+
224
+ **After:**
225
+
226
+ .. code-block:: python
227
+
228
+ class MyClass:
229
+ @property
230
+ def a_property(self):
231
+ pass
232
+
233
+ @staticmethod
234
+ def b_static():
235
+ pass
236
+
237
+ def z_method(self):
238
+ pass
239
+
240
+ *************
241
+ Development
242
+ *************
243
+
244
+ Setting Up Development Environment
245
+ ==================================
246
+
247
+ .. code-block:: bash
248
+
249
+ # Clone the repository
250
+ git clone https://github.com/praw-dev/CodeSorter.git
251
+ cd CodeSorter
252
+
253
+ # Install with development dependencies
254
+ uv sync
255
+
256
+ # Install pre-commit hooks
257
+ uv run pre-commit install
258
+
259
+ Running Tests
260
+ =============
261
+
262
+ .. code-block:: bash
263
+
264
+ # Run all tests
265
+ uv run pytest
266
+
267
+ # Run a specific test file
268
+ uv run pytest tests/test_sort_code.py
269
+
270
+ # Run the full tox matrix (tests, type, pre-commit)
271
+ uv run tox
272
+
273
+ Code Quality
274
+ ============
275
+
276
+ The project uses several tools to maintain code quality:
277
+
278
+ - **Ruff**: Fast linting and formatting
279
+ - **Pyright**: Type checking
280
+ - **Pre-commit**: Automated quality checks
281
+
282
+ Run all quality checks:
283
+
284
+ .. code-block:: bash
285
+
286
+ uv run pre-commit run --all-files
287
+
288
+ **************
289
+ Contributing
290
+ **************
291
+
292
+ 1. Fork the repository
293
+ 2. Create a feature branch: ``git checkout -b feature-name``
294
+ 3. Make your changes and add tests
295
+ 4. Run the test suite: ``uv run pytest``
296
+ 5. Run pre-commit hooks: ``pre-commit run --all-files``
297
+ 6. Commit your changes: ``git commit -m "Add feature"``
298
+ 7. Push to your fork: ``git push origin feature-name``
299
+ 8. Create a Pull Request
300
+
301
+ **********
302
+ Examples
303
+ **********
304
+
305
+ See the ``examples/`` directory for before and after examples of CodeSorter in action:
306
+
307
+ - ``examples/before_example.py``: Unsorted code
308
+ - ``examples/after_example.py``: Same code after sorting
309
+
310
+ *********
311
+ License
312
+ *********
313
+
314
+ This project is licensed under the MIT License - see the `LICENSE.txt
315
+ <https://github.com/praw-dev/CodeSorter/blob/main/LICENSE.txt>`_ file for details.
316
+
317
+ ***********
318
+ Changelog
319
+ ***********
320
+
321
+ See the `change log
322
+ <https://codesorter.readthedocs.io/en/latest/package_info/change_log.html>`_ for the
323
+ full list of changes.