ScriptCollection 3.4.0__py3-none-any.whl → 3.4.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -282,10 +282,12 @@ def BuildCodeUnit() -> int:
282
282
  parser = argparse.ArgumentParser()
283
283
  parser.add_argument('--codeunitfolder', required=False, default=".")
284
284
  parser.add_argument('--verbosity', required=False, default=1)
285
- parser.add_argument('--buildenvironment', required=False, default="QualityCheck")
285
+ parser.add_argument('--targetenvironment', required=False, default="Development")
286
286
  parser.add_argument('--additionalargumentsfile', required=False, default=None)
287
+ parser.add_argument('--assume_dependent_codeunits_are_already_built', type=GeneralUtilities.string_to_boolean, const=True, default=False, nargs='?',)
287
288
  args = parser.parse_args()
288
- TasksForCommonProjectStructure().build_codeunit(args.codeunitfolder, int(args.verbosity), args.buildenvironment, args.additionalargumentsfile)
289
+ TasksForCommonProjectStructure().build_codeunit(args.codeunitfolder, int(args.verbosity), args.targetenvironment, args.additionalargumentsfile,
290
+ False, None, args.assume_dependent_codeunits_are_already_built)
289
291
  return 0
290
292
 
291
293
 
@@ -293,10 +295,10 @@ def BuildCodeUnits() -> int:
293
295
  parser = argparse.ArgumentParser()
294
296
  parser.add_argument('--repositoryfolder', required=False, default=".")
295
297
  parser.add_argument('--verbosity', required=False, default=1)
296
- parser.add_argument('--buildenvironment', required=False, default="QualityCheck")
298
+ parser.add_argument('--targetenvironment', required=False, default="Development")
297
299
  parser.add_argument('--additionalargumentsfile', required=False, default=None)
298
300
  args = parser.parse_args()
299
- TasksForCommonProjectStructure().build_codeunits(args.repositoryfolder, int(args.verbosity), args.buildenvironment, args.additionalargumentsfile)
301
+ TasksForCommonProjectStructure().build_codeunits(args.repositoryfolder, int(args.verbosity), args.targetenvironment, args.additionalargumentsfile)
300
302
  return 0
301
303
 
302
304
 
@@ -29,7 +29,7 @@ from .ProgramRunnerPopen import ProgramRunnerPopen
29
29
  from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
30
30
 
31
31
 
32
- version = "3.4.0"
32
+ version = "3.4.2"
33
33
  __version__ = version
34
34
 
35
35
 
@@ -1556,7 +1556,7 @@ class ScriptCollectionCore:
1556
1556
  self.run_program("openssl", f'genrsa -out {domain}.key {rsa_key_length}', folder)
1557
1557
  self.run_program("openssl", f'req -new -subj /C={subj_c}/ST={subj_st}/L={subj_l}/O={subj_o}/CN={domain}/OU={subj_ou} -x509 ' +
1558
1558
  f'-key {domain}.key -out {domain}.unsigned.crt -days {days_until_expire}', folder)
1559
- self.run_program("openssl", f'pkcs12 -export -out {domain}.pfx -password pass:{password} -inkey {domain}.key -in {domain}.unsigned.crt', folder)
1559
+ self.run_program("openssl", f'pkcs12 -export -out {domain}.selfsigned.pfx -password pass:{password} -inkey {domain}.key -in {domain}.unsigned.crt', folder)
1560
1560
  GeneralUtilities.write_text_to_file(os.path.join(folder, f"{domain}.password"), password)
