1
1
import ast
2
- import collections
3
2
import fnmatch
4
3
import imp
5
4
import logging
6
- import optparse
7
5
import os
8
6
import re
9
- import sys
10
-
11
- from pip .commands .show import search_packages_info
12
- from pip .download import PipSession
13
- from pip .req import parse_requirements
14
- from pip .utils import get_installed_distributions , normalize_name
15
7
16
8
log = logging .getLogger (__name__ )
17
9
@@ -135,52 +127,6 @@ def is_package_file(path):
135
127
return ''
136
128
137
129
138
- def find_missing_reqs (options ):
139
- # 1. find files used by imports in the code (as best we can without
140
- # executing)
141
- used_modules = find_imported_modules (options )
142
-
143
- # 2. find which packages provide which files
144
- installed_files = {}
145
- all_pkgs = (pkg .project_name for pkg in get_installed_distributions ())
146
- for package in search_packages_info (all_pkgs ):
147
- log .debug ('installed package: %s (at %s)' , package ['name' ],
148
- package ['location' ])
149
- for file in package ['files' ] or []:
150
- path = os .path .realpath (os .path .join (package ['location' ], file ))
151
- installed_files [path ] = package ['name' ]
152
- package_path = is_package_file (path )
153
- if package_path :
154
- # we've seen a package file so add the bare package directory
155
- # to the installed list as well as we might want to look up
156
- # a package by its directory path later
157
- installed_files [package_path ] = package ['name' ]
158
-
159
- # 3. match imported modules against those packages
160
- used = collections .defaultdict (list )
161
- for modname , info in used_modules .items ():
162
- # probably standard library if it's not in the files list
163
- if info .filename in installed_files :
164
- used_name = normalize_name (installed_files [info .filename ])
165
- log .debug ('used module: %s (from package %s)' , modname ,
166
- installed_files [info .filename ])
167
- used [used_name ].append (info )
168
- else :
169
- log .debug (
170
- 'used module: %s (from file %s, assuming stdlib or local)' ,
171
- modname , info .filename )
172
-
173
- # 4. compare with requirements.txt
174
- explicit = set ()
175
- for requirement in parse_requirements ('requirements.txt' ,
176
- session = PipSession ()):
177
- log .debug ('found requirement: %s' , requirement .name )
178
- explicit .add (normalize_name (requirement .name ))
179
-
180
- return [(name , used [name ]) for name in used
181
- if name not in explicit ]
182
-
183
-
184
130
def ignorer (ignore_cfg ):
185
131
if not ignore_cfg :
186
132
return lambda candidate : False
@@ -193,63 +139,3 @@ def f(candidate, ignore_cfg=ignore_cfg):
193
139
return True
194
140
return False
195
141
return f
196
-
197
-
198
- def main ():
199
- from pip_missing_reqs import __version__
200
-
201
- usage = 'usage: %prog [options] files or directories'
202
- parser = optparse .OptionParser (usage )
203
- parser .add_option ("-f" , "--ignore-file" , dest = "ignore_files" ,
204
- action = "append" , default = [],
205
- help = "file paths globs to ignore" )
206
- parser .add_option ("-m" , "--ignore-module" , dest = "ignore_mods" ,
207
- action = "append" , default = [],
208
- help = "used module names (globs are ok) to ignore" )
209
- parser .add_option ("-v" , "--verbose" , dest = "verbose" ,
210
- action = "store_true" , default = False , help = "be more verbose" )
211
- parser .add_option ("-d" , "--debug" , dest = "debug" ,
212
- action = "store_true" , default = False , help = "be *really* verbose" )
213
- parser .add_option ("--version" , dest = "version" ,
214
- action = "store_true" , default = False , help = "display version information" )
215
-
216
- (options , args ) = parser .parse_args ()
217
-
218
- if options .version :
219
- sys .exit (__version__ )
220
-
221
- if not args :
222
- parser .error ("no source files or directories specified" )
223
- sys .exit (2 )
224
-
225
- options .ignore_files = ignorer (options .ignore_files )
226
- options .ignore_mods = ignorer (options .ignore_mods )
227
-
228
- options .paths = args
229
-
230
- logging .basicConfig (format = '%(message)s' )
231
- if options .debug :
232
- log .setLevel (logging .DEBUG )
233
- elif options .verbose :
234
- log .setLevel (logging .INFO )
235
- else :
236
- log .setLevel (logging .WARN )
237
-
238
- log .info ('using pip_missing_reqs-%s from %s' , __version__ , __file__ )
239
-
240
- missing = find_missing_reqs (options )
241
-
242
- if missing :
243
- log .warning ('Missing requirements:' )
244
- for name , uses in missing :
245
- for use in uses :
246
- for filename , lineno in use .locations :
247
- log .warning ('%s:%s dist=%s module=%s' ,
248
- os .path .relpath (filename ), lineno , name , use .modname )
249
-
250
- if missing :
251
- sys .exit (1 )
252
-
253
-
254
- if __name__ == '__main__' : # pragma: no cover
255
- main ()
0 commit comments