| 
									
										
										
										
											2017-06-05 16:02:39 +03:00
										 |  |  | # Copyright (c) 2014-present PlatformIO <contact@platformio.org> | 
					
						
							| 
									
										
										
										
											2016-08-31 16:07:35 +03:00
										 |  |  | # | 
					
						
							|  |  |  | # Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  | # you may not use this file except in compliance with the License. | 
					
						
							|  |  |  | # You may obtain a copy of the License at | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #    http://www.apache.org/licenses/LICENSE-2.0 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  | # distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  | # See the License for the specific language governing permissions and | 
					
						
							|  |  |  | # limitations under the License. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import subprocess | 
					
						
							| 
									
										
										
										
											2016-11-24 00:01:15 +02:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2017-12-19 15:38:32 +02:00
										 |  |  | from os.path import dirname, join | 
					
						
							| 
									
										
										
										
											2018-10-25 13:48:47 +03:00
										 |  |  | from time import sleep | 
					
						
							| 
									
										
										
										
											2016-08-31 16:07:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-25 13:44:41 +03:00
										 |  |  | import requests | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-24 02:13:03 +03:00
										 |  |  | from platformio import __version__, exception, util | 
					
						
							| 
									
										
										
										
											2016-08-31 16:07:35 +03:00
										 |  |  | from platformio.managers.package import PackageManager | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 23:28:55 +02:00
										 |  |  | CORE_PACKAGES = { | 
					
						
							| 
									
										
										
										
											2018-11-28 17:23:33 +02:00
										 |  |  |     "contrib-piohome": "^2.0.0", | 
					
						
							| 
									
										
										
										
											2018-11-28 21:32:37 +02:00
										 |  |  |     "contrib-pysite": "~2.%d%d.0" % (sys.version_info[0], sys.version_info[1]), | 
					
						
							| 
									
										
										
										
											2018-12-26 20:54:29 +02:00
										 |  |  |     "tool-pioplus": "^2.0.2", | 
					
						
							| 
									
										
										
										
											2018-03-22 18:18:03 +02:00
										 |  |  |     "tool-unity": "~1.20403.0", | 
					
						
							| 
									
										
										
										
											2019-01-10 23:47:43 +02:00
										 |  |  |     "tool-scons": "~2.20501.7" if util.PY2 else "~3.30003.0" | 
					
						
							| 
									
										
										
										
											2016-10-31 20:05:34 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-08-31 16:07:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 23:28:55 +02:00
										 |  |  | PIOPLUS_AUTO_UPDATES_MAX = 100 | 
					
						
							| 
									
										
										
										
											2016-11-12 00:28:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-30 01:23:52 +03:00
										 |  |  | # pylint: disable=arguments-differ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 16:07:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 23:28:55 +02:00
										 |  |  | class CorePackageManager(PackageManager): | 
					
						
							| 
									
										
										
										
											2016-08-31 16:07:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							| 
									
										
										
										
											2018-10-27 15:24:10 +03:00
										 |  |  |         super(CorePackageManager, self).__init__( | 
					
						
							|  |  |  |             join(util.get_home_dir(), "packages"), [ | 
					
						
							|  |  |  |                 "https://dl.bintray.com/platformio/dl-packages/manifest.json", | 
					
						
							|  |  |  |                 "http%s://dl.platformio.org/packages/manifest.json" % | 
					
						
							|  |  |  |                 ("" if sys.version_info < (2, 7, 9) else "s") | 
					
						
							|  |  |  |             ]) | 
					
						
							| 
									
										
										
										
											2016-08-31 16:07:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:37 +02:00
										 |  |  |     def install(  # pylint: disable=keyword-arg-before-vararg | 
					
						
							|  |  |  |             self, | 
					
						
							|  |  |  |             name, | 
					
						
							|  |  |  |             requirements=None, | 
					
						
							|  |  |  |             *args, | 
					
						
							|  |  |  |             **kwargs): | 
					
						
							| 
									
										
										
										
											2017-06-26 19:16:44 +03:00
										 |  |  |         PackageManager.install(self, name, requirements, *args, **kwargs) | 
					
						
							|  |  |  |         self.cleanup_packages() | 
					
						
							|  |  |  |         return self.get_package_dir(name, requirements) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-30 01:23:52 +03:00
										 |  |  |     def update(self, *args, **kwargs): | 
					
						
							| 
									
										
										
										
											2017-06-26 19:16:44 +03:00
										 |  |  |         result = PackageManager.update(self, *args, **kwargs) | 
					
						
							|  |  |  |         self.cleanup_packages() | 
					
						
							|  |  |  |         return result | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def cleanup_packages(self): | 
					
						
							|  |  |  |         self.cache_reset() | 
					
						
							|  |  |  |         best_pkg_versions = {} | 
					
						
							|  |  |  |         for name, requirements in CORE_PACKAGES.items(): | 
					
						
							|  |  |  |             pkg_dir = self.get_package_dir(name, requirements) | 
					
						
							|  |  |  |             if not pkg_dir: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             best_pkg_versions[name] = self.load_manifest(pkg_dir)['version'] | 
					
						
							|  |  |  |         for manifest in self.get_installed(): | 
					
						
							|  |  |  |             if manifest['name'] not in best_pkg_versions: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if manifest['version'] != best_pkg_versions[manifest['name']]: | 
					
						
							| 
									
										
										
										
											2018-03-16 13:33:59 +02:00
										 |  |  |                 self.uninstall(manifest['__pkg_dir'], after_update=True) | 
					
						
							| 
									
										
										
										
											2017-06-26 19:16:44 +03:00
										 |  |  |         self.cache_reset() | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 16:07:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 23:28:55 +02:00
										 |  |  | def get_core_package_dir(name): | 
					
						
							| 
									
										
										
										
											2017-12-27 22:05:56 +02:00
										 |  |  |     if name not in CORE_PACKAGES: | 
					
						
							|  |  |  |         raise exception.PlatformioException("Please upgrade PIO Core") | 
					
						
							| 
									
										
										
										
											2017-03-11 23:28:55 +02:00
										 |  |  |     requirements = CORE_PACKAGES[name] | 
					
						
							|  |  |  |     pm = CorePackageManager() | 
					
						
							|  |  |  |     pkg_dir = pm.get_package_dir(name, requirements) | 
					
						
							|  |  |  |     if pkg_dir: | 
					
						
							|  |  |  |         return pkg_dir | 
					
						
							|  |  |  |     return pm.install(name, requirements) | 
					
						
							| 
									
										
										
										
											2016-08-31 16:07:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 14:14:29 +03:00
										 |  |  | def update_core_packages(only_check=False, silent=False): | 
					
						
							| 
									
										
										
										
											2017-03-11 23:28:55 +02:00
										 |  |  |     pm = CorePackageManager() | 
					
						
							|  |  |  |     for name, requirements in CORE_PACKAGES.items(): | 
					
						
							|  |  |  |         pkg_dir = pm.get_package_dir(name) | 
					
						
							| 
									
										
										
										
											2017-03-27 14:14:29 +03:00
										 |  |  |         if not pkg_dir: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if not silent or pm.outdated(pkg_dir, requirements): | 
					
						
							| 
									
										
										
										
											2018-10-25 13:44:41 +03:00
										 |  |  |             if name == "tool-pioplus" and not only_check: | 
					
						
							|  |  |  |                 shutdown_piohome_servers() | 
					
						
							| 
									
										
										
										
											2018-10-25 13:48:47 +03:00
										 |  |  |                 if "windows" in util.get_systype(): | 
					
						
							|  |  |  |                     sleep(1) | 
					
						
							| 
									
										
										
										
											2017-03-11 23:28:55 +02:00
										 |  |  |             pm.update(name, requirements, only_check=only_check) | 
					
						
							| 
									
										
										
										
											2017-12-19 15:24:23 +02:00
										 |  |  |     return True | 
					
						
							| 
									
										
										
										
											2016-08-31 16:07:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-25 13:44:41 +03:00
										 |  |  | def shutdown_piohome_servers(): | 
					
						
							|  |  |  |     port = 8010 | 
					
						
							| 
									
										
										
										
											2019-02-19 20:12:07 +02:00
										 |  |  |     while port < 8050: | 
					
						
							| 
									
										
										
										
											2018-10-25 13:44:41 +03:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2019-02-19 20:12:07 +02:00
										 |  |  |             requests.get( | 
					
						
							|  |  |  |                 "http://127.0.0.1:%d?__shutdown__=1" % port, timeout=0.01) | 
					
						
							| 
									
										
										
										
											2018-10-25 13:44:41 +03:00
										 |  |  |         except:  # pylint: disable=bare-except | 
					
						
							| 
									
										
										
										
											2018-11-18 23:53:47 +02:00
										 |  |  |             pass | 
					
						
							|  |  |  |         port += 1 | 
					
						
							| 
									
										
										
										
											2018-10-25 13:44:41 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 16:07:35 +03:00
										 |  |  | def pioplus_call(args, **kwargs): | 
					
						
							| 
									
										
										
										
											2017-06-24 02:13:03 +03:00
										 |  |  |     if "windows" in util.get_systype() and sys.version_info < (2, 7, 6): | 
					
						
							|  |  |  |         raise exception.PlatformioException( | 
					
						
							|  |  |  |             "PlatformIO Core Plus v%s does not run under Python version %s.\n" | 
					
						
							|  |  |  |             "Minimum supported version is 2.7.6, please upgrade Python.\n" | 
					
						
							| 
									
										
										
										
											2018-01-12 02:23:55 +02:00
										 |  |  |             "Python 3 is not yet supported.\n" % (__version__, sys.version)) | 
					
						
							| 
									
										
										
										
											2017-06-24 02:13:03 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 23:28:55 +02:00
										 |  |  |     pioplus_path = join(get_core_package_dir("tool-pioplus"), "pioplus") | 
					
						
							| 
									
										
										
										
											2017-09-05 14:13:00 +03:00
										 |  |  |     pythonexe_path = util.get_pythonexe_path() | 
					
						
							|  |  |  |     os.environ['PYTHONEXEPATH'] = pythonexe_path | 
					
						
							| 
									
										
										
										
											2017-12-23 13:06:38 +02:00
										 |  |  |     os.environ['PYTHONPYSITEDIR'] = get_core_package_dir("contrib-pysite") | 
					
						
							| 
									
										
										
										
											2018-06-26 01:34:26 +03:00
										 |  |  |     os.environ['PIOCOREPYSITEDIR'] = dirname(util.get_source_dir() or "") | 
					
						
							| 
									
										
										
										
											2017-12-13 20:05:39 +02:00
										 |  |  |     os.environ['PATH'] = (os.pathsep).join( | 
					
						
							|  |  |  |         [dirname(pythonexe_path), os.environ['PATH']]) | 
					
						
							| 
									
										
										
										
											2016-08-31 16:07:35 +03:00
										 |  |  |     util.copy_pythonpath_to_osenv() | 
					
						
							| 
									
										
										
										
											2016-11-12 00:28:49 +02:00
										 |  |  |     code = subprocess.call([pioplus_path] + args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # handle remote update request | 
					
						
							|  |  |  |     if code == 13: | 
					
						
							|  |  |  |         count_attr = "_update_count" | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             count_value = getattr(pioplus_call, count_attr) | 
					
						
							|  |  |  |         except AttributeError: | 
					
						
							|  |  |  |             count_value = 0 | 
					
						
							|  |  |  |             setattr(pioplus_call, count_attr, 1) | 
					
						
							|  |  |  |         count_value += 1 | 
					
						
							|  |  |  |         setattr(pioplus_call, count_attr, count_value) | 
					
						
							| 
									
										
										
										
											2017-03-11 23:28:55 +02:00
										 |  |  |         if count_value < PIOPLUS_AUTO_UPDATES_MAX: | 
					
						
							|  |  |  |             update_core_packages() | 
					
						
							| 
									
										
										
										
											2016-11-12 00:28:49 +02:00
										 |  |  |             return pioplus_call(args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # handle reload request | 
					
						
							|  |  |  |     elif code == 14: | 
					
						
							|  |  |  |         return pioplus_call(args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if code != 0: | 
					
						
							|  |  |  |         raise exception.ReturnErrorCode(1) | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return True |