1561
1561
  GeneralUtilities.write_text_to_file(os.path.join(folder, f"{domain}.san.conf"), f"""[ req ]
1562
1562
  default_bits = {rsa_key_length}
@@ -1591,8 +1591,11 @@ DNS = {domain}
1591
1591
  if days_until_expire is None:
1592
1592
  days_until_expire = 397
1593
1593
  ca = os.path.join(ca_folder, ca_name)
1594
- self.run_program("openssl", f'x509 -req -in {domain}.csr -CA {ca}.crt -CAkey {ca}.key -CAserial {ca}.srl ' +
1594
+ password_file = os.path.join(folder, f"{domain}.password")
1595
+ password = GeneralUtilities.read_text_from_file(password_file)
1596
+ self.run_program("openssl", f'x509 -req -in {domain}.csr -CA {ca}.crt -CAkey {ca}.key -CAcreateserial -CAserial {ca}.srl ' +
1595
1597
  f'-out {domain}.crt -days {days_until_expire} -sha256 -extensions v3_req -extfile {domain}.san.conf', folder)
1598
+ self.run_program("openssl", f'pkcs12 -export -out {domain}.pfx -inkey {domain}.key -in {domain}.crt -password pass:{password}', folder)
1596
1599
 
1597
1600
  @GeneralUtilities.check_arguments
1598
1601
  def update_dependencies_of_python_in_requirementstxt_file(self, file: str, verbosity: int):
@@ -470,7 +470,7 @@ class TasksForCommonProjectStructure:
470
470
  <Prefer32Bit>false<\\/Prefer32Bit>
471
471
  <NoWarn>([^<]+)<\\/NoWarn>
472
472
  <WarningsAsErrors>([^<]+)<\\/WarningsAsErrors>
473
- <ErrorLog>\\.\\.\\\\Other\\\\Resources\\\\{codeunit_name_regex}\\.sarif<\\/ErrorLog>
473
+ <ErrorLog>\\.\\.\\\\Other\\\\Resources\\\\CodeAnalysisResult\\\\{codeunit_name_regex}\\.sarif<\\/ErrorLog>
474
474
  <OutputType>([^<]+)<\\/OutputType>
475
475
  <DocumentationFile>\\.\\.\\\\Other\\\\Artifacts\\\\MetaInformation\\\\{codeunit_name_regex}\\.xml<\\/DocumentationFile>(\\n|.)*
476
476
  <\\/PropertyGroup>
@@ -531,7 +531,7 @@ class TasksForCommonProjectStructure:
531
531
  <Prefer32Bit>false<\\/Prefer32Bit>
532
532
  <NoWarn>([^<]+)<\\/NoWarn>
533
533
  <WarningsAsErrors>([^<]+)<\\/WarningsAsErrors>
534
- <ErrorLog>\\.\\.\\\\Other\\\\Resources\\\\{codeunit_name_regex}Tests\\.sarif<\\/ErrorLog>
534
+ <ErrorLog>\\.\\.\\\\Other\\\\Resources\\\\CodeAnalysisResult\\\\{codeunit_name_regex}Tests\\.sarif<\\/ErrorLog>
535
535
  <OutputType>Library<\\/OutputType>(\\n|.)*
536
536
  <\\/PropertyGroup>
537
537
  <PropertyGroup Condition=\\\"'\\$\\(Configuration\\)'=='Development'\\\">
@@ -577,6 +577,8 @@ class TasksForCommonProjectStructure:
577
577
  csproj_file_folder = os.path.dirname(csproj_file)
578
578
  csproj_file_name = os.path.basename(csproj_file)
579
579
  csproj_file_name_without_extension = csproj_file_name.split(".")[0]
580
+ sarif_folder = os.path.join(codeunit_folder, "Other", "Resources", "CodeAnalysisResult")
581
+ GeneralUtilities.ensure_directory_exists(sarif_folder)
580
582
  for runtime in runtimes:
581
583
  outputfolder = originaloutputfolder+runtime
582
584
  self.__sc.run_program("dotnet", "clean", csproj_file_folder, verbosity=verbosity)
@@ -594,7 +596,7 @@ class TasksForCommonProjectStructure:
594
596
  self.__sc.dotnet_sign_file(os.path.join(outputfolder, file), keyfile, verbosity)
595
597
 
596
598
  sarif_filename = f"{csproj_file_name_without_extension}.sarif"
597
- sarif_source_file = os.path.join(codeunit_folder, "Other", "Resources", sarif_filename)
599
+ sarif_source_file = os.path.join(sarif_folder, sarif_filename)
598
600
  if os.path.exists(sarif_source_file):
599
601
  sarif_folder = os.path.join(codeunit_folder, "Other", "Artifacts", "CodeAnalysisResult")
600
602
  GeneralUtilities.ensure_directory_exists(sarif_folder)
@@ -1006,11 +1008,16 @@ class TasksForCommonProjectStructure:
1006
1008
  raise ValueError(f"Repository '{repository_folder}' has uncommitted changes.")
1007
1009
 
1008
1010
  @GeneralUtilities.check_arguments
1009
- def generate_certificate_for_nonproductive_purposes(self, codeunit_folder: str, domain: str,
1010
- subj_c: str, subj_st: str, subj_l: str, subj_o: str, subj_ou: str,
1011
- resource_name: str = "NonProductiveCertificate"):
1012
- target_folder = os.path.join(codeunit_folder, "Other", "Resources", resource_name)
1013
- certificate_file = os.path.join(target_folder, f"{domain}.unsigned.crt")
1011
+ def generate_certificate_for_nonproductive_purposes(self, codeunit_folder: str,
1012
+ resource_name: str = "DevelopmentCertificate"):
1013
+ resources_folder = os.path.join(codeunit_folder, "Other", "Resources")
1014
+ certificate_folder = os.path.join(resources_folder, resource_name)
1015
+ dev_ca_name = "DevelopmentCertificateAuthority"
1016
+ ca_folder = os.path.join(resources_folder, dev_ca_name)
1017
+ codeunit_name = os.path.basename(codeunit_folder)
1018
+ domain = f"{codeunit_name.lower()}.test.local"
1019
+ certificate_file = os.path.join(certificate_folder, f"{domain}.crt")
1020
+ unsignedcertificate_file = os.path.join(certificate_folder, f"{domain}.unsigned.crt")
1014
1021
  certificate_exists = os.path.exists(certificate_file)
1015
1022
  if certificate_exists:
1016
1023
  certificate_expired = GeneralUtilities.certificate_is_expired(certificate_file)
@@ -1018,10 +1025,16 @@ class TasksForCommonProjectStructure:
1018
1025
  else:
1019
1026
  generate_new_certificate = True
1020
1027
  if generate_new_certificate:
1021
- GeneralUtilities.ensure_directory_does_not_exist(target_folder)
1022
- GeneralUtilities.ensure_directory_exists(target_folder)
1023
- GeneralUtilities.write_message_to_stdout("Generate TLS-certificate for non-productive purposes.")
1024
- self.__sc.generate_certificate(target_folder, domain, subj_c, subj_st, subj_l, subj_o, subj_ou)
1028
+ GeneralUtilities.ensure_directory_does_not_exist(certificate_folder)
1029
+ GeneralUtilities.ensure_directory_exists(certificate_folder)
1030
+ GeneralUtilities.ensure_directory_does_not_exist(ca_folder)
1031
+ GeneralUtilities.ensure_directory_exists(ca_folder)
1032
+ GeneralUtilities.write_message_to_stdout("Generate TLS-certificate for development-purposes.")
1033
+ self.__sc.generate_certificate_authority(ca_folder, dev_ca_name, "DE", "SubjST", "SubjL", "SubjO", "SubjOU")
1034
+ self.__sc.generate_certificate(certificate_folder, domain, "DE", "SubjST", "SubjL", "SubjO", "SubjOU")
1035
+ self.__sc.generate_certificate_sign_request(certificate_folder, domain, "DE", "SubjST", "SubjL", "SubjO", "SubjOU")
1036
+ self.__sc.sign_certificate(certificate_folder, ca_folder, dev_ca_name, domain)
1037
+ GeneralUtilities.ensure_file_does_not_exist(unsignedcertificate_file)
1025
1038
 
1026
1039
  @GeneralUtilities.check_arguments
1027
1040
  def get_codeunits(self, repository_folder: str) -> list[str]:
@@ -1378,16 +1391,13 @@ class TasksForCommonProjectStructure:
1378
1391
  self.__sc.replace_version_in_nuspec_file(nuspec_file, codeunit_version)
1379
1392
 
1380
1393
  @GeneralUtilities.check_arguments
1381
- def standardized_tasks_build_for_node_project(self, build_script_file: str, build_environment_target_type: str,
1382
- verbosity: int, commandline_arguments: list[str]):
1383
- # TODO use unused parameter
1394
+ def standardized_tasks_build_for_angular_codeunit(self, build_script_file: str, build_environment_target_type: str,
1395
+ verbosity: int, commandline_arguments: list[str]):
1384
1396
  self.copy_source_files_to_output_directory(build_script_file)
1385
- sc = ScriptCollectionCore()
1386
1397
  verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
1387
- sc.program_runner = ProgramRunnerEpew()
1388
1398
  build_script_folder = os.path.dirname(build_script_file)
1389
1399
  codeunit_folder = GeneralUtilities.resolve_relative_path("../..", build_script_folder)
1390
- sc.run_program("npm", "run build", codeunit_folder, verbosity=verbosity)
1400
+ self.run_with_epew("ng", f"build --configuration {build_environment_target_type}", codeunit_folder, verbosity=verbosity)
1391
1401
  self.standardized_tasks_build_bom_for_node_project(codeunit_folder, verbosity, commandline_arguments)
1392
1402
 
1393
1403
  @GeneralUtilities.check_arguments
@@ -1396,40 +1406,39 @@ class TasksForCommonProjectStructure:
1396
1406
  # TODO
1397
1407
 
1398
1408
  @GeneralUtilities.check_arguments
1399
- def standardized_tasks_linting_for_node_project(self, linting_script_file: str, verbosity: int,
1400
- target_environmenttype: str, commandline_arguments: list[str]):
1401
- # TODO use unused parameter
1402
- sc = ScriptCollectionCore()
1409
+ def standardized_tasks_linting_for_angular_codeunit(self, linting_script_file: str, verbosity: int,
1410
+ build_environment_target_type: str, commandline_arguments: list[str]):
1403
1411
  verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
1404
- sc.program_runner = ProgramRunnerEpew()
1405
1412
  build_script_folder = os.path.dirname(linting_script_file)
1406
1413
  codeunit_folder = GeneralUtilities.resolve_relative_path("../..", build_script_folder)
1407
- sc.run_program("npm", "run lint", codeunit_folder, verbosity=verbosity)
1414
+ self.run_with_epew("ng", "lint", codeunit_folder, verbosity=verbosity)
1408
1415
  # TODO check if there are errors in sarif-file
1409
1416
 
1410
1417
  @GeneralUtilities.check_arguments
1411
- def standardized_tasks_run_testcases_for_node_project(self, runtestcases_script_file: str,
1412
- targetenvironmenttype: str, generate_badges: bool, verbosity: int,
1413
- commandline_arguments: list[str]):
1414
- # TODO use targetenvironmenttype etc.
1415
- sc = ScriptCollectionCore()
1418
+ def standardized_tasks_run_testcases_for_angular_codeunit(self, runtestcases_script_file: str,
1419
+ build_environment_target_type: str, generate_badges: bool, verbosity: int,
1420
+ commandline_arguments: list[str]):
1416
1421
  codeunit_name: str = os.path.basename(str(Path(os.path.dirname(runtestcases_script_file)).parent.parent.absolute()))
1417
1422
  verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
1418
- sc.program_runner = ProgramRunnerEpew()
1419
1423
  codeunit_folder = GeneralUtilities.resolve_relative_path("../..", os.path.dirname(runtestcases_script_file))
1420
- sc.run_program("npm", "run test", codeunit_folder, verbosity=verbosity)
1424
+ self.run_with_epew(
1425
+ "ng", "test --watch=false --browsers ChromeHeadless --code-coverage", codeunit_folder, verbosity=verbosity)
1421
1426
  coverage_folder = os.path.join(codeunit_folder, "Other", "Artifacts", "TestCoverage")
1422
1427
  target_file = os.path.join(coverage_folder, "TestCoverage.xml")
1423
1428
  GeneralUtilities.ensure_file_does_not_exist(target_file)
1424
1429
  os.rename(os.path.join(coverage_folder, "cobertura-coverage.xml"), target_file)
1425
1430
  repository_folder = GeneralUtilities.resolve_relative_path("..", codeunit_folder)
1426
- self.run_testcases_common_post_task(repository_folder, codeunit_name, verbosity, generate_badges, targetenvironmenttype, commandline_arguments)
1431
+ self.run_testcases_common_post_task(repository_folder, codeunit_name, verbosity, generate_badges, build_environment_target_type, commandline_arguments)
1427
1432
 
1428
1433
  @GeneralUtilities.check_arguments
1429
1434
  def do_npm_install(self, package_json_folder: str, verbosity: int):
1430
- sc = ScriptCollectionCore()
1435
+ self.run_with_epew("npm", "install", package_json_folder, verbosity=verbosity)
1436
+
1437
+ @GeneralUtilities.check_arguments
1438
+ def run_with_epew(self, program: str, argument: str, working_directory: str, verbosity: int):
1439
+ sc: ScriptCollectionCore = ScriptCollectionCore()
1431
1440
  sc.program_runner = ProgramRunnerEpew()
1432
- sc.run_program("npm", "install", package_json_folder, verbosity=verbosity)
1441
+ sc.run_program(program, argument, working_directory, verbosity=verbosity)
1433
1442
 
1434
1443
  @GeneralUtilities.check_arguments
1435
1444
  def set_default_constants(self, codeunit_folder: str):
@@ -1510,22 +1519,35 @@ class TasksForCommonProjectStructure:
1510
1519
  raise ValueError("Too many results found.")
1511
1520
 
1512
1521
  @GeneralUtilities.check_arguments
1513
- def set_constants_for_certificate_public_information(self, codeunit_folder: str, domain: str, source_constant_name: str = "NonProductiveCertificate"):
1522
+ def set_constants_for_certificate_public_information(self, codeunit_folder: str, source_constant_name: str = "DevelopmentCertificate"):
1514
1523
  """Expects a certificate-resource and generates a constant for its public information"""
1515
- certificate_file = os.path.join(codeunit_folder, "Other", "Resources", source_constant_name, f"{domain}.unsigned.crt")
1524
+ codeunit_name = os.path.basename(codeunit_folder)
1525
+ domain = f"{codeunit_name}.test.local"
1526
+ certificate_file = os.path.join(codeunit_folder, "Other", "Resources", source_constant_name, f"{domain}.crt")
1516
1527
  with open(certificate_file, encoding="utf-8") as text_wrapper:
1517
1528
  certificate = crypto.load_certificate(crypto.FILETYPE_PEM, text_wrapper.read())
1518
1529
  certificate_publickey = crypto.dump_publickey(crypto.FILETYPE_PEM, certificate.get_pubkey()).decode("utf-8")
1519
1530
  self.set_constant(codeunit_folder, source_constant_name+"PublicKey", certificate_publickey)
1520
1531
 
1521
1532
  @GeneralUtilities.check_arguments
1522
- def set_constants_for_certificate_private_information(self, codeunit_folder: str, certificate_resource_name: str = "NonProductiveCertificate"):
1533
+ def set_constants_for_certificate_private_information(self, codeunit_folder: str, certificate_resource_name: str = "DevelopmentCertificate", domain: str = None):
1523
1534
  """Expects a certificate-resource and generates a constant for its sensitive information in hex-format"""
1524
- self.__generate_constant_from_resource(codeunit_folder, certificate_resource_name, "password", "Password")
1525
- self.__generate_constant_from_resource(codeunit_folder, certificate_resource_name, "pfx", "PFX")
1535
+ if domain is None:
1536
+ codeunit_name = os.path.basename(codeunit_folder)
1537
+ domain=codeunit_name
1538
+ self.generate_constant_from_resource_by_filename(codeunit_folder, certificate_resource_name, f"{domain}.test.local.pfx", "PFX")
1539
+ self.generate_constant_from_resource_by_filename(codeunit_folder, certificate_resource_name, f"{domain}.test.local.password", "Password")
1526
1540
 
1527
1541
  @GeneralUtilities.check_arguments
1528
- def __generate_constant_from_resource(self, codeunit_folder: str, resource_name: str, extension: str, constant_name: str):
1542
+ def generate_constant_from_resource_by_filename(self, codeunit_folder: str, resource_name: str, filename: str, constant_name: str):
1543
+ certificate_resource_folder = GeneralUtilities.resolve_relative_path(f"Other/Resources/{resource_name}", codeunit_folder)
1544
+ resource_file = os.path.join(certificate_resource_folder, filename)
1545
+ resource_file_content = GeneralUtilities.read_binary_from_file(resource_file)
1546
+ resource_file_as_hex = resource_file_content.hex()
1547
+ self.set_constant(codeunit_folder, f"{resource_name}{constant_name}Hex", resource_file_as_hex)
1548
+
1549
+ @GeneralUtilities.check_arguments
1550
+ def generate_constant_from_resource_by_extension(self, codeunit_folder: str, resource_name: str, extension: str, constant_name: str):
1529
1551
  certificate_resource_folder = GeneralUtilities.resolve_relative_path(f"Other/Resources/{resource_name}", codeunit_folder)
1530
1552
  resource_file = self.__sc.find_file_by_extension(certificate_resource_folder, extension)
1531
1553
  resource_file_content = GeneralUtilities.read_binary_from_file(resource_file)
@@ -1584,9 +1606,10 @@ class TasksForCommonProjectStructure:
1584
1606
 
1585
1607
  @GeneralUtilities.check_arguments
1586
1608
  def copy_artifacts_from_dependent_code_units(self, repo_folder: str, codeunit_name: str) -> None:
1587
- GeneralUtilities.write_message_to_stdout(f"Get dependent artifacts for codeunit {codeunit_name}.")
1588
1609
  codeunit_file = os.path.join(repo_folder, codeunit_name, codeunit_name + ".codeunit.xml")
1589
1610
  dependent_codeunits = self.get_dependent_code_units(codeunit_file)
1611
+ if len(dependent_codeunits) > 0:
1612
+ GeneralUtilities.write_message_to_stdout(f"Get dependent artifacts for codeunit {codeunit_name}.")
1590
1613
  dependent_codeunits_folder = os.path.join(repo_folder, codeunit_name, "Other", "Resources", "DependentCodeUnits")
1591
1614
  GeneralUtilities.ensure_directory_does_not_exist(dependent_codeunits_folder)
1592
1615
  for dependent_codeunit in dependent_codeunits:
@@ -1628,6 +1651,10 @@ class TasksForCommonProjectStructure:
1628
1651
  test_csproj_file = os.path.join(codeunit_folder, f"{codeunit_name}Tests", f"{codeunit_name}Tests.csproj")
1629
1652
  self.__sc.update_dependencies_of_dotnet_project(test_csproj_file, verbosity)
1630
1653
 
1654
+ @GeneralUtilities.check_arguments
1655
+ def update_dependencies_of_typical_node_codeunit(self, update_script_file: str, verbosity: int, cmd_args: list[str]):
1656
+ pass # TODO
1657
+
1631
1658
  @GeneralUtilities.check_arguments
1632
1659
  def standardized_tasks_update_version_in_docker_examples(self, file, codeunit_version):
1633
1660
  folder_of_current_file = os.path.dirname(file)
@@ -1675,11 +1702,12 @@ class TasksForCommonProjectStructure:
1675
1702
 
1676
1703
  @GeneralUtilities.check_arguments
1677
1704
  def build_codeunit(self, codeunit_folder: str, verbosity: int = 1, target_environmenttype: str = "QualityCheck", additional_arguments_file: str = None,
1678
- is_pre_merge: bool = False, export_target_directory: str = None) -> None:
1705
+ is_pre_merge: bool = False, export_target_directory: str = None, assume_dependent_codeunits_are_already_built: bool = False) -> None:
1679
1706
  codeunit_folder = GeneralUtilities.resolve_relative_path_from_current_working_directory(codeunit_folder)
1680
1707
  codeunit_name = os.path.basename(codeunit_folder)
1681
1708
  repository_folder = os.path.dirname(codeunit_folder)
1682
- self.build_specific_codeunits(repository_folder, [codeunit_name], verbosity, target_environmenttype, additional_arguments_file, is_pre_merge, export_target_directory)
1709
+ self.build_specific_codeunits(repository_folder, [codeunit_name], verbosity, target_environmenttype, additional_arguments_file,
1710
+ is_pre_merge, export_target_directory, assume_dependent_codeunits_are_already_built)
1683
1711
 
1684
1712
  @GeneralUtilities.check_arguments
1685
1713
  def build_codeunits(self, repository_folder: str, verbosity: int = 1, target_environmenttype: str = "QualityCheck", additional_arguments_file: str = None,
@@ -1690,7 +1718,8 @@ class TasksForCommonProjectStructure:
1690
1718
 
1691
1719
  @GeneralUtilities.check_arguments
1692
1720
  def build_specific_codeunits(self, repository_folder: str, codeunits: list[str], verbosity: int = 1, target_environmenttype: str = "QualityCheck",
1693
- additional_arguments_file: str = None, is_pre_merge: bool = False, export_target_directory: str = None) -> None:
1721
+ additional_arguments_file: str = None, is_pre_merge: bool = False, export_target_directory: str = None,
1722
+ assume_dependent_codeunits_are_already_built: bool = True) -> None:
1694
1723
  repository_folder = GeneralUtilities.resolve_relative_path_from_current_working_directory(repository_folder)
1695
1724
  contains_uncommitted_changes = self.__sc.git_repository_has_uncommitted_changes(repository_folder)
1696
1725
  if is_pre_merge and contains_uncommitted_changes:
@@ -1719,7 +1748,8 @@ class TasksForCommonProjectStructure:
1719
1748
  line = "----------"
1720
1749
  for codeunit in sorted_codeunits:
1721
1750
  GeneralUtilities.write_message_to_stdout(line)
1722
- self.__build_codeunit(os.path.join(repository_folder, codeunit), verbosity, target_environmenttype, additional_arguments_file, is_pre_merge, True)
1751
+ self.__build_codeunit(os.path.join(repository_folder, codeunit), verbosity, target_environmenttype,
1752
+ additional_arguments_file, is_pre_merge, assume_dependent_codeunits_are_already_built)
1723
1753
  GeneralUtilities.write_message_to_stdout(line)
1724
1754
  if not contains_uncommitted_changes and self.__sc.git_repository_has_uncommitted_changes(repository_folder) and not is_pre_merge:
1725
1755
  message = f'Due to the build-process the repository "{repository_folder}" has new uncommitted changes.'
@@ -1797,6 +1827,33 @@ class TasksForCommonProjectStructure:
1797
1827
  else:
1798
1828
  raise ValueError("Can not download GRYLibrary.")
1799
1829
 
1830
+ @GeneralUtilities.check_arguments
1831
+ def ensure_ffmpeg_is_available(self, codeunit_folder: str) -> None:
1832
+ ffmpeg_folder = os.path.join(codeunit_folder, "Other", "Resources", "FFMPEG")
1833
+ internet_connection_is_available = GeneralUtilities.internet_connection_is_available()
1834
+ exe_file = f"{ffmpeg_folder}/ffmpeg.exe"
1835
+ exe_file_exists = os.path.isfile(exe_file)
1836
+ if internet_connection_is_available: # Load/Update
1837
+ GeneralUtilities.ensure_directory_does_not_exist(ffmpeg_folder)
1838
+ GeneralUtilities.ensure_directory_exists(ffmpeg_folder)
1839
+ ffmpeg_temp_folder = ffmpeg_folder+"Temp"
1840
+ GeneralUtilities.ensure_directory_does_not_exist(ffmpeg_temp_folder)
1841
+ GeneralUtilities.ensure_directory_exists(ffmpeg_temp_folder)
1842
+ zip_file_on_disk = os.path.join(ffmpeg_temp_folder, "ffmpeg.zip")
1843
+ original_zip_filename = "ffmpeg-master-latest-win64-gpl-shared"
1844
+ zip_link = f"https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/{original_zip_filename}.zip"
1845
+ urllib.request.urlretrieve(zip_link, zip_file_on_disk)
1846
+ shutil.unpack_archive(zip_file_on_disk, ffmpeg_temp_folder)
1847
+ bin_folder_source = os.path.join(ffmpeg_temp_folder, "ffmpeg-master-latest-win64-gpl-shared/bin")
1848
+ bin_folder_target = ffmpeg_folder
1849
+ GeneralUtilities.copy_content_of_folder(bin_folder_source, bin_folder_target)
1850
+ GeneralUtilities.ensure_directory_does_not_exist(ffmpeg_temp_folder)
1851
+ else:
1852
+ if exe_file_exists:
1853
+ GeneralUtilities.write_message_to_stdout("Warning: Can not check for updates of FFMPEG due to missing internet-connection.")
1854
+ else:
1855
+ raise ValueError("Can not download FFMPEG.")
1856
+
1800
1857
  @GeneralUtilities.check_arguments
1801
1858
  def __ensure_plant_uml_is_available(self, codeunit_folder: str) -> None:
1802
1859
  plant_uml_folder = os.path.join(codeunit_folder, "Other", "Resources", "PlantUML")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ScriptCollection
3
- Version: 3.4.0
3
+ Version: 3.4.2
4
4
  Summary: The ScriptCollection is the place for reusable scripts.
5
5
  Home-page: https://github.com/anionDev/ScriptCollection
6
6
  Author: Marius Göcke
@@ -1,14 +1,14 @@
1
- ScriptCollection/Executables.py,sha256=8uVVxyXrndRwTVxcL1rRlbyzaP6ZYvzxj41f7sy6L90,18794
1
+ ScriptCollection/Executables.py,sha256=BanfD3ls0ov3ECnsbuyzNstdYjqz_HplreQYJxrB8Ag,19068
2
2
  ScriptCollection/GeneralUtilities.py,sha256=vZDiW5lWJRCrIZVs1bTCZ-O5slQnM5dv4GcJ-RTMowY,34378
3
3
  ScriptCollection/ProgramRunnerBase.py,sha256=2kyOuoM3oFjBfLc9Q5t5RTz7Ya2CjUxFtB1rBBDmnjU,1937
4
4
  ScriptCollection/ProgramRunnerEpew.py,sha256=nIzY4dG6W-xEpkeoTbozwNZtFSIo-bU_W6t6u1AZKtE,6275
5
5
  ScriptCollection/ProgramRunnerPopen.py,sha256=HOs1QVnXiQtwXy1_xvH79bWBdd0i-2tUyyLloQBvMto,3023
6
- ScriptCollection/ScriptCollectionCore.py,sha256=6MoxE0Xrj1SKZzqCZ9bU6tUUlogYGaPkIkbsxhy2pJw,95771
7
- ScriptCollection/TasksForCommonProjectStructure.py,sha256=1VUPMfK3EWKydgUplqujzlH7ZKZgX3CgFvnVjOoc2Ds,139730
6
+ ScriptCollection/ScriptCollectionCore.py,sha256=6qa2zBQSbxkIBwMZ4heulf6dDhtrMN7gkanutNxeHhk,96083
7
+ ScriptCollection/TasksForCommonProjectStructure.py,sha256=aDhyppnfEgaiLxo4H04fZVJfAjsGisUeexCkq6LyEHo,144098
8
8
  ScriptCollection/UpdateCertificates.py,sha256=Go-JJK-YTi7aBB1phlLxypa8GHkmFHBEPB0_TT9G-bw,7918
9
9
  ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- ScriptCollection-3.4.0.dist-info/METADATA,sha256=S-qHlKVq3dAMCTvoDw4aDUHSHto1vxkyqwE2E2qQe7U,7649
11
- ScriptCollection-3.4.0.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
12
- ScriptCollection-3.4.0.dist-info/entry_points.txt,sha256=dJKdWcH41owxlKx_khj4P7DItr9lhxWP9JU2Dq8GSsQ,2088
13
- ScriptCollection-3.4.0.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
14
- ScriptCollection-3.4.0.dist-info/RECORD,,
10
+ ScriptCollection-3.4.2.dist-info/METADATA,sha256=evfc3SpJ8Vv-CaWAdN61NruiT4me5XscExweMZkxWUw,7649
11
+ ScriptCollection-3.4.2.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
12
+ ScriptCollection-3.4.2.dist-info/entry_points.txt,sha256=dJKdWcH41owxlKx_khj4P7DItr9lhxWP9JU2Dq8GSsQ,2088
13
+ ScriptCollection-3.4.2.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
14
+ ScriptCollection-3.4.2.dist-info/RECORD,,