public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "André Erdmann" <dywi@mailerd.de>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/packagerules/parser/context/
Date: Thu, 13 Jun 2013 16:34:27 +0000 (UTC)	[thread overview]
Message-ID: <1370379327.ad1e9bcc9a2f64c9de4a8ff210628d78e8264c16.dywi@gentoo> (raw)

commit:     ad1e9bcc9a2f64c9de4a8ff210628d78e8264c16
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Jun  4 20:55:27 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Jun  4 20:55:27 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=ad1e9bcc

package rule parser, actions: parse info actions

This commit adds support for parsing actions that modify package info dicts.

Currently, a package's ebuild name, category and src_uri destfile can be set
to a specific value or edited using a sed-like regex statement.

The basic syntax for set-to-value is

* set <key> <value>
* set_<key> <value>

regex-rename syntax:
* set <key> s/<regex>/<replacement>/[<flags>]
* set_<key> ...

"/" can be replaced by any other char (but --print-package-rules will always use
"/").

<flags> (e.g. "g") is not implemented. All occurences of <regex> will be
replaced.

---
 roverlay/packagerules/parser/context/action.py | 173 +++++++++++++++++++++++--
 1 file changed, 164 insertions(+), 9 deletions(-)

diff --git a/roverlay/packagerules/parser/context/action.py b/roverlay/packagerules/parser/context/action.py
index f9a2e80..c58f7ca 100644
--- a/roverlay/packagerules/parser/context/action.py
+++ b/roverlay/packagerules/parser/context/action.py
@@ -4,9 +4,13 @@
 # Distributed under the terms of the GNU General Public License;
 # either version 2 of the License, or (at your option) any later version.
 
+import re
+
 import roverlay.strutil
 
 import roverlay.packagerules.actions.evar
+import roverlay.packagerules.actions.info
+import roverlay.packagerules.actions.relocate
 import roverlay.packagerules.actions.trace
 import roverlay.packagerules.parser.context.base
 
@@ -41,11 +45,165 @@ class RuleActionContext (
       'keywords' : roverlay.packagerules.actions.evar.KeywordsEvarAction,
    }
 
+   # default info set-to/rename actions
+   #  using the lazy variant for renaming
+   #
+   DEFAULT_MODIFY_INFO_ACTIONS = (
+      roverlay.packagerules.actions.info.InfoSetToAction,
+      roverlay.packagerules.actions.info.LazyInfoRenameAction
+   )
+
+   # dict { key => None | { None | SetTo_Action, None | Rename_Action }
+   #   where None is "use default action(s)"
+   #
+   MODIFIABLE_INFO_KEYS = {
+      'name' : (
+         None,
+         roverlay.packagerules.actions.info.InfoRenameAction
+      ),
+      'category' : None,
+      'destfile' : (
+         None,
+         roverlay.packagerules.actions.relocate.SrcDestRenameAction
+      ),
+   }
+
+   # TODO / Notes:
+   #
+   # * "combined" actions, e.g. name,category as "pseudo" actions?
+   #
+   # dict { pseudo_key => tuple ( argparse_function, set { real key[s] } ) }
+   #
+##   DEMUX_INFO_KEYS = {
+##      'cp' : ( argstr_parse(), { 'name', 'category', } )
+##   }
+
    def __init__ ( self, namespace ):
       super ( RuleActionContext, self ).__init__ ( namespace )
       self._actions = list()
    # --- end of __init__ (...) ---
 
