* [PATCH v2 1/4] bitbake-setup: define a color_enabled() helper function
2026-02-18 13:15 [PATCH v2 0/4] bitbake-setup: Improve readability Antonin Godard
@ 2026-02-18 13:15 ` Antonin Godard
2026-02-18 13:15 ` [PATCH v2 2/4] bitbake-setup: improve readability of choices Antonin Godard
` (2 subsequent siblings)
3 siblings, 0 replies; 10+ messages in thread
From: Antonin Godard @ 2026-02-18 13:15 UTC (permalink / raw)
To: bitbake-devel; +Cc: Thomas Petazzoni, Antonin Godard
This will be re-used in the next commits to force subprocess commands to
color their outputs, as passing --color=auto in them always render
without coloring.
Signed-off-by: Antonin Godard <antonin.godard@bootlin.com>
---
bin/bitbake-setup | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/bin/bitbake-setup b/bin/bitbake-setup
index 927c03a1033..3e17e631bfb 100755
--- a/bin/bitbake-setup
+++ b/bin/bitbake-setup
@@ -35,6 +35,13 @@ GLOBAL_ONLY_SETTINGS = (
"top-dir-name",
)
+def color_enabled() -> bool:
+ """
+ Our logger has a BBLogFormatter formatter which holds whether color is
+ enabled or not. Return this value.
+ """
+ return logger.handlers[0].formatter.color_enabled
+
# If bitbake is from a release tarball or somewhere like pypi where
# updates may not be straightforward, prefer to use the git repo as the
# default registry
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v2 2/4] bitbake-setup: improve readability of choices
2026-02-18 13:15 [PATCH v2 0/4] bitbake-setup: Improve readability Antonin Godard
2026-02-18 13:15 ` [PATCH v2 1/4] bitbake-setup: define a color_enabled() helper function Antonin Godard
@ 2026-02-18 13:15 ` Antonin Godard
2026-02-18 13:15 ` [PATCH v2 3/4] bitbake-setup: print colored diffs Antonin Godard
2026-02-18 13:15 ` [PATCH v2 4/4] bitbake-setup: drop get_diff and replace by run_git_diff Antonin Godard
3 siblings, 0 replies; 10+ messages in thread
From: Antonin Godard @ 2026-02-18 13:15 UTC (permalink / raw)
To: bitbake-devel; +Cc: Thomas Petazzoni, Antonin Godard
Bold the configuration names and align the descriptions for improved
readability. For this, define a print_configs() function which should
also help factorizing the code as this is done in multiple places.
If color_enabled() is false, keep the text plain.
Signed-off-by: Antonin Godard <antonin.godard@bootlin.com>
---
bin/bitbake-setup | 74 ++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 51 insertions(+), 23 deletions(-)
diff --git a/bin/bitbake-setup b/bin/bitbake-setup
index 3e17e631bfb..9b0ecc8d0e4 100755
--- a/bin/bitbake-setup
+++ b/bin/bitbake-setup
@@ -42,6 +42,33 @@ def color_enabled() -> bool:
"""
return logger.handlers[0].formatter.color_enabled
+def print_configs(prompt: str, choices: list[str], descriptions: list[str] = []):
+ """
+ Helper function to print a list of choices and align the output.
+ Each option name is made bold to stand out, unless color is not enabled in
+ our logger.
+ """
+ if not prompt.endswith(':'):
+ prompt += ":"
+ logger.plain(prompt)
+
+ if not descriptions:
+ descriptions = ["" for _ in choices]
+
+ # maximum size of all choices, for alignment
+ cmax = max([len(c) for c in choices]) + 1
+
+ for n, c in enumerate(choices):
+ msg = f"{n + 1}. "
+ if color_enabled():
+ # make it bold
+ msg += "\033[1m"
+ msg += f"{c:<{cmax}}"
+ if color_enabled():
+ msg += "\033[0m"
+ msg += f" {descriptions[n]}"
+ logger.plain(msg)
+
# If bitbake is from a release tarball or somewhere like pypi where
# updates may not be straightforward, prefer to use the git repo as the
# default registry
@@ -497,36 +524,39 @@ def choose_bitbake_config(configs, parameters, non_interactive):
if non_interactive:
raise Exception("Unable to choose from bitbake configurations in non-interactive mode: {}".format(configs_dict))
- logger.plain("\nAvailable bitbake configurations:")
- for n, config_data in enumerated_configs:
- logger.plain("{}. {}\t{}".format(n, config_data["name"], config_data["description"]))
+ logger.plain("")
+ print_configs("Available bitbake configurations",
+ [c["name"] for c in flattened_configs],
+ [c["description"] for c in flattened_configs])
config_n = int_input([i[0] for i in enumerated_configs],
"\nPlease select one of the above bitbake configurations by its number: ") - 1
return flattened_configs[config_n]
def choose_config(configs, non_interactive):
not_expired_configs = [k for k in sorted(configs.keys()) if not has_expired(configs[k].get("expires", None))]
- config_list = list(enumerate(not_expired_configs, 1))
- if len(config_list) == 1:
- only_config = config_list[0][1]
+ if len(not_expired_configs) == 1:
+ only_config = not_expired_configs[0]
logger.plain("\nSelecting the only available configuration {}\n".format(only_config))
return only_config
if non_interactive:
raise Exception("Unable to choose from configurations in non-interactive mode: {}".format(not_expired_configs))
- logger.plain("\nAvailable Configuration Templates:")
- for n, config_name in config_list:
- config_data = configs[config_name]
- expiry_date = config_data.get("expires", None)
- config_desc = config_data["description"]
+ descs = []
+ for c in not_expired_configs:
+ d = configs[c]["description"]
+ expiry_date = configs[c].get("expires", None)
if expiry_date:
- logger.plain("{}. {}\t{} (supported until {})".format(n, config_name, config_desc, expiry_date))
- else:
- logger.plain("{}. {}\t{}".format(n, config_name, config_desc))
- config_n = int_input([i[0] for i in config_list],
- "\nPlease select one of the above Configuration Templates by its number: ") - 1
- return config_list[config_n][1]
+ d += f" (supported until {expiry_date})"
+ descs.append(d)
+
+ logger.plain("")
+ print_configs("Available Configuration Templates",
+ [c for c in not_expired_configs],
+ descs)
+ config_n = int_input([i[0] for i in list(enumerate(not_expired_configs, 1))],
+ "\nPlease select one of the above configurations by its number: ") - 1
+ return not_expired_configs[config_n]
def choose_fragments(possibilities, parameters, non_interactive, skip_selection):
choices = {}
@@ -552,13 +582,11 @@ def choose_fragments(possibilities, parameters, non_interactive, skip_selection)
if non_interactive:
raise Exception(f"Unable to choose from options in non-interactive mode: {[o['name'] for o in options]}")
- logger.plain("\n" + v["description"] + ":")
+ logger.plain("")
+ print_configs(v["description"],
+ [o['name'] for o in options],
+ [o['description'] for o in options])
options_enumerated = list(enumerate(options, 1))
- for n,o in options_enumerated:
- opt_str = f"{n}. {o['name']}"
- if o["description"]:
- opt_str += f"\t{o['description']}"
- logger.plain(opt_str)
option_n = int_input([i[0] for i in options_enumerated],
"\nPlease select one of the above options by its number: ") - 1
choices[k] = options_enumerated[option_n][1]["name"]
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v2 3/4] bitbake-setup: print colored diffs
2026-02-18 13:15 [PATCH v2 0/4] bitbake-setup: Improve readability Antonin Godard
2026-02-18 13:15 ` [PATCH v2 1/4] bitbake-setup: define a color_enabled() helper function Antonin Godard
2026-02-18 13:15 ` [PATCH v2 2/4] bitbake-setup: improve readability of choices Antonin Godard
@ 2026-02-18 13:15 ` Antonin Godard
2026-02-18 15:27 ` Antonin Godard
2026-02-18 13:15 ` [PATCH v2 4/4] bitbake-setup: drop get_diff and replace by run_git_diff Antonin Godard
3 siblings, 1 reply; 10+ messages in thread
From: Antonin Godard @ 2026-02-18 13:15 UTC (permalink / raw)
To: bitbake-devel; +Cc: Thomas Petazzoni, Antonin Godard
Define a new run_git_diff() function that can be used to print diffs
between two paths (files or directories), or show a diff in a Git
repository. This function also uses color_enabled() to force showing
color or not in the subprocess. Replace the different calls of `diff`
and `git diff` by this helper function.
Signed-off-by: Antonin Godard <antonin.godard@bootlin.com>
---
bin/bitbake-setup | 41 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/bin/bitbake-setup b/bin/bitbake-setup
index 9b0ecc8d0e4..e456aa93bf3 100755
--- a/bin/bitbake-setup
+++ b/bin/bitbake-setup
@@ -69,6 +69,39 @@ def print_configs(prompt: str, choices: list[str], descriptions: list[str] = [])
msg += f" {descriptions[n]}"
logger.plain(msg)
+def run_git_diff(revision: str = "", path1: str = "", path2: str = "", repo_path: str = "") -> str:
+ """
+ Run git diff from either the current working directory, or in the path
+ specified by repo_path.
+ Then, run git diff with either:
+ - no argument,
+ - or a revision,
+ - or two files / two directories.
+ """
+ assert not (revision and (path1 or path2)), \
+ "run_git_diff can only be called with a revision or two paths, not both"
+ assert not (path1 and not path2), \
+ "run_git_diff only received one path, two expected"
+
+ path = f"-C {repo_path}" if repo_path else ""
+ color = "--color=always" if color_enabled() else "--color=never"
+ git_cmd = f"git {path} diff {color}"
+ if revision:
+ git_cmd += f" {revision}"
+ elif path1:
+ git_cmd += f" {path1} {path2}"
+
+ diff = ""
+ try:
+ diff = bb.process.run(f"{git_cmd}")[0].strip()
+ except bb.process.ExecutionError as e:
+ if e.exitcode == 1:
+ diff = e.stdout
+ else:
+ raise e
+
+ return diff
+
# If bitbake is from a release tarball or somewhere like pypi where
# updates may not be straightforward, prefer to use the git repo as the
# default registry
@@ -202,7 +235,7 @@ be preserved in a backup directory.""".format(r_name, r_path))
status = bb.process.run('git -C {} status --porcelain'.format(r_path))[0]
if status:
return True
- diff = bb.process.run('git -C {} diff {}'.format(r_path, rev))[0]
+ diff = run_git_diff(revision=rev, repo_path=r_path)
if diff:
return True
return False
@@ -728,7 +761,9 @@ def init_config(top_dir, settings, args):
def get_diff(file1, file2):
try:
- bb.process.run('diff -uNr {} {}'.format(file1, file2))
+ bb.process.run('diff --color={} -uNr {} {}'.format("always" if BBSETUP_COLOR else "never",
+ file1,
+ file2))
except bb.process.ExecutionError as e:
if e.exitcode == 1:
return e.stdout
@@ -786,7 +821,7 @@ def build_status(top_dir, settings, args, d, update=False):
new_upstream_config = obtain_config(top_dir, registry, args, source_overrides, d)
write_upstream_config(confdir, new_upstream_config)
- config_diff = bb.process.run('git -C {} diff'.format(confdir))[0]
+ config_diff = run_git_diff(repo_path=confdir)
if config_diff:
logger.plain('\nConfiguration in {} has changed:\n{}'.format(setupdir, config_diff))
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v2 3/4] bitbake-setup: print colored diffs
2026-02-18 13:15 ` [PATCH v2 3/4] bitbake-setup: print colored diffs Antonin Godard
@ 2026-02-18 15:27 ` Antonin Godard
2026-02-19 9:36 ` [bitbake-devel] " Alexander Kanavin
0 siblings, 1 reply; 10+ messages in thread
From: Antonin Godard @ 2026-02-18 15:27 UTC (permalink / raw)
To: bitbake-devel; +Cc: Thomas Petazzoni, Antonin Godard
Hi,
On Wed Feb 18, 2026 at 2:15 PM CET, Antonin Godard wrote:
[...]
> @@ -728,7 +761,9 @@ def init_config(top_dir, settings, args):
>
> def get_diff(file1, file2):
> try:
> - bb.process.run('diff -uNr {} {}'.format(file1, file2))
> + bb.process.run('diff --color={} -uNr {} {}'.format("always" if BBSETUP_COLOR else "never",
> + file1,
> + file2))
Oops, this slipped through, but shouldn't be changed at all since it is removed
in the next commit. I will resend the series.
Antonin
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [bitbake-devel] [PATCH v2 3/4] bitbake-setup: print colored diffs
2026-02-18 15:27 ` Antonin Godard
@ 2026-02-19 9:36 ` Alexander Kanavin
2026-02-19 10:18 ` Antonin Godard
0 siblings, 1 reply; 10+ messages in thread
From: Alexander Kanavin @ 2026-02-19 9:36 UTC (permalink / raw)
To: antonin.godard; +Cc: bitbake-devel, Thomas Petazzoni
On Wed, 18 Feb 2026 at 16:27, Antonin Godard via
lists.openembedded.org
<antonin.godard=bootlin.com@lists.openembedded.org> wrote:
> Oops, this slipped through, but shouldn't be changed at all since it is removed
> in the next commit. I will resend the series.
Also the function is *way* over-engineered. I only wanted to avoid
repeating the color logic, so perhaps just this bit could be
abstracted and used in all three locations?
def get_color_param():
return "always" if BBSETUP_COLOR else "never"
Alex
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [bitbake-devel] [PATCH v2 3/4] bitbake-setup: print colored diffs
2026-02-19 9:36 ` [bitbake-devel] " Alexander Kanavin
@ 2026-02-19 10:18 ` Antonin Godard
2026-02-19 11:13 ` Alexander Kanavin
0 siblings, 1 reply; 10+ messages in thread
From: Antonin Godard @ 2026-02-19 10:18 UTC (permalink / raw)
To: Alexander Kanavin; +Cc: bitbake-devel, Thomas Petazzoni
Hi,
On Thu Feb 19, 2026 at 10:36 AM CET, Alexander Kanavin wrote:
> On Wed, 18 Feb 2026 at 16:27, Antonin Godard via
> lists.openembedded.org
> <antonin.godard=bootlin.com@lists.openembedded.org> wrote:
>
>> Oops, this slipped through, but shouldn't be changed at all since it is removed
>> in the next commit. I will resend the series.
>
> Also the function is *way* over-engineered. I only wanted to avoid
> repeating the color logic, so perhaps just this bit could be
> abstracted and used in all three locations?
>
> def get_color_param():
> return "always" if BBSETUP_COLOR else "never"
Not sure I follow.
def color_enabled() -> bool:
return logger.handlers[0].formatter.color_enabled
IMO this is better than the previous version which did:
global BBSETUP_COLOR
if args.color == 'always' or (args.color == 'auto' and sys.stdout.isatty() and os.environ.get('NO_COLOR', '') == ''):
BBSETUP_COLOR = True
That logic is already present in the logger object, in msg.py, when creating the
logger:
if color == 'always' or (color == 'auto' and output.isatty() and os.environ.get('NO_COLOR', '') == ''):
format.enable_color()
The proposal here was to get rid of BBSETUP_COLOR entirely and avoid
duplication. Not sure how this is *way* over-engineered, I'd rather see it as a
simplification
Antonin
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [bitbake-devel] [PATCH v2 3/4] bitbake-setup: print colored diffs
2026-02-19 10:18 ` Antonin Godard
@ 2026-02-19 11:13 ` Alexander Kanavin
2026-02-20 9:14 ` Antonin Godard
0 siblings, 1 reply; 10+ messages in thread
From: Alexander Kanavin @ 2026-02-19 11:13 UTC (permalink / raw)
To: Antonin Godard; +Cc: bitbake-devel, Thomas Petazzoni
On Thu, 19 Feb 2026 at 11:18, Antonin Godard <antonin.godard@bootlin.com> wrote:
> Not sure I follow.
>
> def color_enabled() -> bool:
> return logger.handlers[0].formatter.color_enabled
>
> IMO this is better than the previous version which did:
>
> global BBSETUP_COLOR
> if args.color == 'always' or (args.color == 'auto' and sys.stdout.isatty() and os.environ.get('NO_COLOR', '') == ''):
> BBSETUP_COLOR = True
>
> That logic is already present in the logger object, in msg.py, when creating the
> logger:
>
> if color == 'always' or (color == 'auto' and output.isatty() and os.environ.get('NO_COLOR', '') == ''):
> format.enable_color()
>
> The proposal here was to get rid of BBSETUP_COLOR entirely and avoid
> duplication. Not sure how this is *way* over-engineered, I'd rather see it as a
> simplification
Apologies, I started writing emails before putting enough coffee in my
bloodstream and got everyone confused.
What I mean is that run_git_diff() ended up being too complex, because
it aims to cover all possible use cases of getting a diff. I know I
had asked for that :) but I wonder if instead of that whole new
function, we could simply add:
def get_color_param():
return "--color={}".format("always" if color_enabled() else "never")
and then tweak all existing invocations of 'diff' and 'git diff', e.g.:
- bb.process.run('diff -uNr {} {}'.format(file1, file2))
+ bb.process.run('diff {} -uNr {} {}'.format(get_color_param(),
file1, file2))
Would be a much simpler change, with the same end result.
Alex
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [bitbake-devel] [PATCH v2 3/4] bitbake-setup: print colored diffs
2026-02-19 11:13 ` Alexander Kanavin
@ 2026-02-20 9:14 ` Antonin Godard
0 siblings, 0 replies; 10+ messages in thread
From: Antonin Godard @ 2026-02-20 9:14 UTC (permalink / raw)
To: alex.kanavin; +Cc: bitbake-devel, Thomas Petazzoni
On Thu Feb 19, 2026 at 12:13 PM CET, Alexander Kanavin via lists.openembedded.org wrote:
> On Thu, 19 Feb 2026 at 11:18, Antonin Godard <antonin.godard@bootlin.com> wrote:
>> Not sure I follow.
>>
>> def color_enabled() -> bool:
>> return logger.handlers[0].formatter.color_enabled
>>
>> IMO this is better than the previous version which did:
>>
>> global BBSETUP_COLOR
>> if args.color == 'always' or (args.color == 'auto' and sys.stdout.isatty() and os.environ.get('NO_COLOR', '') == ''):
>> BBSETUP_COLOR = True
>>
>> That logic is already present in the logger object, in msg.py, when creating the
>> logger:
>>
>> if color == 'always' or (color == 'auto' and output.isatty() and os.environ.get('NO_COLOR', '') == ''):
>> format.enable_color()
>>
>> The proposal here was to get rid of BBSETUP_COLOR entirely and avoid
>> duplication. Not sure how this is *way* over-engineered, I'd rather see it as a
>> simplification
>
> Apologies, I started writing emails before putting enough coffee in my
> bloodstream and got everyone confused.
>
> What I mean is that run_git_diff() ended up being too complex, because
> it aims to cover all possible use cases of getting a diff. I know I
> had asked for that :) but I wonder if instead of that whole new
> function, we could simply add:
>
> def get_color_param():
> return "--color={}".format("always" if color_enabled() else "never")
>
> and then tweak all existing invocations of 'diff' and 'git diff', e.g.:
>
> - bb.process.run('diff -uNr {} {}'.format(file1, file2))
> + bb.process.run('diff {} -uNr {} {}'.format(get_color_param(),
> file1, file2))
>
> Would be a much simpler change, with the same end result.
Gotcha, just sent a new version :)
Antonin
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 4/4] bitbake-setup: drop get_diff and replace by run_git_diff
2026-02-18 13:15 [PATCH v2 0/4] bitbake-setup: Improve readability Antonin Godard
` (2 preceding siblings ...)
2026-02-18 13:15 ` [PATCH v2 3/4] bitbake-setup: print colored diffs Antonin Godard
@ 2026-02-18 13:15 ` Antonin Godard
3 siblings, 0 replies; 10+ messages in thread
From: Antonin Godard @ 2026-02-18 13:15 UTC (permalink / raw)
To: bitbake-devel; +Cc: Thomas Petazzoni, Antonin Godard
We have a new run_git_diff() function that can be used both for showing
diffs in git repositories, but also for printing diffs between two
directories or files, making get_diff() redundant. Replace the single
call to get_diff() by run_git_diff().
Signed-off-by: Antonin Godard <antonin.godard@bootlin.com>
---
bin/bitbake-setup | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/bin/bitbake-setup b/bin/bitbake-setup
index e456aa93bf3..56c579d19f7 100755
--- a/bin/bitbake-setup
+++ b/bin/bitbake-setup
@@ -430,7 +430,7 @@ def setup_bitbake_build(bitbake_config, layerdir, setupdir, thisdir, update_bb_c
bb.process.run("{} -c '. {} && bitbake-config-build enable-fragment {}'".format(shell, init_script, " ".join(fragments)))
if os.path.exists(backup_bitbake_confdir):
- conf_diff = get_diff(backup_bitbake_confdir, bitbake_confdir)
+ conf_diff = run_git_diff(path1=backup_bitbake_confdir, path2=bitbake_confdir)
if not conf_diff:
logger.plain('New bitbake configuration from upstream is the same as the current one, no need to update it.')
shutil.rmtree(bitbake_confdir)
@@ -759,18 +759,6 @@ def init_config(top_dir, settings, args):
bb.event.remove("bb.build.TaskProgress", None)
-def get_diff(file1, file2):
- try:
- bb.process.run('diff --color={} -uNr {} {}'.format("always" if BBSETUP_COLOR else "never",
- file1,
- file2))
- except bb.process.ExecutionError as e:
- if e.exitcode == 1:
- return e.stdout
- else:
- raise e
- return None
-
def are_layers_changed(layers, layerdir, d):
def _is_git_remote_changed(r_remote, repodir):
changed = False
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread