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/depres/
Date: Wed,  6 Jun 2012 19:52:35 +0000 (UTC)	[thread overview]
Message-ID: <1339011890.1202ca5c63080cf066a6997709a23088996322ef.dywi@gentoo> (raw)

commit:     1202ca5c63080cf066a6997709a23088996322ef
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed Jun  6 19:44:50 2012 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed Jun  6 19:44:50 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=1202ca5c

dependency resolution

* can now resolve dependencies using dictionary-like 'SimpleDependencyRules'

	new file:   roverlay/depres/communication.py
	new file:   roverlay/depres/depenv.py
	modified:   roverlay/depres/depresolver.py
	modified:   roverlay/depres/deprule.py
	deleted:    roverlay/depres/rulereader.py
	new file:   roverlay/depres/simpledeprule.py

---
 roverlay/depres/communication.py |  115 +++++++++++++++++++++++++
 roverlay/depres/depenv.py        |   47 +++++++++++
 roverlay/depres/depresolver.py   |  161 +++++++++++++++++++++++++++++-------
 roverlay/depres/deprule.py       |   90 +++++----------------
 roverlay/depres/rulereader.py    |   88 --------------------
 roverlay/depres/simpledeprule.py |  170 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 482 insertions(+), 189 deletions(-)

diff --git a/roverlay/depres/communication.py b/roverlay/depres/communication.py
new file mode 100644
index 0000000..65050f1
--- /dev/null
+++ b/roverlay/depres/communication.py
@@ -0,0 +1,115 @@
+# R overlay --
+# Copyright 2006-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import logging
+
+from roverlay.depres.depenv import DepEnv
+
+class DependencyResolverListener:
+
+	def __init__ ( self ):
+		self.ident = id ( self )
+
+	def notify ( event_type, pkg_env=None, **extra ):
+		"""Notify this listener about an event."""
+		pass
+
+
+class DependencyResolverChannel ( DependencyResolverListener ):
+
+	def __init__ ( self, main_resolver, *args ):
+		super ( DependencyResolverChannel, self ) . __init__ ()
+		self._depres_master = main_resolver
+
+	def close ( self ):
+		"""Closes this channel."""
+		pass
+
+	def enabled ( self ):
+		return True
+
+
+class EbuildJobChannel ( DependencyResolverChannel ):
+	# this channel has a strict control flow:
+	#  add deps -> while not done(): "wait" -> if satisfy_request(): collect/lookup
+
+	def __init__ ( self, main_resolver=None, name=None ):
+		super ( EbuildJobChannel, self ) . __init__ ( main_resolver )
+		self.dep_env_list    = list ()
+		self._done           = False
+		self._collected_deps = None
+
+		if not name is None:
+			self.name = name
+
+	def get_name ( self ):
+		return self.name if hasattr ( self, 'name' ) else None
+
+
+
+	def depcount ( self ):
+		if isinstance ( self.dep_env_list, list ):
+			return len ( self.dep_env_list )
+		else:
+			return -1
+
+
+	def done ( self ):
+		if not self._done:
+			self._done = self._depres_master.done (
+				self.ident, len ( self.dep_env_list )
+			)
+		return self._done
+
+	def add_dependency ( self, dep_str ):
+		if self._done:
+			raise Exception ( "This channel is 'done', it doesn't accept new dependencies." )
+		else:
+			dep_env = DepEnv ( dep_str )
+			self.dep_env_list.append ( dep_env )
+			self._depres_master.enqueue ( dep_env, self.ident )
+
+		return None
+
+	def add_dependencies ( self, dep_list ):
+		for dep_str in dep_list: self.add_dependency ( dep_str )
+		return None
+
+	def satisfy_request ( self, delete_list_if_unresolvable=True ):
+		if self._done:
+			if self.dep_env_list is None:
+				return False
+
+			dep_collected = list()
+
+			for dep_env in self.dep_env_list:
+				if dep_env.is_resolved ():
+					dep_collected.append ( dep_env.get_result() [1] )
+				else:
+					if delete_list_if_unresolvable:
+						del self.dep_env_list
+						self.dep_env_list = None
+					return False
+
+			self._collected_deps = dep_collected
+			return True
+
+		return False
+
+	def lookup ( self, dep_str ):
+		"""Looks up a specific dep str. Use collect_dependencies() for getting
+		all dependencies if order doesn't matter.
+		"""
+		raise Exception ( "TODO" )
+		return None
+
+	def collect_dependencies ( self ):
+		"""Returns a tuple ( dep str, resolved by )."""
+		if self._done:
+			logging.critical ( str ( self._collected_deps ) )
+			return self._collected_deps
+		raise Exception ( "cannot do that" )
+
+	def trigger_run ( self ):
+		self._depres_master.run()

