| 
									
										
										
										
											2020-01-19 12:50:04 -08:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2020-01-18 15:45:52 +01:00
										 |  |  | import sys | 
					
						
							|  |  |  | import subprocess | 
					
						
							| 
									
										
										
										
											2021-06-06 15:11:17 +02:00
										 |  |  | import pkg_resources | 
					
						
							| 
									
										
										
										
											2023-02-18 12:50:42 +01:00
										 |  |  | import warnings | 
					
						
							| 
									
										
										
										
											2020-10-19 08:26:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  | local_dir = os.path.dirname(__file__) | 
					
						
							|  |  |  | requirements_files = {os.path.join(local_dir, 'requirements.txt')} | 
					
						
							| 
									
										
										
										
											2021-06-06 15:30:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-19 08:26:31 +02:00
										 |  |  | if sys.version_info < (3, 8, 6): | 
					
						
							|  |  |  |     raise RuntimeError("Incompatible Python Version. 3.8.7+ is supported.") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-06 15:11:17 +02:00
										 |  |  | update_ran = getattr(sys, "frozen", False)  # don't run update if environment is frozen/compiled | 
					
						
							| 
									
										
										
										
											2020-01-19 23:30:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-06 15:30:20 +02:00
										 |  |  | if not update_ran: | 
					
						
							| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  |     for entry in os.scandir(os.path.join(local_dir, "worlds")): | 
					
						
							| 
									
										
										
										
											2022-10-01 17:38:39 +02:00
										 |  |  |         # skip .* (hidden / disabled) folders | 
					
						
							|  |  |  |         if not entry.name.startswith("."): | 
					
						
							|  |  |  |             if entry.is_dir(): | 
					
						
							|  |  |  |                 req_file = os.path.join(entry.path, "requirements.txt") | 
					
						
							|  |  |  |                 if os.path.exists(req_file): | 
					
						
							|  |  |  |                     requirements_files.add(req_file) | 
					
						
							| 
									
										
										
										
											2021-06-06 15:30:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-18 15:45:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | def update_command(): | 
					
						
							| 
									
										
										
										
											2021-06-06 15:11:17 +02:00
										 |  |  |     for file in requirements_files: | 
					
						
							|  |  |  |         subprocess.call([sys.executable, '-m', 'pip', 'install', '-r', file, '--upgrade']) | 
					
						
							| 
									
										
										
										
											2020-01-19 23:30:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-22 20:35:30 +01:00
										 |  |  | def update(yes=False, force=False): | 
					
						
							| 
									
										
										
										
											2020-01-18 15:45:52 +01:00
										 |  |  |     global update_ran | 
					
						
							|  |  |  |     if not update_ran: | 
					
						
							|  |  |  |         update_ran = True | 
					
						
							| 
									
										
										
										
											2021-07-26 23:05:41 +02:00
										 |  |  |         if force: | 
					
						
							|  |  |  |             update_command() | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2021-06-06 15:11:17 +02:00
										 |  |  |         for req_file in requirements_files: | 
					
						
							|  |  |  |             path = os.path.join(os.path.dirname(sys.argv[0]), req_file) | 
					
						
							|  |  |  |             if not os.path.exists(path): | 
					
						
							|  |  |  |                 path = os.path.join(os.path.dirname(__file__), req_file) | 
					
						
							|  |  |  |             with open(path) as requirementsfile: | 
					
						
							| 
									
										
										
										
											2021-11-07 14:00:13 +01:00
										 |  |  |                 for line in requirementsfile: | 
					
						
							| 
									
										
										
										
											2023-02-18 12:50:42 +01:00
										 |  |  |                     if not line or line[0] == "#": | 
					
						
							|  |  |  |                         continue  # ignore comments | 
					
						
							| 
									
										
										
										
											2022-10-21 23:26:40 +02:00
										 |  |  |                     if line.startswith(("https://", "git+https://")): | 
					
						
							|  |  |  |                         # extract name and version for url | 
					
						
							|  |  |  |                         rest = line.split('/')[-1] | 
					
						
							|  |  |  |                         line = "" | 
					
						
							|  |  |  |                         if "#egg=" in rest: | 
					
						
							|  |  |  |                             # from egg info | 
					
						
							|  |  |  |                             rest, egg = rest.split("#egg=", 1) | 
					
						
							| 
									
										
										
										
											2023-02-18 12:50:42 +01:00
										 |  |  |                             egg = egg.split(";", 1)[0].rstrip() | 
					
						
							| 
									
										
										
										
											2022-10-21 23:26:40 +02:00
										 |  |  |                             if any(compare in egg for compare in ("==", ">=", ">", "<", "<=", "!=")): | 
					
						
							| 
									
										
										
										
											2023-02-18 12:50:42 +01:00
										 |  |  |                                 warnings.warn(f"Specifying version as #egg={egg} will become unavailable in pip 25.0. " | 
					
						
							|  |  |  |                                                "Use name @ url#version instead.", DeprecationWarning) | 
					
						
							| 
									
										
										
										
											2022-10-21 23:26:40 +02:00
										 |  |  |                                 line = egg | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             egg = "" | 
					
						
							|  |  |  |                         if "@" in rest and not line: | 
					
						
							|  |  |  |                             raise ValueError("Can't deduce version from requirement") | 
					
						
							|  |  |  |                         elif not line: | 
					
						
							|  |  |  |                             # from filename | 
					
						
							|  |  |  |                             rest = rest.replace(".zip", "-").replace(".tar.gz", "-") | 
					
						
							|  |  |  |                             name, version, _ = rest.split("-", 2) | 
					
						
							|  |  |  |                             line = f'{egg or name}=={version}' | 
					
						
							| 
									
										
										
										
											2023-02-18 12:50:42 +01:00
										 |  |  |                     elif "@" in line and "#" in line: | 
					
						
							|  |  |  |                         # PEP 508 does not allow us to specify a version, so we use custom syntax | 
					
						
							|  |  |  |                         # name @ url#version ; marker | 
					
						
							|  |  |  |                         name, rest = line.split("@", 1) | 
					
						
							|  |  |  |                         version = rest.split("#", 1)[1].split(";", 1)[0].rstrip() | 
					
						
							|  |  |  |                         line = f"{name.rstrip()}=={version}" | 
					
						
							|  |  |  |                         if ";" in rest:  # keep marker | 
					
						
							|  |  |  |                             line += rest[rest.find(";"):] | 
					
						
							| 
									
										
										
										
											2021-11-07 14:00:13 +01:00
										 |  |  |                     requirements = pkg_resources.parse_requirements(line) | 
					
						
							| 
									
										
										
										
											2023-02-18 12:50:42 +01:00
										 |  |  |                     for requirement in map(str, requirements): | 
					
						
							| 
									
										
										
										
											2021-11-07 14:00:13 +01:00
										 |  |  |                         try: | 
					
						
							|  |  |  |                             pkg_resources.require(requirement) | 
					
						
							|  |  |  |                         except pkg_resources.ResolutionError: | 
					
						
							|  |  |  |                             if not yes: | 
					
						
							|  |  |  |                                 import traceback | 
					
						
							|  |  |  |                                 traceback.print_exc() | 
					
						
							| 
									
										
										
										
											2023-02-18 12:50:42 +01:00
										 |  |  |                                 try: | 
					
						
							|  |  |  |                                     input(f"\nRequirement {requirement} is not satisfied, press enter to install it") | 
					
						
							|  |  |  |                                 except KeyboardInterrupt: | 
					
						
							|  |  |  |                                     print("\nAborting") | 
					
						
							|  |  |  |                                     sys.exit(1) | 
					
						
							| 
									
										
										
										
											2021-11-07 14:00:13 +01:00
										 |  |  |                             update_command() | 
					
						
							|  |  |  |                             return | 
					
						
							| 
									
										
										
										
											2020-01-18 15:45:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-06 23:37:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-18 15:45:52 +01:00
										 |  |  | if __name__ == "__main__": | 
					
						
							| 
									
										
										
										
											2021-07-26 23:05:41 +02:00
										 |  |  |     import argparse | 
					
						
							| 
									
										
										
										
											2022-01-22 20:35:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-26 23:05:41 +02:00
										 |  |  |     parser = argparse.ArgumentParser(description='Install archipelago requirements') | 
					
						
							|  |  |  |     parser.add_argument('-y', '--yes', dest='yes', action='store_true', help='answer "yes" to all questions') | 
					
						
							|  |  |  |     parser.add_argument('-f', '--force', dest='force', action='store_true', help='force update') | 
					
						
							| 
									
										
										
										
											2022-05-03 22:14:03 +02:00
										 |  |  |     parser.add_argument('-a', '--append', nargs="*", dest='additional_requirements', | 
					
						
							|  |  |  |                         help='List paths to additional requirement files.') | 
					
						
							| 
									
										
										
										
											2021-07-26 23:05:41 +02:00
										 |  |  |     args = parser.parse_args() | 
					
						
							| 
									
										
										
										
											2022-05-03 22:14:03 +02:00
										 |  |  |     if args.additional_requirements: | 
					
						
							|  |  |  |         requirements_files.update(args.additional_requirements) | 
					
						
							| 
									
										
										
										
											2021-07-26 23:05:41 +02:00
										 |  |  |     update(args.yes, args.force) |