| 1 | """ | 
|---|
| 2 | Dependency management for tools. | 
|---|
| 3 | """ | 
|---|
| 4 |  | 
|---|
| 5 | import os.path | 
|---|
| 6 |  | 
|---|
| 7 | import logging | 
|---|
| 8 | log = logging.getLogger( __name__ ) | 
|---|
| 9 |  | 
|---|
| 10 | class DependencyManager( object ): | 
|---|
| 11 |     """ | 
|---|
| 12 |     A DependencyManager attempts to resolve named and versioned dependencies | 
|---|
| 13 |     by searching for them under a list of directories. Directories should be | 
|---|
| 14 |     of the form: | 
|---|
| 15 |  | 
|---|
| 16 |         $BASE/name/version/... | 
|---|
| 17 |  | 
|---|
| 18 |     and should each contain a file 'env.sh' which can be sourced to make the | 
|---|
| 19 |     dependency available in the current shell environment. | 
|---|
| 20 |     """ | 
|---|
| 21 |  | 
|---|
| 22 |     def __init__( self, base_paths=[] ): | 
|---|
| 23 |         """ | 
|---|
| 24 |         Create a new dependency manager looking for packages under the  | 
|---|
| 25 |         paths listed in `base_paths`. | 
|---|
| 26 |         """ | 
|---|
| 27 |         self.base_paths = [] | 
|---|
| 28 |         for base_path in base_paths: | 
|---|
| 29 |             if not os.path.exists( base_path ): | 
|---|
| 30 |                 log.warn( "Path '%s' does not exist, ignoring", base_path ) | 
|---|
| 31 |             if not os.path.isdir( base_path ): | 
|---|
| 32 |                 log.warn( "Path '%s' is not directory, ignoring", base_path ) | 
|---|
| 33 |             self.base_paths.append( os.path.abspath( base_path ) ) | 
|---|
| 34 |  | 
|---|
| 35 |     def find_dep( self, name, version=None ): | 
|---|
| 36 |         """ | 
|---|
| 37 |         Attempt to find a dependency named `name` at version `version`. If | 
|---|
| 38 |         version is None, return the "default" version as determined using a  | 
|---|
| 39 |         symbolic link (if found). Returns a triple of: | 
|---|
| 40 |             env_script, base_path, real_version | 
|---|
| 41 |         """ | 
|---|
| 42 |         if version is None: | 
|---|
| 43 |             return self._find_dep_default( name ) | 
|---|
| 44 |         else: | 
|---|
| 45 |             return self._find_dep_versioned( name, version ) | 
|---|
| 46 |  | 
|---|
| 47 |     def _find_dep_versioned( self, name, version ): | 
|---|
| 48 |         for base_path in self.base_paths: | 
|---|
| 49 |             path = os.path.join( base_path, name, version ) | 
|---|
| 50 |             script = os.path.join( path, 'env.sh' ) | 
|---|
| 51 |             if os.path.exists( script ): | 
|---|
| 52 |                 return script, path, version | 
|---|
| 53 |         else: | 
|---|
| 54 |             return None, None | 
|---|
| 55 |  | 
|---|
| 56 |     def _find_dep_default( self, name ): | 
|---|
| 57 |         version = None | 
|---|
| 58 |         for base_path in self.base_paths: | 
|---|
| 59 |             path = os.path.join( base_path, name, 'default' ) | 
|---|
| 60 |             if os.path.islink( path ): | 
|---|
| 61 |                 real_path = os.path.realpath( path ) | 
|---|
| 62 |                 real_version = os.path.basename( real_path ) | 
|---|
| 63 |                 script = os.path.join( real_path, 'env.sh' ) | 
|---|
| 64 |                 if os.path.exists( script ): | 
|---|
| 65 |                     return script, real_path, real_version | 
|---|
| 66 |         else: | 
|---|
| 67 |             return None, None | 
|---|
| 68 |  | 
|---|
| 69 |  | 
|---|