diff --git a/roverlay/depres/depenv.py b/roverlay/depres/depenv.py
new file mode 100644
index 0000000..b6c945c
--- /dev/null
+++ b/roverlay/depres/depenv.py
@@ -0,0 +1,47 @@
+# R overlay --
+# Copyright 2006-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+
+class DepEnv:
+
+	STATUS_UNDONE       = 1
+	STATUS_RESOLVED     = 2
+	STATUS_UNRESOLVABLE = 4
+
+	def __init__ ( self, dep_str ):
+		self.ident       = id ( self )
+		self.dep_str     = dep_str
+		self.status      = DepEnv.STATUS_UNDONE
+		self.resolved_by = None
+
+		# TODO: analyze dep_str: extract dep name, dep version, useless comments,...
+
+
+	def set_resolved ( self, resolved_by, append=False ):
+		if self.resolved_by is None:
+			self.resolved_by = resolved_by
+		elif append:
+			raise Exception ( "appending is not supported..." ) #TODO
+			#self.resolved_by.append ( resolved_by )
+		else:
+			raise Exception ( "dependency is already resolved and append is disabled." )
+
+		self.status |= DepEnv.STATUS_RESOLVED
+
+	def set_unresolvable ( self, force=False ):
+		if force or not self.status & DepEnv.STATUS_RESOLVED:
+			self.resolved_by = None
+			self.status |= DepEnv.STATUS_UNRESOLVABLE
+		else:
+			raise Exception ("dependency is already marked as resolved." )
+
+	def zap ( self ):
+		self.status      = DepEnv.STATUS_UNDONE
+		self.resolved_by = None
+
+	def is_resolved ( self ):
+		return bool ( self.status & DepEnv.STATUS_RESOLVED )
+
+	def get_result ( self ):
+		return ( self.dep_str, self.resolved_by )

diff --git a/roverlay/depres/depresolver.py b/roverlay/depres/depresolver.py
index ebb88cd..c8b4729 100644
--- a/roverlay/depres/depresolver.py
+++ b/roverlay/depres/depresolver.py
@@ -2,14 +2,53 @@
 # Copyright 2006-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
+import logging
+
+from collections import deque
+
+#from roverlay.depres import deprule
+from roverlay.depres import simpledeprule, communication
+#from roverlay.depres.depenv import DepEnv
+
+
 
 class DependencyResolver:
 
-	def __init__ ( self ):
-		self.logger    = None
-		self.channels  = list ()
-		self.listeners = list ()
+	LOGGER = logging.getLogger ( "DependencyResolver" )
 
+	def __init__ ( self ):
+		# these loggers are temporary helpers
+		self.logger              = DependencyResolver.LOGGER
+		self.logger_unresolvable = self.logger.getChild ( "UNRESOLVABLE" )
+		self.logger_resolved     = self.logger.getChild ( "RESOLVED" )
+		self.channels            = dict ()
+		self.listeners           = dict ()
+
+		self._depqueue           = deque ()
+		self._depqueue_failed    = deque ()
+		self._depdone            = dict ()
+
+		self.static_rule_pools = list ()
+
+	def log_unresolvable ( self, dep_env ):
+		msg = "'" + dep_env.dep_str + "'"
+		if not dep_env.dep_str:
+			self.logger_unresolvable.warning ( msg + " empty? fix that!" )
+		else:
+			self.logger_unresolvable.info ( msg )
+
+	def log_resolved ( self, dep_env ):
+		msg = "'" + dep_env.dep_str + "' as '" + str ( dep_env.resolved_by ) + "'"
+		self.logger_resolved.info ( msg )
+
+	def sort ( self ):
+		for pool in self.static_rule_pools: pool.sort()
+		self.static_rule_pools.sort ( key = lambda pool : ( pool.priority, pool.rule_weight ) )
+
+	def add_rulepool ( self, rulepool, pool_type=None ):
+		self.static_rule_pools.append ( rulepool )
+		self.sort()
+		return None
 
 	def _report_event ( self, event, pkg_env=None, **extra ):
 		"""Reports an event to the log, channels and listeners."""
