summaryrefslogtreecommitdiffstats
path: root/action.py
diff options
context:
space:
mode:
Diffstat (limited to 'action.py')
-rw-r--r--action.py420
1 files changed, 420 insertions, 0 deletions
diff --git a/action.py b/action.py
new file mode 100644
index 0000000..b2c67ce
--- /dev/null
+++ b/action.py
@@ -0,0 +1,420 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#################################################################################
+# LAYMAN ACTIONS
+#################################################################################
+# File: action.py
+#
+# Handles layman actions.
+#
+# Copyright:
+# (c) 2005 - 2006 Gunnar Wrobel
+# Distributed under the terms of the GNU General Public License v2
+#
+# Author(s):
+# Gunnar Wrobel <wrobel@gentoo.org>
+#
+''' Provides the different actions that can be performed by layman.'''
+
+__version__ = "$Id: action.py 312 2007-04-09 19:45:49Z wrobel $"
+
+#===============================================================================
+#
+# Dependencies
+#
+#-------------------------------------------------------------------------------
+
+import sys
+
+from layman.db import DB, RemoteDB
+
+from layman.debug import OUT
+
+#===============================================================================
+#
+# Class Fetch
+#
+#-------------------------------------------------------------------------------
+
+class Fetch:
+ ''' Fetches the overlay listing.
+
+ >>> import os
+ >>> here = os.path.dirname(os.path.realpath(__file__))
+ >>> cache = os.tmpnam()
+ >>> config = {'overlays' :
+ ... 'file://' + here + '/tests/testfiles/global-overlays.xml',
+ ... 'cache' : cache,
+ ... 'nocheck' : True,
+ ... 'proxy' : None,
+ ... 'quietness':3}
+ >>> a = Fetch(config)
+ >>> a.run()
+ 0
+ >>> b = open(a.db.path(config['overlays']))
+ >>> b.readlines()[24]
+ ' A collection of ebuilds from Gunnar Wrobel [wrobel@gentoo.org].\\n'
+
+ >>> b.close()
+ >>> os.unlink(a.db.path(config['overlays']))
+
+ >>> a.db.overlays.keys()
+ [u'wrobel', u'wrobel-stable']
+ '''
+
+ def __init__(self, config):
+ self.db = RemoteDB(config)
+
+ def run(self):
+ '''Fetch the overlay listing.'''
+ try:
+ self.db.cache()
+ except Exception, error:
+ OUT.die('Failed to fetch overlay list!\nError was: '
+ + str(error))
+
+ return 0
+
+#===============================================================================
+#
+# Class Sync
+#
+#-------------------------------------------------------------------------------
+
+class Sync:
+ ''' Syncs the selected overlays.'''
+
+ def __init__(self, config):
+
+ self.db = DB(config)
+
+ self.rdb = RemoteDB(config)
+
+ self.selection = config['sync']
+
+ if config['sync_all'] or 'ALL' in self.selection:
+ self.selection = self.db.overlays.keys()
+
+ def run(self):
+ '''Synchronize the overlays.'''
+
+ OUT.debug('Updating selected overlays', 6)
+
+ warnings = []
+ success = []
+ for i in self.selection:
+ ordb = self.rdb.select(i)
+ odb = self.db.select(i)
+ if ordb and odb and ordb.src != odb.src:
+ warnings.append(
+ 'The source of the overlay "' + i + '" seems to have c'
+ 'hanged. You currently sync from "' + odb.src + '" whi'
+ 'le the global layman list reports "' + ordb.src + '" '
+ 'as correct location. Please consider removing and rea'
+ 'dding the overlay!')
+
+ try:
+ self.db.sync(i)
+ success.append('Successfully synchronized overlay "' + i + '".')
+ except Exception, error:
+ warnings.append(
+ 'Failed to sync overlay "' + i + '".\nError was: '
+ + str(error))
+
+ if success:
+ OUT.info('\nSuccess:\n------\n', 3)
+ for i in success:
+ OUT.info(i, 3)
+
+ if warnings:
+ OUT.warn('\nErrors:\n------\n', 2)
+ for i in warnings:
+ OUT.warn(i + '\n', 2)
+ return 1
+
+ return 0
+
+#===============================================================================
+#
+# Class Add
+#
+#-------------------------------------------------------------------------------
+
+class Add:
+ ''' Adds the selected overlays.'''
+
+ def __init__(self, config):
+
+ self.config = config
+
+ self.db = DB(config)
+
+ self.rdb = RemoteDB(config)
+
+ self.selection = config['add']
+
+ if 'ALL' in self.selection:
+ self.selection = self.rdb.overlays.keys()
+
+ def run(self):
+ '''Add the overlay.'''
+
+ OUT.debug('Adding selected overlays', 6)
+
+ result = 0
+
+ for i in self.selection:
+ overlay = self.rdb.select(i)
+
+ OUT.debug('Selected overlay', 7)
+
+ if overlay:
+ try:
+ self.db.add(overlay)
+ OUT.info('Successfully added overlay "' + i + '".', 2)
+ except Exception, error:
+ OUT.warn('Failed to add overlay "' + i + '".\nError was: '
+ + str(error), 2)
+ result = 1
+ else:
+ OUT.warn('Overlay "' + i + '" does not exist!', 2)
+ result = 1
+
+ return result
+
+#===============================================================================
+#
+# Class Delete
+#
+#-------------------------------------------------------------------------------
+
+class Delete:
+ ''' Deletes the selected overlays.'''
+
+ def __init__(self, config):
+
+ self.db = DB(config)
+
+ self.selection = config['delete']
+
+ if 'ALL' in self.selection:
+ self.selection = self.db.overlays.keys()
+
+ def run(self):
+ '''Delete the overlay.'''
+
+ OUT.debug('Deleting selected overlays', 6)
+
+ result = 0
+
+ for i in self.selection:
+ overlay = self.db.select(i)
+
+ OUT.debug('Selected overlay', 7)
+
+ if overlay:
+ try:
+ self.db.delete(overlay)
+ OUT.info('Successfully deleted overlay "' + i + '".', 2)
+ except Exception, error:
+ OUT.warn('Failed to delete overlay "' + i + '".\nError was: '
+ + str(error), 2)
+ result = 1
+ else:
+ OUT.warn('Overlay "' + i + '" does not exist!', 2)
+ result = 1
+
+ return result
+
+#===============================================================================
+#
+# Class List
+#
+#-------------------------------------------------------------------------------
+
+class List:
+ ''' Lists the available overlays.
+
+ >>> import os
+ >>> here = os.path.dirname(os.path.realpath(__file__))
+ >>> cache = os.tmpnam()
+ >>> config = {'overlays' :
+ ... 'file://' + here + '/tests/testfiles/global-overlays.xml',
+ ... 'cache' : cache,
+ ... 'proxy' : None,
+ ... 'nocheck' : False,
+ ... 'verbose': False,
+ ... 'quietness':3}
+ >>> a = List(config)
+ >>> a.rdb.cache()
+ >>> OUT.color_off()
+ >>> a.run()
+ * wrobel [Subversion] (source: https://overlays.gentoo.or...)
+ 0
+ >>> a.config['verbose'] = True
+ >>> a.run()
+ * wrobel
+ * ~~~~~~
+ * Source : https://overlays.gentoo.org/svn/dev/wrobel
+ * Contact : nobody@gentoo.org
+ * Type : Subversion; Priority: 10
+ *
+ * Description:
+ * Test
+ *
+ * *** This is no official gentoo overlay ***
+ *
+ * wrobel-stable
+ * ~~~~~~~~~~~~~
+ * Source : rsync://gunnarwrobel.de/wrobel-stable
+ * Contact : nobody@gentoo.org
+ * Type : Rsync; Priority: 50
+ *
+ * Description:
+ * A collection of ebuilds from Gunnar Wrobel [wrobel@gentoo.org].
+ *
+ 0
+ '''
+
+ def __init__(self, config):
+
+ OUT.debug('Creating RemoteDB handler', 6)
+
+ self.rdb = RemoteDB(config)
+ self.config = config
+
+ def run(self):
+ ''' List the available overlays.'''
+
+ for i in self.rdb.list(self.config['verbose']):
+ # Is the overlay supported?
+ if i[1]:
+ # Is this an official overlay?
+ if i[2]:
+ OUT.info(i[0], 1)
+ # Unofficial overlays will only be listed if we are not
+ # checking or listing verbose
+ elif self.config['nocheck'] or self.config['verbose']:
+ # Give a reason why this is marked yellow if it is a verbose
+ # listing
+ if self.config['verbose']:
+ OUT.warn('*** This is no official gentoo overlay ***\n', 1)
+ OUT.warn(i[0], 1)
+ # Unsupported overlays will only be listed if we are not checking
+ # or listing verbose
+ elif self.config['nocheck'] or self.config['verbose']:
+ # Give a reason why this is marked red if it is a verbose
+ # listing
+ if self.config['verbose']:
+ OUT.error('*** You are lacking the necessary tools to insta'
+ 'll this overlay ***\n')
+ OUT.error(i[0])
+
+ return 0
+
+#===============================================================================
+#
+# Class ListLocal
+#
+#-------------------------------------------------------------------------------
+
+class ListLocal:
+ ''' Lists the local overlays.'''
+
+ def __init__(self, config):
+ self.db = DB(config)
+ self.config = config
+
+ def run(self):
+ '''List the overlays.'''
+
+ for i in self.db.list(self.config['verbose']):
+
+ OUT.debug('Printing local overlay.', 8)
+
+ # Is the overlay supported?
+ if i[1]:
+ # Is this an official overlay?
+ if i[2]:
+ OUT.info(i[0], 1)
+ # Unofficial overlays will only be listed if we are not
+ # checking or listing verbose
+ else:
+ # Give a reason why this is marked yellow if it is a verbose
+ # listing
+ if self.config['verbose']:
+ OUT.warn('*** This is no official gentoo overlay ***\n', 1)
+ OUT.warn(i[0], 1)
+ # Unsupported overlays will only be listed if we are not checking
+ # or listing verbose
+ else:
+ # Give a reason why this is marked red if it is a verbose
+ # listing
+ if self.config['verbose']:
+ OUT.error('*** You are lacking the necessary tools to insta'
+ 'll this overlay ***\n')
+ OUT.error(i[0])
+
+ return 0
+
+#===============================================================================
+#
+# Class Actions
+#
+#-------------------------------------------------------------------------------
+
+class Actions:
+ '''Dispatches to the actions the user selected. '''
+
+ # Given in order of precedence
+ actions = [('fetch', Fetch),
+ ('add', Add),
+ ('sync', Sync),
+ ('sync_all', Sync),
+ ('delete', Delete),
+ ('list', List),
+ ('list_local', ListLocal),]
+
+ def __init__(self, config):
+
+ # Make fetching the overlay list a default action
+ if not 'nofetch' in config.keys():
+ # Actions that implicitely call the fetch operation before
+ fetch_actions = ['fetch', 'sync', 'sync_all', 'list']
+ for i in fetch_actions:
+ if i in config.keys():
+ # Implicitely call fetch, break loop
+ Fetch(config).run()
+ break
+
+ result = 0
+
+ for i in self.actions:
+
+ OUT.debug('Checking for action', 7)
+
+ if i[0] in config.keys():
+ result += i[1](config).run()
+
+
+ if not result:
+ sys.exit(0)
+ else:
+ sys.exit(1)
+
+#===============================================================================
+#
+# Testing
+#
+#-------------------------------------------------------------------------------
+
+if __name__ == '__main__':
+ import doctest, sys
+
+ # Ignore warnings here. We are just testing
+ from warnings import filterwarnings, resetwarnings
+ filterwarnings('ignore')
+
+ doctest.testmod(sys.modules[__name__])
+
+ resetwarnings()