|
14 | 14 | import json
|
15 | 15 | from pathlib import Path
|
16 | 16 | from argparse import ArgumentParser, RawTextHelpFormatter
|
17 |
| -from winpython import utils, piptree |
| 17 | +from winpython import utils, piptree, associate |
18 | 18 |
|
19 | 19 | # Workaround for installing PyVISA on Windows from source:
|
20 | 20 | os.environ["HOME"] = os.environ["USERPROFILE"]
|
@@ -234,182 +234,167 @@ def install_bdist_direct(self, package, install_options=None):
|
234 | 234 | self._print_done()
|
235 | 235 |
|
236 | 236 | def main(test=False):
|
237 |
| - if test: |
238 |
| - sbdir = Path(__file__).parents[3] / "sandbox" |
239 |
| - tmpdir = sbdir / "tobedeleted" |
240 |
| - fname = sbdir / "VTK-5.10.0-Qt-4.7.4.win32-py2.7.exe" |
241 |
| - print(Package(str(fname))) |
| 237 | + |
| 238 | + registerWinPythonHelp = f"Register distribution: associate file extensions, icons and context menu with this WinPython" |
| 239 | + unregisterWinPythonHelp = f"Unregister distribution: de-associate file extensions, icons and context menu from this WinPython" |
| 240 | + parser = ArgumentParser( |
| 241 | + description="WinPython Package Manager: handle a WinPython Distribution and its packages", |
| 242 | + formatter_class=RawTextHelpFormatter, |
| 243 | + ) |
| 244 | + parser.add_argument( |
| 245 | + "fname", |
| 246 | + metavar="package", |
| 247 | + nargs="?", |
| 248 | + default="", |
| 249 | + type=str, |
| 250 | + help="optional package name or package wheel", |
| 251 | + ) |
| 252 | + parser.add_argument( |
| 253 | + "--register", |
| 254 | + dest="registerWinPython", |
| 255 | + action="store_true", # Store True when flag is present |
| 256 | + help=registerWinPythonHelp, |
| 257 | + ) |
| 258 | + parser.add_argument( |
| 259 | + "--unregister", |
| 260 | + dest="unregisterWinPython", |
| 261 | + action="store_true", |
| 262 | + help=unregisterWinPythonHelp, |
| 263 | + ) |
| 264 | + parser.add_argument( |
| 265 | + "-v", "--verbose", |
| 266 | + action="store_true", |
| 267 | + help="show more details on packages and actions", |
| 268 | + ) |
| 269 | + parser.add_argument( |
| 270 | + "-ls", "--list", |
| 271 | + action="store_true", |
| 272 | + help="list installed packages matching the given [optional] package expression: wppm -ls, wppm -ls pand", |
| 273 | + ) |
| 274 | + parser.add_argument( |
| 275 | + "-p", |
| 276 | + dest="pipdown", |
| 277 | + action="store_true", |
| 278 | + help="show Package dependencies of the given package[option]: wppm -p pandas[test]", |
| 279 | + ) |
| 280 | + parser.add_argument( |
| 281 | + "-r", |
| 282 | + dest="pipup", |
| 283 | + action="store_true", |
| 284 | + help=f"show Reverse dependancies of the given package[option]: wppm -r pytest[test]", |
| 285 | + ) |
| 286 | + parser.add_argument( |
| 287 | + "-l", "--levels", |
| 288 | + type=int, |
| 289 | + default=2, |
| 290 | + help="show 'LEVELS' levels of dependencies (with -p, -r), default is 2: wppm -p pandas -l1", |
| 291 | + ) |
| 292 | + parser.add_argument( |
| 293 | + "-lsa", |
| 294 | + dest="all", |
| 295 | + action="store_true", |
| 296 | + help=f"list details of package names matching given regular expression: wppm -lsa pandas -l1", |
| 297 | + ) |
| 298 | + parser.add_argument( |
| 299 | + "-t", "--target", |
| 300 | + default=sys.prefix, |
| 301 | + help=f'path to target Python distribution (default: "{sys.prefix}")', |
| 302 | + ) |
| 303 | + parser.add_argument( |
| 304 | + "-i", "--install", |
| 305 | + action="store_true", |
| 306 | + help="install a given package wheel (use pip for more features)", |
| 307 | + ) |
| 308 | + parser.add_argument( |
| 309 | + "-u", "--uninstall", |
| 310 | + action="store_true", # Store True when flag is present |
| 311 | + help="uninstall package (use pip for more features)", |
| 312 | + ) |
| 313 | + args = parser.parse_args() |
| 314 | + targetpython = None |
| 315 | + if args.target and args.target != sys.prefix: |
| 316 | + targetpython = args.target if args.target.lower().endswith('.exe') else str(Path(args.target) / 'python.exe') |
| 317 | + if args.install and args.uninstall: |
| 318 | + raise RuntimeError("Incompatible arguments: --install and --uninstall") |
| 319 | + if args.registerWinPython and args.unregisterWinPython: |
| 320 | + raise RuntimeError("Incompatible arguments: --install and --uninstall") |
| 321 | + if args.pipdown: |
| 322 | + pip = piptree.PipData(targetpython) |
| 323 | + pack, extra, *other = (args.fname + "[").replace("]", "[").split("[") |
| 324 | + print(pip.down(pack, extra, args.levels, verbose=args.verbose)) |
242 | 325 | sys.exit()
|
243 |
| - target = Path(utils.BASE_DIR) / "build" / "winpython-2.7.3" / "python-2.7.3" |
244 |
| - fname = Path(utils.BASE_DIR) / "packages.src" / "docutils-0.9.1.tar.gz" |
245 |
| - dist = Distribution(str(target), verbose=True) |
246 |
| - pack = Package(str(fname)) |
247 |
| - print(pack.description) |
248 |
| - # dist.install(pack) |
249 |
| - # dist.uninstall(pack) |
250 |
| - else: |
251 |
| - registerWinPythonHelp = f"Register distribution: associate file extensions, icons and context menu with this WinPython" |
252 |
| - unregisterWinPythonHelp = f"Unregister distribution: de-associate file extensions, icons and context menu from this WinPython" |
253 |
| - parser = ArgumentParser( |
254 |
| - description="WinPython Package Manager: handle a WinPython Distribution and its packages", |
255 |
| - formatter_class=RawTextHelpFormatter, |
256 |
| - ) |
257 |
| - parser.add_argument( |
258 |
| - "fname", |
259 |
| - metavar="package", |
260 |
| - nargs="?", |
261 |
| - default="", |
262 |
| - type=str, |
263 |
| - help="optional package name or package wheel", |
264 |
| - ) |
265 |
| - parser.add_argument( |
266 |
| - "--register", |
267 |
| - dest="registerWinPython", |
268 |
| - action="store_true", # Store True when flag is present |
269 |
| - help=registerWinPythonHelp, |
270 |
| - ) |
271 |
| - parser.add_argument( |
272 |
| - "--unregister", |
273 |
| - dest="unregisterWinPython", |
274 |
| - action="store_true", |
275 |
| - help=unregisterWinPythonHelp, |
276 |
| - ) |
277 |
| - parser.add_argument( |
278 |
| - "-v", "--verbose", |
279 |
| - action="store_true", |
280 |
| - help="show more details on packages and actions", |
281 |
| - ) |
282 |
| - parser.add_argument( |
283 |
| - "-ls", "--list", |
284 |
| - action="store_true", |
285 |
| - help="list installed packages matching the given [optional] package expression: wppm -ls, wppm -ls pand", |
286 |
| - ) |
287 |
| - parser.add_argument( |
288 |
| - "-p", |
289 |
| - dest="pipdown", |
290 |
| - action="store_true", |
291 |
| - help="show Package dependencies of the given package[option]: wppm -p pandas[test]", |
292 |
| - ) |
293 |
| - parser.add_argument( |
294 |
| - "-r", |
295 |
| - dest="pipup", |
296 |
| - action="store_true", |
297 |
| - help=f"show Reverse dependancies of the given package[option]: wppm -r pytest[test]", |
298 |
| - ) |
299 |
| - parser.add_argument( |
300 |
| - "-l", "--levels", |
301 |
| - type=int, |
302 |
| - default=2, |
303 |
| - help="show 'LEVELS' levels of dependencies (with -p, -r), default is 2: wppm -p pandas -l1", |
304 |
| - ) |
305 |
| - parser.add_argument( |
306 |
| - "-lsa", |
307 |
| - dest="all", |
308 |
| - action="store_true", |
309 |
| - help=f"list details of package names matching given regular expression: wppm -lsa pandas -l1", |
310 |
| - ) |
311 |
| - parser.add_argument( |
312 |
| - "-t", "--target", |
313 |
| - default=sys.prefix, |
314 |
| - help=f'path to target Python distribution (default: "{sys.prefix}")', |
315 |
| - ) |
316 |
| - parser.add_argument( |
317 |
| - "-i", "--install", |
318 |
| - action="store_true", |
319 |
| - help="install a given package wheel (use pip for more features)", |
320 |
| - ) |
321 |
| - parser.add_argument( |
322 |
| - "-u", "--uninstall", |
323 |
| - action="store_true", # Store True when flag is present |
324 |
| - help="uninstall package (use pip for more features)", |
325 |
| - ) |
326 |
| - args = parser.parse_args() |
327 |
| - targetpython = None |
328 |
| - if args.target and args.target != sys.prefix: |
329 |
| - targetpython = args.target if args.target.lower().endswith('.exe') else str(Path(args.target) / 'python.exe') |
330 |
| - if args.install and args.uninstall: |
331 |
| - raise RuntimeError("Incompatible arguments: --install and --uninstall") |
332 |
| - if args.registerWinPython and args.unregisterWinPython: |
333 |
| - raise RuntimeError("Incompatible arguments: --install and --uninstall") |
334 |
| - if args.pipdown: |
335 |
| - pip = piptree.PipData(targetpython) |
336 |
| - pack, extra, *other = (args.fname + "[").replace("]", "[").split("[") |
337 |
| - print(pip.down(pack, extra, args.levels, verbose=args.verbose)) |
338 |
| - sys.exit() |
339 |
| - elif args.pipup: |
340 |
| - pip = piptree.PipData(targetpython) |
341 |
| - pack, extra, *other = (args.fname + "[").replace("]", "[").split("[") |
342 |
| - print(pip.up(pack, extra, args.levels, verbose=args.verbose)) |
343 |
| - sys.exit() |
344 |
| - elif args.list: |
345 |
| - pip = piptree.PipData(targetpython) |
346 |
| - todo = [l for l in pip.pip_list(full=True) if bool(re.search(args.fname, l[0]))] |
347 |
| - titles = [['Package', 'Version', 'Summary'], ['_' * max(x, 6) for x in utils.columns_width(todo)]] |
348 |
| - listed = utils.formatted_list(titles + todo, max_width=70) |
349 |
| - for p in listed: |
350 |
| - print(*p) |
351 |
| - sys.exit() |
352 |
| - elif args.all: |
353 |
| - pip = piptree.PipData(targetpython) |
354 |
| - todo = [l for l in pip.pip_list(full=True) if bool(re.search(args.fname, l[0]))] |
355 |
| - for l in todo: |
356 |
| - # print(pip.distro[l[0]]) |
357 |
| - title = f"** Package: {l[0]} **" |
358 |
| - print("\n" + "*" * len(title), f"\n{title}", "\n" + "*" * len(title)) |
359 |
| - for key, value in pip.raw[l[0]].items(): |
360 |
| - rawtext = json.dumps(value, indent=2, ensure_ascii=False) |
361 |
| - lines = [l for l in rawtext.split(r"\n") if len(l.strip()) > 2] |
362 |
| - if key.lower() != 'description' or args.verbose: |
363 |
| - print(f"{key}: ", "\n".join(lines).replace('"', "")) |
| 326 | + elif args.pipup: |
| 327 | + pip = piptree.PipData(targetpython) |
| 328 | + pack, extra, *other = (args.fname + "[").replace("]", "[").split("[") |
| 329 | + print(pip.up(pack, extra, args.levels, verbose=args.verbose)) |
| 330 | + sys.exit() |
| 331 | + elif args.list: |
| 332 | + pip = piptree.PipData(targetpython) |
| 333 | + todo = [l for l in pip.pip_list(full=True) if bool(re.search(args.fname, l[0]))] |
| 334 | + titles = [['Package', 'Version', 'Summary'], ['_' * max(x, 6) for x in utils.columns_width(todo)]] |
| 335 | + listed = utils.formatted_list(titles + todo, max_width=70) |
| 336 | + for p in listed: |
| 337 | + print(*p) |
| 338 | + sys.exit() |
| 339 | + elif args.all: |
| 340 | + pip = piptree.PipData(targetpython) |
| 341 | + todo = [l for l in pip.pip_list(full=True) if bool(re.search(args.fname, l[0]))] |
| 342 | + for l in todo: |
| 343 | + # print(pip.distro[l[0]]) |
| 344 | + title = f"** Package: {l[0]} **" |
| 345 | + print("\n" + "*" * len(title), f"\n{title}", "\n" + "*" * len(title)) |
| 346 | + for key, value in pip.raw[l[0]].items(): |
| 347 | + rawtext = json.dumps(value, indent=2, ensure_ascii=False) |
| 348 | + lines = [l for l in rawtext.split(r"\n") if len(l.strip()) > 2] |
| 349 | + if key.lower() != 'description' or args.verbose: |
| 350 | + print(f"{key}: ", "\n".join(lines).replace('"', "")) |
| 351 | + sys.exit() |
| 352 | + if args.registerWinPython: |
| 353 | + print(registerWinPythonHelp) |
| 354 | + if utils.is_python_distribution(args.target): |
| 355 | + dist = Distribution(args.target) |
| 356 | + else: |
| 357 | + raise OSError(f"Invalid Python distribution {args.target}") |
| 358 | + print(f"registering {args.target}") |
| 359 | + print("continue ? Y/N") |
| 360 | + theAnswer = input() |
| 361 | + if theAnswer == "Y": |
| 362 | + associate.register(dist.target, verbose=args.verbose) |
364 | 363 | sys.exit()
|
365 |
| - if args.registerWinPython: |
366 |
| - print(registerWinPythonHelp) |
367 |
| - if utils.is_python_distribution(args.target): |
368 |
| - dist = Distribution(args.target) |
369 |
| - else: |
370 |
| - raise OSError(f"Invalid Python distribution {args.target}") |
371 |
| - print(f"registering {args.target}") |
372 |
| - print("continue ? Y/N") |
373 |
| - theAnswer = input() |
374 |
| - if theAnswer == "Y": |
375 |
| - from winpython import associate |
376 |
| - associate.register(dist.target, verbose=args.verbose) |
377 |
| - sys.exit() |
378 |
| - if args.unregisterWinPython: |
379 |
| - print(unregisterWinPythonHelp) |
380 |
| - if utils.is_python_distribution(args.target): |
381 |
| - dist = Distribution(args.target) |
382 |
| - else: |
383 |
| - raise OSError(f"Invalid Python distribution {args.target}") |
384 |
| - print(f"unregistering {args.target}") |
385 |
| - print("continue ? Y/N") |
386 |
| - theAnswer = input() |
387 |
| - if theAnswer == "Y": |
388 |
| - from winpython import associate |
389 |
| - associate.unregister(dist.target, verbose=args.verbose) |
390 |
| - sys.exit() |
391 |
| - elif not args.install and not args.uninstall: |
392 |
| - args.install = True |
393 |
| - if not Path(args.fname).is_file() and args.install: |
394 |
| - if args.fname == "": |
395 |
| - parser.print_help() |
396 |
| - sys.exit() |
397 |
| - else: |
398 |
| - raise FileNotFoundError(f"File not found: {args.fname}") |
| 364 | + if args.unregisterWinPython: |
| 365 | + print(unregisterWinPythonHelp) |
399 | 366 | if utils.is_python_distribution(args.target):
|
400 |
| - dist = Distribution(args.target, verbose=True) |
401 |
| - try: |
402 |
| - if args.uninstall: |
403 |
| - package = dist.find_package(args.fname) |
404 |
| - dist.uninstall(package) |
405 |
| - else: |
406 |
| - package = Package(args.fname) |
407 |
| - if args.install: |
408 |
| - dist.install(package) |
409 |
| - except NotImplementedError: |
410 |
| - raise RuntimeError("Package is not (yet) supported by WPPM") |
| 367 | + dist = Distribution(args.target) |
411 | 368 | else:
|
412 | 369 | raise OSError(f"Invalid Python distribution {args.target}")
|
| 370 | + print(f"unregistering {args.target}") |
| 371 | + print("continue ? Y/N") |
| 372 | + theAnswer = input() |
| 373 | + if theAnswer == "Y": |
| 374 | + associate.unregister(dist.target, verbose=args.verbose) |
| 375 | + sys.exit() |
| 376 | + elif not args.install and not args.uninstall: |
| 377 | + args.install = True |
| 378 | + if not Path(args.fname).is_file() and args.install: |
| 379 | + if args.fname == "": |
| 380 | + parser.print_help() |
| 381 | + sys.exit() |
| 382 | + else: |
| 383 | + raise FileNotFoundError(f"File not found: {args.fname}") |
| 384 | + if utils.is_python_distribution(args.target): |
| 385 | + dist = Distribution(args.target, verbose=True) |
| 386 | + try: |
| 387 | + if args.uninstall: |
| 388 | + package = dist.find_package(args.fname) |
| 389 | + dist.uninstall(package) |
| 390 | + else: |
| 391 | + package = Package(args.fname) |
| 392 | + if args.install: |
| 393 | + dist.install(package) |
| 394 | + except NotImplementedError: |
| 395 | + raise RuntimeError("Package is not (yet) supported by WPPM") |
| 396 | + else: |
| 397 | + raise OSError(f"Invalid Python distribution {args.target}") |
413 | 398 |
|
414 | 399 |
|
415 | 400 | if __name__ == "__main__":
|
|
0 commit comments