Skip to main content

manageprojects - Manage Python / Django projects

manageprojects @ PyPi Python Versions License GPL-3.0-or-later

Mix the idea of Ansible with CookieCutter Templates and Django Migrations to manage and update your Python Packages and Django Projects...

The main idea it to transfer changes of a CookieCutter template back to the created project. Manageprojects used git to create a patch of the template changes and applies it to the created project.

Besides this, manageprojects also includes other generic helper for Python packages:

Read below the Helper section.

Documentation: docs/ (WIP)

GitHub suspended me!

Important notice:


GitHub suspended my account sometime in late August 2026 ! There was no warning beforehand, nor any explanation of the reasons afterwards. Since then, I have had no access or control over my data on GitHub.

All my projects and everything about me have completely disappeared. Everything just results in a 404 "Not Found" error page.

A support request still hasn't been answered, even after several weeks (apart from a confirmation that the request was received).

For that reason, I have been looking for a new home for all my OpenSource projects. (Or rather, I am in the process of republishing all my projects elsewhere.)

Now you can find my on these places:

That is why there will probably be a lot of broken links pointing to my GitHub account for quite some time!


install

You can use pipx to install and use PyHardLinkBackup, e.g.:

sudo apt install pipx

pipx install manageprojects

After this you can call the CLI via manageprojects command.

To upgrade an existing installation, use:

pipx upgrade PyHardLinkBackup

see: https://pipx.pypa.io/stable/docs/#pipx-upgrade

The output of manageprojects --help looks like:

usage: manageprojects [-h] {clone-project,format-file,reverse,shell-completion,start-project,update-project,version,wiggle}



╭─ options ──────────────────────────────────────────────────────────────────────────────╮
│ -h, --help            show this help message and exit                                  │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ subcommands ──────────────────────────────────────────────────────────────────────────╮
│ (required)                                                                             │
│   • clone-project     Clone existing project by replay the cookiecutter template in a  │
│                       new directory.                                                   │
│                                                                                        │
│                       e.g.:                                                            │
│                                                                                        │
│                       manageprojects clone-project ~/foo/bar ~/cloned/                 │
│   • format-file       Format and check the given python source code file with ruff,    │
│                       codespell and mypy.                                              │
│                                                                                        │
│                       If the given file is a directory, all python files that are      │
│                       tracked as changed by git will be formatted.                     │
│                                                                                        │
│                       The optional fallback values will be only used, if we can't get  │
│                       them from the project meta files like ".editorconfig" and        │
│                       "pyproject.toml"                                                 │
│   • reverse           Create a cookiecutter template from a managed project.           │
│                                                                                        │
│                       e.g.:                                                            │
│                                                                                        │
│                       manageprojects reverse ~/my_managed_project/                     │
│                       ~/my_new_cookiecutter_template/                                  │
│   • shell-completion  Setup shell completion for this CLI (Currently only for bash     │
│                       shell)                                                           │
│   • start-project     Start a new "managed" project via a CookieCutter Template. Note: │
│                       The CookieCutter Template *must* be use git!                     │
│                                                                                        │
│                       e.g.:                                                            │
│                                                                                        │
│                       manageprojects start-project                                     │
│                       git+https://codeberg.org/jedie/cookiecutter_templates/           │
│                       --directory uv-python ~/foobar/                                  │
│   • update-project    Update a existing project.                                       │
│                                                                                        │
│                       e.g. update by overwrite (and merge changes manually via git):   │
│                                                                                        │
│                       manageprojects update-project ~/foo/bar/                         │
│   • version           Print version and exit                                           │
│   • wiggle            Run wiggle to merge *.rej in given directory.                    │
│                       https://github.com/neilbrown/wiggle                              │
│                                                                                        │
│                       e.g.:                                                            │
│                                                                                        │
│                       manageprojects wiggle ~/my_managed_project/                      │
╰────────────────────────────────────────────────────────────────────────────────────────╯

most important commands

start-project

Help from manageprojects start-project --help Looks like:

usage: manageprojects start-project [-h] [START-PROJECT OPTIONS] STR PATH

Start a new "managed" project via a CookieCutter Template. Note: The CookieCutter Template *must* be use git!

e.g.:

manageprojects start-project git+https://codeberg.org/jedie/cookiecutter_templates/ --directory uv-python ~/foobar/