+   def _add_as_info_action ( self, keyword, argstr, orig_str, lino ):
+      """Tries to add <keyword, argstr> as package info-manipulating action.
+
+      Returns true if such an action has been created and added, else False.
+      Invalid values/lines will be catched here. A return value of False
+      simply means that keyword/argstr do not represent an info action.
+
+      arguments:
+      * keyword  --
+      * argstr   --
+      * orig_str --
+      * lino     --
+
+      Raises:
+      * ActionUnknown
+      * ActionNeedsValue
+      """
+      # get action_type_str (and, possibly, key)
+      action_type_str, sepa, key = keyword.partition ( "_" )
+      action_type_str = action_type_str.lower()
+
+      if action_type_str == "set":
+         # is a set-to info action, continue
+         action_type = 0
+      elif action_type_str == "rename":
+         # is a rename info action, continue
+         action_type = 1
+      else:
+         # not an info action
+         return False
+      # -- end if;
+
+      if not sepa:
+         # get key from argstr
+         argv = roverlay.strutil.split_whitespace ( argstr, maxsplit=1 )
+         if argv:
+            key = roverlay.strutil.unquote ( argv [0].lower() )
+            if not key:
+               # better safe than sorry ;)
+               #return False
+               raise ActionUnknown ( orig_str )
+         else:
+            #return False
+            raise ActionUnknown ( orig_str )
+
+
+         # dont unquote value here,
+         #  this operation might depend on key in future
+         value = argv [1]
+      else:
+         value = argstr
+      # -- end if;
+
+      # get action class (raises KeyError)
+      try:
+
+         # ( ( cls_tuple or <default> ) [action_type] ) or <default>
+         action_cls = (
+            (
+               self.MODIFIABLE_INFO_KEYS [key]
+               or self.DEFAULT_MODIFY_INFO_ACTIONS
+            ) [action_type]
+            or self.DEFAULT_MODIFY_INFO_ACTIONS [action_type]
+         )
+      except KeyError:
+         raise ActionUnknown ( orig_str )
+
+      # create and add action
+      if action_type == 0:
+         # info action (1 arg)
+         value = roverlay.strutil.unquote ( value )
+
+         if value:
+            self._actions.append ( action_cls ( key, value, lino ) )
+         else:
+            raise ActionNeedsValue ( orig_str )
+      else:
+         # rename action (1 arg)
+         #  sed-like replace statement "s/a/b/flags?"
+         #
+         # FIXME/TODO *** flags are not implemented ***
+         #
+         # len ( value ) >= len (
+         #    "s" + sepa + len(a)>=1 + sepa + len(b)>=1 + sepa + len(flags)>=0
+         # )
+         # => 6 relevant parts (3x sepa, 2x value), len (value) has to be > 5
+         #
+
+         value = roverlay.strutil.unquote ( value )
+
+         if len ( value ) > 5 and value[0] == 's' and value[1] == value[-1]:
+
+            # double-escaped backslash
+            re_splitter = self.namespace.get_object (
+               re.compile, '(?<!\\\)' + value [1]
+            )
+
+            # (redef argv)
+            argv = re_splitter.split ( value, maxsplit=3 )
+
+            if len ( argv ) > 3 and all ( argv[:4] ):
+               raise NotImplementedError ( "flags are not supported yet." )
+
+            elif len ( argv ) > 2 and all ( argv[:3] ):
+               self._actions.append (
+                  action_cls (
+                     key,
+                     self.namespace.get_object ( re.compile, argv [1] ),
+                     argv [2],
+                     lino
+                  )
+               )
+            else:
+               raise ActionNeedsValue ( orig_str )
+         else:
+            raise ActionNeedsValue ( orig_str )
+      # -- end if;
+
+      return True
+   # --- end of _add_as_info_action (...) ---
+
    def feed ( self, _str, lino ):
       """Feeds this action block with input.
 
@@ -74,31 +232,28 @@ class RuleActionContext (
          if argv [0] in self.KEYWORDS_ACTION_TRACE:
             if len ( argv ) > 1 and argv [1]:
                self._actions.append (
-                  self.namespace.get_object (
-                     roverlay.packagerules.actions.trace.TraceAction,
+                  roverlay.packagerules.actions.trace.TraceAction (
                      roverlay.strutil.unquote ( argv [1] ),
                      lino
                   )
                )
             else:
                self._actions.append (
-                  self.namespace.get_object (
-                     roverlay.packagerules.actions.trace.MarkAsModifiedAction,
+                  roverlay.packagerules.actions.trace.MarkAsModifiedAction (
                      lino
                   )
                )
 
+         elif self._add_as_info_action ( argv [0], argv [1], _str, lino ):
+            pass
+
          else:
             evar_cls = self.KEYWORDS_EVAR.get ( argv [0], None )
 
             try:
                if evar_cls:
                   self._actions.append (
-                     self.namespace.get_object (
-                        evar_cls,
-                        roverlay.strutil.unquote ( argv [1] ),
-                        lino
-                     )
+                     evar_cls ( roverlay.strutil.unquote ( argv [1] ), lino )
                   )
                else:
                   raise ActionUnknown ( _str )


             reply	other threads:[~2013-06-13 16:34 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-13 16:34 André Erdmann [this message]
  -- strict thread matches above, loose matches on Subject: below --
2013-08-19 15:42 [gentoo-commits] proj/R_overlay:master commit in: roverlay/packagerules/parser/context/ André Erdmann
2013-08-19 15:42 André Erdmann
2013-08-01 17:14 André Erdmann
2013-06-13 16:34 André Erdmann
2013-06-05 18:08 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
2013-06-13 16:34 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
2013-04-25 16:44 André Erdmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1370379327.ad1e9bcc9a2f64c9de4a8ff210628d78e8264c16.dywi@gentoo \
    --to=dywi@mailerd.de \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox