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.
- codesorter-0.1.0/.github/dependabot.yml +14 -0
- codesorter-0.1.0/.github/workflows/ci.yml +17 -0
- codesorter-0.1.0/.github/workflows/pre-commit_autoupdate.yml +14 -0
- codesorter-0.1.0/.github/workflows/prepare_release.yml +20 -0
- codesorter-0.1.0/.github/workflows/pypi.yml +29 -0
- codesorter-0.1.0/.github/workflows/scorecard.yml +40 -0
- codesorter-0.1.0/.github/workflows/stale_action.yml +12 -0
- codesorter-0.1.0/.github/workflows/tag_release.yml +10 -0
- codesorter-0.1.0/.gitignore +39 -0
- codesorter-0.1.0/.libcst.codemod.yaml +36 -0
- codesorter-0.1.0/.pre-commit-config.yaml +53 -0
- codesorter-0.1.0/.pre-commit-hooks.yaml +15 -0
- codesorter-0.1.0/.python-version +1 -0
- codesorter-0.1.0/.readthedocs.yaml +14 -0
- codesorter-0.1.0/CHANGES.rst +19 -0
- codesorter-0.1.0/LICENSE.txt +22 -0
- codesorter-0.1.0/PKG-INFO +323 -0
- codesorter-0.1.0/README.rst +268 -0
- codesorter-0.1.0/codesorter/__init__.py +5 -0
- codesorter-0.1.0/codesorter/cli.py +227 -0
- codesorter-0.1.0/codesorter/const.py +25 -0
- codesorter-0.1.0/codesorter/py.typed +0 -0
- codesorter-0.1.0/codesorter/sort_code.py +334 -0
- codesorter-0.1.0/docs/Makefile +19 -0
- codesorter-0.1.0/docs/code_overview/sort_code.rst +20 -0
- codesorter-0.1.0/docs/conf.py +30 -0
- codesorter-0.1.0/docs/docutils.conf +2 -0
- codesorter-0.1.0/docs/genindex.rst +3 -0
- codesorter-0.1.0/docs/index.rst +18 -0
- codesorter-0.1.0/docs/make.bat +35 -0
- codesorter-0.1.0/docs/package_info/change_log.rst +1 -0
- codesorter-0.1.0/examples/after_example.py +150 -0
- codesorter-0.1.0/examples/before_example.py +150 -0
- codesorter-0.1.0/pyproject.toml +195 -0
- codesorter-0.1.0/tests/__init__.py +1 -0
- codesorter-0.1.0/tests/conftest.py +31 -0
- codesorter-0.1.0/tests/test_files/basic_function_input.py +10 -0
- codesorter-0.1.0/tests/test_files/basic_function_output.py +10 -0
- codesorter-0.1.0/tests/test_files/class_global_dependency_input.py +77 -0
- codesorter-0.1.0/tests/test_files/class_global_dependency_output.py +77 -0
- codesorter-0.1.0/tests/test_files/class_inheritance_input.py +74 -0
- codesorter-0.1.0/tests/test_files/class_inheritance_output.py +74 -0
- codesorter-0.1.0/tests/test_files/class_method_input.py +9 -0
- codesorter-0.1.0/tests/test_files/class_method_output.py +9 -0
- codesorter-0.1.0/tests/test_files/classmethod_input.py +12 -0
- codesorter-0.1.0/tests/test_files/classmethod_output.py +12 -0
- codesorter-0.1.0/tests/test_files/comprehensive_input.py +187 -0
- codesorter-0.1.0/tests/test_files/comprehensive_output.py +187 -0
- codesorter-0.1.0/tests/test_files/custom_decorators_input.py +76 -0
- codesorter-0.1.0/tests/test_files/custom_decorators_output.py +76 -0
- codesorter-0.1.0/tests/test_files/mixed_decorators_input.py +15 -0
- codesorter-0.1.0/tests/test_files/mixed_decorators_output.py +15 -0
- codesorter-0.1.0/tests/test_files/property_input.py +32 -0
- codesorter-0.1.0/tests/test_files/property_output.py +32 -0
- codesorter-0.1.0/tests/test_files/pytest_fixtures_input.py +46 -0
- codesorter-0.1.0/tests/test_files/pytest_fixtures_output.py +46 -0
- codesorter-0.1.0/tests/test_files/staticmethod_input.py +12 -0
- codesorter-0.1.0/tests/test_files/staticmethod_output.py +12 -0
- codesorter-0.1.0/tests/test_sort_code.py +169 -0
- codesorter-0.1.0/uv.lock +1331 -0
|
@@ -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,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.
|