Skip to content

Commit 8145959

Browse files
committed
Print notice to log when overwriting existing installation when in verbose mode
There are several cases where the functionality of the script relies on overwriting an installation of a platform or library, so this should not be considered cause for a warning, but this information could be useful for troubleshooting.
1 parent ac2444d commit 8145959

File tree

2 files changed

+153
-142
lines changed

2 files changed

+153
-142
lines changed

compilesketches/compilesketches.py

Lines changed: 100 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def install_arduino_cli(self):
206206
arduino_cli_archive_download_url_prefix = "https://downloads.arduino.cc/arduino-cli/"
207207
arduino_cli_archive_file_name = "arduino-cli_" + self.cli_version + "_Linux_64bit.tar.gz"
208208

209-
install_from_download(
209+
self.install_from_download(
210210
url=arduino_cli_archive_download_url_prefix + arduino_cli_archive_file_name,
211211
# The Arduino CLI has no root folder, so just install the arduino-cli executable from the archive root
212212
source_path="arduino-cli",
@@ -224,6 +224,51 @@ def verbose_print(self, *print_arguments):
224224
if self.verbose:
225225
print(*print_arguments)
226226

227+
def install_from_download(self, url, source_path, destination_parent_path, destination_name=None, force=False):
228+
"""Download an archive, extract, and install.
229+
230+
Keyword arguments:
231+
url -- URL to download the archive from
232+
source_path -- path relative to the root folder of the archive to install.
233+
destination_parent_path -- path under which to install
234+
destination_name -- folder name to use for the installation. Set to None to take the name from source_path.
235+
(default None)
236+
force -- replace existing destination folder if present. (default False)
237+
"""
238+
destination_parent_path = pathlib.Path(destination_parent_path)
239+
240+
# Create temporary folder for the download
241+
with tempfile.TemporaryDirectory("-compilesketches-download_folder") as download_folder:
242+
download_file_path = pathlib.PurePath(download_folder, url.rsplit(sep="/", maxsplit=1)[1])
243+
244+
# https://stackoverflow.com/a/38358646
245+
with open(file=str(download_file_path), mode="wb") as out_file:
246+
with contextlib.closing(thing=urllib.request.urlopen(url=url)) as file_pointer:
247+
block_size = 1024 * 8
248+
while True:
249+
block = file_pointer.read(block_size)
250+
if not block:
251+
break
252+
out_file.write(block)
253+
254+
# Create temporary folder for the extraction
255+
with tempfile.TemporaryDirectory("-compilesketches-extract_folder") as extract_folder:
256+
# Extract archive
257+
shutil.unpack_archive(filename=str(download_file_path), extract_dir=extract_folder)
258+
259+
archive_root_path = get_archive_root_path(extract_folder)
260+
261+
absolute_source_path = pathlib.Path(archive_root_path, source_path).resolve()
262+
263+
if not absolute_source_path.exists():
264+
print("::error::Archive source path:", source_path, "not found")
265+
sys.exit(1)
266+
267+
self.install_from_path(source_path=absolute_source_path,
268+
destination_parent_path=destination_parent_path,
269+
destination_name=destination_name,
270+
force=force)
271+
227272
def install_platforms(self):
228273
"""Install Arduino boards platforms."""
229274
platform_list = self.Dependencies()
@@ -424,10 +469,10 @@ def install_platforms_from_path(self, platform_list):
424469
platform_installation_path = self.get_platform_installation_path(platform=platform)
425470

426471
# Install the platform
427-
install_from_path(source_path=source_path,
428-
destination_parent_path=platform_installation_path.path.parent,
429-
destination_name=platform_installation_path.path.name,
430-
force=platform_installation_path.is_overwrite)
472+
self.install_from_path(source_path=source_path,
473+
destination_parent_path=platform_installation_path.path.parent,
474+
destination_name=platform_installation_path.path.name,
475+
force=platform_installation_path.is_overwrite)
431476

432477
def get_platform_installation_path(self, platform):
433478
"""Determines the correct installation path for the given platform and returns an object with the attributes:
@@ -474,6 +519,38 @@ def __init__(self):
474519

475520
return platform_installation_path
476521

522+
def install_from_path(self, source_path, destination_parent_path, destination_name=None, force=False):
523+
"""Copy the source path to the destination path.
524+
525+
Keyword arguments:
526+
source_path -- path to install
527+
destination_parent_path -- path under which to install
528+
destination_name -- folder or filename name to use for the installation. Set to None to take the name from
529+
source_path. (default None)
530+
force -- replace existing destination if present. (default False)
531+
"""
532+
if destination_name is None:
533+
destination_name = source_path.name
534+
535+
destination_path = destination_parent_path.joinpath(destination_name)
536+
537+
if destination_path.exists():
538+
if force:
539+
# Clear existing folder
540+
self.verbose_print("Overwriting installation at:", destination_path)
541+
shutil.rmtree(path=destination_path)
542+
else:
543+
print("::error::Installation already exists:", destination_path)
544+
sys.exit(1)
545+
546+
# Create the parent path if it doesn't already exist
547+
destination_parent_path.mkdir(parents=True, exist_ok=True)
548+
549+
if source_path.is_dir():
550+
shutil.copytree(src=source_path, dst=destination_path)
551+
else:
552+
shutil.copy(src=source_path, dst=destination_path)
553+
477554
def install_platforms_from_repository(self, platform_list):
478555
"""Install libraries by cloning Git repositories
479556
@@ -538,10 +615,10 @@ def install_from_repository(self,
538615
with tempfile.TemporaryDirectory() as clone_folder:
539616
self.clone_repository(url=url, git_ref=git_ref, destination_path=clone_folder)
540617
# Install to the final location
541-
install_from_path(source_path=pathlib.Path(clone_folder, source_path),
542-
destination_parent_path=destination_parent_path,
543-
destination_name=destination_name,
544-
force=force)
618+
self.install_from_path(source_path=pathlib.Path(clone_folder, source_path),
619+
destination_parent_path=destination_parent_path,
620+
destination_name=destination_name,
621+
force=force)
545622

546623
def clone_repository(self, url, git_ref, destination_path):
547624
"""Clone a Git repository to a specified location and check out the specified ref
@@ -585,11 +662,11 @@ def install_platforms_from_download(self, platform_list):
585662

586663
destination_path = self.get_platform_installation_path(platform=platform)
587664

588-
install_from_download(url=platform[self.dependency_source_url_key],
589-
source_path=source_path,
590-
destination_parent_path=destination_path.path.parent,
591-
destination_name=destination_path.path.name,
592-
force=destination_path.is_overwrite)
665+
self.install_from_download(url=platform[self.dependency_source_url_key],
666+
source_path=source_path,
667+
destination_parent_path=destination_path.path.parent,
668+
destination_name=destination_path.path.name,
669+
force=destination_path.is_overwrite)
593670

594671
def install_libraries(self):
595672
"""Install Arduino libraries."""
@@ -661,10 +738,10 @@ def install_libraries_from_path(self, library_list):
661738
# Use the existing folder name
662739
destination_name = None
663740

664-
install_from_path(source_path=source_path,
665-
destination_parent_path=self.libraries_path,
666-
destination_name=destination_name,
667-
force=True)
741+
self.install_from_path(source_path=source_path,
742+
destination_parent_path=self.libraries_path,
743+
destination_name=destination_name,
744+
force=True)
668745

669746
def install_libraries_from_repository(self, library_list):
670747
"""Install libraries by cloning Git repositories
@@ -715,11 +792,11 @@ def install_libraries_from_download(self, library_list):
715792
else:
716793
destination_name = None
717794

718-
install_from_download(url=library[self.dependency_source_url_key],
719-
source_path=source_path,
720-
destination_parent_path=self.libraries_path,
721-
destination_name=destination_name,
722-
force=True)
795+
self.install_from_download(url=library[self.dependency_source_url_key],
796+
source_path=source_path,
797+
destination_parent_path=self.libraries_path,
798+
destination_name=destination_name,
799+
force=True)
723800

724801
def find_sketches(self):
725802
"""Return a list of all sketches under the paths specified in the sketch paths list recursively."""
@@ -1296,38 +1373,6 @@ def __init__(self):
12961373
return input_list
12971374

12981375

1299-
def install_from_path(source_path, destination_parent_path, destination_name=None, force=False):
1300-
"""Copy the source path to the destination path.
1301-
1302-
Keyword arguments:
1303-
source_path -- path to install
1304-
destination_parent_path -- path under which to install
1305-
destination_name -- folder or filename name to use for the installation. Set to None to take the name from
1306-
source_path. (default None)
1307-
force -- replace existing destination if present. (default False)
1308-
"""
1309-
if destination_name is None:
1310-
destination_name = source_path.name
1311-
1312-
destination_path = destination_parent_path.joinpath(destination_name)
1313-
1314-
if destination_path.exists():
1315-
if force:
1316-
# Clear existing folder
1317-
shutil.rmtree(path=destination_path)
1318-
else:
1319-
print("::error::Installation already exists:", destination_path)
1320-
sys.exit(1)
1321-
1322-
# Create the parent path if it doesn't already exist
1323-
destination_parent_path.mkdir(parents=True, exist_ok=True)
1324-
1325-
if source_path.is_dir():
1326-
shutil.copytree(src=source_path, dst=destination_path)
1327-
else:
1328-
shutil.copy(src=source_path, dst=destination_path)
1329-
1330-
13311376
def path_is_sketch(path):
13321377
"""Return whether the specified path is an Arduino sketch.
13331378
@@ -1357,52 +1402,6 @@ def list_to_string(list_input):
13571402
return " ".join([str(item) for item in list_input])
13581403

13591404

1360-
def install_from_download(url, source_path, destination_parent_path, destination_name=None, force=False):
1361-
"""Download an archive, extract, and install.
1362-
1363-
Keyword arguments:
1364-
url -- URL to download the archive from
1365-
source_path -- path relative to the root folder of the archive to install.
1366-
destination_parent_path -- path under which to install
1367-
destination_name -- folder name to use for the installation. Set to None to take the name from source_path.
1368-
(default None)
1369-
force -- replace existing destination folder if present. (default False)
1370-
"""
1371-
destination_parent_path = pathlib.Path(destination_parent_path)
1372-
1373-
# Create temporary folder for the download
1374-
with tempfile.TemporaryDirectory("-compilesketches-download_folder") as download_folder:
1375-
download_file_path = pathlib.PurePath(download_folder, url.rsplit(sep="/", maxsplit=1)[1])
1376-
1377-
# https://stackoverflow.com/a/38358646
1378-
with open(file=str(download_file_path), mode="wb") as out_file:
1379-
with contextlib.closing(thing=urllib.request.urlopen(url=url)) as file_pointer:
1380-
block_size = 1024 * 8
1381-
while True:
1382-
block = file_pointer.read(block_size)
1383-
if not block:
1384-
break
1385-
out_file.write(block)
1386-
1387-
# Create temporary folder for the extraction
1388-
with tempfile.TemporaryDirectory("-compilesketches-extract_folder") as extract_folder:
1389-
# Extract archive
1390-
shutil.unpack_archive(filename=str(download_file_path), extract_dir=extract_folder)
1391-
1392-
archive_root_path = get_archive_root_path(extract_folder)
1393-
1394-
absolute_source_path = pathlib.Path(archive_root_path, source_path).resolve()
1395-
1396-
if not absolute_source_path.exists():
1397-
print("::error::Archive source path:", source_path, "not found")
1398-
sys.exit(1)
1399-
1400-
install_from_path(source_path=absolute_source_path,
1401-
destination_parent_path=destination_parent_path,
1402-
destination_name=destination_name,
1403-
force=force)
1404-
1405-
14061405
def get_archive_root_path(archive_extract_path):
14071406
"""Return the path of the archive's root folder.
14081407

0 commit comments

Comments
 (0)