data_smart: Pass flags through variable rename

Message ID 20220609070631.23346-1-alex.kiernan@gmail.com
State New
Headers show
Series data_smart: Pass flags through variable rename | expand

Commit Message

Alex Kiernan June 9, 2022, 7:06 a.m. UTC
During variable expansion, the flags are not passed through but are
discarded which makes constructs such as:

  ALTERNATIVE_TARGET:${PN}-foo[name] = "value"

fail.

This was previously attempted in 2013:

  https://lists.openembedded.org/g/bitbake-devel/message/3333

It's unclear what the issue called out last time was:

> I think this does not work for all cases but I don't know how to deal
> properly with it. It fixes the case of updates-alternative but breaks
> other code.

  https://lists.openembedded.org/g/bitbake-devel/message/3334

But this code now passes both oe-selftest and bitbake-selftest.

Cc: otavio.salvador@ossystems.com.br
Signed-off-by: Alex Kiernan <alex.kiernan@gmail.com>
Signed-off-by: Alex Kiernan <alexk@zuma.ai>
---
 lib/bb/data_smart.py | 12 +++++++-----
 lib/bb/tests/data.py |  4 ++++
 2 files changed, 11 insertions(+), 5 deletions(-)

Comments

Richard Purdie June 9, 2022, 9:58 a.m. UTC | #1
On Thu, 2022-06-09 at 08:06 +0100, Alex Kiernan wrote:
> During variable expansion, the flags are not passed through but are
> discarded which makes constructs such as:
> 
>   ALTERNATIVE_TARGET:${PN}-foo[name] = "value"

This is a tricky one. I don't think we've ever supported overrides and
flags combined? Is this in use in metadata?

Cheers,