╭─ positional arguments ─────────────────────────────────────────────────────────────────╮
│ STR              The name of the CookieCutter Template. (required)                     │
│ PATH             Target path for the new project. Must not exist yet! (required)       │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ options ──────────────────────────────────────────────────────────────────────────────╮
│ -h, --help       show this help message and exit                                       │
│ -v, --verbosity  Verbosity level; e.g.: -v, -vv, -vvv, etc. (repeatable)               │
│ --directory {None}|STR                                                                 │
│                  Cookiecutter Option: Directory within repo that holds                 │
│                  cookiecutter.json file for advanced repositories with multi templates │
│                  in it (default: None)                                                 │
│ --replay, --no-replay                                                                  │
│                  Cookiecutter Option: Do not prompt for parameters and only use        │
│                  information entered previously (default: False)                       │
│ --input, --no-input                                                                    │
│                  Cookiecutter Option: Do not prompt for parameters and only use        │
│                  cookiecutter.json file content (default: False)                       │
│ --checkout {None}|STR                                                                  │
│                  Cookiecutter Option: Optional branch, tag or commit ID to checkout    │
│                  after clone (default: None)                                           │
│ --password {None}|STR                                                                  │
│                  Cookiecutter Option: Password to use when extracting the repository   │
│                  (default: None)                                                       │
│ --config-file {None}|PATH                                                              │
│                  Cookiecutter Option: Optional path to "cookiecutter_config.yaml"      │
│                  (default: None)                                                       │
╰────────────────────────────────────────────────────────────────────────────────────────╯

update-project

Help from manageprojects update-project --help Looks like:

usage: manageprojects update-project [-h] [UPDATE-PROJECT OPTIONS] PATH

Update a existing project.

e.g. update by overwrite (and merge changes manually via git):

manageprojects update-project ~/foo/bar/

╭─ positional arguments ─────────────────────────────────────────────────────────────────╮
│ PATH             project-path (required)                                               │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ options ──────────────────────────────────────────────────────────────────────────────╮
│ -h, --help       show this help message and exit                                       │
│ -v, --verbosity  Verbosity level; e.g.: -v, -vv, -vvv, etc. (repeatable)               │
│ --overwrite, --no-overwrite                                                            │
│                  Overwrite all Cookiecutter template files to the last template state  │
│                  and do not apply the changes via git patches. The developer is        │
│                  supposed to apply the differences manually via git. Will be aborted   │
│                  if the project git repro is not in a clean state. (default: True)     │
│ --cleanup, --no-cleanup                                                                │
│                  Cleanup created temporary files (default: True)                       │
│ --input, --no-input                                                                    │
│                  Cookiecutter Option: Do not prompt for parameters and only use        │
│                  cookiecutter.json file content (default: False)                       │
│ --password {None}|STR                                                                  │
│                  Cookiecutter Option: Password to use when extracting the repository   │
│                  (default: None)                                                       │
│ --config-file {None}|PATH                                                              │
│                  Cookiecutter Option: Optional path to "cookiecutter_config.yaml"      │
│                  (default: None)                                                       │
╰────────────────────────────────────────────────────────────────────────────────────────╯

workflow

1. Create a new project

Use start-project command and a github url as Cookiecutter template, e.g.:

~/manageprojects$ manageprojects start-project https://codeberg.org/jedie/cookiecutter_templates/ --directory piptools-python ~/my_new_project/
~/manageprojects$ cd ~/my_new_project/your_cool_package/
~/my_new_project/your_cool_package/$ git init
~/my_new_project/your_cool_package/$ git add .
~/my_new_project/your_cool_package/$ git commit --message "my cool new project"

Note: https://codeberg.org/jedie/cookiecutter_templates is a multi template repository, the piptools-python template is here: https://codeberg.org/jedie/cookiecutter_templates/tree/main/piptools-python

After running the start-project command, look into the created files. Manage projects stores all needed meta information about the used Cookiecutter template into pyproject.toml, e.g.:

~/manageprojects$ cat ~/my_new_project/your_cool_package/pyproject.toml
...
[manageprojects] # https://codeberg.org/jedie/manageprojects
initial_revision = "6e4c875"
initial_date = 2022-11-10T12:37:20+01:00
cookiecutter_template = "https://codeberg.org/jedie/cookiecutter_templates/"
cookiecutter_directory = "piptools-python"

[manageprojects.cookiecutter_context.cookiecutter]
...

2. Update existing project

