Mercurial > hg > PaInt
annotate paint/package.py @ 20:11bc01a089e7
return only the dictionary
| author | Jeff Hammel <jhammel@mozilla.com> |
|---|---|
| date | Mon, 27 Feb 2012 13:10:18 -0800 |
| parents | c54db80d6e7f |
| children | 4df3e715817d |
| rev | line source |
|---|---|
| 4 | 1 """ |
| 2 package model for python PAckage INTrospection | |
| 3 """ | |
| 4 | |
| 7 | 5 import os |
|
9
562230cc2e86
now the package class should at least extracts things. it doesnt actually do anything useful
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
6 import shutil |
| 19 | 7 import subprocess |
| 8 import sys | |
| 7 | 9 import tarfile |
| 5 | 10 import tempfile |
| 7 | 11 import urllib2 |
| 12 import utils | |
| 5 | 13 |
| 19 | 14 try: |
| 15 from subprocess import check_call as call | |
| 16 except ImportError: | |
| 17 from subporcess import call | |
| 18 | |
| 10 | 19 __all__ = ['Package'] |
| 20 | |
| 4 | 21 class Package(object): |
| 7 | 22 # XXX much of this is generic resource stuff and should be split off |
| 4 | 23 |
| 24 def __init__(self, src): | |
| 25 self.src = src | |
|
13
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
26 |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
27 # ephemeral data |
| 5 | 28 self._tmppath = None |
|
13
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
29 self._egg_info = None |
| 5 | 30 |
| 31 def path(self): | |
| 32 """filesystem path to package""" | |
| 7 | 33 |
| 34 # return cached copy if it exists | |
| 35 if self._tmppath: | |
| 36 return self._tmppath | |
| 37 | |
| 38 # fetch from the web if a URL | |
| 39 tmpfile = None | |
| 40 src = self.src | |
| 5 | 41 if utils.isURL(self.src): |
| 8 | 42 tmpfile = src = self.fetch() |
| 7 | 43 |
| 44 # unpack if an archive | |
| 45 if self.is_archive(src): | |
| 8 | 46 try: |
| 47 self.unpack(src) | |
| 48 finally: | |
| 49 if tmpfile: | |
| 50 os.remove(tmpfile) | |
| 7 | 51 return self._tmppath |
| 52 | |
| 5 | 53 return self.src |
| 54 | |
| 55 def fetch(self): | |
| 8 | 56 """fetch from remote source to a temporary file""" |
|
15
8c8b7482772f
fix a few failures but still failing
Jeff Hammel <jhammel@mozilla.com>
parents:
14
diff
changeset
|
57 resource = urllib2.urlopen(self.src) |
| 11 | 58 fd, filename = tempfile.mkstemp() |
| 7 | 59 os.write(fd, resource.read()) |
| 60 os.close(fd) | |
| 61 return filename | |
| 62 | |
| 63 def unpack(self, archive): | |
| 64 """unpack the archive to a temporary destination""" | |
| 65 # TODO: should handle zipfile additionally at least | |
| 66 # Ideally, this would be pluggable, etc | |
| 8 | 67 assert tarfile.is_tarfile(archive), "%s is not an archive" % self.src |
|
9
562230cc2e86
now the package class should at least extracts things. it doesnt actually do anything useful
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
68 tf = tarfile.TarFile.open(archive) |
|
562230cc2e86
now the package class should at least extracts things. it doesnt actually do anything useful
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
69 self._tmppath = tempfile.mkdtemp() |
| 19 | 70 members = tf.getmembers() |
| 71 | |
| 72 # cut off the top level directory | |
| 73 assert not [i for i in members if not os.path.sep in i.name] | |
| 74 tld = set() | |
| 75 for member in members: | |
| 76 directory, member.name = member.name.split(os.path.sep, 1) | |
| 77 tld.add(directory) | |
| 78 assert len(tld) == 1 | |
| 79 | |
| 80 # extract | |
| 81 for member in members: | |
| 82 tf.extract(member, path=self._tmppath) | |
| 83 tf.close() | |
| 7 | 84 |
| 85 def is_archive(self, path): | |
| 86 """returns if the filesystem path is an archive""" | |
| 87 # TODO: should handle zipfile additionally at least | |
| 88 # Ideally, this would be pluggable, etc | |
| 89 return tarfile.is_tarfile(path) | |
|
9
562230cc2e86
now the package class should at least extracts things. it doesnt actually do anything useful
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
90 |
|
562230cc2e86
now the package class should at least extracts things. it doesnt actually do anything useful
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
91 def cleanup(self): |
|
562230cc2e86
now the package class should at least extracts things. it doesnt actually do anything useful
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
92 if self._tmppath: |
|
562230cc2e86
now the package class should at least extracts things. it doesnt actually do anything useful
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
93 shutil.rmtree(self._tmppath) |
|
562230cc2e86
now the package class should at least extracts things. it doesnt actually do anything useful
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
94 self._tmppath = None |
|
562230cc2e86
now the package class should at least extracts things. it doesnt actually do anything useful
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
95 |
|
18
4c4d1e194bf7
leave in debugging code for now
Jeff Hammel <jhammel@mozilla.com>
parents:
17
diff
changeset
|
96 # __del__ = cleanup |
| 11 | 97 |
|
13
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
98 ### python-package-specific functionality |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
99 |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
100 def egg_info(self): |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
101 """build the egg_info directory""" |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
102 |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
103 if self._egg_info: |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
104 # return cached copy |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
105 return self._egg_info |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
106 |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
107 directory = self.path() |
| 16 | 108 setup_py = os.path.join(directory, 'setup.py') |
| 109 if not os.path.exists(setup_py): | |
| 17 | 110 raise AssertionError("%s does not exist" % setup_py) |
| 11 | 111 |
|
13
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
112 # setup the egg info |
| 19 | 113 call([sys.executable, 'setup.py', 'egg_info'], cwd=directory, stdout=subprocess.PIPE) |
|
13
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
114 |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
115 # get the .egg-info directory |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
116 egg_info = [i for i in os.listdir(directory) |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
117 if i.endswith('.egg-info')] |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
118 assert len(egg_info) == 1, 'Expected one .egg-info directory in %s, got: %s' % (directory, egg_info) |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
119 egg_info = os.path.join(directory, egg_info[0]) |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
120 assert os.path.isdir(egg_info), "%s is not a directory" % egg_info |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
121 |
|
14
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
122 # cache it |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
123 self._egg_info = egg_info |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
124 return self._egg_info |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
125 |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
126 def info(self): |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
127 """return info dictionary for package""" |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
128 # could use pkginfo |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
129 |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
130 egg_info = self.egg_info() |
|
13
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
131 |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
132 # read the package information |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
133 pkg_info = os.path.join(egg_info, 'PKG-INFO') |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
134 info_dict = {} |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
135 for line in file(pkg_info).readlines(): |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
136 if not line or line[0].isspace(): |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
137 continue # XXX neglects description |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
138 assert ':' in line |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
139 key, value = [i.strip() for i in line.split(':', 1)] |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
140 info_dict[key] = value |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
141 |
|
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
142 # return the information |
|
20
11bc01a089e7
return only the dictionary
Jeff Hammel <jhammel@mozilla.com>
parents:
19
diff
changeset
|
143 return info_dict |
|
13
0dd1f8f83be2
moving towards some sort of organization
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
144 |
| 11 | 145 def dependencies(self): |
|
14
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
146 """return the dependencies""" |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
147 |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
148 egg_info = self.egg_info() |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
149 |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
150 # read the dependencies |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
151 requires = os.path.join(egg_info, 'requires.txt') |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
152 if os.path.exists(requires): |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
153 dependencies = [i.strip() for i in file(requires).readlines() if i.strip()] |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
154 else: |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
155 dependencies = [] |
|
6d27c2136163
a decent structure; need to reuse more
Jeff Hammel <jhammel@mozilla.com>
parents:
13
diff
changeset
|
156 |
