comparison paint/package.py @ 28:c44fb4b6918b

CLI sorta works
author Jeff Hammel <jhammel@mozilla.com>
date Fri, 30 Mar 2012 11:07:15 -0700
parents c54411c721cb
children 59524b6d25c0
comparison
equal deleted inserted replaced
27:7e9eb858d086 28:c44fb4b6918b
1 """ 1 """
2 package model for python PAckage INTrospection 2 package model for python PAckage INTrospection
3 """ 3 """
4 4
5 import os 5 import os
6 import pip
6 import shutil 7 import shutil
7 import subprocess 8 import subprocess
8 import sys 9 import sys
9 import tarfile 10 import tarfile
10 import tempfile 11 import tempfile
18 from subporcess import call 19 from subporcess import call
19 20
20 __all__ = ['Package'] 21 __all__ = ['Package']
21 22
22 class Package(object): 23 class Package(object):
23 # XXX much of this is generic resource stuff and should be split off
24 24
25 def __init__(self, src): 25 def __init__(self, src):
26 self.src = src 26 self.src = src
27 27
28 # ephemeral data 28 # ephemeral data
29 self._tmppath = None 29 self._tmppath = None
30 self._egg_info = None 30 self._egg_info_path = None
31 31
32 def path(self): 32 def path(self):
33 """filesystem path to package""" 33 """filesystem path to package"""
34 34
35 # return cached copy if it exists 35 # return cached copy if it exists
41 src = self.src 41 src = self.src
42 if utils.isURL(self.src): 42 if utils.isURL(self.src):
43 tmpfile = src = self.fetch() 43 tmpfile = src = self.fetch()
44 44
45 # unpack if an archive 45 # unpack if an archive
46 if self.is_archive(src): 46 if self._is_archive(src):
47 try: 47 try:
48 self.unpack(src) 48 self.unpack(src)
49 finally: 49 finally:
50 if tmpfile: 50 if tmpfile:
51 os.remove(tmpfile) 51 os.remove(tmpfile)
81 # extract 81 # extract
82 for member in members: 82 for member in members:
83 tf.extract(member, path=self._tmppath) 83 tf.extract(member, path=self._tmppath)
84 tf.close() 84 tf.close()
85 85
86 def is_archive(self, path): 86 def _is_archive(self, path):
87 """returns if the filesystem path is an archive""" 87 """returns if the filesystem path is an archive"""
88 # TODO: should handle zipfile additionally at least 88 # TODO: should handle zipfile additionally at least
89 # Ideally, this would be pluggable, etc 89 # Ideally, this would be pluggable, etc
90 return tarfile.is_tarfile(path) 90 return tarfile.is_tarfile(path)
91 91
92 def cleanup(self): 92 def _cleanup(self):
93 if self._tmppath: 93 if self._tmppath:
94 shutil.rmtree(self._tmppath) 94 shutil.rmtree(self._tmppath)
95 self._tmppath = None 95 self._tmppath = None
96 96
97 # __del__ = cleanup 97 # __del__ = cleanup
98 98
99 ### python-package-specific functionality 99 ### python-package-specific functionality
100 100
101 def egg_info(self): 101 def _egg_info(self):
102 """build the egg_info directory""" 102 """build the egg_info directory"""
103 103
104 if self._egg_info: 104 if self._egg_info_path:
105 # return cached copy 105 # return cached copy
106 return self._egg_info 106 return self._egg_info_path
107 107
108 directory = self.path() 108 directory = self.path()
109 setup_py = os.path.join(directory, 'setup.py') 109 setup_py = os.path.join(directory, 'setup.py')
110 if not os.path.exists(setup_py): 110 if not os.path.exists(setup_py):
111 raise AssertionError("%s does not exist" % setup_py) 111 raise AssertionError("%s does not exist" % setup_py)
119 assert len(egg_info) == 1, 'Expected one .egg-info directory in %s, got: %s' % (directory, egg_info) 119 assert len(egg_info) == 1, 'Expected one .egg-info directory in %s, got: %s' % (directory, egg_info)
120 egg_info = os.path.join(directory, egg_info[0]) 120 egg_info = os.path.join(directory, egg_info[0])
121 assert os.path.isdir(egg_info), "%s is not a directory" % egg_info 121 assert os.path.isdir(egg_info), "%s is not a directory" % egg_info
122 122
123 # cache it 123 # cache it
124 self._egg_info = egg_info 124 self._egg_info_path = egg_info
125 return self._egg_info 125 return self._egg_info_path
126 126
127 def info(self): 127 def info(self):
128 """return info dictionary for package""" 128 """return info dictionary for package"""
129 # could use pkginfo 129 # could use pkginfo
130 130
131 egg_info = self.egg_info() 131 egg_info = self._egg_info()
132 132
133 # read the package information 133 # read the package information
134 pkg_info = os.path.join(egg_info, 'PKG-INFO') 134 pkg_info = os.path.join(egg_info, 'PKG-INFO')
135 info_dict = {} 135 info_dict = {}
136 for line in file(pkg_info).readlines(): 136 for line in file(pkg_info).readlines():
145 145
146 def dependencies(self): 146 def dependencies(self):
147 """return the dependencies""" 147 """return the dependencies"""
148 148
149 # get the egg_info directory 149 # get the egg_info directory
150 egg_info = self.egg_info() 150 egg_info = self._egg_info()
151 151
152 # read the dependencies 152 # read the dependencies
153 requires = os.path.join(egg_info, 'requires.txt') 153 requires = os.path.join(egg_info, 'requires.txt')
154 if os.path.exists(requires): 154 if os.path.exists(requires):
155 dependencies = [i.strip() for i in file(requires).readlines() if i.strip()] 155 dependencies = [i.strip() for i in file(requires).readlines() if i.strip()]
170 170
171 return dependencies 171 return dependencies
172 172
173 def download(self, directory): 173 def download(self, directory):
174 """download a package and all its dependencies using pip""" 174 """download a package and all its dependencies using pip"""
175 import pip 175 if not os.path.exists(directory):
176 176 os.makedirs(directory)
177 assert os.path.isdir(directory)
178 pip.main(['install', '--download', directory, self.src])
179
180 def pypi(self, directory):
181 """
182 download packages for a pypi directory structure
183 http://k0s.org/portfolio/pypi.html
184 """
185 tempdir = tempfile.mkdtemp()
186 try:
187 pass
188 finally:
189 shutil.rmtree(tempdir)