If the source Cookiecutter changed, then you can apply these changes to your created project, e.g.:

~/manageprojects$ manageprojects update-project ~/my_new_project/your_cool_package/

After this, manageproject will update the own meta information in pyproject.toml by add applied_migrations with the information about the current Cookiecutter version, e.g.:

~/manageprojects$ cat ~/my_new_project/your_cool_package/pyproject.toml
...
[manageprojects] # https://codeberg.org/jedie/manageprojects
initial_revision = "6e4c875"
initial_date = 2022-11-10T12:37:20+01:00
cookiecutter_template = "https://codeberg.org/jedie/cookiecutter_templates/"
cookiecutter_directory = "piptools-python"
applied_migrations = [
    "dd69dcf", # 2022-11-22T19:48:28+01:00
]
...

How?

Everything is based on git ;)

  • manageprojects knows the git hash of the used Cookiecutter Template at creation time and the current git hash.
  • It builds a git patch between these two commits.
  • This patch will be applied to the created project sources.

So theoretically the changes in the template are applied to the project.

However, this does not work in every case, because git can't match the changes.

See below:

drawbacks

One problem is that git can't apply all changes.

But git apply is used with --reject. It applies the parts of the patch that are applicable, and leave the rejected hunks in corresponding *.rej files.

There is a cool tool, called wiggle: https://github.com/neilbrown/wiggle

It tries to apply rejected patches by perform word-wise diffs.

Just run wiggle via manageproject CLI, e.g.:

~/manageprojects$ manageprojects wiggle ~/my_new_project/your_cool_package/

Update by overwrite

A alternative way to update a project:

  1. Just overwrite all files with the current Cookiecutter template output
  2. Merge changes manually via git

So you doesn't have trouble with not applicable git patches ;)

Just add --overwrite, e.g.:

~/manageprojects$ manageprojects update-project --overwrite ~/my_new_project/your_cool_package/

Helper

Below are some generic tools helpful for Python packages.

install_python.py

A script to download, build and install a Python interpreter, but only if the system Python is not the required major version. It's a standalone script with no dependencies. Works with Python 3.9+.

More information: docs/install_python.md

"reverse" - Reverse a project into a Cookiecutter template

A existing managed project can be converted back to a Cookiecutter template, e.g.:

~/manageprojects$ manageprojects reverse ~/my_new_project/ ~/cookiecutter_template/

"format-file" - Format and check the given python source code file

You can use format-file as "Action on save" or manual action in your IDE to fix code style ;)

usage: manageprojects format-file [-h] PATH [-v] [--py-version STR] [--max-line-length INT] [--max-distance INT]

Format and check the given python source code file with ruff, codespell and mypy.

If the given file is a directory, all python files that are tracked as changed by git will be formatted.

The optional fallback values will be only used, if we can't get them from the project meta files like ".editorconfig" and "pyproject.toml"

╭─ positional arguments ─────────────────────────────────────────────────────────────────╮
│ PATH                   file-path (required)                                            │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ options ──────────────────────────────────────────────────────────────────────────────╮
│ -h, --help             show this help message and exit                                 │
│ -v, --verbosity        Verbosity level; e.g.: -v, -vv, -vvv, etc. (repeatable)         │
│ --py-version STR       Fallback Python version for darker/pyupgrade, if version is not │
│                        defined in pyproject.toml (default: 3.10)                       │
│ --max-line-length INT  Fallback max. line length for darker/isort etc., if not defined │
│                        in .editorconfig (default: 119)                                 │
│ --max-distance INT     If we only format the changed lines: The maximum number of      │
│                        lines between two chunks that can be merged. (default: 1)       │
╰────────────────────────────────────────────────────────────────────────────────────────╯

publish

The manageprojects.utilities.publish.publish_package() is designed for external packages, too.

Build and upload (with twine) a project to PyPi with many pre-checks:

  • Has correct version number?
  • Is on main branch and up-to-date with origin?
  • Check if current version already published
  • Build a git tag based on current package version
  • Adds change messages since last release to git tag message

Some checks result in a hard exit, but some can be manually confirmed from the user to continue publishing.

start development

At least uv is needed. Install e.g.: via pipx:

apt-get install pipx
pipx install uv

Clone the project and just start the CLI help commands. A virtual environment will be created/updated automatically.

~$ git clone https://codeberg.org/jedie/manageprojects.git
~$ cd manageprojects
~/manageprojects$ manageprojects --help

For developing manageprojects, there is the dev-cli.py with all development related commands.

The output of ./dev-cli.py --help looks like:

usage: ./dev-cli.py [-h] {coverage,git-hooks,install,lint,mypy,nox,pip-audit,publish,run-git-hooks,shell-completion,test,update,update-readme-history,update-test-snapshot-files,version}



╭─ options ──────────────────────────────────────────────────────────────────────────────╮
│ -h, --help     show this help message and exit                                         │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ subcommands ──────────────────────────────────────────────────────────────────────────╮
│ (required)                                                                             │
│   • coverage   Run tests and show coverage report.                                     │
│   • git-hooks  Setup our "pre-commit" git hooks                                        │
│   • install    Install requirements and 'manageprojects' via pip as editable.          │
│   • lint       Check/fix code style by run: "ruff check --fix"                         │
│   • mypy       Run Mypy (configured in pyproject.toml)                                 │
│   • nox        Run nox                                                                 │
│   • pip-audit  Run pip-audit check against current requirements files                  │
│   • publish    Build and upload this project to PyPi                                   │
│   • run-git-hooks                                                                      │
│                Run the installed "pre-commit" git hooks                                │
│   • shell-completion                                                                   │
│                Setup shell completion for this CLI (Currently only for bash shell)     │
│   • test       Run unittests                                                           │
│   • update     Update dependencies (uv.lock) and git pre-commit hooks                  │
│   • update-readme-history                                                              │
│                Update project history base on git commits/tags in README.md            │
│                                                                                        │
│                Will be exited with 1 if the README.md was updated otherwise with 0.    │
│                                                                                        │
│                Also, callable via e.g.:                                                │
│                    python -m cli_base update-readme-history -v                         │
│   • update-test-snapshot-files                                                         │
│                Update all test snapshot files (by remove and recreate all snapshot     │
│                files)                                                                  │
│   • version    Print version and exit                                                  │
╰────────────────────────────────────────────────────────────────────────────────────────╯

development git hooks

To install the git hooks, run:

~/manageprojects$ ./dev-cli.py git-hooks

History

See also git tags: https://codeberg.org/jedie/manageprojects/tags

Links

Metadata

Release files for manageprojects 0.29.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for manageprojects 0.29.0
File Size Uploaded
manageprojects-0.29.0.tar.gz 157.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for manageprojects 0.29.0
File Interpreter ABI Platform
manageprojects-0.29.0-py3-none-any.whl Python 3 none any Details

Total release size: 254.8 kB

Release files / manageprojects-0.29.0.tar.gz

Download URL manageprojects-0.29.0.tar.gz
Size 157.1 kB
Tags Source
SHA-256 checksum
How to use checksums
e2cabd1aa87d58a29da2a2b439ab7ff5c8b786dc1c7e4087fbd60418e34ce9f0
BLAKE2b-256 checksum
How to use checksums
d78bcf86657ad65ae982ee6f0d61e3eae3c8b6e88a0dfe56e519dbfef783e44f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release files / manageprojects-0.29.0-py3-none-any.whl

Download URL manageprojects-0.29.0-py3-none-any.whl
Size 97.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d4728f37bf1e925662a38eda2eb091d3e2546275c45e8523769a351dec504954
BLAKE2b-256 checksum
How to use checksums
31813cc22f3c280bd0b59d80c0906d969533fd00fb55ab18da16ce7e7bdffab2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release history Release notifications | RSS feed

0.30.0

2 release files

0.29.1

2 release files

This release

0.29.0 This release

2 release files

0.28.2

2 release files

0.28.0

2 release files

0.27.3

2 release files

0.27.2

2 release files

0.27.1

2 release files

0.27.0

2 release files

0.26.0

2 release files

0.24.0

2 release files

0.21.3

2 release files

0.21.2

2 release files

0.21.1

2 release files

0.21.0

2 release files

0.20.0

2 release files

0.19.2

2 release files

0.19.1

2 release files

0.19.0

2 release files

0.18.0

2 release files

0.17.1

2 release files

0.17.0

2 release files

0.16.2

2 release files

0.15.4

2 release files

0.15.0

2 release files

0.14.1

2 release files

0.12.1

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.9

2 release files

0.9.8

2 release files

0.9.7

2 release files

0.9.6

2 release files

0.9.4

2 release files

0.9.3

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.0

2 release files

0.7.3

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page