Tags
I'm really getting into using hatch as my go to build system, and I am really
liking it so far. I am slowly finding new things that just work really well.
hatch new is one of those things that I didn't realize I needed until I had
it.

creating new versions created by myself with stable diffusion

❯ pipx run hatch new --help Usage: hatch new [OPTIONS] [NAME] [LOCATION] Create or initialize a project. Options: -i, --interactive Interactively choose details about the project --cli Give the project a command line interface --init Initialize an existing project -h, --help Show this message and exit.
Note! I am running all of these commands with pipx. I like to use pipx for all of my system level cli applications. To emphasis this point in the article I am going to use
pipx run hatch, but you canpipx install hatchthen just runhatchfrom there.
Interacively create a new project #
Running hatch new -i will ask let you interactivly choose details about the
project, such as the project's name.
pipx run hatch new -i
After running and naming the project Hatch New we end up with the following filetree.
❯ tree . . ├── hatch_new │ ├── __about__.py │ └── __init__.py ├── LICENSE.txt ├── pyproject.toml ├── README.md └── tests └── __init__.py
Non-Interative #
You can also fill in the project name ahead of time, and it will run without any questions.

❯ pipx run hatch new "Another Project" another-project ├── another_project │ ├── __about__.py │ └── __init__.py ├── tests │ └── __init__.py ├── LICENSE.txt ├── README.md └── pyproject.toml
Note! all of these examples will create a project directory within your current working directory.

--init #
existing project
hatch new has an --init flag in order to initialize a new hatch
pyproject.toml in an existing project. This feels like it would be useful if
you are converting a project to hatch, or if like me you sometimes start making
something before you realize it's something that you want to package. Honestly
this doesn't happen too much anymore I package most things, and I hope hatch new completely breaks this habbit of mine.
Let's say I have the following existing project.
❯ tree . └── hatch_init └── __init__.py 1 directory, 1 file
I can setup packaging with hatch by running.
pipx run hatch new --init

The pyproject.toml that comes out is pretty similar to the one that comes out
of the normal hatch new, but without any other files.
Note that you will need to setup a
__about__.pyyourself for the dynamic versioning that it has setup for you.
[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "hatch-init" description = 'initialize an existing project using hatch' readme = "README.md" requires-python = ">=3.7" license = "MIT" keywords = [] authors = [ { name = "Waylon S. Walker", email = "[email protected]" }, ] classifiers = [ "Development Status :: 4 - Beta", "Programming Language :: Python", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", ] dependencies = [] dynamic = ["version"] [project.urls] Documentation = "https://github.com/unknown/hatch-init#readme" Issues = "https://github.com/unknown/hatch-init/issues" Source = "https://github.com/unknown/hatch-init" [tool.hatch.version] path = "hatch_init/__about__.py" [tool.hatch.envs.default] dependencies = [ "pytest", "pytest-cov", ] [tool.hatch.envs.default.scripts] cov = "pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=hatch_init --cov=tests" no-cov = "cov --no-cov" [[tool.hatch.envs.test.matrix]] python = ["37", "38", "39", "310", "311"] [tool.coverage.run] branch = true parallel = true omit = [ "hatch_init/__about__.py", ] [tool.coverage.report] exclude_lines = [ "no cov", "if __name__ == .__main__.:", "if TYPE_CHECKING:", ]
cli #
hatch new does not stop there, it also has a --cli flag to give you a cli
out of the box as well.
❯ pipx run hatch new "new cli" --cli new-cli ├── new_cli │ ├── cli │ │ └── __init__.py │ ├── __about__.py │ ├── __init__.py │ └── __main__.py ├── tests │ └── __init__.py ├── LICENSE.txt ├── README.md └── pyproject.toml
When you use the --cli flag you also get click as a dependency and
project.scripts setup automatically.
[project] name = "new-cli" # ... dependencies = [ "click", ] # ... [project.scripts] new-cli = "new_cli.cli:new_cli"

what's in the cli #
It's a hello-world click application.
# SPDX-FileCopyrightText: 2022-present Waylon S. Walker <[email protected]> # # SPDX-License-Identifier: MIT import click from ..__about__ import __version__ @click.group(context_settings={'help_option_names': ['-h', '--help']}, invoke_without_command=True) @click.version_option(version=__version__, prog_name='new cli') @click.pass_context def new_cli(ctx: click.Context): click.echo('Hello world!')
sneak peek #
I'll dive more into environments and the run command later, but we can run the cli pretty damn quick with two commands. In under 5s I was able to run this cli that it created. This is a pretty incredible startup time.

