@@ -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-
13311376def 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-
14061405def get_archive_root_path (archive_extract_path ):
14071406 """Return the path of the archive's root folder.
14081407
0 commit comments