@@ -26,7 +65,7 @@ class DependencyResolver:
 		"""
 		pass
 
-
+	# def add_listener ( self, listener ): FIXME
 	def add_listener ( self ):
 		"""Adds a listener, which listens to events such as
 		"dependency is unresolvable". Possible use cases include redirecting
@@ -35,11 +74,13 @@ class DependencyResolver:
 		arguments:
 		* listener_type
 		"""
+		# broken due to module "outsourcing"
 		new_listener = DependencyResolverListener()
 		# register the new listener
 		self.listeners [new_listener.ident] = new_listener
 		return new_listener
 
+	# FIXME get_channel is not useful when using various channel types
 	def get_channel ( self, readonly=False ):
 		"""Returns a communication channel to the DependencyResolver.
 		This channel can be used to _talk_, e.g. queue dependencies for resolution
@@ -48,50 +89,108 @@ class DependencyResolver:
 		arguments:
 		* readonly -- whether this channel has write access or not
 		"""
-		new channel = DependencyResolverChannel ( self )
+		# broken due to module "outsourcing"
+		new_channel = DependencyResolverChannel ( self )
 		self.channels [new_channel.ident] = new_channel
 		return new_channel
 
+	def register_channel ( self, channel ):
+		if channel in self.channels:
+			raise Exception ( "channel is already registered." )
 
+		if channel._depres_master is None:
+			channel._depres_master = self
 
-class DependencyResolverListener:
+		self.channels [channel.ident] = channel
 
-	def __init__ ( self ):
-		self.ident = id ( self )
+		return channel
 
-	def notify ( event_type, pkg_env=None, **extra ):
-		"""Notify this listener about an event."""
-		pass
 
+	def get_worker ( self, max_dep_resolve=0 ):
+		"""Returns a dep resolver worker (thread).
+		-- Threading is not implemented, this method is just a reminder.
 