Richard
Alex Kiernan June 9, 2022, 10:33 a.m. UTC | #2
Not that I've found, but I'd really like to use it... I've a layer for
s6-rc (https://skarnet.org/software/s6-rc/) and defining the
configuration using this syntax works really well:

S6_RC_SERVICE_${BPN} ?= "longrun"
S6_RC_SERVICE_${BPN}[producer-for] ?= "${BPN}-log"
S6_RC_SERVICE_${BPN}-log ?= "longrun"
S6_RC_SERVICE_${BPN}-log[consumer-for] ?= "${BPN}"
S6_RC_SERVICE_${BPN}-log[notification-fd] ?= "3"
S6_RC_SERVICE_${BPN}-log[pipeline-name] ?= "${BPN}-pipeline"
S6_RC_SERVICE_${BPN}-log[run] ?= "${@ d.getVar('s6_rc_log') }"

Is the kind of thing I'd like to work.

On Thu, Jun 9, 2022 at 10:58 AM Richard Purdie
<richard.purdie@linuxfoundation.org> wrote:
>
> On Thu, 2022-06-09 at 08:06 +0100, Alex Kiernan wrote:
> > During variable expansion, the flags are not passed through but are
> > discarded which makes constructs such as:
> >
> >   ALTERNATIVE_TARGET:${PN}-foo[name] = "value"
>
> This is a tricky one. I don't think we've ever supported overrides and
> flags combined? Is this in use in metadata?
>
> Cheers,
>
> Richard
Alex Kiernan June 16, 2022, 12:27 p.m. UTC | #3
I've been thinking around this, I guess the bit I really want to work
is for flags to survive through variable renames, rather than
overrides, but the two use cases do tend to collide as we often have
overrides with variable expansion, which is then renaming...

Just realised I c&p my example from our vendor branch which is still
on _ based overrides rather than : based ones, but both seem to work
for me.

On Thu, Jun 9, 2022 at 11:33 AM Alex Kiernan via
lists.openembedded.org <alex.kiernan=gmail.com@lists.openembedded.org>
wrote:
>
> Not that I've found, but I'd really like to use it... I've a layer for
> s6-rc (https://skarnet.org/software/s6-rc/) and defining the
> configuration using this syntax works really well:
>
> S6_RC_SERVICE_${BPN} ?= "longrun"
> S6_RC_SERVICE_${BPN}[producer-for] ?= "${BPN}-log"
> S6_RC_SERVICE_${BPN}-log ?= "longrun"
> S6_RC_SERVICE_${BPN}-log[consumer-for] ?= "${BPN}"
> S6_RC_SERVICE_${BPN}-log[notification-fd] ?= "3"
> S6_RC_SERVICE_${BPN}-log[pipeline-name] ?= "${BPN}-pipeline"
> S6_RC_SERVICE_${BPN}-log[run] ?= "${@ d.getVar('s6_rc_log') }"
>
> Is the kind of thing I'd like to work.
>
> On Thu, Jun 9, 2022 at 10:58 AM Richard Purdie
> <richard.purdie@linuxfoundation.org> wrote:
> >
> > On Thu, 2022-06-09 at 08:06 +0100, Alex Kiernan wrote:
> > > During variable expansion, the flags are not passed through but are
> > > discarded which makes constructs such as:
> > >
> > >   ALTERNATIVE_TARGET:${PN}-foo[name] = "value"
> >
> > This is a tricky one. I don't think we've ever supported overrides and
> > flags combined? Is this in use in metadata?
> >
> > Cheers,
> >
> > Richard
>
>
>
> --
> Alex Kiernan
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#13747): https://lists.openembedded.org/g/bitbake-devel/message/13747
> Mute This Topic: https://lists.openembedded.org/mt/91640731/3618097
> Group Owner: bitbake-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/bitbake-devel/unsub [alex.kiernan@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
Richard Purdie June 27, 2022, 11:10 a.m. UTC | #4
On Thu, 2022-06-16 at 13:27 +0100, Alex Kiernan wrote:
> I've been thinking around this, I guess the bit I really want to work
> is for flags to survive through variable renames, rather than
> overrides, but the two use cases do tend to collide as we often have
> overrides with variable expansion, which is then renaming...
> 
> Just realised I c&p my example from our vendor branch which is still
> on _ based overrides rather than : based ones, but both seem to work
> for me.

I've been pondering this a bit more but I'm not sure we want to wade
into the complexities of how flags+overrides+key expansion can all
collide together.

I did notice this in the metadata though:

RRECOMMENDS:coreutils-dev[nodeprrecs] = "1"

which happens to work as it doesn't use key expansion and doesn't rely
on override expansion for access (the variable named
"RRECOMMENDS:coreutils-dev" exists).

It does mean we have some subset of this problem live in metadata
though :/.

Changing it to RRECOMMENDS:${PN}-dev breaks things.

Cheers,

Richard
Alex Kiernan June 28, 2022, 11:13 a.m. UTC | #5
On Mon, Jun 27, 2022 at 12:10 PM Richard Purdie
<richard.purdie@linuxfoundation.org> wrote:
>
> On Thu, 2022-06-16 at 13:27 +0100, Alex Kiernan wrote:
> > I've been thinking around this, I guess the bit I really want to work
> > is for flags to survive through variable renames, rather than
> > overrides, but the two use cases do tend to collide as we often have
> > overrides with variable expansion, which is then renaming...
> >
> > Just realised I c&p my example from our vendor branch which is still
> > on _ based overrides rather than : based ones, but both seem to work
> > for me.
>
> I've been pondering this a bit more but I'm not sure we want to wade
> into the complexities of how flags+overrides+key expansion can all
> collide together.
>

I guess I understand this, even if I'd like it to work :)

> I did notice this in the metadata though:
>
> RRECOMMENDS:coreutils-dev[nodeprrecs] = "1"
>
> which happens to work as it doesn't use key expansion and doesn't rely
> on override expansion for access (the variable named
> "RRECOMMENDS:coreutils-dev" exists).
>
> It does mean we have some subset of this problem live in metadata
> though :/.
>
> Changing it to RRECOMMENDS:${PN}-dev breaks things.
>

Feels like it merits at least a warning? Though I guess the challenge
is chasing an ever moving set of internal flags which can be attached
to a variable.

Patch

diff --git a/lib/bb/data_smart.py b/lib/bb/data_smart.py
index dd20ca557ee2..308f8eab4913 100644
--- a/lib/bb/data_smart.py
+++ b/lib/bb/data_smart.py
@@ -675,13 +675,15 @@  class DataSmart(MutableMapping):
 
         srcflags = self.getVarFlags(key, False, True) or {}
         for i in srcflags:
-            if i not in (__setvar_keyword__):
+            if i == "_content":
                 continue
             src = srcflags[i]
-
-            dest = self.getVarFlag(newkey, i, False) or []
-            dest.extend(src)
-            self.setVarFlag(newkey, i, dest, ignore=True)
+            if i in (__setvar_keyword__):
+                dest = self.getVarFlag(newkey, i, False) or []
+                dest.extend(src)
+                self.setVarFlag(newkey, i, dest, ignore=True)
+            else:
+                self.setVarFlag(newkey, i, src, ignore=True)
 
         if key in self.overridedata:
             self.overridedata[newkey] = []
diff --git a/lib/bb/tests/data.py b/lib/bb/tests/data.py
index e667c7c7d359..5cdf1494f3c4 100644
--- a/lib/bb/tests/data.py
+++ b/lib/bb/tests/data.py
@@ -440,6 +440,10 @@  class TestFlags(unittest.TestCase):
         self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
         self.assertEqual(self.d.getVarFlag("foo", "flag2", False), None)
 
+    def test_renameflag(self):
+        self.d.renameVar("foo", "bar")
+        self.assertEqual(self.d.getVarFlag("bar", "flag1", False), "value of flag1")
+
 
 class Contains(unittest.TestCase):
     def setUp(self):