Coding 2021-07-08

By Max Woerner Chase

I'm kind of sore and cranky right now, but I want to get work done on the task runner, so I'm going to try to do that.

The first thing I remembered that simplifies things is, I currently don't need the file writing stuff for this project. I will need it, though. The second thing I remembered is, wait, I have a noxfile. I should just be rewriting that.

I gave writing a basic command my best shot. It's... something.

dot_dir = pathlib.Path(".task-runner").resolve()
requirements_dir = pathlib.Path("requirements")
reports_dir = pathlib.Path("reports")

coverage_deleted = api.deleted(pathlib.Path(".coverage"))


# Move this to api
# Add a "freeze data dict" helper
def make_state(data, *changes):
    return api.State((c for change in changes for c in change), data)


def setup_venv(name, requirements_file, commands, project=None):
    changes = []
    final_targets = {}
    venv_path = dot_dir / name
    cmd = ("python", "-m", "venv", "--clear", venv_path)
    make_venv = f"make-venv-{name}"
    bin_dir = venv_path / "bin"
    changes.append(api.add_action(api.Cmd(cmd), make_venv))
    changes.append(api.add_target(bin_dir, make_venv))
    cmd = (bin_dir / "pip", "install", "-U", "pip")
    update_pip = f"update-pip-{name}"
    changes.append(api.add_action(api.Cmd(cmd), update_pip, bin_dir))
    changes.append(api.add_target(update_pip, update_pip))
    cmd = (
        bin_dir / "pip",
        "install",
        "-r",
        requirements_dir / requirements_file,
    )
    if project is not None:
        cmd += (project,)
    install_requirements = f"install-requirements-{name}"
    changes.append(
        api.add_action(api.Cmd(cmd), install_requirements, update_pip)
    )
    for command in commands:
        command_path = bin_dir / command
        changes.append(api.add_target(command_path, install_requirements))
        final_targets[command] = command_path
    return tuple(changes), final_targets


CLEAN_CHANGES, CLEAN_COMMANDS = setup_venv("clean", "coverage", ["coverage"])

CLEAN_CHANGES += (
    api.add_action(
        api.Cmd([CLEAN_COMMANDS["coverage"]], "erase"),
        "coverage-erase",
        CLEAN_COMMANDS["coverage"],
    ),
    api.add_target(coverage_deleted, "coverage-erase"),
)

Takeaways so far:

Anyway, I'm theoretically ready to test this, but I don't think I'm emotionally ready for whatever weird error it's probably going to throw at me.

Sudden thought: "skip" is a bad name for what it is in this app, because the meaning doesn't line up. Suppose I decided I wanted to allow the user to request just erasing the coverage file, but I didn't want that to be considered a default target. Suppose further that the coverage test runs depend on the coverage erase step, (because they will, when I write them) and their dependent targets are named and not skipped (because they represent data that we want by default).

This all means that the "erase" step is called skipped, but it actually runs by default. This behavior doesn't bother me, so the problem must be with the name.

At some point I'm going to have to work on strengthening the naming conventions in this project, and making the names make more sense. Not right now, though. For now, I'm going to look at the code up there and think about what I've done.

Good night.