Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Project's name from command line
I have a pyproject.toml
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "foo"
version = "0.1.0"
How do I get the project name foo from the command line, assuming I'm in the directory containing this file?
I'm on Ubuntu.
4 answers
If you cannot install YQ, you can use awk or grep. It will not be as robust as YQ's actual parser, but likely good enough for many use cases.
# using awk
# explanation: separate columns on ", look for line starting with name and print the second column
$ awk -F '"' '/^name/{ print $2; }' pyproject.toml
foo
# using grep
# explanation: look for lines starting with name, match everything after name = " and only display the part that's matched.
$ grep -oP '^name = "\K[^"]+' pyproject.toml
foo
0 comment threads
Python does not specifically provide any tooling for this, because packaging is considered a separate domain from the language itself.
If you use third-party tooling to build and distribute your project, it may provide this sort of functionality for you. (Note that some of these tools provide their own build backend and expect you to use it rather than the default Setuptools; some of them may even overwrite and update pyproject.toml on your behalf.) However, it seems to be generally assumed that you either know this information already (since you're assumed to have created the project in the first place, or copied it from somewhere that makes the name obvious) or at least don't need to be reminded.
Overall, the simplest, most portable approach is to just read and parse the pyproject.toml file. As shown in ArtOfCode's answer, the yq command can do this elegantly. Otherwise, Python provides (from 3.11 onward) a TOML parser in the standard library (for earlier versions, use tomli, which was the basis for the standard library module), which allows a somewhat complex one-liner:
python -c 'import tomllib; from pathlib import Path; toml=tomllib.loads(Path("pyproject.toml").read_text()); print(toml["project"]["name"])'
Or on multiple lines without pathlib:
python -c 'from tomllib import load
with open("pyproject.toml", "rb") as f:
print(load(f)["project"]["name"])'
which can be made into a system script, Bash function or alias, etc. as necessary.
0 comment threads
You could opt for using sed, which is available by default on most systems and is available even for Windows. The invocation I cooked up should work with non-GNU versions as well. Dissected for the unfamiliar reader's understanding
# sed -n => no output except what is specifically requested
# Single quotes prevent a lot of messy double escaping with shells that do
# interpolation and interpretation of escape sequences with double quotes
# s/.../ => substitute command
# [[:space:]] => the builtin whitespace group
# * => match zero or more times
# name => literal string
# \+ => match one or more times. TOML doesn't mandate spaces around the equals
# sign, but any formatter and sane person adds them anyway
# = and " => literal symbols
# \(...\) => regex matching group for later use
# [a-zA-Z0-9_] => ASCII letters, numbers, and underscore
# \1 => replace everything matched with just group 1 (the only group here)
# /p => print this output (required because of sed -n)
sed -n 's/[[:space:]]*name[[:space:]]\+=[[:space:]]\+"\([a-zA-Z0-9_]\+\)"/\1/p' pyproject.toml
Which prints no more or less than foo

0 comment threads