-class DependencyResolverChannel ( DependencyResolverListener ):
+		arguments:
+		* max_dep_resolve -- if > 0 : worker stops after resolving max_dep_resolve deps
+		                     if   0 : worker stops when queue is empty
+		                     else   : worker does not stop unless told to do so
+		"""
+		raise Exception ( "DependencyResolver.get_worker(...) is TODO!" )
 
-	def __init__ ( self, main_resolver, *args ):
-		super ( DependencyResolverChannel, self ) . __init__ ()
-		self._depres_master = main_resolver
+	def _queue_previously_failed( self ):
+		queue_again = self._depqueue_failed
+		self._depqueue_failed = deque()
+		self._depqueue.extend ( queue_again )
 
-	def close ( self ):
-		"""Closes this channel."""
-		pass
 
+	def run ( self ):
+		"""Resolves dependencies."""
+		# TODO: this method has to be replaced when using threads
 
-class EbuildJobChannel ( DependencyResolverChannel ):
-	def __init__ ( self, main_resolver, *args ):
-		super ( EbuildJobChannel, self ) . __init__ ( main_resolver )
 
+		while len ( self._depqueue ):
 
-	def done ( self ):
-		pass
+			to_resolve = self._depqueue.popleft()
+			channel_id, dep_env = to_resolve
 
-	def add_dependency ( self, dep_str ):
-		pass
+			self.logger.debug ( "Trying to resolve '" + dep_env.dep_str + "'." )
 
-	def add_dependencies ( self, dep_list ):
-		pass
+			if not channel_id in self.channels:
+				# channel has been closed but did not request a cleanup
+				raise Exception ( "dirty queue!" )
 
-	def satisfy_request ( self ):
-		pass
+			#have_new_rule = False
+			resolved      = None
+
+			for rulepool in self.static_rule_pools:
+				result = rulepool.matches ( dep_env )
+				if not result is None and result [0] > 0:
+					resolved = result [1]
+					break
+
+
+
+			if resolved:
+				dep_env.set_resolved ( resolved, append=False )
+				self.log_resolved ( dep_env )
+				self._depdone [channel_id] +=1
+			else:
+				self._depqueue_failed.append ( to_resolve )
+
+			"""
+			## only useful if new rules can be created
+			# new rule found, queue all previously failed dependency searches again
+			if have_new_rule:
+				self._queue_previously_failed
+			"""
+		# --- end while
+
+		# iterate over _depqueue_failed and report unresolved
+
+		while len ( self._depqueue_failed ):
+
+			channel_id, dep_env = self._depqueue_failed.popleft()
+			dep_env.set_unresolvable()
+			self._depdone [channel_id] += 1
+
+			# TODO: temporary log
+			self.log_unresolvable ( dep_env )
 
-	def lookup ( self, dep_str ):
 		return None
 
+
+	def enqueue ( self, dep_env, channel_id ):
+		self._depqueue.append ( ( channel_id, dep_env ) )
+		if not channel_id in self._depdone:
+			# allocate a result counter in depdone
+			self._depdone [channel_id] = 0
+
+
+	def done ( self, channel_id, numdeps ):
+
+		if channel_id in self._depdone:
+			return bool ( self._depdone [channel_id] >= numdeps )
+		else:
+			return False
+
+

diff --git a/roverlay/depres/deprule.py b/roverlay/depres/deprule.py
index b5d1116..83cff66 100644
--- a/roverlay/depres/deprule.py
+++ b/roverlay/depres/deprule.py
@@ -6,60 +6,26 @@ class DependencyRule:
 	def __init__ ( self ):
 		self.max_score = 1000
 
-	def matches ( dep_str ):
+	def matches ( self, dep_env ):
 		return 0
 
-class SimpleDependencyRule ( DependencyRule ):
-
-	def __init__ ( self, resolving_package, dep_str=None, priority=100 ):
-		super ( SimpleDependencyRule, self ) . __init__ ( )
-		self.dep_alias = set ()
-		if dep_str:
-			self.dep_alias.add ( dep_str )
-
-		self.resolving_package = resolving_package
-
-		self.priority = priority
-	# --- end of __init__ (...) ---
-
-	def add_resolved ( self, dep_str ):
-		self.dep_alias.add ( dep_str )
-	# --- end of add_resolved (...) ---
-
-	def matches ( self, dep_str, lowercase=True ):
-		if lowercase:
-			lower_dep_str = dep_str
-			for alias in self.dep_alias:
-				if alias.lower() == lower_dep_str:
-					return self.max_score
-		elif dep_str in self.dep_alias:
-			return self.max_score
-
-		return 0
-	# --- end of matches (...) ---
-
-	def get_dep ( self ):
-		return self.resolving_package
-
-	def export_rule ( self ):
-		pass
-
 class DependencyRulePool:
 
-	def __init__ ( self, name ):
-		self.rules    = list ()
-		self.name     = name
-		self.priority = 0
+	def __init__ ( self, name, priority ):
+		self.rules       = list ()
+		self.name        = name
+		self.priority    = priority
+		# the "rule weight" is the sum of the rules' priorities - it's used to
+		#  compare/sort dependency pools with the same priority (lesser weight is better)
+		self.rule_weight = 0
 	# --- end of __init__ (...) ---
 
 	def sort ( self ):
 		self.rules.sort ( key=lambda rule : rule.priority )
 
-		priority_sum = 0
-		for r in self.rules:
-			priority_sum += r.priority
-
-		self.priority = int ( priority_sum / len ( self.rules ) ) if len ( self.rules ) else 0
+		rule_priority_sum = 0
+		for r in self.rules: rule_priority_sum += r.priority
+		self.rule_weight = rule_priority_sum
 
 		return None
 	# --- end of _sort_rules (...) ---
@@ -73,13 +39,15 @@ class DependencyRulePool:
 		return None
 	# --- end of add (...) ---
 
-	def matches ( self, dep_str, skip_matches=0 ):
+	def matches ( self, dep_env, skip_matches=0 ):
 		"""Tries to find a match in this dependency rule pool.
 		The first match is immediatly returned unless skip_matches is != 0, in
 		which case the first (>0) / last (<0) skip_matches matches are skipped.
