2017-06-05 16:02:39 +03:00
|
|
|
# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
|
2015-11-18 17:16:17 +02: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.
|
2014-05-18 23:38:59 +03:00
|
|
|
|
2017-04-28 01:38:25 +03:00
|
|
|
import os
|
|
|
|
import sys
|
2014-11-29 22:55:32 +02:00
|
|
|
from os.path import join
|
2015-09-10 20:31:26 +03:00
|
|
|
from platform import system
|
2014-06-07 13:34:31 +03:00
|
|
|
from traceback import format_exc
|
2014-05-18 23:38:59 +03:00
|
|
|
|
2014-11-29 22:55:32 +02:00
|
|
|
import click
|
2014-05-18 23:38:59 +03:00
|
|
|
|
2015-02-19 22:02:50 +02:00
|
|
|
from platformio import __version__, exception, maintenance
|
2014-11-29 22:55:32 +02:00
|
|
|
from platformio.util import get_source_dir
|
2014-05-18 23:38:59 +03:00
|
|
|
|
|
|
|
|
2014-11-29 22:55:32 +02:00
|
|
|
class PlatformioCLI(click.MultiCommand): # pylint: disable=R0904
|
2014-05-18 23:38:59 +03:00
|
|
|
|
2014-06-03 21:27:36 +03:00
|
|
|
def list_commands(self, ctx):
|
|
|
|
cmds = []
|
2017-04-28 01:38:25 +03:00
|
|
|
for filename in os.listdir(join(get_source_dir(), "commands")):
|
2014-06-03 21:27:36 +03:00
|
|
|
if filename.startswith("__init__"):
|
|
|
|
continue
|
|
|
|
if filename.endswith(".py"):
|
|
|
|
cmds.append(filename[:-3])
|
|
|
|
cmds.sort()
|
|
|
|
return cmds
|
2014-05-18 23:38:59 +03:00
|
|
|
|
2017-04-15 16:36:59 +03:00
|
|
|
def get_command(self, ctx, cmd_name):
|
2014-11-29 22:55:32 +02:00
|
|
|
mod = None
|
2014-06-07 13:34:31 +03:00
|
|
|
try:
|
2017-04-15 16:36:59 +03:00
|
|
|
mod = __import__("platformio.commands." + cmd_name, None, None,
|
2016-08-03 23:38:20 +03:00
|
|
|
["cli"])
|
2014-06-07 13:34:31 +03:00
|
|
|
except ImportError:
|
2015-04-24 15:48:32 +01:00
|
|
|
try:
|
2017-04-15 16:36:59 +03:00
|
|
|
return self._handle_obsolate_command(cmd_name)
|
2015-04-24 15:48:32 +01:00
|
|
|
except AttributeError:
|
2017-04-15 16:36:59 +03:00
|
|
|
raise click.UsageError('No such command "%s"' % cmd_name, ctx)
|
2014-06-03 21:27:36 +03:00
|
|
|
return mod.cli
|
2014-05-18 23:38:59 +03:00
|
|
|
|
2015-05-06 18:07:17 +01:00
|
|
|
@staticmethod
|
|
|
|
def _handle_obsolate_command(name):
|
2016-05-26 19:43:36 +03:00
|
|
|
if name == "platforms":
|
2016-08-26 14:44:45 +03:00
|
|
|
from platformio.commands import platform
|
|
|
|
return platform.cli
|
2018-12-26 20:54:29 +02:00
|
|
|
if name == "serialports":
|
2016-08-26 14:44:45 +03:00
|
|
|
from platformio.commands import device
|
|
|
|
return device.cli
|
2015-04-24 15:48:32 +01:00
|
|
|
raise AttributeError()
|
|
|
|
|
2014-05-18 23:38:59 +03:00
|
|
|
|
2016-08-03 23:38:20 +03:00
|
|
|
@click.command(
|
|
|
|
cls=PlatformioCLI,
|
|
|
|
context_settings=dict(help_option_names=["-h", "--help"]))
|
2014-11-29 22:55:32 +02:00
|
|
|
@click.version_option(__version__, prog_name="PlatformIO")
|
2016-08-03 23:38:20 +03:00
|
|
|
@click.option(
|
|
|
|
"--force",
|
|
|
|
"-f",
|
|
|
|
is_flag=True,
|
|
|
|
help="Force to accept any confirmation prompts.")
|
2015-09-03 19:04:09 +03:00
|
|
|
@click.option("--caller", "-c", help="Caller ID (service).")
|
2014-11-29 22:55:32 +02:00
|
|
|
@click.pass_context
|
2015-09-03 19:04:09 +03:00
|
|
|
def cli(ctx, force, caller):
|
|
|
|
maintenance.on_platformio_start(ctx, force, caller)
|
2014-05-18 23:38:59 +03:00
|
|
|
|
|
|
|
|
2014-11-29 22:55:32 +02:00
|
|
|
@cli.resultcallback()
|
|
|
|
@click.pass_context
|
2015-09-03 19:04:09 +03:00
|
|
|
def process_result(ctx, result, force, caller): # pylint: disable=W0613
|
2014-11-29 22:55:32 +02:00
|
|
|
maintenance.on_platformio_end(ctx, result)
|
2014-08-03 18:40:20 +03:00
|
|
|
|
|
|
|
|
2017-09-02 18:02:24 +03:00
|
|
|
def configure():
|
|
|
|
if "cygwin" in system().lower():
|
|
|
|
raise exception.CygwinEnvDetected()
|
|
|
|
|
|
|
|
# https://urllib3.readthedocs.org
|
|
|
|
# /en/latest/security.html#insecureplatformwarning
|
2014-06-07 13:34:31 +03:00
|
|
|
try:
|
2017-09-02 18:02:24 +03:00
|
|
|
import urllib3
|
|
|
|
urllib3.disable_warnings()
|
|
|
|
except (AttributeError, ImportError):
|
|
|
|
pass
|
2015-09-10 20:31:26 +03:00
|
|
|
|
2017-09-02 18:02:24 +03:00
|
|
|
# handle PLATFORMIO_FORCE_COLOR
|
|
|
|
if str(os.getenv("PLATFORMIO_FORCE_COLOR", "")).lower() == "true":
|
2015-08-21 23:09:56 +03:00
|
|
|
try:
|
2017-09-02 18:02:24 +03:00
|
|
|
# pylint: disable=protected-access
|
|
|
|
click._compat.isatty = lambda stream: True
|
|
|
|
except: # pylint: disable=bare-except
|
2017-05-27 12:55:46 +03:00
|
|
|
pass
|
2015-08-21 23:09:56 +03:00
|
|
|
|
2017-09-02 18:02:24 +03:00
|
|
|
# Handle IOError issue with VSCode's Terminal (Windows)
|
|
|
|
click_echo_origin = [click.echo, click.secho]
|
2016-01-19 21:03:49 +02:00
|
|
|
|
2017-09-02 18:02:24 +03:00
|
|
|
def _safe_echo(origin, *args, **kwargs):
|
|
|
|
try:
|
|
|
|
click_echo_origin[origin](*args, **kwargs)
|
|
|
|
except IOError:
|
2018-09-20 14:55:55 +03:00
|
|
|
(sys.stderr.write if kwargs.get("err") else sys.stdout.write)(
|
|
|
|
"%s\n" % (args[0] if args else ""))
|
2017-09-02 16:23:24 +03:00
|
|
|
|
2017-09-02 18:02:24 +03:00
|
|
|
click.echo = lambda *args, **kwargs: _safe_echo(0, *args, **kwargs)
|
|
|
|
click.secho = lambda *args, **kwargs: _safe_echo(1, *args, **kwargs)
|
2017-09-02 16:23:24 +03:00
|
|
|
|
|
|
|
|
2017-09-02 18:02:24 +03:00
|
|
|
def main():
|
|
|
|
try:
|
|
|
|
configure()
|
2015-09-03 19:04:09 +03:00
|
|
|
cli(None, None, None)
|
2017-09-24 01:28:41 +03:00
|
|
|
except Exception as e: # pylint: disable=broad-except
|
2015-02-19 22:02:50 +02:00
|
|
|
if not isinstance(e, exception.ReturnErrorCode):
|
|
|
|
maintenance.on_platformio_exception(e)
|
2015-02-20 22:02:38 +02:00
|
|
|
error_str = "Error: "
|
2015-02-19 22:02:50 +02:00
|
|
|
if isinstance(e, exception.PlatformioException):
|
2015-02-20 22:02:38 +02:00
|
|
|
error_str += str(e)
|
2015-02-19 22:02:50 +02:00
|
|
|
else:
|
2015-02-20 22:02:38 +02:00
|
|
|
error_str += format_exc()
|
2015-11-29 19:05:02 +02:00
|
|
|
error_str += """
|
2015-11-26 22:02:59 +02:00
|
|
|
============================================================
|
|
|
|
|
|
|
|
An unexpected error occurred. Further steps:
|
|
|
|
|
|
|
|
* Verify that you have the latest version of PlatformIO using
|
2015-12-18 19:58:09 +02:00
|
|
|
`pip install -U platformio` command
|
|
|
|
|
|
|
|
* Try to find answer in FAQ Troubleshooting section
|
2018-08-15 19:44:02 +03:00
|
|
|
https://docs.platformio.org/page/faq.html
|
2015-12-18 19:58:09 +02:00
|
|
|
|
2015-11-26 22:02:59 +02:00
|
|
|
* Report this problem to the developers
|
2016-12-04 18:59:07 +02:00
|
|
|
https://github.com/platformio/platformio-core/issues
|
2015-11-26 22:02:59 +02:00
|
|
|
|
|
|
|
============================================================
|
|
|
|
"""
|
2015-02-20 22:02:38 +02:00
|
|
|
click.secho(error_str, fg="red", err=True)
|
2016-11-12 00:28:49 +02:00
|
|
|
return int(str(e)) if str(e).isdigit() else 1
|
2015-07-30 18:17:57 +03:00
|
|
|
return 0
|
2014-05-18 23:38:59 +03:00
|
|
|
|
|
|
|
|
2017-04-28 01:38:25 +03:00
|
|
|
def debug_gdb_main():
|
|
|
|
sys.argv = [sys.argv[0], "debug", "--interface", "gdb"] + sys.argv[1:]
|
|
|
|
return main()
|
|
|
|
|
|
|
|
|
2014-05-18 23:38:59 +03:00
|
|
|
if __name__ == "__main__":
|
2017-04-28 01:38:25 +03:00
|
|
|
sys.exit(main())
|