1 Release 0.2.0

Build it yourself. Read the tutorial is the other way to read this part.

If you start at this part, make your clone as Get the project says, and then run this command. It puts in your clone the files that this part starts from. A file that the project deleted before this part stays, so delete it if git check lists it:

git rm -rq --cached --ignore-unmatch -- :/ && git restore --source bfcbe07463b5 --staged --worktree -- :/
just setup

A release gives users a new version. Before it, we tidy the tests, and after it, the lockfile must name the new version too.

The code before this part. The code after it.

1.1 Tests of edge cases

The file tests/test_empty.py tests one edge case, an empty text. A text of spaces alone is another edge case. One file can test both, so it gets a name that fits both, tests/test_edge.py, and a second test.

Apply the patch that renames tests/test_empty.py to tests/test_edge.py, from the top of the project:

curl -fsSL https://github.com/rahuldave/tally/commit/a54eadb267e9052af3b1f4f5b2fe3e8f2a4184f7.diff | git apply --include=tests/test_edge.py

The patch renames tests/test_empty.py to tests/test_edge.py. It also renames the class to Edge, and adds the test test_spaces.

uv run python -m unittest discover -s tests -q

All four tests pass.

Check your files against this move. The command prints nothing when they match, and otherwise shows what differs:

git check a54eadb267e9

If you are stuck, this command puts the files of this move in place of yours. A file that you made yourself stays:

git restore --source bfcbe07463b5 --staged -- :/ && git restore --source a54eadb267e9 --staged --worktree -- :/

What changed

  • tests/test_edge.py: a new name, and a second test. Renamed from tests/test_empty.py, 4 lines added, 1 removed. The file.
    • look at def test_spaces(self):
The patch to tests/test_edge.py
@@ -3,6 +3,9 @@ import unittest
 from tally import count
 
 
-class Empty(unittest.TestCase):
+class Edge(unittest.TestCase):
     def test_empty(self):
         self.assertEqual(count(""), {})
+
+    def test_spaces(self):
+        self.assertEqual(count("  \n\t "), {})

This change on GitHub. The code after it.

1.2 Version 0.2.0

Users tell one release from another by its version. The version is a line of pyproject.toml.

Set the values that this change sets in pyproject.toml. Run this command from the top of the project. It reads your file with tomlkit, a library for TOML files. It sets each of these values as the project has it, and keeps the rest of your file:

uv run --quiet --no-config --no-project --with tomlkit python - <<'PY'
import pathlib, tomlkit
path = pathlib.Path('pyproject.toml')
doc = tomlkit.parse(path.read_text(encoding='utf-8')) if path.exists() else tomlkit.document()
# Each value that the change sets, by its keys
SET = [
    (('project', 'version'), '0.2.0'),
]

def put(table, keys, value):   # make each table on the way; a table goes into the one there, key by key
    for key in keys[:-1]:
        if key not in table:
            table[key] = tomlkit.table(True)
        table = table[key]
    if isinstance(value, dict) and isinstance(table.get(keys[-1]), dict):
        for key, item in value.items():
            put(table[keys[-1]], [key], item)
    else:
        table[keys[-1]] = value

for keys, value in SET:
    put(doc, keys, value)
path.write_text(tomlkit.dumps(doc), encoding='utf-8')
PY

The patch changes one line of pyproject.toml, version, from 0.1.0 to 0.2.0.

grep -n '^version' pyproject.toml

It prints 3:version = "0.2.0". The lockfile, uv.lock, still names version 0.1.0 of tally, so it is out of date. The next move brings it up to date.

Check your files against this move. The command prints nothing when they match, and otherwise shows what differs:

git check aea02344f2e3

If you are stuck, this command puts the files of this move in place of yours. A file that you made yourself stays:

git restore --source a54eadb267e9 --staged -- :/ && git restore --source aea02344f2e3 --staged --worktree -- :/

What changed

  • pyproject.toml: the new version. 1 line added, 1 removed. The file.
    • look at version = "0.2.0"
The patch to pyproject.toml
@@ -1,6 +1,6 @@
 [project]
 name = "tally"
-version = "0.1.0"
+version = "0.2.0"
 description = "Count the words in a text"
 readme = "README.md"
 requires-python = ">=3.12"

This change on GitHub. The code after it.

1.3 The lock, and the list of changes

uv.lock records the exact version of each package of the project, tally too. uv lock writes it again from pyproject.toml.

uv lock

A user of a release wants to know what changed. A new file, CHANGES.md, says it for 0.2.0.

Apply the patch to CHANGES.md, from the top of the project:

curl -fsSL https://github.com/rahuldave/tally/commit/96d6bbd94a65f08776215543e0d3c49575422541.diff | git apply --include=CHANGES.md

The patch makes the file CHANGES.md, with a heading for 0.2.0 and one sentence.

uv lock --check && grep -A1 '^name = "tally"' uv.lock

uv lock --check prints Resolved 1 package and the time it took, and stops with no error, because the lockfile is up to date. Then grep prints the entry of tally, with version = "0.2.0".

Check your files against this move. The command prints nothing when they match, and otherwise shows what differs:

git check 96d6bbd94a65

If you are stuck, this command puts the files of this move in place of yours. A file that you made yourself stays:

git restore --source aea02344f2e3 --staged -- :/ && git restore --source 96d6bbd94a65 --staged --worktree -- :/

What changed

  • CHANGES.md: the changes of 0.2.0. New, 5 lines. The file.
  • uv.lock: the version of tally. 1 line added, 1 removed. It comes from uv lock. The file.
    • look at version = "0.2.0"
The patch to CHANGES.md
@@ -0,0 +1,5 @@
+# Changes
+
+## 0.2.0
+
+The tests of an empty text are now the tests of edge cases, with a test of a text of spaces.

This change on GitHub. The code after it.