+		Returns a tuple ( score, portage dependency ),
+		e.g. ( 1000, 'sys-apps/which' ), if match found, else None.
 
 		arguments:
-		* dep_str -- dependency to look up
+		* dep_env -- dependency to look up
 		* skip_matches --
 		"""
 
@@ -89,41 +57,23 @@ class DependencyRulePool:
 
 		else:
 			skipped = 0
-			order = range ( len ( self.rules ) )
+			# python3 requires list ( range ... )
+			order = list ( range ( len ( self.rules ) ) )
 
 			if skip_matches < 1:
 				skip_matches *= -1
 				order.reverse()
 
 			for index in order:
-				score = self.rules [index].matches ( dep_str )
+				score = self.rules [index].matches ( dep_env )
 				if score:
 					if skipped < skip_matches:
 						skipped += 1
 					else:
-						return score, self.rules [index].get_dep ()
-
+						return ( score, self.rules [index].get_dep () )
 
-		return 0, None
 
+		return None
 
-class SimpleDependencyRulePool ( DependencyRulePool )
 
-	def __init__ ( self, name ):
-		super ( SimpleDependencyRulePool, self ) . __init__ ( name )
-	# --- end of __init__ (...) ---
-
-	def add ( self, rile ):
-		if isinstance ( rule, SimpleDependencyRule ):
-			self.rules.append ( rule )
-		else:
-			raise Exception ( "bad usage (simple dependency rule expected)." )
-	# --- end of add (...) ---
 
-	def export_rules ( self, fh ):
-		for rule in self.rules:
-			to_write = fh.export_rule()
-			if isinstance ( to_write, str ):
-				fh.write ( to_write )
-			else:
-				fh.writelines ( to_write )

diff --git a/roverlay/depres/rulereader.py b/roverlay/depres/rulereader.py
deleted file mode 100644
index 6998cb2..0000000
--- a/roverlay/depres/rulereader.py
+++ /dev/null
@@ -1,88 +0,0 @@
-
-import re
-import logging
-
-from roverlay.depres.deprule import SimpleDependencyRule
-
-class SimpleDependencyRuleReader:
-
-	one_line_separator = re.compile ( '\s+::\s+' )
-	multiline_start    = '{'
-	multiline_stop     = '}'
-	comment_chars      = list ( '#;' )
-
-
-	def __init__ ( self ):
-		pass
-	# --- end of __init__  (...) ---
-
-	def read_file ( self, filepath ):
-		"""Reads a file that contains SimpleDescriptionRules.
-
-		arguments:
-		* filepath -- file to read
-		"""
-
-		lineno = 0
-
-		try:
-			logging.debug ( "Reading simple dependency rule file " + filepath + "." )
-			fh = open ( filepath, 'r' )
-
-			next_rule = None
-			rules = list ()f
-
-			for line in fh.readlines():
-				lineno += 1
-				line = line.strip()
-
-				if not line:
-					pass
-
-				elif not next_rule is None:
-					# in a multiline rule
-					if line [0] == SimpleDependencyRuleReader.multiline_stop:
-						# end of a multiline rule
-						rules.append ( next_rule )
-						next_rule = None
-					else:
-						# new resolved str
-						next_rule.add_resolved ( line )
-
-				elif line [0] in SimpleDependencyRuleReader.comment_chars:
-					# comment
-					pass
-
-				elif line [-1] == SimpleDependencyRuleReader.multiline_start:
-					# start of multiline rule
-					next_rule = SimpleDependencyRule ( line [:-1].rstrip(), None, 100 )
-
-				else:
-					# one line rule?
-					rule_str = SimpleDependencyRuleReader.one_line_separator.split ( line, 1 )
-
-					if len ( rule_str ) == 2:
-						rules.append (
-							SimpleDependencyRule ( rule_str [0], rule_str [1], 90 )
-						)
-					else:
-						logging.error (
-							"In " + filepath + ", line " + str ( lineno ) + ": cannot use this line."
-						)
-				# ---
-
-			if fh: fh.close ()
-
-			logging.info ( filepath + ": read " + str ( len ( rules ) ) + " dependency rules." )
-
-			return rules
-
-		except IOError as ioerr:
-			if lineno:
-				logging.error ( "Failed to read file " + filepath + " after " + str ( lineno ) " lines."
-			else:
-				logging.error ( "Could not read file " + filepath + "." )
-			raise
-
-		# --- end of read_file (...) ---
-

diff --git a/roverlay/depres/simpledeprule.py b/roverlay/depres/simpledeprule.py
new file mode 100644
index 0000000..0f916ec
--- /dev/null
+++ b/roverlay/depres/simpledeprule.py
@@ -0,0 +1,170 @@
+
+import re
+import logging
+
+
+
+from roverlay.depres import deprule
+
+class SimpleDependencyRule ( deprule.DependencyRule ):
+
+	TMP_LOGGER = logging.getLogger ( 'SimpleDependencyRule' )
+
+	def __init__ ( self, resolving_package, dep_str=None, priority=100 ):
+		super ( SimpleDependencyRule, self ) . __init__ ( )
+		self.dep_alias = set ()
+
+		self.logger = SimpleDependencyRule.TMP_LOGGER.getChild ( resolving_package )
+		self.logger.debug ( "new rule" )
+
+		if dep_str:
+			self.logger.debug ( "resolves '" + dep_str + "' now." )
+			self.dep_alias.add ( dep_str )
+
+		self.resolving_package = resolving_package
+
+		self.priority = priority
+
+
+	# --- end of __init__ (...) ---
+
+	def add_resolved ( self, dep_str ):
+		self.dep_alias.add ( dep_str )
+	# --- end of add_resolved (...) ---
+
+	def matches ( self, dep_env, lowercase=True ):
+
+		if lowercase:
+			lower_dep_str = dep_env.dep_str.lower()
+			for alias in self.dep_alias:
+				if alias.lower() == lower_dep_str:
+					self.logger.debug ( "matches '" + lower_dep_str + "'" )
+					return self.max_score
+		elif dep_env.dep_str in self.dep_alias:
+			self.logger.debug ( "matches '" + dep_env.dep_str + "'" )
+			return self.max_score
+
+		return 0
+	# --- end of matches (...) ---
+
+	def get_dep ( self ):
+		return self.resolving_package
+
+	def export_rule ( self ):
+		pass
+
+class SimpleDependencyRulePool ( deprule.DependencyRulePool ):
+
+	def __init__ ( self, name, priority=70, filepath=None ):
+		super ( SimpleDependencyRulePool, self ) . __init__ ( name, priority )
+
+		if not filepath is None:
+			self.load_rule_file ( filepath )
+	# --- end of __init__ (...) ---
+
+	def add ( self, rule ):
+		if isinstance ( rule, SimpleDependencyRule ):
+			self.rules.append ( rule )
+		else:
+			raise Exception ( "bad usage (simple dependency rule expected)." )
+	# --- end of add (...) ---
+
+	def load_rule_file ( self, filepath ):
+		reader = SimpleDependencyRuleReader()
+
+		new_rules = reader.read_file ( filepath )
+		for rule in new_rules:
+			self.add ( rule )
+
+	def export_rules ( self, fh ):
+		for rule in self.rules:
+			to_write = fh.export_rule()
+			if isinstance ( to_write, str ):
+				fh.write ( to_write )
+			else:
+				fh.writelines ( to_write )
+
+
+
+class SimpleDependencyRuleReader:
+
+	one_line_separator = re.compile ( '\s+::\s+' )
+	multiline_start    = '{'
+	multiline_stop     = '}'
+	comment_chars      = list ( '#;' )
+
+
+	def __init__ ( self ):
+		pass
+	# --- end of __init__  (...) ---
+
+	def read_file ( self, filepath ):
+		"""Reads a file that contains SimpleDescriptionRules.
+
+		arguments:
+		* filepath -- file to read
+		"""
+
+		lineno = 0
+
+		try:
+			logging.debug ( "Reading simple dependency rule file " + filepath + "." )
+			fh = open ( filepath, 'r' )
+
+			next_rule = None
+			rules = list ()
+
+			for line in fh.readlines():
+				lineno += 1
+				line = line.strip()
+
+				if not line:
+					pass
+
+				elif not next_rule is None:
+					# in a multiline rule
+					if line [0] == SimpleDependencyRuleReader.multiline_stop:
+						# end of a multiline rule
+						rules.append ( next_rule )
+						next_rule = None
+					else:
+						# new resolved str
+						next_rule.add_resolved ( line )
+
+				elif line [0] in SimpleDependencyRuleReader.comment_chars:
+					# comment
+					pass
+
+				elif line [-1] == SimpleDependencyRuleReader.multiline_start:
+					# start of multiline rule
+					next_rule = SimpleDependencyRule ( line [:-1].rstrip(), None, 100 )
+
+				else:
+					# one line rule?
+					rule_str = SimpleDependencyRuleReader.one_line_separator.split ( line, 1 )
+
+					if len ( rule_str ) == 2:
+						rules.append (
+							SimpleDependencyRule ( rule_str [0], rule_str [1], 90 )
+						)
+					else:
+						logging.error (
+							"In " + filepath + ", line " + str ( lineno ) + ": cannot use this line."
+						)
+				# ---
+
+			if fh: fh.close ()
+
+			logging.info ( filepath + ": read " + str ( len ( rules ) ) + " dependency rules." )
+
+			return rules
+
+		except IOError as ioerr:
+			if lineno:
+				logging.error ( "Failed to read file " + filepath + " after " + str ( lineno ) + " lines." )
+			else:
+				logging.error ( "Could not read file " + filepath + "." )
+			raise
+
+		# --- end of read_file (...) ---
+



             reply	other threads:[~2012-06-06 19:53 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-06 19:52 André Erdmann [this message]
  -- strict thread matches above, loose matches on Subject: below --
2014-08-23 19:03 [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/ André Erdmann
2014-06-05 22:09 André Erdmann
2013-09-03  8:35 André Erdmann
2013-09-02 13:20 André Erdmann
2013-08-28  9:38 André Erdmann
2013-08-27 15:39 André Erdmann
2013-08-27 15:39 André Erdmann
2013-08-27 15:39 André Erdmann
2013-08-23 13:52 André Erdmann
2013-08-20 21:46 André Erdmann
2013-08-20 21:46 André Erdmann
2013-07-18 19:25 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
2013-07-23  7:51 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
2013-07-17 18:10 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
2013-07-17 18:10 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
2013-07-16 16:36 André Erdmann
2013-07-15 22:31 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
2013-07-16 16:36 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
2013-07-11 16:44 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
2013-07-11 16:44 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
2013-07-11  8:49 André Erdmann
2013-06-13 16:34 André Erdmann
2012-08-02 15:14 André Erdmann
2012-07-30 15:53 André Erdmann
2012-07-30  8:52 [gentoo-commits] proj/R_overlay:overlay_wip " André Erdmann
2012-07-30  8:52 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
2012-07-19 16:53 [gentoo-commits] proj/R_overlay:overlay_wip " André Erdmann
2012-07-30  8:52 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
2012-07-16 16:15 André Erdmann
2012-07-13 10:44 [gentoo-commits] proj/R_overlay:depres_wip " André Erdmann
2012-07-16 16:15 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
2012-07-13 10:44 [gentoo-commits] proj/R_overlay:depres_wip " André Erdmann
2012-07-16 16:15 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
2012-07-02 16:52 André Erdmann
2012-07-02 16:52 André Erdmann
2012-06-29 22:48 André Erdmann
2012-06-29 22:48 André Erdmann
2012-06-28 13:29 André Erdmann
2012-06-28 13:29 André Erdmann
2012-06-27 14:46 André Erdmann
2012-06-20 19:03 André Erdmann
2012-06-13 16:34 André Erdmann
2012-06-13  7:45 André Erdmann
2012-06-13  7:45 André Erdmann
2012-06-12 17:17 André Erdmann
2012-06-05 17:30 André Erdmann
2012-06-04 19:07 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=1339011890.1202ca5c63080cf066a6997709a23088996322ef.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