Skip to main content

turn on/off dependency lock and packaging stuff

Project description

Python packaging automation is ripe for exploit. Lets drain the swamp!

Code in Makefile or python scripts should be reduced or removed entirely, in favor of packaged, unittested, and well documented code.

Authors and maintainers deal with lots of repos. Too often boilerplate gets copy and pasted into each package, becoming:

  • an eye sore

  • completely untested code

  • small variations leak in

  • code quality and feature improvements are less likely to happen

Drain swamp focuses on:

  • pyproject.toml dependencies locks

  • semantic versioning – current, tag (in version file), semantic version str

  • build Python package uses plugins

updating

  • Sphinx docs/conf.py

  • CHANGES.rst

  • NOTICE.txt

This is done skillfully, applying a generic technique, snippets. Static config files become dynamic, encouraging automation.

That’s a lot of boilerplate code … gone! Not all, but most.

  • Python 3.9 through 3.12, PyPy

New in 1.2.x

generate version file if missing; ci workflows recreate generated files;

New in 1.1.x

tox-test.ini; tox.ini; gha; build backend DS_CONFIG_SETTINGS support; add gha variable DRAINSWAMP_SET_LOCK;

Extensions

Snip is the generic technique to make an otherwise static config file, dynamic. Simple explanation: static portion is surrounded by comments turning it into a snippet.

This technique is applied to aid DevOps.

Comes with these extensions:

pipenv-unlock – switch on/off dependency locks

pyproject.toml is not dynamic and it’s not supposed to be dynamic. In an ideal world, it would be static.

Authors disappear or die. Unfunded projects quickly become abandonware. Packages with locked dependencies do not age well.

pipenv-unlock is a light switch to turn on/off dependency locking.

refresh both .unlock and .lock files. During build time, .lnk shortcut is created.

An author dies, discovers girls, or gets a job scrapping gum off sidewalks. No worries

refreshes symlinks (.lnk)

pipenv-unlock refresh --set-lock "off"
pipenv-unlock refresh --set-lock "on"

lock / unlock dependencies

pipenv-unlock lock
pipenv-unlock unlock
Following in Click’s footsteps

State

Possible values

lock

“1”, “true”, “t”, “yes”, “y”, “on”

unlock

“0”, “false”, “f”, “no”, “n”, “off”

drain-swamp

In conf.py, there are some dynamic fields. Each package release, has to change these fields:

  • version

  • release

  • release_date

  • copyright (start year and author name)

Reduces reliance on igor.py

scm-version – Version file support

Replaces getting version from setup.py or from setuptools-scm

Get scm (source control management) version

scm-version get

0.5.2.dev0+g2988c13.d20240724

Get from version file

drain-swamp tag

0.5.2

Writes a semantic version str to version file. drain-swamp pretag to check/fix semantic version str

scm-version write "0.5.2post0.dev1"

Whats a snippet?

Within a configuration, often need to run some code to change a some text.

The only requirement is the file format should recognize pound symbol # as a comment.

A snippet without an snippet code (id)

before snippet
# @@@ editable
code block
# @@@ end
after snippet

A snippet with an snippet code (id)

before snippet
# @@@ i_am_a_snippet_co
code block
# @@@ end
after snippet

Replace the text within the snippet

import tempfile
import textwrap
from pathlib import Path

from drain_swamp.snip import Snip

# prepare
contents_existing = textwrap.dedent(
    """\
before snippet
# @@@ editable i_am_a_snippet_co
code block
# @@@ end
after snippet
"""
)

contents_new = """new\ncontents\nhere"""

expected = textwrap.dedent(
    """\
before snippet
# @@@ editable i_am_a_snippet_co
new
contents
here
# @@@ end
after snippet
"""
)

with tempfile.TemporaryDirectory() as f_path:
    path_f = Path(f_path)

    # prepare
    path_some_conf = path_f / "some.conf"
    path_some_conf.write_text(contents_existing)

    # act
    snip = Snip(path_some_conf, is_quiet=True)
    snip.replace(contents_new, id_="i_am_a_snippet_co")

    actual = path_some_conf.read_text()

assert actual == expected

In a temporary folder, created a file, some.conf with contents, contents_existing.

Replace the contents within the snippet, with id i_am_a_snippet_co, with contents_new.

textwrap.dedent(“””means, remove any indention and escape ignore the preceding newline

Snip constructor parameter, is_quiet, turns off logging

Where to use snippets?

Python package authors rarely write and publish just one python package.

We write lots of packages!

In each package, there is boilerplate code, not covered by unittests, that is almost an exact copy as found in other packages.

After a few published packages, this boilerplate code becomes a liability and an eye sore.

Code within Makefile or igor.py needs to brought under control. Like a cancer, waiting to be exploited, less is more.

Ideally cut out in its entirely; preferably, as much as reasonable.

File formats – supported

Lines starting with pound sign # are considered comments:

  • python

  • bash

  • pyproject.toml

  • Linux config files

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

drain_swamp-1.2.1.tar.gz (532.3 kB view hashes)

Uploaded Source

Built Distribution

drain_swamp-1.2.1-py3-none-any.whl (151.7 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page