1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
Adapted from commit 7bc2931
- we are already changing the click dependency by sed
From 7bc29315ab0ace6a6272966c4337e0eae56c57e3 Mon Sep 17 00:00:00 2001
From: Ivan Kravets <me@ikravets.com>
Date: Thu, 11 Jun 2026 14:18:09 +0300
Subject: [PATCH] Add support for the latest Click
--- a/platformio/compat.py
+++ b/platformio/compat.py
@@ -128,84 +128,3 @@ def is_proxy_set(socks=False):
continue
return True
return False
-
-
-def click_launch(url, wait=False, locate=False) -> int:
- return _click_open_url(url, wait=wait, locate=locate)
-
-
-def _click_open_url( # pylint: disable=too-many-branches, too-many-return-statements, consider-using-with, import-outside-toplevel, unspecified-encoding
- url, wait=False, locate=False
-):
- """
- Issue https://github.com/pallets/click/issues/2868
- Keep in sync with https://github.com/pallets/click/blob/main/src/click/_termui_impl.py
- """
- import subprocess
-
- def _unquote_file(url) -> str:
- from urllib.parse import unquote
-
- if url.startswith("file://"):
- url = unquote(url[7:])
-
- return url
-
- if IS_MACOS:
- args = ["open"]
- if wait:
- args.append("-W")
- if locate:
- args.append("-R")
- args.append(_unquote_file(url))
- null = open("/dev/null", "w")
- try:
- return subprocess.Popen(args, stderr=null).wait()
- finally:
- null.close()
- elif IS_WINDOWS:
- if locate:
- url = _unquote_file(url)
- args = ["explorer", f"/select,{url}"]
- else:
- args = ["start"]
- if wait:
- args.append("/WAIT")
- args.append("")
- args.append(url)
- try:
- return subprocess.call(args, shell=True)
- except OSError:
- # Command not found
- return 127
- elif IS_CYGWIN:
- if locate:
- url = _unquote_file(url)
- args = ["cygstart", os.path.dirname(url)]
- else:
- args = ["cygstart"]
- if wait:
- args.append("-w")
- args.append(url)
- try:
- return subprocess.call(args)
- except OSError:
- # Command not found
- return 127
-
- try:
- if locate:
- url = os.path.dirname(_unquote_file(url)) or "."
- else:
- url = _unquote_file(url)
- c = subprocess.Popen(["xdg-open", url])
- if wait:
- return c.wait()
- return 0
- except OSError:
- if url.startswith(("http://", "https://")) and not locate and not wait:
- import webbrowser
-
- webbrowser.open(url)
- return 0
- return 1
--- a/platformio/home/cli.py
+++ b/platformio/home/cli.py
@@ -17,7 +17,7 @@
import click
-from platformio.compat import IS_WINDOWS, click_launch
+from platformio.compat import IS_WINDOWS
from platformio.home.run import run_server
from platformio.package.manager.core import get_core_package_dir
@@ -86,7 +86,7 @@ def cli(port, host, no_open, shutdown_timeout, session_id):
"PlatformIO Home server is already started in another process.", fg="yellow"
)
if not no_open:
- click_launch(home_url)
+ click.launch(home_url)
return
run_server(
--- a/platformio/home/rpc/handlers/os.py
+++ b/platformio/home/rpc/handlers/os.py
@@ -18,9 +18,11 @@
import shutil
from functools import cmp_to_key
+import click
+
from platformio import fs
from platformio.cache import ContentCache
-from platformio.compat import aio_to_thread, click_launch
+from platformio.compat import aio_to_thread
from platformio.device.list.util import list_logical_devices
from platformio.home.rpc.handlers.base import BaseRPCHandler
from platformio.http import HTTPSession, ensure_internet_on
@@ -82,15 +84,15 @@ async def request_content(self, uri, data=None, headers=None, cache_valid=None):
@staticmethod
def open_url(url):
- return click_launch(url)
+ return click.launch(url)
@staticmethod
def reveal_file(path):
- return click_launch(path, locate=True)
+ return click.launch(path, locate=True)
@staticmethod
def open_file(path):
- return click_launch(path)
+ return click.launch(path)
@staticmethod
def call_path_module_func(name, args, **kwargs):
|