Re: [gentoo-portage-dev] [PATCH v2] Add --output-style option to repoman
On 02/13/2014 10:42 AM, Brian Dolbec wrote: On Thu, 13 Feb 2014 03:19:35 -0500 Mike Frysinger vap...@gentoo.org wrote: On Monday, February 10, 2014 20:22:36 Chris Reffett wrote: This patch adds a --output-style option to repoman, which gives the user a choice of output formats for the repoman checks. Choices are default (current style) and column (a greppable format), but it should be easy to add more. Fixes bug 481584. i'd expect a proper structured output would make sense to include in the default set. like JSON. just create a dict and send it to json.dump(). He is working on more changes to repoman and the output. So, if you can, Chris, then do it, add a json option. Will do that after my next set of changes to repoman (to be emailed shortly) v2: Fix docstring to be complete and in the standard format, make use of default choices in --output-style wrt comments by antarus and dol-sen erm, i thought the previous docstring was correct. it followed PEP257 while this new one is like javadoc or something. It is the existing format that has been around in portage for years. There is even a page for it: http://www.gentoo.org/proj/en/portage/doc/policies/docstring-spec.xml It is also the style that epydoc recognizes. -utilities.format_qa_output(f, stats, fails, dofull, dofail, options, qawarnings) +if options.output_style == 'column': + utilities.format_qa_output_column(f, stats, fails, dofull, dofail, options, qawarnings) +else: + utilities.format_qa_output(f, stats, fails, dofull, dofail, options, qawarnings) use a func pointer instead. format_outputs = { 'column': utilities.format_qa_output_column, 'default': utilities.format_qa_output, } format_output = format_outputs.get(options.output_style, format_outputs['default']) format_output(f, stats, fails, dofull, dofail, options, qawarnings) yeah, make it so. Good spot, Mike Committed, thanks for the spot. Since Mike was too slow in replying, make another commit to change it. + formatter.add_literal_data(NumberOf + category + ) prefer to use % rather than + like so: 'NumberOf %s ' % category + formatter.add_literal_data(%s % number) well actually, for simple additions like that, string1 + string2, it is actually faster. But for multiple additions, %s is much better, faster. Also if the string is translated, then use %s regardless. That way the %s can be moved around for the translation. str(number) -mike
[gentoo-portage-dev] [PATCH 0/2] Refactor repoman QA handling
This series of patches alters repoman's QA output to be much more usable. The first patch changes all checks to output a list of either length 1 or 2, splitting the file with the error from the error itself. This will be helpful for making machine-parseable output in the future. The second both makes the variables used to build the output much more consistent and makes the output itself more consistent by removing a few instances where the full path was printed rather than the relative path. This will change the existing repoman output format and potentially break scripts which rely on the old and inconsistent behavior. Chris Reffett (2): Split output for repoman checks into file and message Repoman check code cleanup bin/repoman | 232 +++ pym/repoman/utilities.py | 18 +++- 2 files changed, 128 insertions(+), 122 deletions(-) -- 1.8.5.3
Re: [gentoo-portage-dev] [PATCH 1/2] Split output for repoman checks into file and message
On Wed, 19 Feb 2014 13:10:04 -0500 Chris Reffett creff...@gentoo.org wrote: This wraps the output of emerge checks so that a list of length 1-2 is generated. The first element is the file, the second element (optional) is a more descriptive error message. This change will help us eventually introduce more machine-readable output formats. --- bin/repoman | 232 +++ pym/repoman/utilities.py | 18 +++- 2 files changed, 128 insertions(+), 122 deletions(-) diff --git a/bin/repoman b/bin/repoman index 92b..3d5dde4 100755 --- a/bin/repoman +++ b/bin/repoman @@ -1402,7 +1402,7 @@ for x in effective_scanlist: repoman_settings['PORTAGE_QUIET'] = '1' if not portage.digestcheck([], repoman_settings, strict=1): stats[manifest.bad] += 1 - fails[manifest.bad].append(os.path.join(x, 'Manifest')) + fails[manifest.bad].append([os.path.join(x, 'Manifest')]) repoman_settings.pop('PORTAGE_QUIET', None) This looks so,so to me. I think you are much better off using a namedtuple class for these errors instead. They have built-in formatted printing, etc. from collections import namedtuple and you can have pre-defined named tuple classes that have the error message already embedded. for some examples see the pyGPG ones I created for gpg data mining: https://github.com/dol-sen/pyGPG/blob/master/pyGPG/legend.py NOTE: CLASSES is a list of tuples that have the info to define the classes that subclass the namedtuple class. They are initialized by the code at the bottom of the page when the page is first loaded into memory. This format saves writing out each individual class by hand and makes changes easy. It also reduced the size of the file to about 1/3. I have done similar to tis in 3 modules in the catalys rewrite as well. The data is then available in many ways and will have a consistent output. -- Brian Dolbec dolsen
Re: [gentoo-portage-dev] [PATCH 1/2] Split output for repoman checks into file and message
On Wed, 19 Feb 2014 10:33:15 -0800 Brian Dolbec dol...@gentoo.org wrote: On Wed, 19 Feb 2014 13:10:04 -0500 Chris Reffett creff...@gentoo.org wrote: This wraps the output of emerge checks so that a list of length 1-2 is generated. The first element is the file, the second element (optional) is a more descriptive error message. This change will help us eventually introduce more machine-readable output formats. --- bin/repoman | 232 +++ pym/repoman/utilities.py | 18 +++- 2 files changed, 128 insertions(+), 122 deletions(-) diff --git a/bin/repoman b/bin/repoman index 92b..3d5dde4 100755 --- a/bin/repoman +++ b/bin/repoman @@ -1402,7 +1402,7 @@ for x in effective_scanlist: repoman_settings['PORTAGE_QUIET'] = '1' if not portage.digestcheck([], repoman_settings, strict=1): stats[manifest.bad] += 1 - fails[manifest.bad].append(os.path.join(x, 'Manifest')) + fails[manifest.bad].append([os.path.join(x, 'Manifest')]) repoman_settings.pop('PORTAGE_QUIET', None) This looks so,so to me. I think you are much better off using a namedtuple class for these errors instead. They have built-in formatted printing, etc. from collections import namedtuple and you can have pre-defined named tuple classes that have the error message already embedded. for some examples see the pyGPG ones I created for gpg data mining: https://github.com/dol-sen/pyGPG/blob/master/pyGPG/legend.py NOTE: CLASSES is a list of tuples that have the info to define the classes that subclass the namedtuple class. They are initialized by the code at the bottom of the page when the page is first loaded into memory. This format saves writing out each individual class by hand and makes changes easy. It also reduced the size of the file to about 1/3. I have done similar to tis in 3 modules in the catalys rewrite as well. The data is then available in many ways and will have a consistent output. for smaller simpler examples: http://git.overlays.gentoo.org/gitweb/?p=proj/catalyst.git;a=blob;f=catalyst/hash_utils.py;h=cd31ad3edbdd412c0da4d968596777a71fbd4beb;hb=refs/heads/3.0 http://git.overlays.gentoo.org/gitweb/?p=proj/catalyst.git;a=blob;f=catalyst/contents.py;h=1a9ed28a58cc63ed954ca8bdbcd1b594e8a7f2e5;hb=refs/heads/3.0 -- Brian Dolbec dolsen
Re: [gentoo-portage-dev] [PATCH] portdbapi: Add cache to avoid repeated failing os.access calls
Am 18.02.2014 22:35, schrieb David James: + cache_key = (mycpv, mytree, myrepo) + try: + return self._findname2_cache[cache_key] + except KeyError: + self._findname2_cache[cache_key] = (None, 0) To me, it seems potentially error-prone to cache a (potentially) incorrect value and then correct it later. It is. The problem are all these returns. The whole thing would need to be reorganized to fix this. I'd rather go for a memoize decorator and leave that thing alone. If I just could find a usable one. Would it be possible to refactor your patch so that we only cache the value when we know the final answer? + except TypeError: In what circumstances does it happen that mytree / myrepo are unhashable types? Can you add a comment to explain this? That's my mistake. I was under the impression that mytree is actually mytreeS and would accept a list. I'll remove the except TypeError: in a future version of the patch.
[gentoo-portage-dev] [PATCH] Add an emaint module that can scan for failed merges and that can fix failed merges.
--- pym/portage/emaint/modules/merges/__init__.py | 20 pym/portage/emaint/modules/merges/merges.py | 70 +++ 2 files changed, 90 insertions(+) create mode 100644 pym/portage/emaint/modules/merges/__init__.py create mode 100644 pym/portage/emaint/modules/merges/merges.py diff --git a/pym/portage/emaint/modules/merges/__init__.py b/pym/portage/emaint/modules/merges/__init__.py new file mode 100644 index 000..2cd79af --- /dev/null +++ b/pym/portage/emaint/modules/merges/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2005-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +Scan for failed merges and fix them. + + + +module_spec = { + 'name': 'merges', + 'description': __doc__, + 'provides':{ + 'module1': { + 'name': merges, + 'class': MergesHandler, + 'description': __doc__, + 'functions': ['check', 'fix',], + 'func_desc': {} + } + } + } diff --git a/pym/portage/emaint/modules/merges/merges.py b/pym/portage/emaint/modules/merges/merges.py new file mode 100644 index 000..b243082 --- /dev/null +++ b/pym/portage/emaint/modules/merges/merges.py @@ -0,0 +1,70 @@ +# Copyright 2005-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +import portage +from portage import os +from portage.const import PRIVATE_PATH, VDB_PATH +from portage.util import writemsg + +import shutil +import sys + +if sys.hexversion = 0x300: + # pylint: disable=W0622 + long = int + +class MergesHandler(object): + + short_desc = Remove failed merges + + def name(): + return merges + name = staticmethod(name) + + def __init__(self): + self._eroot = portage.settings['EROOT'] + self._vardb = portage.db[self._eroot][vartree].dbapi + self._vardb_path = os.path.join(self._eroot, VDB_PATH) + os.path.sep + + def can_progressbar(self, func): + return True + + def _failed_packages(self, onProgress): + for cat in os.listdir(self._vardb_path): + pkgs = os.listdir(self._vardb_path + cat) + maxval = len(pkgs) + for i, pkg in enumerate(pkgs): + if onProgress: + onProgress(maxval, i+1) + + if '-MERGING-' in pkg: + yield cat + os.path.sep + pkg + + def check(self, **kwargs): + onProgress = kwargs.get('onProgress', None) + failed_pkgs = [] + for pkg in self._failed_packages(onProgress): + failed_pkgs.append(pkg) + + errors = ['%s' failed to merge. % x for x in failed_pkgs] + return errors + + def fix(self, **kwargs): + onProgress = kwargs.get('onProgress', None) + tracking_path = os.path.join(self._eroot, PRIVATE_PATH, 'failed-merges'); + try: + with open(tracking_path, 'w') as tracking_file: + for failed_pkg in self._failed_packages(onProgress): + tracking_file.write(failed_pkg + '\n') + pkg_path = self._vardb_path + failed_pkg + # Delete failed merge directory + # XXX: Would be a good idea to attempt try removing + # package contents to prevent orphaned files + shutil.rmtree(pkg_path) + # Re-emerge package + pkg_name = '=' + failed_pkg.replace('-MERGING-', '') + features='FEATURES=-collision-detect -protect-owned' + emerge_cmd=emerge --verbose --oneshot --complete-graph=y + os.system('%s %s %s' % (features, emerge_cmd, pkg_name)) + except Exception as ex: + writemsg('Unable to fix failed package: %s' % str(ex)) -- 1.8.3.2
Re: [gentoo-portage-dev] [PATCH] Add an emaint module that can scan for failed merges and that can fix failed merges.
On Wed, Feb 19, 2014 at 12:31 PM, Pavel Kazakov nullishz...@gentoo.orgwrote: --- pym/portage/emaint/modules/merges/__init__.py | 20 pym/portage/emaint/modules/merges/merges.py | 70 +++ 2 files changed, 90 insertions(+) create mode 100644 pym/portage/emaint/modules/merges/__init__.py create mode 100644 pym/portage/emaint/modules/merges/merges.py diff --git a/pym/portage/emaint/modules/merges/__init__.py b/pym/portage/emaint/modules/merges/__init__.py new file mode 100644 index 000..2cd79af --- /dev/null +++ b/pym/portage/emaint/modules/merges/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2005-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +Scan for failed merges and fix them. + Scan for failed merges fix them. + + +module_spec = { + 'name': 'merges', + 'description': __doc__, + 'provides':{ 'module1' ? + 'module1': { + 'name': merges, + 'class': MergesHandler, + 'description': __doc__, + 'functions': ['check', 'fix',], + 'func_desc': {} + } + } + } diff --git a/pym/portage/emaint/modules/merges/merges.py b/pym/portage/emaint/modules/merges/merges.py new file mode 100644 index 000..b243082 --- /dev/null +++ b/pym/portage/emaint/modules/merges/merges.py @@ -0,0 +1,70 @@ +# Copyright 2005-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +import portage +from portage import os +from portage.const import PRIVATE_PATH, VDB_PATH +from portage.util import writemsg + +import shutil +import sys + +if sys.hexversion = 0x300: + # pylint: disable=W0622 + long = int What is this little guy? Can we just do this in a library someplace? + +class MergesHandler(object): + + short_desc = Remove failed merges + @staticmethod decorator? + def name(): + return merges + name = staticmethod(name) + + def __init__(self): Generally you want to be able to change these later, so you might do something like: def __init__(self, eroot=None, vardb=None, vardb_path=None): self._eroot = error or portage.settings['EROOT'] ... and so forth. Also..why can't self._vardb_path be queried from the vardb? + self._eroot = portage.settings['EROOT'] + self._vardb = portage.db[self._eroot][vartree].dbapi + self._vardb_path = os.path.join(self._eroot, VDB_PATH) + os.path.sep + + def can_progressbar(self, func): + return True + + def _failed_packages(self, onProgress): + for cat in os.listdir(self._vardb_path): os.listdir(os.path.join(...)) ? + pkgs = os.listdir(self._vardb_path + cat) + maxval = len(pkgs) + for i, pkg in enumerate(pkgs): + if onProgress: + onProgress(maxval, i+1) + + if '-MERGING-' in pkg: + yield cat + os.path.sep + pkg + + def check(self, **kwargs): + onProgress = kwargs.get('onProgress', None) + failed_pkgs = [] + for pkg in self._failed_packages(onProgress): + failed_pkgs.append(pkg) + + errors = ['%s' failed to merge. % x for x in failed_pkgs] + return errors + + def fix(self, **kwargs): + onProgress = kwargs.get('onProgress', None) + tracking_path = os.path.join(self._eroot, PRIVATE_PATH, 'failed-merges'); + try: + with open(tracking_path, 'w') as tracking_file: is this unicode safe? + for failed_pkg in self._failed_packages(onProgress): + tracking_file.write(failed_pkg + '\n') + pkg_path = self._vardb_path + failed_pkg os.path.join(...) + # Delete failed merge directory + # XXX: Would be a good idea to attempt try removing + # package contents to prevent orphaned files # XXX is terrible style. I realize a bunch of code does that, and it is stupid. # use # TODO: foo + shutil.rmtree(pkg_path) + # Re-emerge package + pkg_name = '=' + failed_pkg.replace('-MERGING-', '') + features='FEATURES=-collision-detect -protect-owned' + emerge_cmd=emerge --verbose --oneshot
Re: [gentoo-portage-dev] [PATCH] Add an emaint module that can scan for failed merges and that can fix failed merges.
On Wed, 19 Feb 2014 12:31:44 -0800 Pavel Kazakov nullishz...@gentoo.org wrote: --- pym/portage/emaint/modules/merges/__init__.py | 20 pym/portage/emaint/modules/merges/merges.py | 70 +++ 2 files changed, 90 insertions(+) create mode 100644 pym/portage/emaint/modules/merges/__init__.py create mode 100644 pym/portage/emaint/modules/merges/merges.py diff --git a/pym/portage/emaint/modules/merges/__init__.py b/pym/portage/emaint/modules/merges/__init__.py new file mode 100644 index 000..2cd79af --- /dev/null +++ b/pym/portage/emaint/modules/merges/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2005-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +Scan for failed merges and fix them. + + + +module_spec = { + 'name': 'merges', + 'description': __doc__, + 'provides':{ + 'module1': { + 'name': merges, + 'class': MergesHandler, + 'description': __doc__, + 'functions': ['check', 'fix',], + 'func_desc': {} + } + } + } diff --git a/pym/portage/emaint/modules/merges/merges.py b/pym/portage/emaint/modules/merges/merges.py new file mode 100644 index 000..b243082 --- /dev/null +++ b/pym/portage/emaint/modules/merges/merges.py @@ -0,0 +1,70 @@ +# Copyright 2005-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +import portage +from portage import os +from portage.const import PRIVATE_PATH, VDB_PATH +from portage.util import writemsg + +import shutil +import sys + +if sys.hexversion = 0x300: + # pylint: disable=W0622 + long = int + +class MergesHandler(object): + + short_desc = Remove failed merges + + def name(): + return merges + name = staticmethod(name) + + def __init__(self): + self._eroot = portage.settings['EROOT'] + self._vardb = portage.db[self._eroot][vartree].dbapi + self._vardb_path = os.path.join(self._eroot, VDB_PATH) + os.path.sep + + def can_progressbar(self, func): + return True + + def _failed_packages(self, onProgress): + for cat in os.listdir(self._vardb_path): + pkgs = os.listdir(self._vardb_path + cat) + maxval = len(pkgs) + for i, pkg in enumerate(pkgs): + if onProgress: + onProgress(maxval, i+1) + + if '-MERGING-' in pkg: + yield cat + os.path.sep + pkg + + def check(self, **kwargs): + onProgress = kwargs.get('onProgress', None) + failed_pkgs = [] + for pkg in self._failed_packages(onProgress): + failed_pkgs.append(pkg) + + errors = ['%s' failed to merge. % x for x in failed_pkgs] + return errors + + def fix(self, **kwargs): + onProgress = kwargs.get('onProgress', None) + tracking_path = os.path.join(self._eroot, PRIVATE_PATH, 'failed-merges'); + try: + with open(tracking_path, 'w') as tracking_file: + for failed_pkg in self._failed_packages(onProgress): + tracking_file.write(failed_pkg + '\n') + pkg_path = self._vardb_path + failed_pkg + # Delete failed merge directory + # XXX: Would be a good idea to attempt try removing + # package contents to prevent orphaned files + shutil.rmtree(pkg_path) + # Re-emerge package + pkg_name = '=' + failed_pkg.replace('-MERGING-', '') + features='FEATURES=-collision-detect -protect-owned' + emerge_cmd=emerge --verbose --oneshot --complete-graph=y + os.system('%s %s %s' % (features, emerge_cmd, pkg_name)) + except Exception as ex: + writemsg('Unable to fix failed package: %s' % str(ex)) Really ? don't use os.system() It is nearly obsolete. use subprocess.call() or Popen(). call() is a direct sub. Use Popen for piping output... Also, it would be better to call emerge with all pkgs in one command. I know it will rarely be more than 1, maybe 2 but, emerge is slow enough just intitializing. You might also want to turn off the progressbar for fix unless you intend to pipe
Re: [gentoo-portage-dev] [PATCH] Add an emaint module that can scan for failed merges and that can fix failed merges.
On Wed, 19 Feb 2014 14:32:02 -0800 Alec Warner anta...@gentoo.org wrote: On Wed, Feb 19, 2014 at 12:31 PM, Pavel Kazakov nullishz...@gentoo.orgwrote: --- pym/portage/emaint/modules/merges/__init__.py | 20 pym/portage/emaint/modules/merges/merges.py | 70 +++ 2 files changed, 90 insertions(+) create mode 100644 pym/portage/emaint/modules/merges/__init__.py create mode 100644 pym/portage/emaint/modules/merges/merges.py diff --git a/pym/portage/emaint/modules/merges/__init__.py b/pym/portage/emaint/modules/merges/__init__.py new file mode 100644 index 000..2cd79af --- /dev/null +++ b/pym/portage/emaint/modules/merges/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2005-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +Scan for failed merges and fix them. + Correct ^^ Scan for failed merges fix them. No, your grammar is wrong + + +module_spec = { + 'name': 'merges', + 'description': __doc__, + 'provides':{ 'module1' ? It is just an identifier, not used other than to group together everything for that module. The plugin system can handle multiple sub-modules within the same general module directory. See the emaint/modules/move/__init__.py. Move supplies 2 submodules. The new websync sync module (emerge-webrsync replacement) we started roughing in also has 2 sub-modules, the 1st will be the module that runs the original bash script. The 2nd will be the new python converted code to replace it. + 'module1': { + 'name': merges, + 'class': MergesHandler, + 'description': __doc__, + 'functions': ['check', 'fix',], + 'func_desc': {} + } + } + } diff --git a/pym/portage/emaint/modules/merges/merges.py b/pym/portage/emaint/modules/merges/merges.py new file mode 100644 index 000..b243082 --- /dev/null +++ b/pym/portage/emaint/modules/merges/merges.py @@ -0,0 +1,70 @@ +# Copyright 2005-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +import portage +from portage import os +from portage.const import PRIVATE_PATH, VDB_PATH +from portage.util import writemsg + +import shutil +import sys + +if sys.hexversion = 0x300: + # pylint: disable=W0622 + long = int What is this little guy? Can we just do this in a library someplace? + +class MergesHandler(object): + + short_desc = Remove failed merges + @staticmethod decorator? Yeah, that is copying legacy emaint code from the original module classes. + def name(): + return merges + name = staticmethod(name) + + def __init__(self): Generally you want to be able to change these later, so you might do something like: def __init__(self, eroot=None, vardb=None, vardb_path=None): self._eroot = error or portage.settings['EROOT'] ... and so forth. The emaint code was not setup to handle init variable assignments. None of the original module classes used any. The plugin system doesn't care. But the TaskHandler class in main.py would need to be modified. Also, all modules must use the same method of initializing, regardless whether they need it or not. In the new sync modules all relevant data is passed in using kwargs, then it saves any info it needs. Also..why can't self._vardb_path be queried from the vardb? + self._eroot = portage.settings['EROOT'] + self._vardb = portage.db[self._eroot][vartree].dbapi + self._vardb_path = os.path.join(self._eroot, VDB_PATH) + os.path.sep + + def can_progressbar(self, func): + return True + + def _failed_packages(self, onProgress): + for cat in os.listdir(self._vardb_path): os.listdir(os.path.join(...)) ? + pkgs = os.listdir(self._vardb_path + cat) + maxval = len(pkgs) + for i, pkg in enumerate(pkgs): + if onProgress: + onProgress(maxval, i+1) + + if '-MERGING-' in pkg: + yield cat + os.path.sep + pkg + + def check(self, **kwargs): + onProgress = kwargs.get('onProgress', None) + failed_pkgs = [] + for pkg in self._failed_packages(onProgress): + failed_pkgs.append(pkg) + + errors = ['%s' failed to merge. % x for x in failed_pkgs] + return errors + + def fix(self, **kwargs): + onProgress = kwargs.get('onProgress', None) +
Re: [gentoo-portage-dev] [PATCH] Add an emaint module that can scan for failed merges and that can fix failed merges.
On 02/19/2014 02:50 PM, Brian Dolbec wrote: Really ? don't use os.system() It is nearly obsolete. use subprocess.call() or Popen(). call() is a direct sub. Use Popen for piping output... Good point, I'll switch over. Also, it would be better to call emerge with all pkgs in one command. I know it will rarely be more than 1, maybe 2 but, emerge is slow enough just intitializing. Yep, makes sense. You might also want to turn off the progressbar for fix unless you intend to pipe emerge's output and hide it. I might be inclined to just run emerge in minimum output mode. It will display what it is doing and any more failed builds/merges. I know I had the other modules output the data without displaying and let the cli handle any display. We should be able to do similar to the progressbar, and connect the emerge stdout pipe to a display code. That way any other frontend could do with the output what they like. I'll disable the progressbar for fix(), and look more into minimizing emerge output. Regards, Pavel